MemCached
一、概述
- 定义:Memcached是一个内存中的键值对存储系统,支持任意存储类型的数据,如字符串、对象等。
- 架构:Memcached采用C/S(客户端/服务器)架构,需要安装Memcached服务端与Memcached API客户端。
- 特点:数据存储在内存中,通过维护一张巨大的Hash表来支持高效的读写操作。
二、数据存储与过期方式
- 数据存储方式:Memcached采用Slab Allocation机制来分配和管理内存。Slab是memcached分配的基本单位,每个slab对应多张Page(默认大小是1MB),每张Page会被划分为多个chunk,chunk中保存了item结构体、一对key和value。
- 数据过期方式:
- LRU(Least Recently Used):当数据空间不足时,会根据LRU算法淘汰最近最少使用的记录。
- Laxzy Expiration(惰性过期):在get操作时检查记录时间,从而确定记录是否已过期。
三、工作原理
- 写入流程:
- 应用程序输入需要写缓存的数据。
- API将Key输入路由算法模块,路由算法根据Key和Memcached集群服务器列表得到一台服务器编号。
- 由服务器编号得到Memcached服务节点的IP地址和端口号。
- API调用通信模块和指定编号的服务器通信,将数据写入该服务器,完成一次分布式缓存的写操作。
- 读取流程:
- 应用程序输入需要读取的Key。
- 路由算法根据Key和Memcached集群服务器列表确定存储该数据的服务器。
- API调用通信模块从指定服务器读取数据。
- 如果缓存命中,则直接返回数据;如果缓存未命中,则先从数据库中查询数据,再将数据缓存到Memcached中。
四、分布式部署
- 依赖:Memcached的分布式部署主要依赖于Memcached的客户端来实现。
- 路由算法:
- 求余数Hash算法:适合大多数据需求,但不适合动态变化的环境。
- 一致性Hash算法:适合在动态变化的环境中使用,通过hash算法将key和机器映射到环中,按顺时针方向将对象存储到离自己最近的机器中。
五、优化与注意事项
- 安装与配置:Memcached的安装依赖于Libevent库,需要先安装Libevent。安装完成后,可以通过配置文件或命令行参数来优化Memcached的性能,如设置最大内存、最大连接数等。
- 数据一致性:由于Memcached是内存缓存,因此不具备数据持久性。当Memcached服务器重启或发生故障时,缓存的数据会丢失。因此,在使用Memcached时,需要考虑数据备份和恢复策略。
- 监控与维护:定期对Memcached进行监控和维护,包括查看缓存命中率、内存使用情况、连接数等指标,以确保Memcached的稳定运行和高效性能。
六、应用场景
Memcached适用于需要频繁访问数据的场景,如动态Web应用、社交网络、电子商务等。通过减少数据库加载,Memcached可以显著提高这些应用的访问速度和性能。
综上所述,Memcached是一款功能强大、性能优异的高性能内存对象缓存系统。通过合理的配置和优化,可以充分发挥其优势,为Web应用提供快速、高效的数据访问服务。
案例
单memcached节点缓存系统
cpp
//设置节点的主机名
主机:192.168.10.101
[root@localhost ~]# hostnamectl set-hostname Memcache1
[root@localhost ~]# bash
主机:192.168.10.103
[root@localhost ~]# hostnamectl set-hostname Memcached-API
[root@localhost ~]# bash
安装 Memcached 服务器
cpp
//安装 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
//安装 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
//设置 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 客户端
cpp
//设置好阿里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 <<EOF>/var/www/html/test1.php
<?php
phpinfo();
?>
EOF
//编译安装 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
//编译安装 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
//配置 PHP 添加 Memcached 组件
[root@memcache2 ~]# vim /etc/php.ini
在第二行添加extension=memcached.so
通过 PHPinfo 查看是否已经添加 Memcached 扩展模块
测试 Memcached-API 功能
cpp
[root@memcached-api ~]# vim /var/www/hrml/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;
?>
Memcached主主复制架构部署
cpp
//安装 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
//安装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行):
//if defined(__FreeBSD__) || defined(__APPLE__)
//endif
[root@memcache1 memcached-1.2.8-repcached-2.2]# make && make install
//启动memcached1服务
[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
//memcached2启动
[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
//使用 telnet 进行简单验证复制功能
Memcached 主主复制+Keepalived高可用架构
在上面案例的基础上添加keepalived
配置主 keepalived
cpp
[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
}
}
配置从keepalived,只需要在主keepalived的配置文件的基础上进行修改即可
cpp
[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_02 //route_id不能相同
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
}
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
}
}
memcached.sh脚本内容
cpp
[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
关闭memcached后,该主机的keepalived也会被脚本关闭,于是VIP就漂移到了另一台主机,待此主机修好后,把memcached和keepalived开启,由于设置了不抢占,VIP不会抢占回来,但是把第二台主机的memcached关闭后,第二台主机的keepalived也会关闭,于是VIP就漂移回了第一台主机。完成故障的转移。