Python-memcached是Django官方支持的memcached驅動程序。python-memcached是否支持一致性散列和二進制協議?
它支持
- 一致性哈希法
- 二進制協議
如果是這樣,我怎麼使用內Django的那些功能?我找不到任何文檔。
Python-memcached是Django官方支持的memcached驅動程序。python-memcached是否支持一致性散列和二進制協議?
它支持
如果是這樣,我怎麼使用內Django的那些功能?我找不到任何文檔。
看着python-memcached v1.45上的_get_server
方法,它似乎沒有使用一致的哈希,而是一個簡單的hash % len(buckets)
。
對於二進制協議也是如此,python-memcache使用,據我可以看到,只有文本命令。
您可能能夠使用此:http://amix.dk/blog/post/19370
它封裝中的python-memcache中的客戶端類,所以按鍵都採用了統一的散列分佈。
編輯 - 我在挖python-memcached
1.4.5源代碼,它看起來可能實際上支持一致的散列。 相關代碼:
from binascii import crc32 # zlib version is not cross-platform
def cmemcache_hash(key):
return((((crc32(key) & 0xffffffff) >> 16) & 0x7fff) or 1)
serverHashFunction = cmemcache_hash
-- SNIP --
def _get_server(self, key):
if isinstance(key, tuple):
serverhash, key = key
else:
serverhash = serverHashFunction(key)
for i in range(Client._SERVER_RETRIES):
server = self.buckets[serverhash % len(self.buckets)]
if server.connect():
#print "(using server %s)" % server,
return server, key
serverhash = serverHashFunction(str(serverhash) + str(i))
return None, None
在此基礎上的代碼,它看起來像它確實實現了算法,除非cmemcache_hash
不是一個有意義的名字,這是不是真正的算法。 (現在已經退役cmemcache做一致性散列)
但我認爲OP指的是更具「彈性」的一致散列, libketama。我不認爲這裏有一個解決方案,看起來你需要捲起袖子編譯/安裝更高級的memcached庫,如pylibmc,並編寫一個自定義的Django後端,使用它來代替python- memcached的。
總之,在這兩種情況下,將在您添加/刪除水桶到池中出現按鍵的一些重映射(甚至libketama,只是比其他算法更少)
對不起,但這是**不**一致哈希。 'cmemcache_hash'只是計算一個鍵的簡單哈希值來選擇將獲取請求的服務器,並且您可以在此清楚地看到該庫使用(加權)服務器列表上的簡單模來執行此操作。另外,'MemcacheRing'的'libketama'正在實現相同的算法,但是'memcacheRing'及其執行'memcache.Client'已準備好進行集成。 – 2010-05-08 09:15:22
現在vbucket是解決一致性哈希來對緩存未命中的影響最小。
如果您需要django的即插即用解決方案,請使用django-memcached-hashring
:https://github.com/jezdez/django-memcached-hashring。
它是一個圍繞django.core.cache.backends.memcached.MemcachedCache
和hash_ring
庫的適配器。
我已經使用了一致性哈希算法。丟失的鑰匙是鑰匙總數的1/n。這意味着成功的密鑰獲取將在85%左右達到6/7 * 100。 here
鏈接只有答案是不鼓勵的。 \t 請引用參考鏈接中答案的基本部分,因爲如果鏈接的頁面發生變化,答案可能會失效。 – 2015-09-15 10:34:52
請檢查此示例python執行一致哈希。 consistent-hashingpython-memcachedcontinnum-circle
實現主要:想象一個continnum圈與許多通過它傳播複製的服務器分。當我們添加新的服務器,總 緩存鍵的1/n將丟失
'''consistent_hashing.py is a simple demonstration of consistent
hashing.'''
import bisect
import hashlib
class ConsistentHash:
'''
To imagine it is like a continnum circle with a number of replicated
server points spread across it. When we add a new server, 1/n of the total
cache keys will be lost.
consistentHash(n,r) creates a consistent hash object for a
cluster of size n, using r replicas.
It has three attributes. num_machines and num_replics are
self-explanatory. hash_tuples is a list of tuples (j,k,hash),
where j ranges over machine numbers (0...n-1), k ranges over
replicas (0...r-1), and hash is the corresponding hash value,
in the range [0,1). The tuples are sorted by increasing hash
value.
The class has a single instance method, get_machine(key), which
returns the number of the machine to which key should be
mapped.'''
def __init__(self,replicas=1):
self.num_replicas = replicas
def setup_servers(self,servers=None):
hash_tuples = [(index,k,my_hash(str(index)+"_"+str(k))) \
for index,server in enumerate(servers)
for k in range(int(self.num_replicas) * int(server.weight)) ]
self.hash_tuples=self.sort(hash_tuples);
def sort(self,hash_tuples):
'''Sort the hash tuples based on just the hash values '''
hash_tuples.sort(lambda x,y: cmp(x[2],y[2]))
return hash_tuples
def add_machine(self,server,siz):
'''This mathod adds a new machine. Then it updates the server hash
in the continuum circle '''
newPoints=[(siz,k,my_hash(str(siz)+"_"+str(k))) \
for k in range(self.num_replicas*server.weight)]
self.hash_tuples.extend(newPoints)
self.hash_tuples=self.sort(self.hash_tuples);
def get_machine(self,key):
'''Returns the number of the machine which key gets sent to.'''
h = my_hash(key)
# edge case where we cycle past hash value of 1 and back to 0.
if h > self.hash_tuples[-1][2]: return self.hash_tuples[0][0]
hash_values = map(lambda x: x[2],self.hash_tuples)
index = bisect.bisect_left(hash_values,h)
return self.hash_tuples[index][0]
def my_hash(key):
'''my_hash(key) returns a hash in the range [0,1).'''
return (int(hashlib.md5(key).hexdigest(),16) % 1000000)/1000000.0
有沒有什麼辦法讓蟒蛇,使用memcached的一致性哈希? – Continuation 2010-04-13 14:17:27
[hash_ring](http://pypi.python.org/pypi/hash_ring)有一個'memcache.Client'的子類實現一致的哈希,[從版本1.1](http://amix.dk/blog/post/ 19370)。 然後,您可以在django中實現[自定義緩存後端](http://docs.djangoproject.com/en/dev/topics/cache/#using-a-custom-cache-backend),繼承原始memcached後端所以它使用'MemcacheRing'。 – 2010-04-13 15:40:21
你真的確定它是否做到這一點?請看我上面的答案。 – adamJLev 2010-05-08 04:16:58