<服务>Memcached
目录:
Memcached是什么,有什么作用?
Memcached是开源的高性能内存缓存系统,通过在事先规划好的内存空间中临时缓存数据库中的各类数据,以减少达到业务对数据库的高并发访问,从而达到提升数据库的访问性能,加速动态应用服务的能力,原理是用于存储动态的数据,如果没有再像后端数据库获取并缓存。
Memcached服务在企业集群架构中应用场景
Memcached有两点应用场景,一种是数据库前端用于处理高并发的访问,适用于读多写少的数据库,session的共享问题,服务器之间的文件共享。
一般在电商秒杀的资格都是进行预热,把数据预热,然后后获取秒杀资格,然后通过秒杀资格再慢慢进行购买,可以JS,node.js进行处理。
Memcached服务在不同企业业务应用场景中的工作流程
当web访问后端数据库会优先获取memcached内存缓存,如果缓存中有数据就返回给前端用户或服务,如果没有命中,会相后端请求数据库服务获取数据,返回给前端并进行缓存。
程序更新时,修改或者删除数据库中已有的数据时,会同时发送请求给Memcached已经缓存过的同一ID的内容旧数据失效,从而保证Memcache中的数据和数据库中的数据一致。 如果高并发场景可以在数据失效后立刻缓存到Memcached中
Memcached服务分布式集群如何实现?
程序端实现,加载所有Memcached的ip列表,通过对key做一致性hash,一台主机是部分数据,所有的Memcached主机存储的为数据库的所有数据。负载均衡器通过对key做一致性hash。
一致性hash不但是保证每个对象只请求一个服务器,而且节点宕机缓存服务器的更新重新分配比例降低到最低。
Memcached服务特点及工作原理是什么?
- C/S架构,通过C语言编写
- 完全基于内存,无法持久化存储数据
- 节点之间相互独立
- 异步I/O模型,基于libevent模型的时间通知机制
- 数据以key,value键值对形式存在 6 .可以对数据设置过期时间,过期数据自动被清除,服务本身不会监控过期,而是在访问的时候查看key时间戳判断是否过期
- 内存中缓存的数据容量达到启动设置的内存值时,会自动使用LRU算法删除过期的缓存数据
- Memcached会设定内存分块,再把多个块分为一组然后提供服务
简述Memcached内存管理机制原理?
malloc全称是memory allocation,动态内存分配,当无法知道内存具体位置的时候,想要真正的绑定内存空间,就需要用到动态的分配内存 早起的Memcache就是用过malloc分配内存,使用完后通过free来回收内存,但是这种方式容易产生内存碎片并且降低操作系统对内存的管理效率,加重操作系统内存管理器的负担,最坏的结果甚至是导致操作系统比Memcachd进程本身还慢,为了解决这个问题产生了Slab Allocator内存分配机制产生 现在的Memcached利用Slab机制分配和管理内存,原理是按照预先规定的大小,并分配给Memcached内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,这些内存块不会释放,可以重复利用。
Memcached服务端保存着slab内空闲的chunk列表,根据该列表选择chunk,然后将数据存入其中,当有数据存入的时候,Memcached根据接受到的数据大小,选择最适合数据大小的slab,如果有100字节的一个数据,就会被分到一个112byte,slab allocator还有重复使用已分配的内存的作用,也就是内存被分配之后就不会释放而是重复利用。 slab allocator解决了内存碎片问题,但是新的机制也给memcached带来了新的问题,就是分配了特定的长度的内存,因此会产生内存浪费。避免内存浪费就预算存入数据大小,或者同一类型的数据存入一个Memcached服务器中,确保存入的数据大小相对均匀,减少浪费。内存组之间的差异大小,默认参数为1.25进行部署,可以通过启动-f的参数来设置。
Memcached的删除原理与删除机制?
Memcached的cache机制为LRU(最近最少用)算法,加上item过期失效,当数据存放到Memcached中可以存放多久,如果memcached的内存不够用了,过期的slabs会优先被替换,接着就轮到最老未使用的slabs,在某些情况下,如果不想使用LRU算法,那么可以通过-M参数启动Memcached,但是如果不使用的话,在内存耗尽时,会返回一个报错信息
return error on memory exhausted (rather than removing items)
Memcached服务端与客户端的安装部署与使用测试
两个网站的连接http://memcached.org/downloads和http://libevent.org/
安装libevent
CentOS系统也可以yum安装
[root@why-2 ~]# tar xf libevent-1.4.13-stable.tar.gz
[root@why-2 ~]# cd libevent-1.4.13-stable
[root@why-2 libevent-1.4.13-stable]# ./configure
[root@why-2 libevent-1.4.13-stable]# make
[root@why-2 libevent-1.4.13-stable]# make install
安装Memcached
[root@why-2 libevent-1.4.13-stable]# cd ..
[root@why-2 ~]# tar xf memcached-1.4.13.tar.gz
[root@why-2 ~]# cd memcached-1.4.13
[root@why-2 memcached-1.4.13]# ./configure
[root@why-2 memcached-1.4.13]# make
[root@why-2 memcached-1.4.13]# make install
-m指定内存大小,工作共一般根据开发需求,根据key的值大小来计算需要的内存量,例如400W,每条100byte,再考虑增长的量,一般不会超过4G -p端口,默认为11211 -d后台启动 -u用户名 -c并发连接数 -vv以veryvrebose模式启动,调试信息和错误输出到控制台 -P设置保存Memcache的pid文件 -l指定监听的服务器IP地址
多实例
[root@why-2 memcached-1.4.13]# memcached -m 16 -p 11211 -d -u root -c 8192
[root@why-2 memcached-1.4.13]# lsof -i:11211
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
memcached 4774 root 26u IPv4 360270 0t0 TCP *:memcache (LISTEN)
memcached 4774 root 27u IPv6 360271 0t0 TCP *:memcache (LISTEN)
memcached 4774 root 28u IPv4 360274 0t0 UDP *:memcache
memcached 4774 root 29u IPv6 360275 0t0 UDP *:memcache
[root@why-2 memcached-1.4.13]# memcached -m 16 -p 11212 -d -u root -c 8192
[root@why-2 memcached-1.4.13]# netstat -nlptu | grep mem
tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN 4774/memcached
tcp 0 0 0.0.0.0:11212 0.0.0.0:* LISTEN 4788/memcached
tcp 0 0 :::11211 :::* LISTEN 4774/memcached
tcp 0 0 :::11212 :::* LISTEN 4788/memcached
udp 0 0 0.0.0.0:11211 0.0.0.0:* 4774/memcached
udp 0 0 0.0.0.0:11212 0.0.0.0:* 4788/memcached
udp 0 0 :::11211 :::* 4774/memcached
udp 0 0 :::11212 :::* 4788/memcached
数据存储
[root@why-2 memcached-1.4.13]# printf "set key001 0 0 6\r\nwhy123\r\n"
set key001 0 0 6
why123
[root@why-2 memcached-1.4.13]# printf "set key001 0 0 6\r\nwhy123\r\n"|nc 127.0.0.1 11211
STORED
- key是存储的键值
- flags是在取回内容时,与数据和发送块一同保存在服务器上的任意16位无符号整形,客户端可以以此位域存储一些特定信息,其对服务器不透明
- exptime是终止时期,如果为0,代表永不过期,非0代表当前时间的偏移秒数
- bytes是数据的字节长度
[root@why-2 memcached-1.4.13]# telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
set key002 0 0 6
why456
STORED
get key002
VALUE key002 0 6
why456
END
^] #ctrl+]
telnet> quit
Connection closed.
Memcache客户端
[root@why-2 ~]# tar xf memcache-2.2.5.tgz
[root@why-2 ~]# cd memcache-2.2.5
[root@why-2 memcache-2.2.5]# /usr/local/php/bin/phpize
[root@why-2 memcache-2.2.5]# ./configure --with-php-config=/usr/local/php/bin/php-config --enable-memcache --with-zlib-dir
[root@why-2 memcache-2.2.5]# make [root@why-2 memcache-2.2.5]# make install
Installing shared extensions: /usr/local/php5.3.27/lib/php/extensions/no-debug-zts-20090626/
[root@why-2 ~]# ll /usr/local/php/lib/php/extensions/no-debug-zts-20090626/
total 624
-rwxr-xr-x 1 root root 395957 Nov 6 21:10 eaccelerator.so
-rwxr-xr-x 1 root root 237746 Feb 11 02:49 memcache.so
[root@why-2 ~]# vi /usr/local/php/lib/php.ini
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-zts-20090626/"
extension=memcache.so
[root@why-2 conf]# vi extra/httpd-vhosts.conf
<VirtualHost *:80>
ServerAdmin 93216193@qq.com
DocumentRoot "/var/html/www"
ServerName www.why.cn
ServerAlias why.com
ErrorLog "logs/www.why.com-error_log"
CustomLog "|/usr/local/sbin/cronolog /var/log/www.why.cn/www.why.cn_%Y%m%d.log" combined
<IfModule dir_module>
DirectoryIndex index.php
</IfModule>
</VirtualHost>
[root@why-2 www]# vi index.php
[root@why-2 www]# cat !$
cat index.php
<?php
phpinfo();
?>
[root@why-2 conf]# /usr/local/apache/bin/apachectl -t
Syntax OK
[root@why-2 conf]# /usr/local/apache/bin/apachectl graceful
这样就可以通过phpinfo来查看模块情况,访问192.168.0.202查看。
如果是Nginx则reload并重启php-fpm
php模拟操作Memcache
[root@why-2 www]# vi testmem.php
[root@why-2 www]# cat !$
cat testmem.php
<?php
$memcache = new Memcache;//创建对象
$memcache->connect('192.168.0.202',11212)or die ("Could not connect");//连接服务器
$memcache->set('key001','why');//添加数据
$memcache->set('key002','mabiao');
$get_value01 = $memcache->get('key001');//读取数据
$get_value02 = $memcache->get('key002');
echo $get_value02."<br>";
echo $get_value01.;
?>
[root@why-2 www]# /usr/local/php/bin/php testmem.php
mabiao<br>why
访问192.168.0.202/testmem.php也可
PHP和Memcache实现集群中的session共享存储?
[root@why-2 php]# vi /usr/local/php/lib/php.ini
session.save_handler = memcache
session.save_path = "tcp:://192.168.0.202:11211"
用memcached等来存储session,一方面memcached内存存储,在读写方面会比普通文件快很多,另一方面可以解决多个服务器共用session的问题,缺点是持久化欠缺,不过session数据来说也不是问题,如果在高并发的场景还是cookies效率会比session强很多。
session同步的几种方式lvs -p,nginx ip_hash,haproxy cookies insert,session共享,软件层session复制,cookies配合session进行回话缓存在本地。
如何获取MEMCACHED服务的状态信息,例如:命中率
[root@why-2 php]# printf "stats\r\n"|nc 192.168.0.202 11211
STAT pid 4774
STAT uptime 20942
STAT time 1486768843
STAT version 1.4.13
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 0.926859
STAT rusage_system 0.862868
STAT curr_connections 10
STAT total_connections 19
STAT connection_structures 13
STAT reserved_fds 20
STAT cmd_get 5 #块获取次数
STAT cmd_set 4
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 4 #块命中次数
STAT get_misses 1 #块丢失次数
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 1319
STAT bytes_written 281
STAT limit_maxbytes 16777216 #划分内存大小
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 expired_unfetched 0
STAT evicted_unfetched 0
STAT bytes 160
STAT curr_items 2 #存储值数量
STAT total_items 4 #存储数据数量
STAT evictions 0
STAT reclaimed 0
END
memcached状态查看
- stats settings 查看memcached设置参数
- stats slabs 查看slabs情况
- stats items 查看items情况
- stats sizes 查看存在的Item个数和大小
- stats cachedump 查看key value
- stats reset 清理统计数据
另外有一个很好的php程序可以很好的监控这些
[root@why-2 ~]# cd /var/html/www
[root@why-2 www]# wget http://www.junopen.com/memadmin/memadmin-1.0.12.tar.gz
[root@why-2 www]# tar xf memadmin-1.0.12.tar.gz
我这边直接下载到网站根目录了,解压后直接访问对应IP地址的/memadmin即可,即192.168.0.202/memadmin 端口服务,命中和反应时间是需要我们主要监控的指标。