memcached分布式缓存

一 缓存

    当一个系统的数据io性能遇到瓶颈的时候,我们常用的手段是缓存,缓存的本质是一个内存hash表,数据缓存以一对key,value的形式存储在hash表中,其读写的时间复杂度为O(1),但是我们也要合理的使用缓存,否则会适得其反。那么什么样的数据要做缓存?如何合理的使用缓存呢?

1 频繁修改的数据不适合做缓存,如果一个数据频繁修改,会出现数据缓存写入后还未来得及读取缓存,数据已经失效。一般来说如果数据的读写比例为2:1(数据写入1次至少读取2次),这样缓存才有意义。

 2 只缓存热点数据,缓存数据保存在内存中,一个系统内存资源有限。

3 解决数据的不一致和脏读

4 保证缓存可用性,有效的预防缓存失效并采取相应的措施保证系统的运行,如果缓存系统崩溃,一般不是重启缓存服务器这么简单,通常的措施是采用分布式缓存来防止缓存服务器的宕机给系统带来的压力,这也是我这里主要说的内容。

5 缓存预热,缓存中存放的是热点数据,热点数据是缓存系统通过一定的算法不断的筛选出来的,这需要一定过得时间,所以新启动的缓存系统是没有任何的数据,因此在缓存系统筛选出热点数据的过程中系统的性能会受到一定的影响,所以在启动缓存系统时可以对一些常用的数据直接加载到内存中。

二 分布式缓存

    当系统数据达到一定的量级的时候就需要分布式缓存,以集群的方式来提供缓存服务,目前的缓存架构主要有两种,一种是需要更新同步的缓存,因为每个分布式中每个服务器保存着相同的数据,如果修改了一个数据,为了保证读到的数据是正确有效的,因此需要额外的手段将改的数据同步到其他的服务器上。还有一种是不需要通信更新同步的缓存,我们这里要说的memcached就是后者的代表。

    memcached采用一种集中式的缓存集群管理,缓存与应用分离部署,缓存系统在一组专门的服务器上,应用程序通过一致性hash等路由算法选择缓存服务器访问缓存数据,缓存服务器之间相互不通信,缓存集群的规模可以很容易的扩展,具有很好的伸缩性(如图)。

Memcached作为高速运行的分布式缓存服务器具有以下特点。

    协议简单:memcached的服务器客户端通信并不使用复杂的MXL等格式,而是使用简单的基于文本的协议。
基于libevent的事件处理:libevent是个程序库,他将Linux 的epoll、BSD类操作系统的kqueue等时间处理功能封装成统一的接口。memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。
内置内存存储方式:为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。由于数据仅存在于内存中,因此重启memcached,重启操作系统会导致全部数据消失。另外,内容容量达到指定的值之后memcached回自动删除不适用的缓存。

    Memcached不互通信的分布式:memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。各个memcached不会互相通信以共享信息。他的分布式主要是通过客户端实现的。
Memcached的内存管理:
    Memcached虽然称为“分布式“缓存服务器,但服务器端并没有“分布式”的功能。Memcached的分布式完全是有客户端实现的。现在我们就看一下memcached是怎么实现分布式缓存的。例如下面假设memcached服务器有node1~node3三台,应用程序要保存键名为“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的数据。首先向memcached中添加“tokyo”。将“tokyo”传给客户端程序库后,客户端实现的算法就会根据“键”来决定保存数据的memcached服务器。服务器选定后,即命令它保存“tokyo”及其值。同样,“kanagawa”“chiba”“saitama”“gunma”都是先选择服务器再保存。接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。接下来获取保存的数据。获取时也要将要获取的键“tokyo”传递给函数库。函数库通过与数据保存时相同的算法,根据“键”选择服务器。使用的算法相同,就能选中与保存时相同的服务器,然后发送get命令。只要数据没有因为某些原因被删除,就能获得保存的值。     


     最近的memcached默认情况下采用了名为Slab Allocatoion的机制分配,管理内存。在改机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。但是这中方式会导致内存碎片,加重操作系统内存管理器的负担。Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块,已完全解决内存碎片问题。Slab Allocation  的原理相当简单。将分配的内存分割成各种尺寸的块(chucnk),并把尺寸相同的块分成组(chucnk的集合),Memcached根据收到的数据的大小,选择最合适数据大小的Slab (图2) memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk,然后将数据缓存于其中。Memcached删除数据时数据不会真正从memcached中消失。Memcached不会释放已分配的内存。记录超时后,客户端就无法再看见该记录(invisible 透明),其存储空间即可重复使用。Lazy Expriationmemcached内部不会监视记录是否过期,而是在get时查看记录的时间戳,检查记录是否过期。这种技术称为lazy expiration.因此memcached不会再过期监视上耗费CPU时间。对于缓存存储容量满的情况下的删除需要考虑多种机制,一方面是按队列机制,一方面应该对应缓存对象本身的优先级,根据缓存对象的优先级进行对象的删除。Memcached会优先使用已超时的记录空间,但即使如此,也会发生追加新纪录时空间不足的情况。此时就要使用名为Least Recently Used (LRU)机制来分配空间。这就是删除最少使用的记录的机制。因此当memcached的内存空间不足时(无法从slab class)获取到新空间时,就从最近未使用的记录中搜索,并将空间分配给新的记录。

memcached 分布式原理

    memcached的分布式通过一致性hash算法实现,首先求出memcached服务器(节点)的哈希值, 并将其配置到0~232的圆(continuum)上。 然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。 然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。 如果超过232仍然找不到服务器,就会保存到第一台memcached服务器上。


这只是最简单的实现, 也有很多问题,比如算法对命中率的影响,如果某个节点的数据访问频率明显高于其他节点会造成摸个节点的压力明显增加,对于这些问题会有更复杂的方法来解决.这里介绍的更加详细:点击打开链接

三 适用memcached的业务场景?

1)如果网站包含了访问量很大的动态网页,因而数据库的负载将会很高。由于大部分数据库请求都是读操作,那么memcached可以显著地减小数据库负载。
2)如果数据库服务器的负载比较低但CPU使用率很高,这时可以缓存计算好的结果( computed objects )和渲染后的网页模板(enderred templates)。
3)利用memcached可以缓存session数据、临时数据以减少对他们的数据库写操作。
4)缓存一些很小但是被频繁访问的文件。
5)缓存Web 'services'(非IBM宣扬的Web Services,译者注)或RSS feeds的结果。

四 memcached如何处理容错
在节点失效的情况下,集群没有必要做任何容错处理。如果发生了节点失效,应对的措施完全取决于用户。节点失效时,下面列出几种方案供您选择:
1)忽略它! 在失效节点被恢复或替换之前,还有很多其他节点可以应对节点失效带来的影响。
2)把失效的节点从节点列表中移除。做这个操作千万要小心!在默认情况下(余数式哈希算法),客户端添加或移除节点,会导致所有的缓存数据不可用!因为哈希参照的节点列表变化了,大部分key会因为哈希值的改变而被映射到(与原来)不同的节点上。
3)启动热备节点,接管失效节点所占用的IP。这样可以防止哈希紊乱(hashing chaos)。
4)如果希望添加和移除节点,而不影响原先的哈希结果,可以使用一致性哈希算法(consistent hashing)。
5)两次哈希(reshing)。当客户端存取数据时,如果发现一个节点down了,就再做一次哈希(哈希算法与前一次不同),重新选择另一个节点(需要注意的时,客户端并没有把down的节点从节点列表中移除,下次还是有可能先哈希到它)。如果某个节点时好时坏,两次哈希的方法就有风险了,好的节点和坏的节点上都可能存在脏数据(stale data)。

参考文章:

 https://www.cnblogs.com/datastack/p/3855590.html

 https://www.cnblogs.com/52php/p/5675711.html

http://blog.csdn.net/cutesource/article/details/5848253

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值