Memcached
Memcached是一个高性能的分布式缓存系统,但是它的服务端没有分布式,服务器之间不会相互通信,而是依赖客户端,由客户端选择服务器。
具体步骤:
1、向Memcached添加数据,首先客户端的算法根据key值找到key值对应的服务器;
2、服务器选定之后,保存缓存数据。
3、获取数据的时候,也是根据key,定位到具体的服务器,从而获取数据。
所以,这个算法就显得尤为重要。
哈希算法
普通的哈希算法:根据key值取余。有一个很明显的缺点,一旦有一台机器宕机,除数一变,所有节点的值都会跟着变。
常见哈希算法:
1、MD5:Message-Digest Algorith5。把大容量信息压缩成一种保密格式,即把任意长度的字节串变换成定长的16进制数字串。
2、CRC:CyclicRedundancyCheck,循环冗余校验。
3、MurmurHash 算法:高运算性能,低碰撞率,现已应用到 Hadoop、libstdc++、nginx、libmemcached 等开源系统。Java 界中 Redis,Memcached,Cassandra,HBase,Lucene和Guava 都在使用它。
4、FNV 算法:Fowler-Noll-Vo 算法, FNV 能快速 hash 大量数据并保持较小的冲突率,它的高度分散使它适用于 hash 一些非常相近的字符串,比如 URL,hostname,文件名,text 和 IP 地址等。
5、Ketama 算法:一致性哈希算法的实现之一,其他的哈希算法有通用的一致性哈希算法实现,只不过是替换了哈希映射函数而已,但 Ketama 是一整套的流程。
一致性哈希算法
第一步:服务器形成一个环。
第二步:计算出key值的hash key,映射到环上,然后顺时针选择的最近的服务器就是该缓存的服务器。
如上图所示:hash key为1的数据落在B服务器上,
hash key为2、3的数据落在C服务器上,
hash key为4、5的数据落在D服务器上,
hash key为6、7的数据落在D服务器上,
假设服务器B宕机,那么依靠在它身上的节点就会顺时针挂在其他服务器上,那么会变成下图:
如上图所示:hash key为1的数据落在B服务器上 ,
hash key为1、2、3的数据落在C服务器上,
hash key为4、5的数据落在D服务器上,
hash key为6、7的数据落在D服务器上,
影响的节点只有1号,把影响降到了最低。
但是,会存在一个问题,服务器分布不均衡,这时候,就要使用虚拟节点了。如下:
1,2,3,4都会落在服务器A上,不均匀,可创建虚拟节点优化此现象。
落在哪个服务器的虚拟节点上,就等于落在哪个服务器上了。
hash key为1、4的数据落在A服务器上,
hash key为2的数据落在B服务器上,
hash key为3的数据落在C服务器上,
就很均匀啦~
虚拟节点越多,hash环上的节点就越多,被均匀分布的概率就越大。