如何初始化Redis客户端写入master和从slave读取
How to initialize Redis client to write to master and read from slaves
假设我有一个复制的主从 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,它们都是从谈论当从机成为主机时的自动故障转移开始的,我不确定这是我需要的。我需要的是一个始终如一的主人,我可以承受失去一段时间(我可以在队列中保留更新)。
Sentinel 可以做到这一点:
You can also create Redis client connections from a Sentinel instance. You can connect to either the master (for write operations) or a slave (for read-only operations).
>>> 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,例如:
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(...)
您是否有意拆分读取和写入,并且这样做是因为您已经知道您将压倒 Redis 实例?如果没有,请不要担心在服务器之间拆分 r/w。使用客户端的 Sentinel 作为查找来查看哪个节点是主节点并连接到它以执行所有读取和写入操作。
您最终必须将读取的内容从您的代码中分离出来,这样您就可以为每个读取从属建立一个连接,并且只向它发送读取。您需要检测故障转移以重新分配您的 r/w 拆分。
现在,如果您有一个单独的只读进程,您可以让它在 sentinel 中查询 slave 代替 master,或者您可以设置一个不可提升的 slave 以用于该进程 - 尽管如果它运行下来你会失去你的访问权限。
You Aint Gonna Need It (YAGNI) 是一个很好的遵循原则,避免过早优化。单个 Redis 实例可以非常快,并且不会因传统 SQL 数据存储中发现的高度复杂的查询而遭受同样的性能下降。因此,我建议您使用标准设置 运行 缺少数据,您只需查询当前主站的哨兵并使用它 returns.
假设我有一个复制的主从 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,它们都是从谈论当从机成为主机时的自动故障转移开始的,我不确定这是我需要的。我需要的是一个始终如一的主人,我可以承受失去一段时间(我可以在队列中保留更新)。
Sentinel 可以做到这一点:
You can also create Redis client connections from a Sentinel instance. You can connect to either the master (for write operations) or a slave (for read-only operations).
>>> 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,例如:
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(...)
您是否有意拆分读取和写入,并且这样做是因为您已经知道您将压倒 Redis 实例?如果没有,请不要担心在服务器之间拆分 r/w。使用客户端的 Sentinel 作为查找来查看哪个节点是主节点并连接到它以执行所有读取和写入操作。
您最终必须将读取的内容从您的代码中分离出来,这样您就可以为每个读取从属建立一个连接,并且只向它发送读取。您需要检测故障转移以重新分配您的 r/w 拆分。
现在,如果您有一个单独的只读进程,您可以让它在 sentinel 中查询 slave 代替 master,或者您可以设置一个不可提升的 slave 以用于该进程 - 尽管如果它运行下来你会失去你的访问权限。
You Aint Gonna Need It (YAGNI) 是一个很好的遵循原则,避免过早优化。单个 Redis 实例可以非常快,并且不会因传统 SQL 数据存储中发现的高度复杂的查询而遭受同样的性能下降。因此,我建议您使用标准设置 运行 缺少数据,您只需查询当前主站的哨兵并使用它 returns.