聊聊缓存

说起缓存,其实就是在说哈希,缓存其实就是用哈希表临时存储中间结果,加上哈希O(1)的复杂度本身固有的特性,可以为我们的系统大大节省耗时。

哈希分为多种,不同的方式计算性能和碰撞率不同。最常规的方式,就是hash取模,最低级装备,满足不了分布式缓存的需要。随着系统访问量增加,缓存系统不得不通过增加机器节点的方式提高集群的相应速度和数据承载量,一旦增加机器节点,缓存数据需要重新建立,甚至是进行整体的缓存数据迁移,工作量和风险都会增加。分布式缓存,主要面临下面两个问题:

  1. n个节点中有一个宕掉了,或者需要新增机器,怎样做到cache的迁移做到最少,降低cache无法命中的概率。
  2. 集群中节点的硬件处理性能有高有低,想让性能高的节点多被分配一些Job,保证集群负载均衡。

那怎样的分布式缓存系统能够最大限度的解决上面的问题呢?

随之而来的一致性哈希算法就是专门来解决这个问题的。我们直接来看一下Consistent Hashing(1997年Consistenthashing and random trees)这种改良型的一致性哈希装备是怎么产生的。

一致性哈希算法其实也是采用取模的方法,只不过不是对机器取模,而是对2^32取模。那为什么要讲Consistent Hashing呢,因为这套装备最大限度地降低cache无法命中的概率,并在服务器数量比较少的时候通过增加虚拟节点取得比较好的负载均衡的效果。

首先讲为什么对2的32次方 取模,因为机器IP为32位,这样使用IP哈希计算后的结果肯定处于0~ 2的32-1之间。将这个区间比作一个圆环,圆环上有2的32次方个点,则集群上的机器一定散落在这些点上。同样我们也将我们要缓存的数据取md5值后同样对2的32次方取模,将其映射到这个圆环上,放心2^32有43亿大小,对于一般的缓存系统来说这个量级也是足够的。从缓存数据的位置逆时针找到第一个机器就是该数据的缓存物理机器,以后直接取这台机器查找数据即可。先在这阐明一点,一致性哈希采用TreeMap作为数据结构。

这里引用一篇文章能更好的解释Consistent Hashing算法。

假设你已经通过上面这篇文章理解了Consistent Hashing这种利器,同时附一篇该利器的代码实现。

另外延伸另外一种hash算法-MurmurHash。该算法已经应用到Redis,Memcached,Cassandra,HBase,Lucene等开源项目中,速度快,而且碰撞率低。以后可以尽量应用该算法来解决哈希问题。

你可能感兴趣的:(缓存)