源码分析Memcached-Java-Client一致性hash算法
2014-07-02 17:24
483 查看
源码分析Memcached-Java-Client一致性hash算法
url: http://thrillerzw.iteye.com/blog/20554872014-04-25 23:27
memcached的分布式主要体现在client端,server之间没有关系。
一致性hash算法:cache不能命中的问题仍然存在,但是只存在于2个节点之间的位置。相对于取模的算法,一致性hash算法除了计算key的hash值外,还会计算每个server对应的hash值,然后将这些hash值映射到一个有限的值域上(比如0~2^32)。通过寻找hash值等于大于hash(key)的最小server作为存储该key数据的目标server。如果找不到,则直接把具有最小hash值的server作为目标server。
源码版本:Memcached-Java-Client-release_2.6.1
1、计算每个server对应的hash值,将值存入treemap 排序模拟圆,主要方法代码入下。
private void populateConsistentBuckets() { // store buckets in tree map consistentBuckets = new TreeMap<Long, String>(); MessageDigest md5 = MD5.get(); if (this.totalWeight <= 0 && this.weights != null) { for (int i = 0; i < this.weights.length; i++) this.totalWeight += (this.weights[i] == null) ? 1 : this.weights[i]; } else if (this.weights == null) { this.totalWeight = this.servers.length; } for (int i = 0; i < servers.length; i++) { int thisWeight = 1; if (this.weights != null && this.weights[i] != null) thisWeight = this.weights[i]; double factor = Math.floor(((double) (40 * this.servers.length * thisWeight)) / (double) this.totalWeight); //根据权重控制虚拟节点数量 (factor * 4)。 for (long j = 0; j < factor; j++) { byte[] d = md5.digest((servers[i] + "-" + j).getBytes()); //192.168.211.240:11212-0 。。。 192.168.211.240:11212-39 // System.out.println("server key="+servers[i] + "-" + j); for (int h = 0; h < 4; h++) { Long k = ((long) (d[3 + h * 4] & 0xFF) << 24) | ((long) (d[2 + h * 4] & 0xFF) << 16) | ((long) (d[1 + h * 4] & 0xFF) << 8) | ((long) (d[0 + h * 4] & 0xFF)); //按Long值从小到大排序 consistentBuckets.put(k, servers[i]); } } // Create a socket pool for each host // Create an object pool to contain our active connections GenericObjectPool gop; SchoonerSockIOFactory factory; if (authInfo != null) { factory = new AuthSchoonerSockIOFactory(servers[i], isTcp, bufferSize, socketTO, socketConnectTO, nagle, authInfo); } else { factory = new SchoonerSockIOFactory(servers[i], isTcp, bufferSize, socketTO, socketConnectTO, nagle); } gop = new GenericObjectPool(factory, maxConn, GenericObjectPool.WHEN_EXHAUSTED_BLOCK, maxIdle, maxConn); factory.setSockets(gop); socketPool.put(servers[i], gop); } System.out.println("consistentBuckets="+consistentBuckets); }
输出:
consistentBuckets={7786957=192.168.211.240:11212, 13055238=192.168.211.240:11212, 15819052=192.168.211.240:11211,。。。 4294784513=192.168.211.240:11212}
2、计算存储数据key hash,寻找目标server。
consistentBuckets.get(bucket) //计算客户端key hash值 private static long md5HashingAlg(String key) { MessageDigest md5 = MD5.get(); md5.reset(); md5.update(key.getBytes()); byte[] bKey = md5.digest(); long res = ((long) (bKey[3] & 0xFF) << 24) | ((long) (bKey[2] & 0xFF) << 16) | ((long) (bKey[1] & 0xFF) << 8) | (long) (bKey[0] & 0xFF); System.out.println("key="+key+" hash result="+res); return res; } 输出: key=1 hash result=943901380 key=2 hash result=2373066440 //查找目标server private final Long findPointFor(Long hv) { // this works in java 6, but still want to release support for java5 // Long k = this.consistentBuckets.ceilingKey( hv ); // return ( k == null ) ? this.consistentBuckets.firstKey() : k; //hash值等于大于hash(key)的最小server作为存储该key数据的目标server。 SortedMap<Long, String> tmap = this.consistentBuckets.tailMap(hv); System.out.println("hash result="+hv+" tailMap="+tmap); //如果找不到,则直接把具有最小hash值的server作为目标server。 return (tmap.isEmpty()) ? this.consistentBuckets.firstKey() : tmap.firstKey(); } 输出: hash result=943901380 tailMap={948021698=192.168.211.240:11212, 973571166=192.168.211.240:11212, 。。。4294784513=192.168.211.240:11212}
相关文章推荐
- memcache-client-forjava 源码分析之MemcachedCacheManager
- SSO单点登录系列1:cas客户端源码分析cas-client-java-2.1.1.jar
- Memcached-Java-Client 如何开启一致性hash?
- Hash算法以及java hashmap的源码分析
- 一致性hash算法在Memcache Java client中的应用
- hash算法及Java的HashTable源码分析
- memcache-client-forjava 源码分析之DefaultCacheImpl分析
- libmemcached一致性hash算法详解(1)----php-memcached客户端一致性哈希与crc算法共用产生的bug分析
- Redis Java Client Jedis 源码分析
- Java多线程 -- JUC包源码分析17 -- 弱一致性与无锁队列
- SSO单点登录系列1:cas客户端源码分析cas-client-java-2.1.1.jar
- 转: memcached Java客户端spymemcached的一致性Hash算法
- OpenStack_Swift源码分析——Ring基本原理及一致性Hash算法
- SSO单点登录系列1:cas客户端源码分析cas-client-java-2.1.1.jar
- libmemcached一致性hash算法详解(1)----php-memcached客户端一致性哈希与crc算法共用产生的bug分析
- java版的memcached client及使用文档
- java源码分析:Arrays.sort
- Java源码分析:深入探讨Iterator模式-Java基础-Java-编程开发
- JDK源码分析:java.lang.Boolean
- Java源码分析:深入探讨Iterator模式