假设我有一个复制的主从Redis设置,我如何从客户端库实际访问它?据推测,我需要每个主机都有一个客户端实例,我需要决定将其用于写入和阅读,例如:
master = redis.Redis(master_host, port)
clients = [redis.Redis(host, port) for host in slave_hosts]
master.set('key', 'value')
client = random.choice(clients)
client.get('other-key')
我在想库中应该有一些魔法,我可以提供一个主机列表来自动进行这样的路由,但是找不到它。
我也研究过redis-cluster和redis-sentinel,他们都谈到奴隶成为主人时的自动故障转移,我不确定它是我需要的。我需要的是一个一致的主人,我可以负担一段时间(我可以在队列中保留更新)。
答案 0 :(得分:1)
Sentinel可以做到这一点:
您还可以从Sentinel实例创建Redis客户端连接。您可以连接到主设备(用于写入操作)或从设备(用于只读操作)。
>>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
>>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
>>> master.set('foo', 'bar')
>>> slave.get('foo')
'bar'
我也在使用Redis。在我的例子中,我有一个包装类,如:
class RedisConnection:
def __init__(self, master_host, slave_host):
self.__master = redis.Redis...
self.__slave == redis.Redis...
def write_xxx(self, value):
self.__master.set(...)
def read_xxx(self):
self.__slave.get(...)
答案 1 :(得分:1)
你是否故意拆分读写,这样做因为你已经知道你会压倒Redis实例?如果没有,请不要担心在服务器之间拆分r / w。从客户端使用Sentinel作为查找,以查看哪个节点是主节点并连接到它以执行所有读取和写入。
你最终必须分离读取代码的人需要编写,以便为每个读取从属建立连接并仅向其发送读取。您需要检测故障转移以重新分配您的r / w拆分。
现在,如果你有一个单独的只读进程,你可以让它为slave代替master来查询sentinel,或者你可以设置一个不可升级的slave来用于该进程 - 尽管如果它关闭了你& #39; d失去你的访问权。
你不需要它(YAGNI)是一个很好的原则,因为它避免了过早的优化。由于您在传统SQL数据存储中发现的高度复杂的查询,单个Redis实例可以非常快,并且不会遭受相同的性能下降。因此,我建议您使用标准设置运行缺少数据,只需查询当前主设备的Sentinel并使用它返回的设备。