4

Python-memcached - официальный поддерживаемый драйвер memcached для Django.Поддерживает ли python-memcached поддержку хэширования и бинарного протокола?

Поддерживает ли

  1. Последовательная хеширования
  2. Двоичный протокол

Если да, то как я могу использовать эти функции в рамках Django? Я не мог найти никакой документации.

ответ

2

Глядя на метод _get_server на python-memcached v1.45, кажется, что он не использует последовательное хеширование, а просто hash % len(buckets).

То же самое касается бинарного протокола, python-memcache использует, насколько я могу видеть в источнике, только текстовые команды.

+0

Есть ли способ сделать Python-Memcached использовать последовательное хэширование? – Continuation

+1

[hash_ring] (http://pypi.python.org/pypi/hash_ring) имеет подкласс «memcache.Client», реализующий последовательное хеширование, [из версии 1.1] (http://amix.dk/blog/post/ 19370). Затем вы можете реализовать [пользовательский кеш-сервер] (http://docs.djangoproject.com/en/dev/topics/cache/#using-a-custom-cache-backend) в django, подклассифицируя исходный сервер memcached поэтому он использует «MemcacheRing». –

+0

Действительно ли вы это подтвердили или нет? См. Мой ответ выше. – adamJLev

1

Вы могли бы использовать это: http://amix.dk/blog/post/19370

Он инкапсулирует класс клиента Python-Memcache, с тем ключи распределяются с использованием последовательного хэширования.

EDIT- Я копаю в 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 lib, например pylibmc, и написать собственный бэкэнд Django, который использует это вместо python- Memcached.

Во всяком случае, в любом случае, некоторые переназначение клавиш будет происходить при добавлении/удалении ведрами в бассейн (даже с libketama, только меньше, чем с другими алгоритмами)

+1

Извините, но это ** не ** согласованное хеширование. 'cmemcache_hash' просто вычислит простой хэш ключа, чтобы выбрать сервер, который получит запрос, и вы можете ясно видеть здесь, что библиотека делает это с простым модулем в списке (взвешенных) серверов. Кроме того, 'libketama'' MemcacheRing' реализует один и тот же алгоритм, но 'MemcacheRing', с его внедрением' memcache.Client' готов к интеграции. –

0

Теперь vbucket грядет для разрешения последовательного хэширования с наименьшим влиянием на пропуски в кэше.

0

Я использовал последовательный алгоритм хэширования. Потерянные ключи составляют 1/n от общего количества ключей. Это означает, что успешная выборка ключа будет составлять 6/7 * 100 около 85%. here

+0

Ссылка только ответы обескуражены. \t Просьба указать основные части ответа из ссылочной ссылки (ссылок), так как ответ может стать недействительным, если связанная страница (ы) изменится. –

1

Пожалуйста, проверьте этот пример реализации python последовательного хэширования.

реализации основной: представьте continnum круг с числом копий точек серверов, разбросанных по ней.При добавлении нового сервера, 1/п от общих ключей кэшей будут потеряны

'''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 
Смежные вопросы