Memcached 是一套开源的高性能分布式内存对象缓存系统,它将所有的数据都存储在内存中,因为内存中会统一维护一张巨大的Hash 表,所以支持任意存储类型的数据。很多网站使用emcached 提高网站的访问速度,尤其是需要频繁访问数据的大型网站。
Memcached 是典型的C/S 架构,因此需要构建Memcached 服务器端与MemcachedAPI客户端。Memcached 服务器端是用C 语言编写的,而Memcached API 客户端可用任何语言来编写(如PHP、Python、Perl 等),并通过Memcached 协议与Memcached 服务器端进行通信。
1:数据存储方式与数据过期方式
(1)数据存储方式:Slab Allocation
Slab Allocation 即按组分配内存,每次先分配一个Slab,相当于一个大小为1M的页。然后,在1M 的空间里根据数据划分大小相同的Chunk,该方法可以有效解决内存碎片问题,但也可能会使内存空间产生浪费。
(2)数据过期方式:LRU、Laxzy Expiration
LUR 是指追加的数据空间不足时,会根据LRU 的情况淘汰最近最少使用的记录。
Laxzy Expiration 即惰性过期,是指使用get 时查看记录时间,从而检查记录是否已经过期。
2:Memcached 缓存机制
缓存是常驻在内存的数据,能够快速进行读取,而Memcached 就是这样一款非常出色的缓存软件。当程序写入缓存数据请求时,Memcached 的API 接口将Key 输入路由算法模块并路由到集群中的一台服务器,之后由API 接口与服务器进行通信,完成一次分布式缓存写入。
3:Memcached 分布式
Memcached分布式部署主要依赖于Memcached的客户来端实现,多个Memcached 服务器是独立的。分布式数据如何存储是由路由算法所决定。当数据到达客户端程序库,客户端的算法就依据路由算法来决定保的Memcached 服务器。读取数据时,客户端依据使用保存数据时相同的路由算法选中和存储数据时相同的服务器来读取数据。
4:Memcached 路由算法
(1)求余数hash 算法
(2)一致性hash 算法
一、 案例环境
1:本案例环境
主机 | 操作系统 | 主机名/IP地址 | 主要软件及版本 |
服务器 | Centos7.9 | Memcache1/192.168.10.101 | libevent-2.1.8-stable.tar.gz |
服务器 | Centos7.9 | Memcache2/192.168.10.102 | libevent-2.1.8-stable.tar.gz |
客户端 | Centos7.9 | Memcached-API/192.168.10.103 | httpd-2.4.25.tar.gz |
二:案例一
单memcached节点缓存系统
1:设置各节点的主机名
主机: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
2:安装 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 已经被广泛的应用,作为底层的网络库;比如 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
3:Memcached API 客户端
设置好阿里yum源
yum -y install httpd mariadb mariadb-server phpphp-devel php-mysql
systemctl start mariadb
mysqladmin -u root password 'pwd123'
systemctl start httpd
cat <<EOF>/var/www/html/test1.php
<?php
phpinfo();
?>
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 扩展
如果是用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
[root@memcached-api memcached-2.2.0]# make && make install
3:配置PHP 添加Memcached 组件
如果使用的yum安装的php
[root@memcache2 ~]# vim /etc/php.ini
去掉extension_dir=" "
只添加extension=memcached.so
[root@memcached-api php5]# systemctl restart httpd
(2)通过PHPinfo 查看是否已经添加Memcached 扩展模块
使用浏览器进行访问
4:测试Memcached-API 功能
[root@memcached-api ~]# vim /usr/local/httpd/htdocs/test2.php
<?php
$memcache = new Memcached();
$memcache->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
4: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,最后一位显示的是更新因子,每更新一次更新因子数会加一
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
三:案例二
Memcached 实现主主复制和高可用的方式
1: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
# 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
(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
2: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
<?php
$memcache = new Memcached();
$memcache->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)浏览器访问测试
pkill memcached
检查当前主机的memceched进程和keepalived进程,
关闭memcached后,该主机的keepalived也会被脚本关闭,于是VIP就漂移到了另一台主机,待此主机修好后,把memcached和keepalived开启,由于设置了不抢占,VIP不会抢占回来,但是把第二台主机的memcached关闭后,第二台主机的keepalived也会关闭,于是VIP就漂移回了第一台主机。完成故障的转移。