[关闭]
@22221cjp 2016-08-17T15:27:17.000000Z 字数 2433 阅读 1416

MemberCache学习

技术


1. MemberCache安装

我的百度网盘路径: 我的文件/membercache目录下
安装epel软件源
安装命令:rpm -Uvh epel-release-6-7.noarch.rpm

要修改软件源中的链接

解决办法:

vi /etc/yum.repos.d/epel.repo

编辑[epel]下的baseurl前的#号去掉,mirrorlist前添加#号。正确配置如下:

[epel] name=Extra Packages for Enterprise Linux 6 - basearch #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6

安装命令:yum install memcache* -y

2. memcache使用

2.1 启动

2.2 连接

2.3 基本操作

3. memcache内存管理和失效机制

3.1 memcache如何避免内存碎片化

slab 和 chunk
每个slab是1M,slab中有很多chunk,同一个slab中chunk的大小是一样的。
不同的slab中chunk的大小是成增长因子(可在memcache启动参数中配置)增加的。
如 增长因子(glow factor)是2,第一个slab中的chunk都是 8k,那么第二个是16k,32k。。。以此类推。

3.2 如何分配内存

假设增长因子为2,有一个25k的数据,那么就会分配到32k chunk的slab中,如果这个slab已经没有空闲的chunk了呢?这时不会分配到64k的slab中,而是将32k中最老的chunk(LRU算法)替换掉

3.3 缓存失效

memcache缓存失效是被动的,也就是在get的时候判断数据是否失效,如果失效就get不到,同时删除掉这个key。

注意:如果没有设置过期时间,也不能保证该key永远存在于memcache中,因为可能被LRU替换掉

3.4 参数限制

key:最大250字节
value:最大1M
32位系统:memcache最大管理2G内存

4. memcache实战

使用过程:需要获取数据,先查memcache,有:直接返回,没有:查数据库,返回,并将数据写入memcache

插入数据:插入数据库、插入缓存

更新数据:更新数据库、更新缓存

删除数据:删除数据库、删除缓存

每天在凌晨(数据库负载低的时候)做数据库和memcache同步

另一个应用:中继Mysql主从同步,Mysql主从同步有一定延时,这时候向主中写数据的时候,也写入memcache,这时候如果立即读,优先从memcache中读,读不到的情况下,再从备机中读。这样会解决因为主从同步延时造成的数据不一致。Mysql5.6 有一个主从强一致特性,且不影响写入性能(同步写)

5. memcache集群

memcache不像mongo、mysql等其他数据库有集群方案、memcache理论上来说不支持集群,因为不同的节点之间不会同步数据,也不需要针对集群做单独的配置,集群中的节点和单机节点是完全一样的。也就是说,memcache集群访问控制需要我们自己在代码中实现。

5.1 如何将数据均匀的分布到集群中的不同节点上?

采用hash(key)的方式,但是hash函数如何选择?

一致性哈希算法(不能直接取摸)

若有n个节点,在key的取值范围内取n等分。

但是这种情况下,只要有一个节点down掉,压力就会传给相邻的下一个节点上。能不能在一个节点down的情况下,将原来的这个节点的数据,均匀的分配到其余所有的节点上。

可以这样:如实际有n个真实的节点。每个真实节点取n-1个虚拟节点。这样实际参与分配key范围的节点数是n*(n-1)。然后将节点交错开。

加入有3个真实节点:A、B、C
那么每个真实节点应该取2个虚拟节点,如下:
A: A0,A1
B: B0,B1
C: C0,C1
这样实际参与瓜分key范围的节点数是6个

A0-B0-A1-C0-B1-C1-

这样首位连起来形成一个环,加入A节点失效了,在环中A0 A1都失效了,这样会发现会均匀的分配到B和C上,同理其他也是这样。

6. memcache经典的问题和现象

6.1 缓存雪崩

缓存雪崩是指:因为某些节点挂掉,导致cache命中大大降低,然后短时间内大量的操作数据库,导致数据库也挂掉。

或者由于缓存失效时间比较集中,比如每6个小时失效一次,在失效时刻,会大量访问数据库,导致数据库挂掉。

解决方法:
1. 将缓存时间放长,比如24小时、48小时。然后每天夜里,在访问量比较小,负载比较低的时候,做缓存和数据库同步。

  1. 将缓存失效时间设置一个随机的值,如在3-9小时内随机,这样避免失效时间比较集中

6.2 缓存无底洞

当节点数越多的情况下,数据就越分散。这样在访问一个页面的时候,可能需要连很多个节点(这样大量的链接也耗费了很多资源),这样造成性能下降。

适当的选择key的映射方式,如user-111-age, user-111-name,user-111-address,这些key表示用户111的基本信息,如果完全将它们作为不同的key映射,很可能分散到不同的节点中。但是如取user-111作为key映射存储节点位置,则肯定在同一个节点中,这样只需要链接一次,就可以将该用户的所有信息都拿出来。

6.3 永远数据被踢

前面也提到过,并不是设置一个key没有过期时间,这个key就会永远存在于memcache中,因为还有LRU方式会踢掉。

如果防止永远数据被踢掉呢?

将永久数据很非永久数据分开存储。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注