python -- 一致性Hash
python有一个python模块--hash_ring,即python中的一致性hash,使用起来也挺简单。
可以参考下官方例子:https://pypi.python.org/pypi/hash_ring/
1 Basic example of usage (for managing memcached instances): 2 3 memcache_servers = ['192.168.0.246:11212', 4 '192.168.0.247:11212', 5 '192.168.0.249:11212'] 6 7 ring = HashRing(memcache_servers) 8 server = ring.get_node('my_key') 9 Example using weights: 10 11 memcache_servers = ['192.168.0.246:11212', 12 '192.168.0.247:11212', 13 '192.168.0.249:11212'] 14 weights = { 15 '192.168.0.246:11212': 1, 16 '192.168.0.247:11212': 2, 17 '192.168.0.249:11212': 1 18 } 19 20 ring = HashRing(memcache_servers, weights) 21 server = ring.get_node('my_key')
由于项目中其他代码使用的是C编写的Conhash.lib,测试后发现,hash_ring和conhash.lib hash出来的值不一样;
据说可以与C语言很好交互,Google后,果然可以,于是参考:官网ctypes介绍,花了点时间将通过python成功调用
了conhash接口,测试成功,代码如下(比较混乱,暂未整理):
1 from ctypes import * 2 import os 3 from ctypes.util import find_library 4 5 class _Util_Rbtree_Node_S(Structure): 6 pass 7 8 _Util_Rbtree_Node_S._fields_ = [('key',c_long), 9 ('parent',POINTER(_Util_Rbtree_Node_S)), 10 ('right',POINTER(_Util_Rbtree_Node_S)), 11 ('left',POINTER(_Util_Rbtree_Node_S)), 12 ('color',c_int), 13 ('data',c_void_p)] 14 15 class _Util_Rbtree_S(Structure): 16 _fields_ = [('root',POINTER(_Util_Rbtree_Node_S)), 17 ('null',_Util_Rbtree_Node_S), 18 ('size',c_uint)] 19 20 class _ConHash_S(Structure): 21 _fields_ = [('vnode_tree',_Util_Rbtree_S), 22 ('ivnodes',c_uint), 23 ('cb_hashfunc',CFUNCTYPE(c_long,c_char_p))] 24 25 class _Node_S(Structure): 26 _fields_ = [('iden',c_char * 64), 27 ('replicas',c_uint), 28 ('flag',c_uint),] 29 30 class ConHash: 31 def __init__(self): 32 try: 33 conhash_lib_path = find_library('conhash') 34 if not conhash_lib_path: 35 print 'cannot find libconhash.so' 36 return 37 38 self.__conhash_lib_path = conhash_lib_path 39 self.__conhash_lib = cdll.LoadLibrary(self.__conhash_lib_path) 40 41 self.__conhash_lib.conhash_init.restype = POINTER(_ConHash_S) 42 self.__conhash_lib.conhash_lookup.restype = POINTER(_Node_S) 43 44 self.conhash_init = self.__conhash_lib.conhash_init 45 self.conhash_fini = self.__conhash_lib.conhash_fini 46 self.conhash_set_node = self.__conhash_lib.conhash_set_node 47 self.conhash_add_node = self.__conhash_lib.conhash_add_node 48 self.conhash_del_node = self.__conhash_lib.conhash_del_node 49 #self.conhash_update_node = self.__conhash_lib.conhash_update_node 50 self.conhash_lookup = self.__conhash_lib.conhash_lookup 51 self.conhash_md5_digest = self.__conhash_lib.conhash_md5_digest 52 self.conhash_get_vnodes_num = self.__conhash_lib.conhash_get_vnodes_num 53 self.conhash_get_vnodes = self.__conhash_lib.conhash_get_vnodes 54 except Exception, ex: 55 print ex 56 57 '''try: 58 conhash_lib_path = find_library('conhash') 59 ConHash = cdll.LoadLibrary(conhash_lib_path) 60 ConHash.conhash_init.restype = POINTER(_ConHash_S) 61 ConHash.conhash_lookup.restype = POINTER(_Node_S) 62 except Exception, ex: 63 print ex 64 ''' 65 66 67 node1 = _Node_S() 68 node2 = _Node_S() 69 node3 = _Node_S() 70 node4 = _Node_S() 71 node5 = _Node_S() 72 node6 = _Node_S() 73 node7 = _Node_S() 74 node8 = _Node_S() 75 node9 = _Node_S() 76 node10 = _Node_S() 77 78 #ConHash.conhash_init.restype = POINTER(_ConHash_S) 79 conhash_inst = ConHash() 80 conhash = conhash_inst.conhash_init(None) 81 conhash_inst.conhash_set_node(byref(node2), "192.168.79.101:6380\0", 100) 82 conhash_inst.conhash_set_node(byref(node3), "192.168.79.101:6381\0", 100) 83 conhash_inst.conhash_set_node(byref(node4), "192.168.79.101:6382\0", 100) 84 conhash_inst.conhash_set_node(byref(node5), "192.168.79.101:6383\0", 100) 85 conhash_inst.conhash_set_node(byref(node1), "192.168.79.101:6384\0", 100) 86 conhash_inst.conhash_set_node(byref(node6), "192.168.79.101:6385\0", 100) 87 conhash_inst.conhash_set_node(byref(node7), "192.168.79.101:6386\0", 100) 88 conhash_inst.conhash_set_node(byref(node8), "192.168.79.101:6387\0", 100) 89 conhash_inst.conhash_set_node(byref(node9), "192.168.79.101:6388\0", 100) 90 conhash_inst.conhash_set_node(byref(node10), "192.168.79.101:6389\0", 100) 91 conhash_inst.conhash_add_node(conhash, byref(node1)) 92 conhash_inst.conhash_add_node(conhash, byref(node2)) 93 conhash_inst.conhash_add_node(conhash, byref(node3)) 94 conhash_inst.conhash_add_node(conhash, byref(node4)) 95 conhash_inst.conhash_add_node(conhash, byref(node5)) 96 conhash_inst.conhash_add_node(conhash, byref(node6)) 97 conhash_inst.conhash_add_node(conhash, byref(node7)) 98 conhash_inst.conhash_add_node(conhash, byref(node8)) 99 conhash_inst.conhash_add_node(conhash, byref(node9)) 100 conhash_inst.conhash_add_node(conhash, byref(node10)) 101 102 while True: 103 print 'input key:', 104 key = raw_input() 105 node11 = conhash_inst.conhash_lookup(conhash, key) 106 print (key, node11.contents.iden)
参考:
http://www.codeproject.com/Articles/56138/Consistent-hashing