Memcached(高性能内存对象缓存)

金鞍玉勒寻芳客,未信我庐别有春。这篇文章主要讲述Memcached(高性能内存对象缓存)相关的知识,希望能为你提供帮助。
案例:高性能内存对象缓存
Memcached
技能目标:
理解 Memcached 核心概念
会进行 Memcached 相关部署操作
会进行 Memcached 主主复制操作
会进行 Memcached 服务高可用配置
2.1 案例分析
2.1.1 案例概述
Memcached 是一套开源的高性能分布式内存对象缓存系统,它将所有的数据都存储在内
存中,因为内存中会统一维护一张巨大的 Hash 表,所以支持任意存储类型的数据。很多网
站使用 Memcached 提高网站的访问速度,尤其是需要频繁访问数据的大型网站。
Memcached 是典型的 C/S 架构,因此需要构建 Memcached 服务器端与 Memcached API 客
户端。Memcached 服务器端是用 C 语言编写的,而 Memcached API 客户端可用任何语言来编
写,如 php、python、Perl 等,并通过 Memcached 协议与 Memcached 服务器端进行通信。
常用典型架构如图 2.1 所示。
图 2.1 Memcache 常用架构
当 Web 客户端发出请求到 Web 服务器的应用程序时,应用程序会调用 Memcached API
客户端程序库接口去连接 Memcached 服务器查询数据。如果 Web 客户端所请求的数据在
Memcached 服务端中已经缓存,则 Memcached 服务端会将数据返回给 Web 客户端;否则,会将 Web 客户端请求发送至 mysql 数据库,由数据库查询并返回请求的数据给 Memcached 以及Web 客户端,与此同时 Memcached 服务器也会将数据进行保存,方便下次用户请求使用。
2.1.2 案例前置知识点
1. 数据存储方式与数据过期方式
Memcached 具有独特的数据存储方式和数据过期方式。
1)数据存储方式:Slab Allocation
Slab Allocation 即按组分配内存,每次先分配一个 Slab,相当于一个大小为 1M
的页。然后,在 1M 的空间里根据数据划分大小相同的 Chunk,如图 2.2 所示。该方法
可以有效解决内存碎片问题,但也可能会使内存空间产生浪费。

Memcached(高性能内存对象缓存)

文章图片

图 2.2 Slab Allocation 2)数据过期方式:LRU、Laxzy Expiration
LRU 和 Laxzy Expiration 是数据过期的两种方式。
? LUR 是指追加的数据空间不足时,会根据 LRU 的情况淘汰最近最少使用的记录。
? Laxzy Expiration 即惰性过期,是指使用 get 时查看记录时间,从而检查记录是
否已经过期。
2. Memcached 缓存机制
缓存是常驻在内存的数据,能够快速进行读取,而 Memcached 就是这样一款非常
出色的缓存软件。当程序写入缓存数据请求时,Memcached 的 API 接口将 Key 输入路
由算法模块路由到集群中一台服务,之后由 API 接口与服务器进行通信,完成一次分
布式缓存写入,如图 2.3 所示。
Memcached(高性能内存对象缓存)

文章图片

图 2.3 Memcached 缓存机制
3. Memcached 分布式
Memcached 分布式部署主要依赖于 Memcached 的客户来端实现,多个 Memcached
服务器是独立的。分布式数据如何存储是由路由算法所决定。
当 数 据 到 达 客 户 端 程 序 库 , 客 户 端 的 算 法 就 依 据 路 由 算 法 来 决 定 保 存 的
Memcached 服务器。读取数据时,客户端依据使用保存数据时相同的路由算法选中和
存储数据时相同的服务器来读取数据,如图 2.4 所示。
Memcached(高性能内存对象缓存)

文章图片

图 2.4 Memcached 分布式
4. Memcached 路由算法
1)求余数 hash 算法
求余数 hash 算法先用 key 做 hash 运算得到一个整数,再去做 hash 算法,根据
余数进行路由,这种算法适合大多数据需求。但是不适合用在动态变化的环境中,比
如有大有量机器添加或者删除,这样会导致大量的对象存储位置失效。
2)一致性 hash 算法
一致性 hash 算法适合在动态变化的环境中使用。原理是按照 hash 算法把对应的
key 通过一定的 hash 算法处理后映射形成一个首尾相接闭合循环,然后通过使用与对
象存储一样的 hash 算法将机器也映射到环中,顺时针方向计算将所有对象存储到里
自己最近的机器中,如图 2.5 所示。
图 2.5 一致性 hash 算法
 
2.1.3 案例环境
本案例使用三台 CentOS 7.3 系统完成,其中:两台是 Memcached 服务器,另一台是基
于 LAMP 架构进行 Memcached 扩展的 Memcached API 客户端,具体需根据企业需求进行架构调整。案例环境如表 2-1 所示。
 
Memcached(高性能内存对象缓存)

文章图片

2.2.1 安装 Memcached 服务器
1. 安装 Libevent
Libevent 是一款跨平台的事件处理接口的封装,可以兼容多个操作系统的事件访问。
Memcached 的安装依赖于 Libevent,因此需要先完成 Libevent 的安装。
[root@Memcache1 ~]# tar -zxvf libevent-2.1.8-stable.tar.gz -C /usr/src/
[root@Memcache1 libevent-2.1.8-stable]# ./configure --prefix=/usr/local/libevent
[root@Memcache1 libevent-2.1.8-stable]# make & & make install
到此 Libevent 安装完毕,接下来就可以安装 Memcached。
2. 安装 Memcached
采用源码的方式进行 Memcached 的编译安装,安装时需要指定 Libevent 的安装
路径。
[root@Memcache1 ~]# tar -zxvf memcached-1.5.1.tar.gz -C /usr/src/ [root@Memcache1 ~]# cd
/usr/src/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 服务脚本
Memcached 服务器安装完成后,可以使用安装目录下的 bin/memcached 来启动服
务。但是,为了更加方便的管理 Memcached,编写脚本来管理 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 其中启动 Memcached 时,-d 选项的作用是以守护进程的方式运行 Memcached 服务,
-m 是为 Memcached 分配 128M 的内存,应根据企业需要调整,-u 指定运行的用户账号。
之后设置脚本权限,启动 Memcached 服务。
[root@Memcache1 ~]# chmod 755 /usr/local/memcached/memcached_service.sh
[root@Memcache1 ~]# /usr/local/memcached/memcached_service.sh start
服务启动之后,监听 11211/tcp 端口。
[root@memcached ~]# netstat -antp |grep memcached
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 10196/memcached
tcp6 0 0 :::11211 :::* LISTEN 10196/memcached
2.2.2 Memcached API 客户端
为了使得程序可以直接调用 Memcached 库和接口,可以使用 Memcached 扩展组件
将 Memcache 添加为 PHP 的一个模块。此扩展使用了 Libmemcached 库提供的 API 与
Memcached 服务端进行交互。
客户端需要安装 apache 与 php 来测试 memcache,对于 Apache 与 PHP 的配置过程
这里省略。
1. 编译安装 Libmemcached
在编译 Memcached 扩展组件时,需要指定 Libmemcached 库的位置,所以先安装
Libmemcached 库。
[root@memcached-api ~]# tar -xzvf 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
2. 编译安装 Memcached 扩展
安装 Libmemcached 库后,就可以进行 PHP 的 Memcached 扩展组件安装。
[root@memcached-api ~]# wget ??http://pecl.php.net/get/memcached-2.2.0.tgz??
[root@memcached-api ~]# tar -xzvf memcached-2.2.0.tgz
[root@memcached-api ~]# cd memcached-2.2.0/
注意:配置 Memcached API 时,memcached-2.2.0.tgz 源码包中默认没有 configure 配
置脚本,需要使用 PHP 的 phpize 脚本生成配置脚本 configure。
[root@memcached-api memcached-2.2.0]# /usr/local/php5/bin/phpize
Configuring for:
PHP Api Version: 20121113
Zend Module Api No: 20121212
Zend Extension Api No: 220121212
[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
注意:配置时使用--disable-memcached-sasl 选项,关闭 Memcached 的 SASL 认证功能,
否则会报错。
[root@memcached-api memcached-2.2.0]# make
[root@memcached-api memcached-2.2.0]# make test
[root@memcached-api memcached-2.2.0]# make install
[root@localhost memcached-2.2.0]# make install
Installing shared extensions: /usr/local/php5/lib/php/extensions/no-debug-zts-20121212/
//共享组建的位置
3. 配置 PHP 添加 Memcached 组件
编辑 PHP 配置文件 php.ini,添加 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 可以通过 phpinfo,查看是否已经添加 Memcached 扩展模块。
[root@memcached ~]# vim /usr/local/httpd/htdocs/index.php
< ?php
phpinfo();
?>
使用浏览器进行访问,结果如图 2.6 所示,已经添加成功。
图 2.6 phpinfo 信息
4. 测试 Memcached-API 功能
通过编写简单的 PHP 测试代码调用 Memcache 程序接口来测试是否与 Memcached 服务器
协同工作,代码如下:
[root@memcached-api ~]# vim /usr/local/httpd/htdocs/test.php
< ?php
$memcache = new Memcached();
$memcache-> addServer(192.168.9.200, 11211);
$memcache-> set(key, Memcache test successful!, 0, 60);
$result = $memcache-> get(key);
unset($memcache);
echo $result;
?>
此段代码的作用是在客户端连接 Memcached 服务器,设置名为‘key’的键的值为
‘Memcache test successful!’,并读取显示,成功表示服务器与客户端协同工作正常,使
用浏览器进行访问,测试结果如图 2.7 所示。
图 2.7 测试页面
2.3 Memcached 数据库操作与管理
Memcache 协议简单可直接使用 telnet 连接 Memcached 的 11211 端口对 Memcached 数据
库进行操作与管理。
[root@Memcache1 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is ^].
//输入操作指令
操作命令格式:< command name> < key> < flags> < exptime> < bytes> < data block>
下面是 Memcached 数据库的常见操作指令。
1. 添加一条键值数据
add username 0 0 7
example
STORED
其中 add username 0 0 7 表示键值名为 username,标记位表示自定义信息为 0,过期
时间为 0(永不过期,单位为秒),字节数为 7; example 为键值,注意输入长度为 7 字节,
与设定值符合。
2. 查询键值数据
get username
VALUE username 0 7
example
END
gets username
VALUE username 0 7 4
example
END
其中 get 后跟键名,如果检查最近是否更新,可以使用 gets,最后一位显示的是更新
因子,每更新一次更新因子数会加一。
3. 更新一条键值数据
set username 0 0 10
everything
STORED
get username
VALUE username 0 10
everything
END
其中 set 后跟需要更新的键名、标记位、过期时间、字节数。如果键名不存在,set 相
当于 add 添加。如果仅仅是想单纯的更新没有添加功能,使用 replace。此时更新的键名必
须存在,如果键名不存在会报 NOT_STORED 的错误。
replace username 0 0 7
lodging
STORED
gets username
VALUE username 0 7 6
lodging
END
replace username1 0 0 7
example
NOT_STORED
4. 清除一条缓存数据
delete username
DELETED
get username
END
使用 delete 删除一条键值为 usernmame 的缓存数据,使用 get 查看没有内容存在。
5. 检查后更新 check and set
gets username
VALUE username 0 7 7
example
END
cas username 0 0 7 1
lodging
EXISTS
cas username 0 0 7 7
lodging
STORED
gets username
VALUE username 0 7 8
lodging
END
如果 cas 的最后一个更新因子数与 gets 返回的更新因子数相等,则更新;否则返回
EXISTS。
6. 追加数据
append username 0 0 7 //后追加 7 字节
example
STORED
get username
VALUE username 0 14
lodgingexample
END
在键名 username 原键值后追加数据使用 append。
prepend username 0 0 2 //前追加 2 字节
un
STORED
get username
VALUE username 0 16
unlodgingexample
END
在键名 username 原键值前追加数据使用 prepend。
7. 清除所有缓存数据
flush_all
OK
8. 查看服务器统计信息
stats
stats items //返回所有键值对统计信息
stats cachedump 1 0 //返回指定存储空间的键值对
stats slabs //显示各个 slab 的信息,包括 chunk 的大小、数目、使用情况等
stats sizes //输出所有 item 的大小和个数
stats reset //清空统计数据
2.4 Memcached 实现主主复制和高可用的方式
Memcached 主主复制是指在任意一台 Memcahed 服务器修改数据都会被同步到另外一台,
但是 Memcahed API 客户端是无法判断连接到哪一台 Memcahed 服务器,所以需要设置 VIP
地址,提供给 Memcahed API 客户端连接。可以使用 keepalived 产生 VIP 地址连接主 Memcahed
服务器,并且提供高可用架构。
2.4.1 Memcached 主主复制架构
Memcached 的复制功能支持多个 Memcached 之间相互复制(双向复制,主备都是可读可
写的),可以解决 Memcached 的容灾问题。
要使用Memcached复制架构,需要卸载之前memcache1机器上的1.5.1版本的memcached,
重新下载支持复制功能的 Memcached 安装包。
[root@Memcache1 ~]# yum -y install psmisc
[root@Memcache1 ~]# /usr/local/memcached/memcached_service.sh stop
[root@Memcache1 ~]# netstat -lnupt | grep memcached
安装过程与之前安装的 Memcached 方法相同,这里简略说一下。
1.安装带有复制功能的 Memcached
安装完成 libevent 之后,将下载的 memcached-1.2.8-repcached-2.2.tar.gz 进
行解压,之后完成配置编译安装。
[root@Memcached1 ~]# 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
修改 memcached.c 配置文件
[root@memcached1 memcached-1.2.8-repcached-2.2]# vim memcached.c
#ifndef IOV_MAX
#if defined(__FreeBSD__) || defined(__APPLE__)
# define IOV_MAX 1024
#endif
#endif
改成:
/* FreeBSD 4.x doesnt have IOV_MAX exposed. */
#ifndef IOV_MAX
# define IOV_MAX 1024
#endif
编译安装
[root@memcached1 memcached-1.2.8-repcached-2.2]# make & & make install
2.启动 Memcached 服务
复制功能的 Memcached 安装完成之后,需要将编译安装的 libevent-2.1.so.6 模
块复制到/usr/lib64 目录下,否则在启动带有复制功能的 Memcached 服务时报错。
[root@memcached1 ~]# ln -s /usr/local/libevent/lib/libevent-2.1.so.6 /usr/lib64/
启动服务时,使用-x 选项指向对端。
[root@Memcached1 ~]# /usr/local/memcached_replication/bin/memcached -d -u root -m 128 -x
192.168.9.202
[root@Memcached1 ~]# netstat -antp |grep memcached
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN
16863/memcached
tcp 0 0 192.168.9.200:42786 192.168.9.202:11212 ESTABLISHED
16863/memcached
tcp6 0 0 :::11211 :::* LISTEN
16863/memcached
同样启动 memcached2 服务器,注意启动 Memcached 服务时指向对端。
3.使用 telnet 进行简单验证复制功能
1)在 Memcached1 上插入一条具有特点的键值
安装 telnet 工具
[root@Memcached1 ~]#yum -y install telnet*
连接 memcached
[root@ Memcached1 lib]#
Memcached(高性能内存对象缓存)

文章图片

图 2.8 Memcached 高可用架构
keepalived 通 过 不 断 检 测 Memcached 主 服 务 器 的 11211 端 口 , 如 果 检 测 到
Memcached 服务发生宕机或者死机等,就会将 VIP 从主服务器移至从服务器,从而实
现 Memcached 的高可用性。
1.安装配置 keepalived
[root@Memcached1 ~]# yum install –y keepalived
1)配置主 keepalived
[root@Memcached1 ~]# 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_DEVEL //路由标识,主从保持一致
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0

vrrp_instance VI_1
state MASTER //主备状态均为 MASTER
interface ens33
virtual_router_id 51 //虚拟路由 ID,主从相同
priority 100 //优先级,主的高于备
advert_int 1
nopreempt //不主动抢占资源,只在 Master 或者高优先级服务器上设置
authentication
auth_type PASS
auth_pass 1111

virtual_ipaddress
192.168.1.100 //定义 VIP 地址


virtual_server 192.168.1.100 11211//VIP 故障检测
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 20
protocol TCP
sorry_server 192.168.9.202 11211 //对端
real_server 192.168.9.200 11211//本机
weight 3
notify_down /root/memcached.sh //当 memcached 宕机,停止 keepalived 服务
TCP_CHECK
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 11211



设置执行脚本:
[root@Memcached1 ~]# echo "/usr/bin/systemctl stop keepalived" > /root/memcached.sh
[root@Memcached1 ~]# chmod +x memcached.sh
2)配置备 keepalived
主从 keepalived 配置文件内容差不多,直接复制进行修改,以下只把不一样的
地方整理出来。
[root@Memcached1 ~]# scp /etc/keepalived/keepalived.conf 192.168.9.202:/etc/keepalived/
//省略
vrrp_instance VI_1
state MASTER //备机状态也为 MASTER
interface eth0
virtual_router_id 51 //虚拟路由 ID,主从相同
priority 99 //优先级低
advert_int 1
//去掉 nopreempt
authentication
auth_type PASS
auth_pass 1111

//省略
virtual_server 192.168.1.100 11211//VIP 故障检测
delay_loop 6
lb_algo rr
lb_kind NAT
persistence_timeout 20
protocol TCP
sorry_server 192.168.9.200 11211 //对端
real_server 192.168.9.202 11211//本机
weight 3
notify_down /root/memcached.sh //当 memcached 宕机,停止 keepalived 服务
//省略
同样设置脚本:
[root@memcached2 ~]# echo "/usr/bin/systemctl stop keepalived" > /root/memcached.sh
[root@memcached2 ~]# chmod +x memcached.sh
2.测试验证
分别启动主从的 keepalived 服务。
[root@Memcached1 ~]# systemctl start keepalived
[root@memcached2 ~]# systemctl start keepalived
1)验证主 keepalived 获取 VIP 地址
使用 ip address show 命令查看 VIP 地址(使用 ifconfig 无法查看)。
[root@Memcached1 ~]# ip address
//省略
2: eth0: < BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:f0:23:a6 brd ff:ff:ff:ff:ff:ff
inet 192.168.9.200/24 brd 192.168.9.255 scope global dynamic eth0
valid_lft 7181sec preferred_lft 7181sec
inet 192.168.1.100/32 scope global eth0 //已获得 VIP 地址
valid_lft forever preferred_lft forever
inet6 fe80::dcdb:41a6:7a18:680b/64 scope link
valid_lft forever preferred_lft forever 2)验证高可用性
关闭 Memcached1 服务器的 Memcached 服务,在 Memcached2 服务器上查看地址信
息。(注:一定要关闭两台机器的 selinux)
[root@Memcached1 ~]#setenforce 0
[root@memcached2 ~]#setenforce 0
[root@Memcached1 ~]# killall memcached
[root@memcached2 ~]# ip addr
//省略
2: eth0: < BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:ad:1e:2b brd ff:ff:ff:ff:ff:ff
inet 192.168.9.202/24 brd 192.168.9.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.1.100/32 scope global eth0 //已获取 VIP 地址
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fead:1e2b/64 scope link
valid_lft forever preferred_lft forever
3.本架构特点
Keepalived 能够在主 Memcached 数据库上产生一个 VIP 地址,程序连接这个固定的 VIP
地址到主 Memcached 数据库,即使后端数据库主从切换,也不需要进行修改地址。因为当主
Memcached 数据库上 Memcached 服务停止时,keepalived 能在从 Memcached 服务器重新获取
原来的 VIP 地址,从而实现主从的切换,这个过程叫做 VIP 地址漂移。
【Memcached(高性能内存对象缓存)】


    推荐阅读