数据库 \ redis \ redis 一致性hash部署

redis 一致性hash部署

总点击72
简介:原文地址:http://www.cnblogs.com/lulu/archive/2013/06/10/3130906.html 使用zookeeper实现一致性hash。

原文地址:http://www.cnblogs.com/lulu/archive/2013/06/10/3130906.html

使用zookeeper 实现一致性hash。

redis服务启动时,将自己的路由信息通过临时节点方式写入zk,客户端通过zk client读取可用的路由信息。

redis 一致性hash部署

 

服务端

使用python 脚本写的守护进程:https://github.com/LittlePeng/redis-manager脚本部署在redis-server本机,定时ping redis-server节点失效的情况:1.服务器与ZK服务器失去连接 Session Expired ,环境网络波动造成,需要根据网络情况设置适当zookeeper的Timeout时间,避免此情况发生2. 服务器宕机,Zookeeper server 发现zkclient ping超时,就会通知节点下线3. redis-server 挂了,redis-manager ping 超时主动断开与zookeeper server的连接 

客户端

需要zkclient监控 节点变化,及时更新路由策略

下面是C# 版本一致性hash算法:

1: class KetamaNodeLocator

2: {

3: private Dictionary<long,RedisCluster> ketamaNodes;

4: private HashAlgorithm hashAlg;

5: private int numReps = 160;

6: private long[] keys;

7:  

8: public KetamaNodeLocator(List<RedisCluster> nodes)

9: {

10: ketamaNodes = new Dictionary<long,RedisCluster>();

11:  

12: //对所有节点,生成nCopies个虚拟结点

13: for (int j = 0; j < nodes.Count; j++) {

14: RedisCluster node = nodes[j];

15: int numReps = node.Weight;

16:  

17: //每四个虚拟结点为一组

18: for (int i = 0; i < numReps / 4; i++) {

19: byte[] digest = ComputeMd5(

20: String.Format("{0}_{1}_{2}",node.RoleName,node.RouteValue,i));

21:  

22: /** Md5是一个16字节长度的数组,将16字节的数组每四个字节一组,

23: * 分别对应一个虚拟结点,这就是为什么上面把虚拟结点四个划分一组的原因*/

24: for (int h = 0; h < 4; h++) {

25:  

26: long rv = ((long)(digest[3 + h * 4] & 0xFF) << 24)

27: | ((long)(digest[2 + h * 4] & 0xFF) << 16)

28: | ((long)(digest[1 + h * 4] & 0xFF) << 8)

29: | ((long)digest[0 + h * 4] & 0xFF);

30:  

31: rv = rv & 0xffffffffL; /* Truncate to 32-bits */

32: ketamaNodes[rv] = node;

33: }

34: }

35: }

36:  

37: keys = ketamaNodes.Keys.OrderBy(p => p).ToArray();

38: }

41: public RedisCluster GetWorkerNode(string k)

42: {

43: byte[] digest = ComputeMd5(k);

44: return GetNodeInner(Hash(digest,0));

45: }

46:  

47: RedisCluster GetNodeInner(long hash)

48: {

49: if (ketamaNodes.Count == 0)

50: return null;

51: long key = hash;

52: int near = 0;

53: int index = Array.BinarySearch(keys,hash);

54: if (index < 0) {

55: near = (~index);

56: if (near == keys.Length)

57: near = 0;

58: }

59: else {

60: near = index;

61: }

62:  

63: return ketamaNodes[keys[near]];

64: }

65:  

66: public static long Hash(byte[] digest,int nTime)

67: {

68: long rv = ((long)(digest[3 + nTime * 4] & 0xFF) << 24)

69: | ((long)(digest[2 + nTime * 4] & 0xFF) << 16)

70: | ((long)(digest[1 + nTime * 4] & 0xFF) << 8)

71: | ((long)digest[0 + nTime * 4] & 0xFF);

72:  

73: return rv & 0xffffffffL; /* Truncate to 32-bits */

74: }

 

79: public static byte[] ComputeMd5(string k)

80: {

81: MD5 md5 = new MD5CryptoServiceProvider();

82:  

83: byte[] keyBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(k));

84: md5.Clear();

85: return keyBytes;

86: }

87: }

意见反馈 常见问题 官方微信 返回顶部