高性能内存对象缓存Memcached原理与部署

Memcached概述

Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象,减少对数据库的访问,从而提高Web应用的响应速度。

原理

架构

Memcached采用的是一种简单的Key-Value存储系统,主要由以下几个部分组成:

  1. 客户端:负责向Memcached服务器发送存储和获取数据的请求。
  2. 服务器:负责接收客户端的请求,进行数据存储和管理。
  3. 存储管理:在服务器内存中存储数据,并通过LRU(Least Recently Used,最近最少使用)算法管理缓存数据。
  4. 网络通信:基于TCP/IP协议进行通信。

工作流程

  1. 数据存储

    • 客户端发送存储请求,包含Key和Value。
    • 服务器接收到请求后,将数据存储在内存中,并根据LRU策略管理缓存数据。
    • 服务器返回存储成功的响应。
  2. 数据获取

    • 客户端发送获取请求,包含Key。
    • 服务器接收到请求后,根据Key查找对应的Value。
    • 如果找到对应的Value,服务器返回数据;如果没有找到,返回空。
  3. 缓存失效

    • 当内存空间不足时,Memcached会根据LRU算法移除最久未使用的数据。
    • 客户端可以设置数据的过期时间,过期数据会自动失效并被移除。

部署

单memcached节点缓存系统

设置各节点的主机名

主机:192.168.10.101

root@localhost \~\]# hostnamectl set-hostname Memcache1 \[root@localhost \~\]# bash 主机:192.168.10.102 \[root@localhost \~\]# hostnamectl set-hostname Memcache2 \[root@localhost \~\]# bash 主机:192.168.10.103 \[root@localhost \~\]# hostnamectl set-hostname Memcached-API \[root@localhost \~\]# bash #### 安装 Memcached 服务器 ###### 1:安装 Libevent \[root@memcache1 \~\]# systemctl stop firewalld \[root@memcache1 \~\]# yum -y install gcc\* \[root@memcache1 \~\]# tar zxvf libevent-2.1.8-stable.tar.gz \[root@memcache1 \~\]# cd libevent-2.1.8-stable \[root@memcache1 libevent-2.1.8-stable\]# ./configure --prefix=/usr/local/libevent \[root@memcache1 libevent-2.1.8-stable\]# make \&\& make install 备注: Libevent 是一个用[C语言](https://baike.baidu.com/item/C%E8%AF%AD%E8%A8%80/105958 "C语言")[编写](https://baike.baidu.com/item/%E7%BC%96%E5%86%99/1517598 "编写")的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大;源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 \*BSD 和 Mac Os;支持多种 I/O [多路复用技术](https://baike.baidu.com/item/%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8%E6%8A%80%E6%9C%AF/5785640 "多路复用技术"), epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。 Libevent 已经被广泛的应用,作为底层的网络库;比如 memcached、 Vomit、 Nylon、 Netchat等等。 ###### 2:安装 Memcached \[root@memcache1 \~\]# tar zxvf memcached-1.5.1.tar.gz \[root@memcache1 \~\]# cd memcached-1.5.1 \[root@memcache1 memcached-1.5.1\]# ./configure \\ --prefix=/usr/local/memcached \\ --with-libevent=/usr/local/libevent \[root@memcache1 memcached-1.5.1\]# make \&\& make install 3:**设置** **Memcached** **服务脚本** \[root@memcache1 \~\]# vim /usr/local/memcached/memcached_service.sh #!/bin/bash CMD="/usr/local/memcached/bin/memcached" start(){ $CMD -d -m 128 -u root } stop(){ killall memcached; } ACTION=$1 case $ACTION in 'start') start;; 'stop') stop;; 'restart') stop sleep 2 start;; \*) echo 'Usage:{start\|stop\|restart}' esac \[root@memcache1 \~\]# yum -y install psmisc 备注: psmisc提供了killall命令 \[root@memcache1 \~\]# chmod 755 /usr/local/memcached/memcached_service.sh \[root@memcache1 \~\]# /usr/local/memcached/memcached_service.sh start \[root@memcache1 \~\]# netstat -anpt \| grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:\* LISTEN 20564/memcached tcp6 0 0 :::11211 :::\* LISTEN 20564/memcached ###### Memcached API 客户端 **注意:** **客户端需要有apache\***\*和php的环境,如果有之前做的LAMP的快照,可以使用这个快照\*\* **(如果已经有此环境,\***\*安装apache和安装php可以省略)\*\* **设置好阿里yum\***\*源\*\* yum -y install httpd mariadb mariadb-server php php-devel php-mysql systemctl start mariadb mysqladmin -u root password 'pwd123' systemctl start httpd cat \<\/var/www/html/test1.php \ EOF ###### 1:编译安装 Libmemcached \[root@memcached-api \~\]# systemctl stop firewalld \[root@memcached-api \~\]# setenforce 0 \[root@memcached-api \~\]# yum -y install gcc\* \[root@memcached-api \~\]# tar zxvf libmemcached-1.0.18.tar.gz \[root@memcached-api \~\]# cd libmemcached-1.0.18 *\*\[root@memcached-api libmemcached-1.0.18\]# ./configure \** *\*--prefix=/usr/local/libmemcached \** **--with-memcached=/usr/local/memcached** **\[root@memcached-api libmemcached-1.0.18\]# make \&\& make install** 备注: libmemcached 是一个 memcached 的库,客户端库,C 和 C++ 语言实现的客户端库,具有低内存占用率、线程安全、并提供对memcached功能的全面支持 ###### 2:编译安装 Memcached 扩展 (1)如果lamp是用源码包安装的,使用如下方法 \[root@memcached-api \~\]# **tar -xzvf memcached-2.2.0.tgz** \[root@memcached-api \~\]# **cd memcached-2.2.0/** \[root@memcached-api memcached-2.2.0\]# **/usr/local/php5/bin/phpize** **备注:** **此命令可以在\***\*memcached-2.2.0下生成memcached的配置脚本\*\* **phpize\*** \*命令需要autoconf包的支持\*\* **:\***\*yum -y install autoconf\*\* \[root@memcached-api memcached-2.2.0\]# **cp -r /usr/local/php5/include/php/ext/ ./** \[root@memcached-api memcached-2.2.0\]# *\*./configure \** *\*--enable-memcached \** *\*--with-php-config=/usr/local/php5/bin/php-config \** *\*--with-libmemcached-dir=/usr/local/libmemcached \** **--disable-memcached-sasl** \[root@memcached-api memcached-2.2.0\]# **make** \[root@memcached-api memcached-2.2.0\]# **make test** **注意:** **最后会提示发送邮件报告,可以选否(\***\*n)\*\* \[root@memcached-api memcached-2.2.0\]# **make install** (2)如果lamp是用yum安装的,使用如下方法 如果是用yum安装的lamp环境,使用如下方法安装 Memcached 扩展 \[root@memcached-api \~\]# yum -y install zlib zlib-devel \[root@memcached-api \~\]# tar -xzvf memcached-2.2.0.tgz \[root@memcached-api \~\]# cd memcached-2.2.0/ \[root@memcached-api memcached-2.2.0\]# /usr/bin/phpize \[root@memcached-api memcached-2.2.0\]# ./configure --with-php-config=/usr/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached --disable-memcached-sasl --with-zlib-dir 备注: 1. SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。简单来说SASL是一个胶合(glue)库,通过这个库把应用层与形式多样的认证系统整合在一起。这有点类似于 PAM,但是后者是认证方式,决定什么人可以访问什么服务,而SASL是认证过程,侧重于信任建立过程,这个过程可以调用PAM来建立信任关系。在这里Memcached就是上面提到的应用层,具体的认证交给SASL库,SASL会根据相应的认证机制来完成验证功能。 \[root@memcached-api memcached-2.2.0\]# make \&\& make install 备注: 如果安装的是php7的版本,会报错:php_smart_str.h: No such file or directory 3:**配置** **PHP** **添加** **Memcached** **组件** **(1)添加**Memcached \[root@memcached-api \~\]# **cd /usr/local/php5/** \[root@memcached-api php5\]# **vim php.ini** extension_dir = "/usr/local/php5/lib/php/extensions/no-debug-zts-20121212/" extension=memcached.so 备注: 如果使用的yum安装的php, \[root@memcache2 \~\]# vim /etc/php.ini 去掉extension_dir=" " 只添加extension=memcached.so \[root@memcached-api php5\]# systemctl restart httpd (2)通过 PHPinfo 查看是否已经添加 Memcached 扩展模块 使用浏览器进行访问 ![](https://i-blog.csdnimg.cn/direct/cfb8de37d9ee46daac6043ad0d23d72f.png) 4:**测试** **Memcached-API** **功能** \[root@memcached-api \~\]# **vim /usr/local/httpd/htdocs/test2.php** \addServer('192.168.10.101', 11211); $memcache-\>set('key', 'Memcache test successful!', 0, 60); result = memcache-\>get('key'); unset($memcache); echo $result; ?\> 备注: 如果是用yum安装的lamp,此文件所在的目录在/var/www/html 访问测试:[http://192.168.10.103/test2.php](http://192.168.10.103/test.php "http://192.168.10.103/test2.php") ![](https://i-blog.csdnimg.cn/direct/83a34eed6aa049d6b7ff0fcef7cd37fb.png) ##### Memcached 数据库操作与管理 \[root@memcache1 \~\]# yum -y install telnet \[root@memcache1 \~\]# telnet 127.0.0.1 11211 1:添加一条键值数据 add username 0 0 8 zhangsan STORED 备注: 表示键值名为 username, 标记位表示自定义信息为 0, 过期时间为 0(永不过期,单位为秒) 字节数为 8; zhangsan 为值,这里需要注意输入长度为8 字节,与设定值符合 2:查询键值数据 get username VALUE username 0 8 zhangsan END gets username VALUE username 0 8 2 zhangsan END 备注: get 后跟键名。如果检查最近是否更新,可以使用 gets,最后一位显示的是更新因子,每更新一次更新因子数会加一 3:更新一条键值数据 set username 0 0 4 lisi STORED get username VALUE username 0 4 everything END gets username VALUE username 0 4 4 lisi END 4:清除一条缓存数据 delete username DELETED get username END 5:检查后更新 check and set add username 0 0 8 zhangsan STORED gets username VALUE username 0 8 7 zhangsan END cas username 0 0 8 1 ##注意,因为更新因子和gets得到的不一致,这个语句的更新会失败 lodging EXISTS cas username 0 0 8 7 zhangsai STORED gets username VALUE username 0 7 8 lodging END 备注: cas命令的最后一个数字是更新因子,如果gets获取到的更新因子和cas命令提供的更新因子一致,则更新改数据,否则不会更新,会提示exists cas命令的第三个数字是要更新的数据的字节数,和接下来输入进去的字符串的字节数要一致,否则会报错 6:追加数据 append username 0 0 8 //后追加 8 字节 zhangsan STORED get username VALUE username 0 14 lodgingzhangsan END 7:清除所有缓存数据 flush_all OK 8:查看服务器统计信息 stats stats items //返回所有键值对统计信息 stats cachedump 1 0 //返回指定存储空间的键值对 stats slabs //显示各个 slab 的信息,包括 chunk 的大小、数目、使用情况等 stats sizes //输出所有 item 的大小和个数 stats reset //清空统计数据 9:退出 quit ### 案例二 ### Memcached 实现主主复制和高可用的方式 ### Memcached 主主复制架构 Memcached 的复制功能支持多个 Memcached 之间相互复制(双向复制,主备都是可读可写的),可以解决 Memcached 的容灾问题。 ###### 1:安装带有复制功能的 Memcached (此步骤在两台memcache服务器上都执行) (1)安装 Libevent \[root@memcache1 \~\]# systemctl stop firewalld \[root@memcache1 \~\]# setenforce 0 \[root@memcache1 \~\]# yum -y install gcc\* psmisc \[root@memcache1 \~\]# tar zxvf libevent-2.1.8-stable.tar.gz \[root@memcache1 \~\]# cd libevent-2.1.8-stable \[root@memcache1 libevent-2.1.8-stable\]# ./configure --prefix=/usr/local/libevent \[root@memcache1 libevent-2.1.8-stable\]# make \&\& make install (2)安装memcached-1.2.8-repcached \[root@memcache1 \~\]# tar zxvf memcached-1.2.8-repcached-2.2.tar.gz \[root@memcache1 \~\]# cd memcached-1.2.8-repcached-2.2 \[root@Memcached1 memcached-1.2.8-repcached-2.2\]# *\*./configure \** *\*--prefix=/usr/local/memcached_replication \** *\*--enable-replication \** **--with-libevent=/usr/local/libevent** \[root@memcache1 memcached-1.2.8-repcached-2.2\]# vim memcached.c #找到如下几行(在55行--60行): /\* FreeBSD 4.x doesn't have IOV_MAX exposed. \*/ #ifndef IOV_MAX #if defined(**FreeBSD** ) \|\| defined(**APPLE**) # define IOV_MAX 1024 #endif #endif #修改成如下所示:(删掉上面红色的两行) /\* FreeBSD 4.x doesn't have IOV_MAX exposed. \*/ #ifndef IOV_MAX # define IOV_MAX 1024 #endif \[root@memcache1 memcached-1.2.8-repcached-2.2\]# make \&\& make install ###### **2** :启动**Memcached** **服务** (1)在memcache1上启动 \[root@memcache1 \~\]# ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/ \[root@Memcached1 \~\]# **/usr/local/memcached_replication/bin/memcached -d -u root -m 128 -x 192.168.10.102** 注意: 启动时要指向对端 -d:守护进程方式启动 -u:指定用户 -x:指定对端服务器的地址 -m:最大的内存使用单位是MB 默认是64MB (2)在memcache2上启动 \[root@memcache1 \~\]# ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/ \[root@Memcached1 \~\]# **/usr/local/memcached_replication/bin/memcached -d -u root -m 128 -x 192.168.10.101** 备注: -x 对方IP -p \ 监听的TCP端口(默认: 11211) -U \ UDP监听端口 (默认: 11211, 0 时关闭) -d 以守护进程方式运行 -u \ 运行运行 [Memcached](https://so.csdn.net/so/search?q=Memcached&spm=1001.2101.3001.7020 "Memcached")的账户 非root用户 -m \ 最大的内存使用单位是MB 默认是64MB -c \ 软连接数量默认是1024 -v 输出警告和错误信息 -vv 打印客户端的请求和返回信息 -h 打印帮助信息 -i 打印memcached和libevent的版权信息 -l \ 绑定地址 (默认:所有都允许,无论内外网或者本机更换IP,有安全隐患,若设置为127.0.0.1就只能本机访问) -P \ 将PID写入文件\,这样可以使得后边进行快速进程终止, 需要与 -d 一起使用 (3)在两台服务器上检查进程 \[root@memcache1 \~\]# netstat -antp \|grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:\* LISTEN 52646memcached tcp 0 0 192.168.10.101:11212 192.168.10.102:38298 ESTABLISHED 52646memcached tcp6 0 0 :::11211 :::\* LISTEN 52646memcached \[root@memcache2 \~\]# netstat -antp \|grep memcached tcp 0 0 0.0.0.0:11211 0.0.0.0:\* LISTEN 29976memcached tcp 0 0 192.168.10.102:38298 192.168.10.101:11212 ESTABLISHED 29976memcached tcp6 0 0 :::11211 :::\* LISTEN 29976memcached ###### 3:使用 telnet 进行简单验证复制功能 (1)在 Memcached1 上插入一条具有特点的键值 \[root@memcache1 \~\]# yum -y install telnet \[root@memcache1 \~\]# telnet 192.168.10.102 11211 set username 0 0 8 #自定义信息+永不过期+8个字节 12345678 STORED get username VALUE username 0 8 12345678 END quit (2)在 Memcached2 上进行查看刚刚插入的键值 \[root@memcache2 \~\]# yum -y install telnet \[root@memcache2 \~\]# telnet 192.168.10.102 11211 get username VALUE username 0 8 12345678 END gets username VALUE username 0 8 1 #1代表更新因子, 12345678 END cas username 0 0 8 1 #自定义信息+永不过期+8个字节+更新因子(要与gets得到的一致) zhangsan STORED (3)在 Memcached1 上查看复制的情况 \[root@localhost \~\]# telnet 192.168.10.101 11211 Trying 192.168.10.101... Connected to 192.168.10.101. Escape character is '\^\]'. get username VALUE username 0 8 zhangsan END ###### Memcached 主主复制+Keepalived 高可用架构 1:**安装配置** **keepalived**(两台主机都安装) \[root@memcache1 \~\]# yum -y install keepalived (1)配置主 keepalived \[root@memcache1 \~\]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_01 vrrp_skip_check_adv_addr #vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_script check_down { ##定义要执行的脚本 script "/etc/keepalived/memcached.sh" ##脚本路径和名称 interval 1 ##间隔1秒执行一次 } vrrp_instance VI_1 { state BACKUP ##master角色不能设置nopreempt,所以此处要设置为BACKUP interface ens33 virtual_router_id 51 priority 100 ##从主机的优先级要小于此数字 advert_int 1 nopreempt ##添加,此语句关闭了抢占功能,从主机不需要 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.100 } track_script { ##调用前面的脚本 check_down } } 备注: vrrp_strict:严格遵守VRRP协议,禁止以下状况:1.无VIP地址 2.配置了单播邻居 3.在VRRP版本2中有IPv6地址,开启动此项会自动开启iptables防火墙规则,建议关闭此项配置 \[root@memcached1 keepalived\]# vim /etc/keepalived/memcached.sh #!/bin/bash # if \[ $(ps -C memcached --no-header \| wc -l) -eq 0 \]; then systemctl stop keepalived fi \[root@memcached1 keepalived\]# chmod +x /etc/keepalived/memcached.sh (2)配置从keepalived \[root@memcache2 \~\]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { acassen@firewall.loc failover@firewall.loc sysadmin@firewall.loc } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_02 vrrp_skip_check_adv_addr #vrrp_strict vrrp_garp_interval 0 vrrp_gna_interval 0 } vrrp_script check_down { ##定义要执行的脚本 script "/etc/keepalived/memcached.sh" ##脚本路径和名称 interval 1 ##间隔1秒执行一次 } vrrp_instance VI_1 { state BACKUP interface ens33 virtual_router_id 51 priority 99 ##从主机的优先级要小于此数字 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.10.100 } track_script { ##调用前面的脚本 check_down } } \[root@memcached2 keepalived\]# vim /etc/keepalived/memcached.sh #!/bin/bash # if \[ $(ps -C memcached --no-header \| wc -l) -eq 0 \]; then systemctl stop keepalived fi \[root@memcached2 keepalived\]# chmod +x /etc/keepalived/memcached.sh 备注: vrrp_strict #严格遵守VRRP协vim议 这将禁止VIPs unicast peers (虚拟IP单播对等体),这样会使得这个VIP无法进行单播通信 2:**测试验证** (1)在两台服务器上启动keepalived \[root@Memcached1 \~\]# **systemctl start keepalived** \[root@memcached2 \~\]# **systemctl start keepalived** (2)在客户端修改缓存服务器地址 \[root@memcached-api \~\]# vim /usr/local/httpd/htdocs/test3.php \addServer('192.168.10.100', 11211); $memcache-\>set('key', 'Memcache test successful!', 0, 60); result = memcache-\>get('key'); unset($memcache); echo $result; ?\> 注意: 如果是yum安装的httpd,次此文件在/var/www/html目录下 (3)浏览器访问测试 ![](https://i-blog.csdnimg.cn/direct/b70e0a8f623748dcb25f78f5b8da9973.png) 备注: pkill memcached 检查当前主机的memceched进程和keepalived进程, 关闭memcached后,该主机的keepalived也会被脚本关闭,于是VIP就漂移到了另一台主机,待此主机修好后,把memcached和keepalived开启,由于设置了不抢占,VIP不会抢占回来,但是把第二台主机的memcached关闭后,第二台主机的keepalived也会关闭,于是VIP就漂移回了第一台主机。完成故障的转移。

相关推荐
Java初学者小白36 分钟前
秋招Day15 - Redis - 缓存设计
java·数据库·redis·缓存
绅士玖1 小时前
前端数据存储总结:Cookie、localStorage、sessionStorage与IndexedDB的使用与区别
前端·javascript·数据库
倔强的石头1062 小时前
飞算JavaAI:重构软件开发范式的智能引擎
java·数据库·重构
Q_970956392 小时前
java+vue+SpringBoo足球社区管理系统(程序+数据库+报告+部署教程+答辩指导)
java·开发语言·数据库
行星0083 小时前
PostgreSQL大表创建分区实战
数据库·postgresql
isNotNullX3 小时前
什么是数据分析?常见方法全解析
大数据·数据库·数据仓库·人工智能·数据分析
唐可盐3 小时前
第六章 SQL编程系列-Gbase8a从入门到进阶
数据库·sql·gbase8a
旷世奇才李先生3 小时前
SQLite 安装使用教程
数据库·sqlite
码小跳4 小时前
软件无法连接MySql数据库
数据库·mysql
工一木子8 小时前
URL时间戳参数深度解析:缓存破坏与前端优化的前世今生
前端·缓存