版权声明: https://blog.csdn.net/weixin_42061048/article/details/83043150
【Web 集群实战】21_Memcached 服务应用
标签(空格分隔): Web集群实战
文章目录
- 【Web 集群实战】21_Memcached 服务应用
- 1. Memcached 介绍
- 1.1 Memcached 是什么?
- 1.2 Memcached 的作用
- 1.3 Memcached 常见用途工作流程
- 1.4 网站读取 Memcached 数据时工作流程
- 1.5 网站更新 Memcached 数据时的工作原理
- 1.6 Memcached 的特点
- 1.7 Memcached 内存管理机制
- 1.8 Memcached 的检测过期与删除机制
- 2. Memcached 服务安装
- 3. Memcached 服务的基本管理
- 4. 安装 Memcached 客户端
- 4.1 Memcached 缓存 PHP 扩展插件安装
- 4.2 配置 Memcached 客户端,使其生效
- 4.3 重启 php fpm 服务使 PHP 的配置修改生效
- 4.4 编写测试 Memcached 服务的 PHP 脚本
- 5 Memcached 应用管理
1. Memcached 介绍
1.1 Memcached 是什么?
- Memcached 是一个开源的、支持高性能 、高并发的分布式内存缓存系统。 “Mem” 即内存;“cache” 即缓存;“d" 是 daemon,代表是服务器端守护进程模式服务。Memcached 服务分为服务器端和客户端两部分。
1.2 Memcached 的作用
- 使用 Memcached 的主要目的是,通过在自身内存中缓存关系型数据库的查询结果,减少数据库被访问的次数,以提高动态 Web 应用的速度,提高网站架构的并发能力和可扩展性。
- Memcached 服务的运行原理是通过在事先规划好的系统内存空间中临时缓存数据库中的各类数据,以达到减少前端业务对数据库的直接高并发访问,从而提升大规模网站集群中动态服务的并发访问能力。
1.3 Memcached 常见用途工作流程
- Memcached 是一种内存缓存软件,在工作中经常用来缓存数据库的查询数据,数据被缓存在事先预分配的 Memcached 管理的内存中,可以通过 API 或命令的方式存取内存中缓存的这些数据,Memcached 服务内存中缓存的数据就像一张巨大的 hash 表,每一条数据都是以 key-value 对的形式存在。
1.4 网站读取 Memcached 数据时工作流程
- 使用 Memcached 缓存查询数据来减少数据库压力的具体工作流程如下:
- Web 程序首先检查客户端请求的数据是否在 Memcached 缓存中存在,如果存在,直接把请求的数据返回给客户端,此时不再请求后端数据库。
- 如果请求的数据在 Memcached 缓存中不存在,则程序会去请求你数据库服务,把从数据库中取到的数据返回给客户端,同时把新到的数据缓存一份到 Memcached 缓存中。
1.5 网站更新 Memcached 数据时的工作原理
- 当程序更新或删除数据时,会首先处理后端数据库中的数据。
- 在处理后端数据库中数据的同时,也会通知 Memcached,告诉它对应的旧数据失效,从而保证 Memcached 中缓存的数据始终和数据库中的一致,这个数据一致性非常重要,也是大型网站分布式缓存集群的关注问题。
- 如果是在高并发读写场合,除了要程序通知 Memcached 过期的缓存失效外,还可能要通过相关机制,例如在数据库上部署相关程序(如在数据库中设置触发器使用 UDFs),实现当数据库有更新时就把数据更新到 Memcached 服务中,这样一来,客户端在访问新数据时,因预先把更新过的数据库数据复制到 Memcached 中缓存起来了,所以可以减少第一次查询数据库带来的访问压力,提升 Memcached 中缓存的命中率。还可把持久化存储 Redis 做成 MySQL 数据库的从库,实现真正的主从复制。
1.6 Memcached 的特点
-
协议简单。采用的是基于文本行的协议,能通过 telnet/nc 等命令直接操作 Memcached 服务存取数据。
-
支持 epoll/kqueue 异步 I/O 模型,使用 libevent 作为时间处理通知机制。
- 简单的说,libevent 是一套利用 C 开发的程序库,它将 BSD 系统的 kqueue、Linux 系统的 epoll 等事件处理功能封装成一个接口,确保即使服务器端的连接数增加也能发挥很好的性能。
-
采用 key/value 键值数据类型。
-
全内存缓存,效率高。
- Memcached 管理内存的方式非常高效,即全部的数据都存放于 Memcached 服务事先分配好的内存中,无持久化存储的设计,和系统的物理内存一样,当重启系统或 Memcached 服务时,Memcached 内存中的数据就会丢失。如果希望重启后,数据依然能保留,那么就可以采用 Redis 这样的持久性内存缓存系统。
- 当内存中缓存的数据容量达到服务启动时设定的内存值时,就会自动使用 LRU 算法删除过期的缓存数据。也可以在存放数据时对存储的数据设置过期时间,这样过期后数据就自动被清除,Memcached 服务本身不会监控数据过期,而是在访问的时候查看 key 的时间戳判断是否过期。
-
可支持分布式集群
- Memcached 没有像 MySQL 那样的主从复制方式,分布式 Memcached 集群的不同服务器之间是互不通信的,每一个节点都独立存取数据,并且数据内容也不一样。通过对 web 应用端的程序设计或者通过支持 hash 算法的负载均衡软件,可以让 Memcached 支持大规模海量分布式缓存集群应用。
1.7 Memcached 内存管理机制
- Mc 早期内存管理机制为 malloc(动态内存分配)。
- malloc(动态内存分配)产生内存碎片,导致操作系统性能急剧下降。
- Slab 内存分配机制可以解决内存碎片问题。
- Memcached 服务的内存预先分割成特定长度的内存块,称为 chunk,用于缓存数据的内存空间或内存块,相当于磁盘的 block,只不过一个磁盘的每一个 block 都是相等的,而 chunk 只有在同一个 Slab Class 内才是相等的。
- Slab Class 指特定大小(MB)的包含多个 chunk 的集合或组,一个 Memcached 包含多个 Slab Class,每个 Slab Class 包含多个相同大小的 chunk。
1.8 Memcached 的检测过期与删除机制
- 不主动检测 item 对象是否过期,而是在 get 时才会检查 item 对象是否过期以及是否应该删除。
- 当删除 item 对象时,一般不释放内存空间,而是做删除标记,将指针放入slot 回收插槽,下次分配的时候直接使用。
- 当内存空间满的时候,将会根据 LRU 算法把最近最少使用的 item 对象删除。
- 数据存入可以设定过期时间,但是数据过期后不会被立即删除,而是在 get 时检查 item 对象是否过期以及是否应该删除。
- 如果不希望系统使用 LRU 算法清除数据,可以使用 -M 参数。
2. Memcached 服务安装
2.1 安装 libevent 及连接 Memcached 工具 nc
- 系统安装环境如下:
[root@cache001 ~]# cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
[root@cache001 ~]# uname -m
x86_64
[root@cache001 ~]# uname -r
3.10.0-693.el7.x86_64
- 安装 libevent
[root@cache001 ~]# yum install -y libevent libevent-devel nc
[root@cache001 ~]# rpm -qa libevent libevent-devel nc
libevent-devel-2.0.21-4.el7.x86_64
libevent-2.0.21-4.el7.x86_64
2.2 安装 Memcached
[root@cache001 ~]# yum install -y memcached
[root@cache001 ~]# rpm -qa memcached
memcached-1.4.15-10.el7_3.1.x86_64
3. Memcached 服务的基本管理
3.1 启动 Memcached
- 启动命令如下:
[root@cache001 ~]# which memcached
/bin/memcached
[root@cache001 ~]# memcached -m -16m -p 11211 -d -u root -c 8192
- 检查启动结果
[root@cache001 ~]# lsof -i :11211
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
memcached 945 memcached 26u IPv4 18588 0t0 TCP *:memcache (LISTEN)
memcached 945 memcached 27u IPv6 18589 0t0 TCP *:memcache (LISTEN)
memcached 945 memcached 28u IPv4 18592 0t0 UDP *:memcache
memcached 945 memcached 29u IPv6 18593 0t0 UDP *:memcache
[root@cache001 ~]# ps -ef|grep memcached|grep -v grep
memcach+ 945 1 0 20:34 ? 00:00:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
- 将上述启动命令放入 /etc/rc.local
[root@cache001 ~]# vim /etc/rc.local
[root@cache001 ~]# tail -2 /etc/rc.local
#start up memcached by ylt at 20181012
memcached -m -16m -p 11211 -d -u root -c 8192
3.2 向 Memcached 中写入数据并检查
通过 printf
- 通过 printf 配合 nc 向 Memcached 中写入数据:
[root@cache001 ~]# printf "set key1 0 0 3\r\nylt\r\n"|nc 127.0.0.1 11211
STORED
- 通过 printf 配合 nc 向 Memcached 中读取数据:
[root@cache001 ~]# printf "get key1\r\n"|nc 127.0.0.1 11211
VALUE key1 0 3
ylt
END
- 通过 printf 配合 nc 向 Memcached 中删除数据:
[root@cache001 ~]# printf "delete key1\r\n"|nc 127.0.0.1 11211
DELETED
通过 Telnet
- 安装 telnet 工具
[root@cache001 ~]# yum install telnet -y
[root@cache001 ~]# rpm -qa telnet
telnet-0.17-64.el7.x86_64
- 通过 telnet 向 Memcached 中写入数据
[root@cache001 ~]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set user01 0 0 4
ylt1
STORED
get user01
VALUE user01 0 4
ylt1
END
delete user01
DELETED
quit
Connection closed by foreign host.
3.3 关闭 Memcached
- 单实例关闭 Memcached 的方法如下:
[root@cache001 ~]# ps -ef|grep memcache|grep -v grep
memcach+ 945 1 0 20:34 ? 00:00:00 /usr/bin/memcached -u memcached -p 11211 -m 64 -c 1024
[root@cache001 ~]# killall memcached 或 pkill memcached
- 若启动了多个实例 Memcached,使用 killall 或 pkill 方式就会同时关闭这些实例。因此最好在启动时增加 -P 参数指定固定的 pid 文件,这样便于管理不同的实例。
[root@cache001 ~]# memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[root@cache001 ~]# memcached -m -16m -p 11212 -d -u root -c 8192 -P /var/run/11212.pid
[root@cache001 ~]# ps -ef|grep memcache|grep -v grep
root 1781 1 0 20:58 ? 00:00:00 memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
root 1788 1 0 20:58 ? 00:00:00 memcached -m -16m -p 11212 -d -u root -c 8192 -P /var/run/11212.pid
- 此时,即可通过 kill 命令关闭 Memcached
[root@cache001 ~]# kill `cat /var/run/11211.pid`
[root@cache001 ~]# lsof -i:11211
[root@cache001 ~]# lsof -i:11212
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
memcached 1788 root 26u IPv4 23322 0t0 TCP *:11212 (LISTEN)
memcached 1788 root 27u IPv6 23323 0t0 TCP *:11212 (LISTEN)
memcached 1788 root 28u IPv4 23326 0t0 UDP *:11212
memcached 1788 root 29u IPv6 23327 0t0 UDP *:11212
- 关闭 Memcached 的方法小结
ps -ef|grep memcache|grep -v grep|awk '{print $2}'|xargs kill
kill `cat /var/run/11211.pid`
killall memcached
pkill memcached
4. 安装 Memcached 客户端
4.1 Memcached 缓存 PHP 扩展插件安装
[root@cache001 tools]# git clone https://github.com/websupport-sk/pecl-memcache memcache
[root@cache001 tools]# cd memcache/
[root@cache001 memcache]# /application/php/bin/phpize
Configuring for:
PHP Api Version: 20160303
Zend Module Api No: 20160303
Zend Extension Api No: 320160303
[root@cache001 memcache]# ./configure --enable-memcache --with-php-config=/application/php/bin/php-config
[root@cache001 memcache]# make
[root@cache001 memcache]# make install
Installing shared extensions: /application/php-7.1.22/lib/php/extensions/no-debug-non-zts-20160303/
[root@cache001 tools]# ll /application/php/lib/php/extensions/no-debug-non-zts-20160303/
-rwxr-xr-x 1 root root 508496 Oct 12 22:54 memcache.so
4.2 配置 Memcached 客户端,使其生效
- 修改 PHP 的配置文件 php.ini,加入 Memcached 客户端的配置
[root@cache001 tools]# cd /application/php/lib
[root@cache001 lib]# vim php.ini
[root@cache001 lib]# tail -2 php.ini
extension_dir = "/application/php/lib/php/extensions/no-debug-non-zts-20160303/"
extension=memcache.so
4.3 重启 php fpm 服务使 PHP 的配置修改生效
- 检查 php-fpm 语法
[root@cache001 ~]# /application/php/sbin/php-fpm -t
[12-Oct-2018 21:00:48] NOTICE: configuration file /application/php-7.1.22/etc/php-fpm.conf test is successful
- 重启 fpm
[root@cache001 ~]# pkill php-fpm
[root@cache001 ~]# ps -ef|grep php-fpm|grep -v grep
[root@cache001 ~]# /application/php/sbin/php-fpm
[root@cache001 ~]# ps -ef|grep php-fpm|grep -v grep
root 1815 1 0 21:00 ? 00:00:00 php-fpm: master process (/application/php-7.1.22/etc/php-fpm.conf)
nginx 1816 1815 0 21:00 ? 00:00:00 php-fpm: pool www
nginx 1817 1815 0 21:00 ? 00:00:00 php-fpm: pool www
- 打开浏览器访问 phpinfo 页面,出现下图则表示 Memcached 客户端安装成功
4.4 编写测试 Memcached 服务的 PHP 脚本
[root@cache001 blog]# cat -n op_mem.php
1 <?php
2 $memcache = new Memcache;
3 $memcache->connect('192.168.2.135', 11211) or die ("Could not connect Mc server");
4 $memcache->set('key', 'ylt book');
5 $get= $memcache->get('key');
6 echo $get;
7 ?>
- 测试
[root@cache001 blog]# /application/php/bin/php op_mem.php
ylt book
5 Memcached 应用管理
5.1 通过命令管理 Memcached
通过脚本模拟用户插入及删除数据来监控 Memcached 服务是否正常
- 脚本内容如下:
[root@cache001 ~]# cat -n mon_mc.sh
1 #!bin/sh
2 export MemcachedIp=$1
3 export MemcachedPort=$2
4 export NcCmd="nc $MemcachedIp $MemcachedPort"
5 export MD5=3fe396c01f03425cb5e2da8186eb090d
6 USAGE(){
7 echo "$0 MemcachedIp MemcachePort"
8 exit 3
9 }
10 [ $# -ne 2 ] && USAGE
11 printf "set $MD5 0 0 6\r\noldboy\r\n"|$NcCmd >/dev/null 2>&1
12 if [ $? -eq 0 ];then
13 if [ `printf "get $MD5\r\n"|$NcCmd|grep oldboy|wc -l` -eq 1 ];then
14 echo "Memcached status is ok"
15 printf "delete $MD5\r\n"|$NcCmd >/dev/null 2>&1
16 exit 0
17 else
18 echo "Memcached status is error1"
19 exit 2
20 fi
21 else
22 echo "Could not connect Mc server"
23 exit 2
24 fi
- Memcached 服务正常的情况下,测试检验脚本
[root@cache001 ~]# sh mon_mc.sh 127.0.0.1 11211
Memcached status is ok
- 然后关闭 Memcached 服务,测试检验脚本
[root@cache001 ~]# pkill memcached
[root@cache001 ~]# lsof -i:11211
[root@cache001 ~]# sh mon_mc.sh 127.0.0.1 11211
Could not connect Mc server
- 最后开启 Memcached 服务,测试检验脚本
[root@cache001 ~]# memcached -m -16m -p 11211 -d -u root -c 8192 -P /var/run/11211.pid
[root@cache001 ~]# sh mon_mc.sh 127.0.0.1 11211
Memcached status is ok
通过 nc 命令查看 Memcached 服务的运行状态信息
[root@cache001 ~]# printf "stats\r\n"|nc 127.0.0.1 11211
STAT pid 11025
STAT uptime 110
STAT time 1539360955
STAT version 1.4.15
STAT libevent 2.0.21-stable
STAT pointer_size 64
STAT rusage_user 0.004133
STAT rusage_system 0.008266
STAT curr_connections 10
STAT total_connections 15
STAT connection_structures 11
STAT reserved_fds 20
STAT cmd_get 1
STAT cmd_set 1
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 0
STAT delete_misses 0
STAT delete_hits 1
STAT incr_misses 0
STAT incr_hits 0
STAT decr_misses 0
STAT decr_hits 0
STAT cas_misses 0
STAT cas_hits 0
STAT cas_badval 0
STAT touch_hits 0
STAT touch_misses 0
STAT auth_cmds 0
STAT auth_errors 0
STAT bytes_read 146
STAT bytes_written 81
STAT limit_maxbytes 18446744073692774400
STAT accepting_conns 1
STAT listen_disabled_num 0
STAT threads 4
STAT conn_yields 0
STAT hash_power_level 16
STAT hash_bytes 524288
STAT hash_is_expanding 0
STAT bytes 0
STAT curr_items 0
STAT total_items 1
STAT expired_unfetched 0
STAT evicted_unfetched 0
STAT evictions 0
STAT reclaimed 0
END