python有一个python模块--hash_ring,即python中的一致性hash,使用起来也挺简单。
可以参考下官方例子:https://pypi.python.org/pypi/hash_ring/
Basic example of usage (for managing memcached instances): memcache_servers = ['192.168.0.246:11212',
'192.168.0.247:11212',
'192.168.0.249:11212'] ring = HashRing(memcache_servers)
server = ring.get_node('my_key')
Example using weights: memcache_servers = ['192.168.0.246:11212',
'192.168.0.247:11212',
'192.168.0.249:11212']
weights = {
'192.168.0.246:11212': 1,
'192.168.0.247:11212': 2,
'192.168.0.249:11212': 1
} ring = HashRing(memcache_servers, weights)
server = ring.get_node('my_key')
由于项目中其他代码使用的是C编写的Conhash.lib,测试后发现,hash_ring和conhash.lib hash出来的值不一样;
据说可以与C语言很好交互,Google后,果然可以,于是参考:官网ctypes介绍,花了点时间将通过python成功调用
了conhash接口,测试成功,代码如下(比较混乱,暂未整理):
from ctypes import *
import os
from ctypes.util import find_library class _Util_Rbtree_Node_S(Structure):
pass _Util_Rbtree_Node_S._fields_ = [('key',c_long),
('parent',POINTER(_Util_Rbtree_Node_S)),
('right',POINTER(_Util_Rbtree_Node_S)),
('left',POINTER(_Util_Rbtree_Node_S)),
('color',c_int),
('data',c_void_p)] class _Util_Rbtree_S(Structure):
_fields_ = [('root',POINTER(_Util_Rbtree_Node_S)),
('null',_Util_Rbtree_Node_S),
('size',c_uint)] class _ConHash_S(Structure):
_fields_ = [('vnode_tree',_Util_Rbtree_S),
('ivnodes',c_uint),
('cb_hashfunc',CFUNCTYPE(c_long,c_char_p))] class _Node_S(Structure):
_fields_ = [('iden',c_char * 64),
('replicas',c_uint),
('flag',c_uint),] class ConHash:
def __init__(self):
try:
conhash_lib_path = find_library('conhash')
if not conhash_lib_path:
print 'cannot find libconhash.so'
return self.__conhash_lib_path = conhash_lib_path
self.__conhash_lib = cdll.LoadLibrary(self.__conhash_lib_path) self.__conhash_lib.conhash_init.restype = POINTER(_ConHash_S)
self.__conhash_lib.conhash_lookup.restype = POINTER(_Node_S) self.conhash_init = self.__conhash_lib.conhash_init
self.conhash_fini = self.__conhash_lib.conhash_fini
self.conhash_set_node = self.__conhash_lib.conhash_set_node
self.conhash_add_node = self.__conhash_lib.conhash_add_node
self.conhash_del_node = self.__conhash_lib.conhash_del_node
#self.conhash_update_node = self.__conhash_lib.conhash_update_node
self.conhash_lookup = self.__conhash_lib.conhash_lookup
self.conhash_md5_digest = self.__conhash_lib.conhash_md5_digest
self.conhash_get_vnodes_num = self.__conhash_lib.conhash_get_vnodes_num
self.conhash_get_vnodes = self.__conhash_lib.conhash_get_vnodes
except Exception, ex:
print ex '''try:
conhash_lib_path = find_library('conhash')
ConHash = cdll.LoadLibrary(conhash_lib_path)
ConHash.conhash_init.restype = POINTER(_ConHash_S)
ConHash.conhash_lookup.restype = POINTER(_Node_S)
except Exception, ex:
print ex
''' node1 = _Node_S()
node2 = _Node_S()
node3 = _Node_S()
node4 = _Node_S()
node5 = _Node_S()
node6 = _Node_S()
node7 = _Node_S()
node8 = _Node_S()
node9 = _Node_S()
node10 = _Node_S() #ConHash.conhash_init.restype = POINTER(_ConHash_S)
conhash_inst = ConHash()
conhash = conhash_inst.conhash_init(None)
conhash_inst.conhash_set_node(byref(node2), "192.168.79.101:6380\0", 100)
conhash_inst.conhash_set_node(byref(node3), "192.168.79.101:6381\0", 100)
conhash_inst.conhash_set_node(byref(node4), "192.168.79.101:6382\0", 100)
conhash_inst.conhash_set_node(byref(node5), "192.168.79.101:6383\0", 100)
conhash_inst.conhash_set_node(byref(node1), "192.168.79.101:6384\0", 100)
conhash_inst.conhash_set_node(byref(node6), "192.168.79.101:6385\0", 100)
conhash_inst.conhash_set_node(byref(node7), "192.168.79.101:6386\0", 100)
conhash_inst.conhash_set_node(byref(node8), "192.168.79.101:6387\0", 100)
conhash_inst.conhash_set_node(byref(node9), "192.168.79.101:6388\0", 100)
conhash_inst.conhash_set_node(byref(node10), "192.168.79.101:6389\0", 100)
conhash_inst.conhash_add_node(conhash, byref(node1))
conhash_inst.conhash_add_node(conhash, byref(node2))
conhash_inst.conhash_add_node(conhash, byref(node3))
conhash_inst.conhash_add_node(conhash, byref(node4))
conhash_inst.conhash_add_node(conhash, byref(node5))
conhash_inst.conhash_add_node(conhash, byref(node6))
conhash_inst.conhash_add_node(conhash, byref(node7))
conhash_inst.conhash_add_node(conhash, byref(node8))
conhash_inst.conhash_add_node(conhash, byref(node9))
conhash_inst.conhash_add_node(conhash, byref(node10)) while True:
print 'input key:',
key = raw_input()
node11 = conhash_inst.conhash_lookup(conhash, key)
print (key, node11.contents.iden)
参考:
http://www.codeproject.com/Articles/56138/Consistent-hashing