一个简单的consistent hashing的例子,很容易理解。
首先有一个设备类,定义了机器名和ip:
- public class Cache
- {
- public String name;
- public String ipAddress;
- }
然后是主要的实现:
- public class Shard<T> {
- //hash 算法并不是保证绝对的平衡,如果 cache 较少的话,对象并不能被均匀的映射到 cache 上,
- //所以增加虚拟节点
- private TreeMap<Long, T> nodes;
- private List<T> shards; //节点碎片
- private final int NODE_NUM = 10; // 每个机器节点关联的虚拟节点个数
- public Shard(List<T> shards) {
- this.shards = shards;
- init();
- }
- private void init() {
- nodes = new TreeMap<Long, T>();
- for (int i = 0; i < shards.size(); i++)
- { // 遍历真实节点
- final T shardInfo = shards.get(i);
- for (int n = 0; n < NODE_NUM; n++)
- {
- // 真实节点关联虚拟节点,真实节点是VALUE;
- nodes.put((long) Hash("SHARD-" + i + "-NODE-" + n), shardInfo);
- }
- System.out.println(shardInfo);
- }
- }
- public T getShardInfo(String key) {
- SortedMap<Long, T> tail = nodes.tailMap((long) Hash(key));
- if (tail.size() == 0) {
- return nodes.get(nodes.firstKey());
- }
- //找到最近的虚拟节点
- return tail.get(tail.firstKey());
- }
- /**
- * 改进的32位FNV算法,高离散
- *
- * @param string
- * 字符串
- * @return int值
- */
- public static int Hash(String str)
- {
- final int p = 16777619;
- int hash = (int) 2166136261L;
- for (byte b : str.getBytes())
- hash = (hash ^ b) * p;
- hash += hash << 13;
- hash ^= hash >> 7;
- hash += hash << 3;
- hash ^= hash >> 17;
- hash += hash << 5;
- return hash;
- }
- }
到这里就完了,是不是很简单,下面来测试下:
- public class Test
- {
- /**
- * @param args
- */
- public static void main(String[] args)
- {
- List<Cache> myCaches=new ArrayList<Cache>();
- Cache cache1=new Cache();
- cache1.name="COMPUTER1";
- Cache cache2=new Cache();
- cache2.name="COMPUTER2";
- myCaches.add(cache1);
- myCaches.add(cache2);
- Shard<Cache> myShard=new Shard<Cache>(myCaches);
- Cache currentCache=myShard.getShardInfo("info1");
- System.out.println(currentCache.name);
- // for(int i=0;i<20;i++)
- // {
- // String object=getRandomString(20);//产生20位长度的随机字符串
- // Cache currentCache=myShard.getShardInfo(object);
- // System.out.println(currentCache.name);
- // }
- }
- public static String getRandomString(int length) { //length表示生成字符串的长度
- String base = "abcdefghijklmnopqrstuvwxyz0123456789";
- Random random = new Random();
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < length; i++) {
- int number = random.nextInt(base.length());
- sb.append(base.charAt(number));
- }
- return sb.toString();
- }
- }
我们有两台设备,computer1和computer2,第一次初始化要构建一个2的32次方的环,并往上面放设备。这个环由改进的FNV算法实现。位置也由hash算法确定。
但我们只有两台设备,很明显在环上会分布不均匀(这个就不解释了,网上很多资料)。于是我们每台设备增加10个虚拟设备。
最后分布如下:
- <SPAN style="COLOR: #003300">-1561290727=Hash.Cache@10f11b8,
- -1083588870=Hash.Cache@10f11b8,
- -697149481=Hash.Cache@10f11b8,
- -253517545=Hash.Cache@10f11b8,
- 397383558=Hash.Cache@10f11b8,
- 1078505027=Hash.Cache@10f11b8,
- 1810977445=Hash.Cache@10f11b8,
- 1844081498=Hash.Cache@10f11b8,
- 2004894833=Hash.Cache@10f11b8,
- 2051863688=Hash.Cache@10f11b8</SPAN>
-2147483648到2147483647之间是不是比较均匀,这是java的,如果是c#的就是0~2的32次方。我们hash计算出KEY值为2049553054,然后顺时针找到最近的位置,即为
结果我们定位到了COMPUTER1
最好我们要看看平衡性如何:取消上面注释的代码,循环20次,得到结果如下:
COMPUTER1
COMPUTER2
COMPUTER1
COMPUTER2
COMPUTER1
COMPUTER2
COMPUTER1
COMPUTER1
COMPUTER1
COMPUTER2
COMPUTER2
COMPUTER2
COMPUTER1
COMPUTER2
COMPUTER1
COMPUTER1
COMPUTER1
COMPUTER2
COMPUTER1
COMPUTER2
大家可以自己取试试,
FNV哈希算法是一种高离散性的哈希算法,特别适用于哈希非常相似的字符串,例如:URL,IP,主机名,文件名等。
以下服务使用了FNV:
1、calc
2、DNS
3、mdbm key/value查询函数
4、数据库索引hash
5、主流web查询/索引引擎
6、高性能email服务
7、基于消息ID查询函数
8、auti-spam反垃圾邮件过滤器
9、NFS实现(比如freebsd 4.3, linux NFS v4)
10、Cohesia MASS project
11、Ada 95的spellchecker
12、开源x86汇编器:flatassembler user-defined symbol hashtree
13、PowerBASIC
14、PS2、XBOX上的文本资源
15、非加密图形文件指纹
16、FRET
17、Symbian DASM
18、VC++ 2005的hash_map实现
19、memcache中的libketama
20、 PHP 5.x
21、twitter中用于改进cache碎片
22、BSD IDE project
23、deliantra game server
24、 Leprechaun
25、IPv6流标签
相关推荐
在分布式系统中,常常需要使用缓存,而且通常是集群,访问缓存和添加缓存都需要一个 hash 算法来寻找到合适的 Cache 节点。但,通常不是用取余hash,而是使用我们今天的主角—— 一致性 hash 算法。
总之,`ConsistentHashing`是一个用于Python的工具,它实现了高效的一致性哈希算法,有助于构建稳定、可扩展的分布式系统。对于处理大数据量、高并发场景以及需要动态扩展的系统,这个库是十分实用的。
一致性哈希算法(Consistent Hashing)是一种在分布式系统中实现负载均衡的算法,尤其在分布式缓存如Memcached和Redis等场景下广泛使用。它解决了传统哈希算法在节点增减时导致的大量数据迁移问题,提高了系统的可用...
一致性哈希算法(Consistent Hashing)是一种在分布式系统中平衡数据分布的策略,尤其适用于缓存服务如Memcached或Redis。它的核心思想是通过哈希函数将对象映射到一个固定大小的环形空间中,然后将服务器也映射到这个...
总的来说,一致性哈希算法通过环形空间和虚拟节点的设计,实现了在动态调整系统规模时,尽可能少地改变已分配的对象,提高了系统的扩展性和可用性。随着节点数量的增加,一致性哈希能够保持较高的缓存命中率,减轻对...
一致性哈希算法
一致性哈希(Consistent Hashing)是一种特殊的哈希算法,它在分布式缓存和负载均衡等场景中被广泛应用。它通过将数据和服务器节点映射到一个哈希环上,提供了一种在节点增减时能够最小化数据重新分配的机制。本文将...
一致性哈希算法的工作流程如下: 1. 所有节点(包括服务器和数据)被哈希成一个唯一的值,并映射到一个闭合的哈希环上。 2. 当查找一个数据的存储位置时,同样对数据的键进行哈希,然后在哈希环上找到该键对应的点。...
“ConsistentHashingandRandomTrees: Distributed Caching Protocols for Relieving Hot Spots on the Worldwide Web”指的是由David Karger等人撰写的关于一致性哈希算法(Consistent Hashing)以及如何运用该算法...
一致性哈希算法(Consistent Hashing)是一种常用于分布式系统中的数据分片策略,它有效地解决了数据在多台服务器间均匀分布的问题,同时减少了因节点加入或离开时的数据迁移成本。 首先,一致性哈希的基本原理是将...
一致性哈希算法(Consistent Hashing)是一种特殊的哈希算法,设计目的是为了在分布式缓存系统中解决节点动态增减时导致的键值映射大量变更的问题。它最早在1997年的论文《Consistent hashing and random trees》中被...
一致性哈希算法(Consistent Hashing)是一种特殊的哈希算法,设计目的是为了在分布式缓存系统中解决节点动态增减时导致的数据分布不均问题。该算法最早在1997年的论文《Consistent Hashing and Random Trees》中被...
1. **哈希函数选择**:一致性哈希算法中的哈希函数需确保在整个哈希空间中分布均匀,避免热点现象。可以使用MD5或SHA系列函数进行哈希。 2. **虚拟节点机制**:为了解决实际节点数量较少导致的数据不平衡问题,一致...
在这个Java实现中,我们看到的是Ketama一致性哈希算法,这是一种在实践中广泛应用的一致性哈希变体。 Ketama一致性哈希算法由Last.fm的工程师开发,其设计目标是优化分布式哈希表的性能,特别是在处理大量小键值对...
一致性哈希(Consistent Hashing)是一种分布式哈希表(DHT)的算法,它主要应用于分布式缓存、负载均衡等场景,旨在解决在动态扩展或收缩系统规模时,尽量减少数据迁移的问题。在这个简单的实现中,我们将探讨如何...