Memcache
目录
Memcache 1
一、Memcache介绍 1
1.What is Memcache? 1
2.Memcache作用? 1
3.互联网常见缓存软件: 1
4.Memcached在企业工作中的应用场景 1
5.Memcached服务的软件特点 2
6.Memcached工作原理 3
7.Memcached工作原理深入(内存管理机制) 4
Memcached内存管理机制缺点及优化策略 4
二、Memcache部署 4
1.安装memcached 5
2.Memcached状态查看 6
3.关闭memcached,测试数据是否丢失 9
4.Memcached服务管理命令 9
三、监控Memcached 10
1.memcache.php 10
2.check_tcp 10
3.Nagios check_memcached插件 12
一、Memcache介绍
1.What is Memcache?
Memcache是一款开源的、高性能的纯内存缓存服务软件,Memcache项目诞生于2003年。Mem就是内存的意思,cache是缓存的意思,d是daemon的意思。Memcache服务分为服务端和客户端两部分,C/S模式。
服务端软件:memcached-1.4.13
客户端软件:memcache-2.25
Memcache官方网站:http://memcache.org
2.Memcache作用?
在启动Memcached时,会指定一个内存大小参数,然后会被分配一个内存空间。当我们读取数据库后的业务数据,放入Memcached缓存中,下一次请求同样数据的用户,直接去Memcachd取数据返回给用户。
这样做的好处?
(1)对于用户来说,用户访问网站更快了,体验更好了。
(2)数据库压力降低了,内存没有的时候,就会请求数据库。
(3)提升网站并发访问,服务器数量变少。
3.互联网常见缓存软件:
Memcached 纯内存 用来缓存后端数据库的数据(用户信息,帖子,博文等)
Memcachedb 内存+磁盘 新浪开发,Memcacehd+BDB 缓存后端数据库数据,直接做数据库用
Redis 内存+磁盘 作用同Memcachedb 主从复制,数据类型更丰富。
squid 内存+磁盘
varinish 内存
缓存静态图片,JS,CSS,HTML,视频等。CDN就是利用这类软件做的分布式缓存。
4.Memcached在企业工作中的应用场景
1|作为数据库的前端缓存应用
(1)完整缓存(易)
例如:京东的商品分类,就可以事先放到Memcached内存里,然后在对外提供数据访问。这个被称之为预热。
此时可以只读取缓存就能读到商品分类数据,无需读取数据库,所以数据库的压力就降下来了。
(2)热点缓存(难)
热点缓存一般是指用户更新的商品,例如淘宝的卖家,当卖新增商品后,淘宝网的程序就会把商品写入数据库,然后读取写入的数据,把这部分数据,放入Memcached内存中,下一次访问这个商品的请求直接从Memcached内存中取走了。这种方法用来缓存网站热点的数据,即Memcached中缓存经常被访问的数据。
这个过程可以通过程序实现,也可以在数据库上安装Memcache插件,直接由数据库触发更新内容到Memcached中。
2|Memcached作为集群后端的session会话保持
web集群session共享存储设置:
默认php.ini中session的类型和配置路径:
#session.save_handler = files
#session.save_path = "/tmp"
修改成如下配置:
session.save_handler = memcache
session.save_path = "tcp://10.0.0.18:11211"
3|Memcached分布式缓存
[分布式应用1]
Memcache支持分布式,我们在应用服务器上改造,就可以更好的支持。
例如:可以根据key适当进行有规律的,比如以用户为主的网站来说,每个用户都有UserID,那么可以根据ID来进行提取和存取,比如1开头的用户保存在第一台Memcache服务器上,以2开头的保存在第二台Memcache服务器上,存取数据都先按照UserID来进行转换和存取。
[分布式应用2]
在应用服务器上通过程序及URL_HASH,一致性哈希算法去访问Memcached服务
[分布式应用3]
门户网站,例如百度,会通过一个中间件代理(透明)负责请求后端的Cache服务。
[分布式应用4]
可以用常见的LVS,haproxy做Cache的负载均衡,和普通web应用服务相比,这里的重点是调度算法,Cache一般会选择URL_HASH及一致性hash算法。
分布式缓存集群:
(1)所有MC服务器内存的内容都是不一样的。这些服务器内容加起来接近数据库的容量
(2)通过在客户端程序或者MC的负载均衡器上用HASH算法,让同一内容都分配到一个MC服务器
(3)普通的HASH算法对于节点宕机会带来大量的数据流动(失效),可能会引起雪崩效应
(4)一致性HASH算法可以让节点宕机对节点的数据流动(失效)降到最低
5.Memcached服务的软件特点
C/S模式架构
Memcached是一套C/S模式架构的软件,由C语言编写,总共2000多行代码。
协议简单
使用基于文本行的协议,能通过telnet/nc直接操作Memcached服务存取数据。
异步I/O 模型,使用libevent作为事件处理通知机制。
libevent是一套利用C开发的程序库,它将BSD系统的kqueue,Linux系统的epoll等事件处理功能封装成一个接口,确保即使服务器端的连接数增加也能发挥很好的性能。
key/value键值数据类型
被缓存的数据以key/value键值形式存在
纯内存存取管理模式
Memcached有一套自己管理内存的方式,这套管理方式非常高效,即全部数据都存放于Memcached服务事先分配的内存中,无持久性存储的设计,和系统内存一样,重启系统或Memcached服务,Memcached内存中的数据库丢失。
当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU算法删除过期的缓存数据。也可以对存储的数据设置过期时间,这样过期后数据自动被清除,服务本身不会监控过期,而是在访问的时候查看key的时间戳判断是否过期。
如果希望重启后,数据依然保留,那么就需要类似sina开发的memcacehdb,redis等持久化内存缓存系统。
多个Memcached集群节点互不通信
各个Memcached服务器之间互相不通信,都是独立的存取数据,不共享任何信息,并且数据内容应该是不一致的。通过对客户端的设计,让Memcached具有分布式,能支持海量缓存和大规模应用。
淘宝的Tengine支持了一致性HASH模块
http://tengine.taobao.org/document_cn/http_upstream_consistent_hash_cn.html
6.Memcached工作原理
Memcached是一套C/S模式架构的软件,在服务端启动服务守护进程可以为memcached服务器指定监听的IP地址、端口号、并发访问连接数以及分配多少内存来处理客户端的请求参数。
Memcached由C语言开发, 全部代码2000多行,采用异步I/O模式,其实现方式是基于libevent事件的单进程、单线程的。使用libevent作为事件通知机制,多个服务器端可以协同工作,但这些服务器端之间是没有任何通信联系的,每个服务器端只对自己的数据进行管理。应用程序端通过制定缓存服务器的IP地址和端口,就可以连接memcacehd服务互相通信。
需要被缓存的数据以key/value键值对的形式保存在服务器端预分配的内存区中,每个被缓存的数据都有唯一的标识key,操作Memcached中的数据通过这个唯一标识key进行。缓存到Memcached中的数据仅放置在Memcached服务预分的内存中,而非存储在Memcached所在的磁盘上,因此存取速度非常快。
由于Memcached服务自身没有对缓存的数据进行持久性存储的设计,因此,在服务器端的memcached服务进程重启之后,存储在内存中的这些数据就会丢失。且当内存中缓存的数据容量达到启动时设定的内存值时,就自动使用LRU算法删除过期的缓存数据。
开发Memcached的初衷就是仅为内存缓存而设计的,因此并没有过多考虑数据的永久存储问题。因此,如果使用memcached作为缓存数据服务,要考虑数据丢失后带来的问题,例如:是否可以重新生成数据,还有,在高并发场合数据丢失会不会导致网站架构雪崩。
企业场景如何正确重启Memcached集群服务?在前端控制入口访问量。然后,启动Memcached集群并进行数据预热,所有数据都预热完毕后,在逐步的开放前端流量。
7.Memcached工作原理深入(内存管理机制)
说Memcached内存管理机制之前,先说一下malloc。
malloc的全称是memory allocation(动态内存分配),当无法知道内存具体位置的时,想要绑定真正的内存空间,就需要用到动态分配内存。
早期的Memcached内存管理方式是通过malloc分配的内存,使用完后通过free来回收内存。这种方式容易产生内存碎片并降低操作系统对内存的管理效率。加重操作系统内存管理器的负担,最坏的情况下,会导致操作系统比memcached进程本身还慢,为了解决上述问题,Slab Allocator内存分配机制就诞生了。
现在的Memcached利用Slab Allocation机制来分配和管理内存的。
Slab Allocation内存分配机制原理是按照预先规定的大小,将内存给Memcached服务的内存预先分割成特定长度的内存块(chunk),再把尺寸相同的内存块(chunk)分成组(chunks slabclass),这些内存块不会释放,可以重复利用。
Memcached服务器中保存着slab内空闲chunk的列表,根据该列选择chunk,然后将数据缓存于其中。当有数据存入时,Memcached根据接收到的数据大小,选择最合适数据大小的slab分配一一个能存下这个数据的最小内存快(chunk)。
例如:有100个字节的一个数据,就会被分配存入112字节的一个内存块中,这样会有12字节被浪费掉,这部分空间不能被使用了,这也是SlabAllocator机制的一个缺点。
Memcached内存管理机制小结:
(1)memcached的早期内存管理机制为malloc(动态内存分配)
(2)malloc产生内存碎片,导致操作系统性能急剧下降
(3)slab内存分配机制可以解决内存碎片问题
(4)memcached服务的内存预先分割成特定长度的内存块,称为chunk,用于缓存数据的内存空间或内存块,相当于硬盘的block,只不过磁盘的每一个block都是相等的,而chunk只有同一个slab class内才是相等的
(5)slab class是特定大小的包含多个chunk的集合或者组,一个memcached包含多个slab class,每个slab class包含多个相同大小的chunk
(6)slab机制也有缺点,chunk的空间会浪费。
8.Memcached内存管理机制缺点及优化策略
避免浪费内存的办法就是,预先计算出应用存入的数据大小,或把同一业务类型的数据存入一个Memcached服务器中,确保存入的数据大小相对均匀,这样就可以减少内存的浪费。还有一种办法是,在启动时指定"-f"参数,能在某种程度上控制内存组之间的大小差异。在应用中使用Memcached时,通常可以不重新设置这个参数,使用默认值1.25进行部署。如果想优化Memcached对内存的使用,可以考虑重新计算数据的预期平均长度,调整这个参数来获得合适的设置值。
-f<factor> chunk size growth factor(default:1.25!)
memcachked在启动时制定Growth Factor因子(通过-f选项),就可以控制slab之间的差异。默认值为1.25
memcached -f 2 vv
二、Memcache部署
1.安装memcached
(1)安装libevent
wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
[root@memcached tools]# tar xf libevent-1.4.13-stable.tar.gz
[root@memcached tools]# cd libevent-1.4.13-stable
[root@memcached libevent-1.4.13-stable]# ./configure
[root@memcached libevent-1.4.13-stable]# make && make install
(2)安装memcached
[root@memcached tools]# tar xf memcached-1.4.13.tar.gz
[root@memcached tools]# cd memcached-1.4.13
[root@memcached memcached-1.4.13]# ./configure
[root@memcached memcached-1.4.13]# make && make install
(3)启动memcached
配置ld.so.conf路径防止启动memcached时报错
memcached -h
memcached:error while loading shared libraries:libevent-1.4.so.2:cannot open shared object file:
No such file or directory
echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig
[root@memcached ~]# memcached -d -c10240 -p11211 -m16 -P /var/run/memcached.pid -uroot -l 192.168.51.91
-d 作为守护进程在后台运行
-m 指定memcached服务可以缓存数据的最大内存。默认为64MB
-c 最大并发访问连接数(default:1024),按照服务器的并发访问量来设定
-p 指定memcached服务侦听TCP端口号,默认额外11211
-P 指定pid
-u 运行memcached的用户
-l 指定侦听的服务器IP地址
-vv以very vrebose模式启动,调试信息和错误输出到控制台
-P设置保存memcached的pid文件($$)
-h 显示所有可用选项
-f 调优因子
(4)检查启动结果
[root@memcached ~]# ps -ef|grep memcached
root 117028 1 0 19:38 ? 00:00:00 memcached -d -c10240 -p11211 -m16 -P /var/run/memcached.pid -uroot -l 192.168.51.91
root 117037 107682 0 19:38 pts/1 00:00:00 grep memcached
[root@memcached ~]# ss -ntulp|grep 11211
udp UNCONN 0 0 192.168.51.91:11211 *:* users:(("memcached",117028,27))
tcp LISTEN 0 128 192.168.51.91:11211 *:* users:(("memcached",117028,26))
[root@memcached ~]#
(5)写入数据检查结果
向memcached中添加数据:键值对
[root@memcached ~]# printf "set key001 0 0 10\r\nxiaoyi1234\r\n"|nc 192.168.51.91 11211
STORED
[root@memcached ~]# printf "get key001\r\n"|nc 192.168.51.91 11211
VALUE key001 0 10
xiaoyi1234
END
[root@memcached ~]#
[root@memcached ~]# telnet 192.168.51.91 11211
Trying 192.168.51.91...
Connected to 192.168.51.91.
Escape character is '^]'.
get key001
VALUE key001 0 10
xiaoyi1234
END
2.Memcached状态查看
stats 统计memcached的各种信息
stats settings 可以查看一些memcached设置
stats slabs查看slabs相关情况,通过这个命令能获取每个slabs的chunk size长度,从而确定数据到底保存在哪个slab
stats items查看items相关情况
stats sizes 查看存在的item个数和大小
stats cachedump查看key value
stats reset 重新统计数据
[root@memcached ~]# printf "stats\r\n"|nc 192.168.51.91 11211
STAT pid 117028
STAT uptime 737
STAT time 1449229825
STAT version 1.4.13
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 0.003999
STAT rusage_system 0.029995
STAT curr_connections 5
STAT total_connections 22
STAT connection_structures 6
STAT reserved_fds 20
STAT cmd_get 5
STAT cmd_set 2
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 3
STAT get_misses 2
STAT delete_misses 0
STAT delete_hits 0
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 250
STAT bytes_written 134
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 82
STAT curr_items 1
STAT total_items 2
STAT evictions 0
STAT reclaimed 0
END
####################################################
stats settings
STAT maxbytes 16777216
STAT maxconns 10240
STAT tcpport 11211
STAT udpport 11211
STAT inter 192.168.51.91
STAT verbosity 0
STAT oldest 0
STAT evictions on
STAT domain_socket NULL
STAT umask 700
STAT growth_factor 1.25
STAT chunk_size 48
STAT num_threads 4
STAT num_threads_per_udp 4
STAT stat_key_prefix :
STAT detail_enabled no
STAT reqs_per_event 20
STAT cas_enabled yes
STAT tcp_backlog 1024
STAT binding_protocol auto-negotiate
STAT auth_enabled_sasl no
STAT item_size_max 1048576
STAT maxconns_fast no
STAT hashpower_init 0
STAT slab_reassign no
STAT slab_automove no
END
#######################################################
stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 1
STAT 1:free_chunks 1
STAT 1:free_chunks_end 10920
STAT 1:mem_requested 82
STAT 1:get_hits 4
STAT 1:cmd_set 2
STAT 1:delete_hits 0
STAT 1:incr_hits 0
STAT 1:decr_hits 0
STAT 1:cas_hits 0
STAT 1:cas_badval 0
STAT 1:touch_hits 0
STAT active_slabs 1
STAT total_malloced 1048512
END
##############################################
stats items
STAT items:1:number 1
STAT items:1:age 7998
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0
STAT items:1:evicted_time 0
STAT items:1:outofmemory 0
STAT items:1:tailrepairs 0
STAT items:1:reclaimed 0
STAT items:1:expired_unfetched 0
STAT items:1:evicted_unfetched 0
END
######################################
stats sizes
STAT 96 1
END
####################################
3.关闭memcached,测试数据是否丢失
[root@memcached ~]# printf "set key001 0 0 10\r\nxiaoyi1234\r\n"|nc 192.168.51.91 11211
STORED
[root@memcached ~]# printf "get key001\r\n"|nc 192.168.51.91 11211
VALUE key001 0 10
xiaoyi1234
END
[root@memcached ~]# pkill memcached
[root@memcached ~]# memcached -d -c10240 -p11211 -m16 -P /var/run/memcached.pid -uroot -l 192.168.51.91
[root@memcached ~]# printf "get key001\r\n"|nc 192.168.51.91 11211
END
4.Memcached服务管理命令
操作memcached命令的语法:
<command name> <key><flags><exptime><bytes>\r\n
-<command name>是set,add,repalce
set"存储此数据"
add"存储此数据,只在服务器未保留此键值的数据时"
replace"存储此数据,只在服务器曾保留此键值的数据时"
-<key>是接下来的客户端所要求存储的数据的键值
-<flags>是在取回内容时,与数据和发送块一同保存服务器上的任意16位无符号×××(用十进制来书写)。客户端可以用它作为"位域"来存储-一些特定的信息;它对服务器是不透明的。
-<exptime>是终止时间。如果为0,该项永不过期(虽然它可能被删除,以便为其他缓存项目腾出位置)。如果非0(Unix时间戳或当前时刻的秒偏移),到达终止时间后,客户端无法再获得这项内容
-<bytes>是随后的数据区块的字节长度,不包括"\r\n".它可以是0(这时后面跟随一个空的数据区块)。
-<data block>是大段的8位数据,其长度由前面的命令行中的<bytes>指定。
-"STORED\r\n"表明成功。
-"NOT_S"表明数据没有被存储,但不是因为发生错误。这通常意味着add或replace命令的条件不成立,或者,项目已经位列删除队列。
三、监控Memcached
1.memcache.php
下载地址http://livebookmark.net/memcachephp/memcachephp.zip
vim memcache.php
.....
define('ADMIN_USERNAME','memcache'); // 定义用户名
define('ADMIN_PASSWORD','password'); // 定义密码
.....
$MEMCACHE_SERVERS[] = 'mymemcache-server:11211'; //定义要查看的ip和端口
$MEMCACHE_SERVERS[] = 'mymemcache-server2:11212'; //可添加多个
2.check_tcp
通过nagios的check_tcp脚本,信息量太大,不过可以将此信息通过自己编写脚本自定义监控memcached,不过有现成的Nagios-Plugins-Memcached插件
[root@memcached html]# /usr/local/nagios/libexec/check_tcp -H 192.168.51.91 -p 11211 -t 5 -E -s 'stats\r\nquit\r\n' -e 'uptime' -M crit
TCP OK - 0.001 second response time on port 11211 [STAT pid 119204
STAT uptime 9454
STAT time 1449493920
STAT version 1.4.13
STAT libevent 1.4.13-stable
STAT pointer_size 64
STAT rusage_user 0.193970
STAT rusage_system 0.250961
STAT curr_connections 5
STAT total_connections 270
STAT connection_structures 7
STAT reserved_fds 20
STAT cmd_get 2
STAT cmd_set 4
STAT cmd_flush 0
STAT cmd_touch 0
STAT get_hits 1
STAT get_misses 1
STAT delete_misses 0
STAT delete_hits 0
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 1982
STAT bytes_written 264950
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 328
STAT curr_items 4
STAT total_items 4
STAT evictions 0
STAT reclaimed 0
END]|time=0.000525s;;;0.000000;5.000000
3.Nagios check_memcached插件
http://search.cpan.org/CPAN/authors/id/Z/ZI/ZIGOROU/Nagios-Plugins-Memcached-0.02.tar.gz
[root@memcached ~]# tar xf Nagios-Plugins-Memcached-0.02.tar.gz
[root@memcached ~]# cd Nagios-Plugins-Memcached-0.02
[root@memcached Nagios-Plugins-Memcached-0.02]# perl Makefile.PL
*** Module::AutoInstall version 1.03
*** Checking for Perl dependencies...
[Core Features]
- Carp::Clan ...missing.
- Cache::Memcached ...missing.
- FindBin ...loaded. (1.50)
- Nagios::Plugin ...missing.
- Time::HiRes ...loaded. (1.9721)
==> Auto-install the 3 mandatory module(s) from CPAN? [y] y
Can't locate CPAN.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/AutoInstall.pm line 635, <STDIN> line 1.
yum install perl-CPAN -y
[root@memcached Nagios-Plugins-Memcached-0.02]# perl Makefile.PL
[root@memcached Nagios-Plugins-Memcached-0.02]# make && make install
command.cfg
define command{
command_name check_memcached_response
command_line $USER1$/check_memcached -H $HOSTADDRESS$ -w $ARG1$ -c $ARG2$
}
define command{
command_name check_memcached_size
command_line $USER1$/check_memcached -H $HOSTADDRESS$ --size-warning $ARG1$ --size-critical $ARG2$
}
define command{
command_name check_memcached_hit
command_line $USER1$/check_memcached -H $HOSTADDRESS$ --hit-warning $ARG1 --hit-critical $ARG2$
}
vim host.cfg
define host{
use linux-server
host_name memcached
alias memcached
address 192.168.51.91
}
vim services.cfg
define service {
use generic-service
host_name memcached
service_description memcached
check_command check_memcached_response!30!40
}
define service {
use generic-service
host_name memcached
service_description memcached_size
check_command check_memcached_size!30!40
}
define service {
use generic-service
host_name memcached
service_description memcached_hit
check_command check_memcached_hit!40!30
}
[root@memcached objects]# /usr/local/nagios/libexec/check_memcached -H 192.168.51.91 -w 30 -c 40
Base class package "Nagios::Plugin" is empty.
(Perhaps you need to 'use' the module which defines that package first,
or make that module available in @INC (@INC contains: /usr/local/nagios/libexec/../lib /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .).
at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 6
BEGIN failed--compilation aborted at /usr/local/share/perl5/Nagios/Plugins/Memcached.pm line 6.
Compilation failed in require at /usr/local/nagios/libexec/check_memcached line 12.
BEGIN failed--compilation aborted at /usr/local/nagios/libexec/check_memcached line 12.
[root@memcached objects]#
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum -y install perl-Params-Validate perl-Math-Calc-Units perl-Regexp-Commonperl-Class-Accessor perl-Config-Tiny perl-Nagios-Plugin.noarch
[root@memcached Nagios-Plugins-Memcached-0.02]# /usr/local/nagios/libexec/check_memcached -H 192.168.51.91
MEMCACHED OK - OK
转载于:https://blog.51cto.com/gongxiaoyi/1825483