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')
View Code

由于项目中其他代码使用的是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)
View Code

参考:

http://www.codeproject.com/Articles/56138/Consistent-hashing

http://docs.python.org/2/library/ctypes.html

https://www.google.com.hk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CDQQFjAA&url=https%3a%2f%2fpypi%2epython%2eorg%2fpypi%2fhash_ring%2f&ei=tyrgUfeTJY3AkQWRrIGIAw&usg=AFQjCNETI2uzy4Nhiup7I_y6zKrGXfANaQ&bvm=bv.48705608,d.dGI&cad=rjt

posted @ 2013-07-28 21:22  good90  阅读(2715)  评论(0编辑  收藏  举报