Memcached是一个开源的、高性能的内存缓存软件,
Memcached的作用
通过在事先规划好的内存空间中临时缓存数据库中的各类数据,以达到减少业务对数据库的直接高并发访问,从而达到提升数据库的访问性能,回事网站集群动态应用服务的能力。
Memcached在企业集群架构中的应用场景

1、作为数据库的前端缓存应用
完整缓存(静态缓存 ),例如商品分类,预热,用户访问时可以只读取memcached缓存,不读取数据库了。
热点缓存,需要前端WEB程序配合,先预热数据库里的基础数据,然后再动态更新。

2、作为集群的session会话共享存储

Memcached服务在不同企业应用场景中的工作流程
a.当web程序需要访问后端数据库获取数据时会优先访问Memcached内存缓存 ,如果缓存中有数据就直接获取返回前端服务及用户,如果没有数据,再由程序请求后端的数据库服务器,获取 到对应的数据后,除了返回给前端服务及用户数据外,还会把数据放到Memcached内存中进行缓存 ,等待下次请求被访问,Memcached内存始终是数据库的挡箭牌,从而大大的减轻数据库的访问压力,提高整个网站架构的响应速度,提升了用户体验。
b.当程序更新,修改或删除数据库中已有数据时,会同时发送请求通知Memcached已经缓存过的同一个ID内容的旧数据失效外,还会通过相关机制 ,使得在用户访问新数据前,通过程序预先把更新过的数据摄像头到Memcached中缓存起来,这样可以减少数据库的访问压力,提升Memcached中的缓存 的命中率。
c.有一款数据库插件可以再写入更新数据库后,自动抛给Memchaed缓存起来,自身不再Cache,类似inotity.

3、Memcached服务分布式集群实现

a.程序端实现
程序加载所有的mc的ip列表 ,通过对Key做一致性hash
memcached集群和web服务集群是不一样的,所有memcached的数据总和才是数据库的数据。每台memcached都是部分数据

b.负载均衡器
通过对Key做一致性hash
一致性哈希算法的目的是不但保证每个对象只请求一个对应的服务器,而且当节点宕机缓存服务器的更新重新分配比例降到最低

4、缓存介绍 - 计算机体系缓存
硬盘 –> 内存 –> 三级缓存 –> 二级缓存 –> 一级缓存

5、缓存介绍 - 缓存应用系统

首先访问较快的存储介质, 如果命中且未生效则返回内容. 如果命中或失效则访问较慢的存储介质将内容返回同时更新缓存.

6、Memcached内存管理机制
malloc 动态内存分配
slab Allocator 内存分配机制
按照预先规定的大小,将分配给memcached的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,这些内存块不会释放,可以重复利用
chunk:用于缓存数据的内存空间或内存卖假
slab class 特定大小的多个chunk的集合

7、架构原理与分析

3.1 内存算法

Memcached利用slab allocation机制来分配和管理内存,它按照预先规定的大小,将分配的内存分割成特定长度的内存块,再把尺寸相同的内存块分成组,数据在存放时,根据键值 大小去匹配slab大小,找就近的slab存放,所以存在空间浪费现象。

传统的内存管理方式是,使用完通过malloc分配的内存后通过free来回收内存,这种方式容易产生内存碎片并降低操作系统对内存的管理效率。

Memcached的内存管理制效率高,而且不会造成内存碎片,但是它最大的缺点就是会导致空间浪费。因为每个 Chunk都分配了特定长度的内存空间,所以变长数据无法充分利用这些空间。如图二所示,将100个字节的数据缓存到128个字节的Chunk中,剩余的28个字节就浪费掉了。

如何避免内存浪费

预先计算出应用存入的数据大小,或把同一业务类型的数据存入一个Memcached服务器中,确保存入的数据大小相对均匀,这样就可以减少对内存的浪费

在启动时指定“-f”参数,能在某种程度上控制内存组之间的大小差异
在应用中使用Memcached时,通常可以不重新设置这个参数,使用默认值1.25进行部署
如果想优化Memcached对内存的使用,可以考虑重新计算数据的预期平均长度,调整这个参数来获得合适的设置值

3.2 删除机制(缓存策略)

Memcached的缓存策略是LRU(最近最少使用)加上到期失效策略。当你在memcached内存储数据项时,你有可能会指定它在缓存的失效时间,默认为永久。当memcached服务器用完分配的内时,失效的数据被首先替换,然后也是最近未使用的数据。在LRU中,memcached使用的是一种Lazy Expiration策略,自己不会监控存入的key/vlue对是否过期,而是在获取key值时查看记录的时间戳,检查key/value对空间是否过期,这样可减轻服务器的负载。

当空间占满时

使用LRU算法来分配空间,删除最近最少使用的key/value对
如果不使用LRU的话, 在启动参数上加入”-M”, 内存耗尽时,会返回报错信息

3.3 分布式概述

memcached不相互通信,那么memcached是如何实现分布式的呢?

memcached的分布式实现主要依赖客户端的实现.

当数据到达客户端, 客户端实现的算法会根据”键”来决定保存的memcached服务器.
服务器选定后, 命令他保存数据.
取的时候也一样, 客户端根据”键”选择服务器, 使用保存时候的相同算法就能保存选中和存的时候相同的服务器.

也就是说,存取数据分二步走,第一步,选择服务器,第二步存取数据。

使用什么算法选择服务器呢?

client 使用Hash算法来完成数据分散存储.

3.4 分布式算法(Hash算法)

当向memcached集群存入/取出key/value时,memcached客户端程序根据一定的算法计算存入哪台服务器,然后再把key/value值存到此服务器中。也就是说,存取数据分二步走,第一步,选择服务器,第二步存取数据。

常用的算法有两种: 余数计算分散法 和 一致性Hash算法.
3.4.1 余数计算分散法

标准的memcached分布式算法

CRC($key)%N

客户端首先根据key来计算CPC, 然后结果对服务器取模得到memcached服务器节点

被匹配到的服务器无法连接时
rehash: 尝试将连接的次数加到key后面, 重新hash

添加/移除服务器
余数计算分散发相当简单,数据分散也很优秀
几乎所有的缓存都会失效, 缓存重组的代价相当的大。
权重不易实现

3.4.2 一致性hash算法

将server的hash值分配至02^32的圆环上, 用同样的方法求出存储数值键的hash值并映射到圆上. 然后从数据映射到的位置开始顺时针查找, 将数据存放至找到的第一台服务器上. 如果超过02^32还找不到, 则将数据存放至第一台服务器.

如果新添/删除一台server, 在一致性hash算法下会有什么影响?

如图, 新添/删除server时, 只在圆上增加服务器的逆时针方向的第一台服务器上的键会受到影响。

优化一致性hash算法

一般的一致性hash算法最大限度的抑制了键的重新分配, 并且有的实现方式还采用了虚拟节点的思想

服务器的映射地点的分布非常的不均匀, 导致数据访问倾斜, 大量的key被映射到同一台服务器上.
虚拟节点: 每台机器计算出多个hash值, 每个值对应环上的一个节点位置
key的映射方式不变, 就多了层从虚拟节点到再映射到物理机的过程

优化后: 在物理机很少的情况下, 只要虚拟节点足够多, 也能使的key分布相对均匀. 提升了算法的平衡性

8、memcache安装和使用

# 安装依赖包
wget http://pan.aomtop.com:8820/soft/sources/libevent/libevent-2.0.21-stable.tar.gz 
tar -zxvf libevent-2.0.21-stable.tar.gz 
cd libevent-2.0.21-stable 
 ./configure --prefix=/opt/libevent 
make && make install 


#安装Memcached
wget http://memcached.org/latest
tar -zxvf memcached-1.x.x.tar.gz
cd memcached-1.x.x
./configure && make && make test && sudo make install

#启动memcached
memcached -p 11211 -d -u root -P /tmp/memcached.pid

-P是表示使用TCP,默认端口为11211
-d表示后台启动一个守护进程(daemon)
-u表示指定root用户启动,默认不能用root用户启动
-P表示进程的pid存放地点,此处“p”为大写“P”
-l,后面跟IP地址,手工指定监听IP地址,默认所有IP都在监听
-m后面跟分配内存大小,以MB为单位,默认为64M
-c最大运行并发连接数,默认为1024
-f 块大小增长因子,默认是1.25
-M 内存耗尽时返回错误,而不是删除项,即不用LRU算法 在64位系统中,会报libevent-1.4.so.2文件无法找到,解决办法是把32位目录里的同名文件链接至64位目录中,即像windows那样建立快捷方式。 Shell > /usr/local/lib/libevent-1.4.so.2 /usr/lib64/libevent-1.4.so.2 启动后如果发现没有端口在监听,是因为命动命令时带pid参数的“p”是大写“P”,你可能写成小写了。

php使用memcached

yum -y install libmemcached.x86_64 libmemcached-devel.x86_64

cd /usr/src
git clone https://github.com/php-memcached-dev/php-memcached.git
cd php-memcached/
git checkout php7
/alidata/server/php/bin/phpize
./configure --with-php-config=/alidata/server/php/bin/php-config
make
make install

实现集群中的session共享存储

php.ini
Session
session.save_path = “tcp://192.168.100.235:11211”
session.save_handler = memcache

查看memcached状态
printf “stats\r\n”|nc 192.168.100.235 11211

memcached管理后台
https://github.com/junstor/memadmin
安装memcache扩展

文档更新时间: 2019-12-19 21:02   作者:老王