Last active
August 29, 2015 14:00
-
-
Save chrisseto/11401474 to your computer and use it in GitHub Desktop.
RedisCluster class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import crc16 | |
from redis import Redis | |
TOTAL_HASH_SLOTS = 16384 | |
#TODO | |
SHARDED_COMMANDS = [ | |
'get', | |
'set', | |
'append', | |
'exists', | |
'sadd', | |
'scard' | |
] | |
class RedisNode(Redis): | |
def __init__(self, node): | |
self.port = node['port'] | |
self.host = node.get('host', 'localhost') | |
super(Redis, self).__init__(port=self.port, host=self.host) | |
class RedisCluster(object): | |
@classmethod | |
def get_hash_slot(cls, key): | |
return crc16.crc16xmodem(key) % TOTAL_HASH_SLOTS | |
@classmethod | |
def create_cluster(cls, nodes=[{'port': 7000}, {'port': 7001}, {'port': 7002}]): | |
_nodes = [] | |
try: | |
for node in nodes: | |
_nodes.append(RedisNode(node)) | |
except KeyError: | |
raise KeyError('A node must be formatted as {host, port}') | |
except TypeError: | |
raise TypeError('Nodes must be a list of dictionaries.') | |
return cls(_nodes) | |
def __init__(self, nodes): | |
self._nodes = nodes | |
# def get(self, key): | |
# node = self._get_proper_node(key) | |
# return node.get(key) | |
# def set(self, key, value): | |
# node = self._get_proper_node(key) | |
# return node.set(key, value) | |
def get_shard(self, key): | |
slot = self.get_hash_slot(key) | |
node = self._nodes[slot % len(self._nodes)] | |
return node | |
def __getattr__(self, attr): | |
if attr in SHARDED_COMMANDS: | |
original_func = getattr(Redis, attr) | |
import ipdb; ipdb.set_trace() | |
new_func = lambda *args, **kwargs: original_func(self.get_shard(args[0]), *args, **kwargs) | |
new_func.__doc__ = original_func.__doc__ | |
return new_func | |
else: | |
node = self._nodes[0] | |
return getattr(node, attr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment