JBOssCache和Memcached分布式缓存架构

(1)分布式缓存的伸缩性设计

和所有服务器都部署相同应用的应用服务器集群不同,分布式缓存服务器集群中不同服务器中缓存的数据各不相同,缓存访问请求不可以在缓存服务器集群中的任意一台处理,必须先找到缓存中有需要数据的服务,然后才能访问。这个特点会严重制约分布式缓存集群的伸缩性设计,因为新上线的缓存服务器没有缓存任何数据,而已下线的缓存服务器还缓存着网站的许多热点数据。

必须让新上线的缓存服务器对整个分布式缓存集群影响最小,也就是说新加入缓存服务器后应使整个缓存服务器集群中已经缓存的数据尽可能还被访问到,这是分布式缓存集群伸缩性设计的主要目标。


JBOssCache和Memcached分布式缓存架构_第1张图片

应用程序通过Memcached客户端方位Memcached服务器集群,Mencached客户端主要由一组API Memcached服务器集群路由算法、Mencached服务器集群列表及通信模块构成。

其中路由算法负责根据应用程序输入的缓存数据Key 计算得到的应该将数据写入到Memcached的哪台服务器(写缓存)或者应该从哪台服务器读数据(读缓存)。

一个典型的缓存写操作如上图所示,应用程序输入需要写缓存的数据<‘BEIJING’,DATA>,API将key("BEIJING")输入路由算法模块,路由算法根据KEY和Memcached集群服务器列表计算得到一台服务编号(NODE1),进而得到该机器的ip地址和端口(10.0.0.0:91000)。API调用通信模块和编号为NODE1的服务器通信,将数据<"BEIJING”,DATA>写入该服务器,完成一次分布式缓存的写操作。

(2)Memcached分布式缓存集群的伸缩性挑战

在Memcached分布式缓存系统中,对于服务器集群的管理,路由算法至关重要,和均衡负载算法一样,决定着究竟该访问集群中的哪台服务器。

分布式缓存的一致性Hash算法:

一致性Hash算法通过一个叫做一致性Hash环的数据结构实现KEY到缓存服务器的Hash映射。

JBOssCache和Memcached分布式缓存架构_第2张图片

  • 具体算法过程:先构造一个长度为0-2的32次方的整数环(这个环被称作一致性Hash环),根据节点名称的Hash值(其分布范围同样为0-2的32次方)将缓存服务器节点放置在这个Hash环上,然后根据需要缓存的数据的Key值计算得到其Hash值,然后在Hash环上顺时针查找距离这个Key的Hash值最近的缓存服务器节点,完成key到服务器的Hash映射查找。
  • 假设NODE1的Hash值是3,594,963,432,Node2的hash值为1,845,328,979,而Key0的hash值为2,534,256,785,那么key0在换上顺时针查找,找到最近的节点就是Node1。
  • 当缓存服务器需要扩容的时候,只需要将新加入的节点名称NOde3的hash值放入一致性hash环中,由于key是顺顺时针查找距离其最近的节点,因此新加入的节点只影响整个环中的一小段。
  • JBOssCache和Memcached分布式缓存架构_第3张图片
  • 假设node3的Hash值是2,790324,235,那么加入Node3后,key0(hash值为2,534,256,785)顺时针查找得到的节点就是Node3.
  • 加入新节点node3后,原来key大部分还能继续计算得到原来的节点,只有key3、key0从原来的node1重新计算到node3.这样就能保证大部分被缓存的数据还可以继续命中,虽然有小部分数据缓存在服务器中不能被读到,但是这个比例足够小,通过方位数据库获取也不会对数据库造成致命的负载压力。


(3)缓存指缓存应用部署在多个服务器组成的集群中,以集群方式提供缓存服务,其架构方式有两种:一种以JBossCache为代表的需要更新同步的分布式缓存,一种是以Mencached为代表的不互相通信的分布式缓存。

JBossCache的分布式缓存在集群中所有服务器中保存相同的缓存数据,当某台服务器有缓存数据更新时,会通知集群中其他机器更新缓存数据或清除缓存数据。

JBOssCache和Memcached分布式缓存架构_第4张图片

JBoss Cache通常将应用程序和缓存部署在同一台服务器上,应用程序可从本地快速获取缓存,但这种方式带来问题是缓存数据的数量受限于单一的服务器的内存空间,而且当集群规模较大的时候,缓存更新信息需要同步到所有集群所有机器,代价惊人,因而这种方案更多件与企业应用系统中,很少在大型网站中使用。

大型网站需要缓存的数据量一般都很庞大,可能会需要数TB的内存做缓存,这时候需要另一种分布式缓存:Memcached缓存,采用一种集中式的缓存集群管理,也被称作互不通信的分布式架构方式,缓存与应用分离部署,缓存系统部署在一组专门的服务器上,应用程序通过一致性Hash等路由算法选择缓存服务器远程访问缓存数据,缓存服务器之间不通信,缓存集群的模式可以很容易实现扩容,具有良好可伸缩性。


JBOssCache和Memcached分布式缓存架构_第5张图片

(1)通信协议:远程通信中要考虑两方面的要素:一是通信协议,即选择TCP协议还是UDP协议,一种是通信协议序列化协议,数据传输的两端,必须使用彼此可识别的数据序列化方式才能使通信得以完成,如XML、Json等文本序列化协议。Memcached使用Tcp协议(UDP也支持)通信,其序列化协议则是一套基于文本的自定义协议,非常简单,以一个命令关键字开头,后面是一组命令操作数,例如读取一个数据的命令协议是get

(2)高效的内存管理

内存管理中一个令人头痛问题就是内存碎片管理。操作系统、虚拟机垃圾回收在这方面想了很多办法:压缩、复制等。Memcached使用了一个非常简单的办法--固定空间分配,Mecached将内存空间分为一组slab,每个slab里又包含一组chunk,同一个slab里的每个chunk的大小是固定的,拥有相同大小chunk的slab被组织在一起,叫做slab_class,存储数据时根据数据的Size大小,寻找一个大于Size的最小chunk将数据写入,这种内存管理方式避免了内存碎片管理的问题,内存的分配和释放都是与chunk为单位的,和其他缓存一样,Memcached采用LRU算法释放最近最久未被访问的数据占用的空间,释放的chunk被标记为未用,等待下个一合适大小数据的写入。

这种方式也会带来内存浪费。数据只能存入一个比它大的chunk里,而一个chunk只能存一个数据,其余空间就被浪费了。


你可能感兴趣的:(分布式系统)