Python-memcachedは、Djangoでサポートされている公式のmemcachedドライバーです。
サポートしていますか
- コンシステントハッシュ
- バイナリプロトコル
もしそうなら、Django内でこれらの機能をどのように使用しますか?ドキュメントが見つかりませんでした。
Python-memcachedは、Djangoでサポートされている公式のmemcachedドライバーです。
サポートしていますか
もしそうなら、Django内でこれらの機能をどのように使用しますか?ドキュメントが見つかりませんでした。
python-memcached v1.45のメソッドを見ると、_get_server
コンシステントハッシュを使用していないようですが、単純hash % len(buckets)
です。
バイナリプロトコルについても同じことが言えます。python-memcacheは、ソースで確認できる限り、テキストコマンドのみを使用します。
あなたはこれを使うことができるかもしれません:http://amix.dk/blog/post/19370
python-memcacheのClientクラスをカプセル化するため、コンシステントハッシュを使用してキーが分散されます。
編集-1.4.5のソースコードを掘り下げてpython-memcached
いますが、実際にはコンシステントハッシュをサポートしているようです。関連コード:
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などのより「回復力のある」コンシステントハッシュを参照していると思います。そのための解決策はないと思います。袖をまくり上げて、pylibmcなどのより高度なmemcached libをコンパイル/インストールし、pythonの代わりにそれを使用するカスタムDjangoバックエンドを作成する必要があるようです- memcached。
とにかく、どちらの場合でも、バケットをプールに追加/削除すると、キーの再マッピングが発生します(libketamaを使用した場合でも、他のアルゴリズムよりもわずかに少なくなります)
djangoのプラグアンドプレイソリューションが必要な場合は、httpsdjango-memcached-hashring
: //github.com/jezdez/django-memcached-hashringを使用してください。
それは周りのアダプターdjango.core.cache.backends.memcached.MemcachedCache
とhash_ring
ライブラリです。
コンシステントハッシュのこのサンプルPython実装を確認してください。 コンシステントハッシュpython-memcachedcontinnum -circle
実装の原則:複製されたサーバーポイントの数が分散している連続円を想像してください。新しいサーバーを追加すると、キャッシュキー全体の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
現在、 vbucketは、キャッシュミスへの影響を最小限に抑えてコンシステントハッシュを解決するために登場しています。
コンシステントハッシュアルゴリズムを使用しました。失われたキーは、キーの総数の1/nです。これは、成功するキーフェッチが6/7 * 100約85%になることを意味します。 ここ