【问题标题】:Redis failover and Partitioning?Redis 故障转移和分区?
【发布时间】:2014-10-05 00:27:30
【问题描述】:
我在 4 节点 redis 设置上使用客户端分区。写入和读取分布在节点之间。 Redis 被用作易失性数据的持久层以及应用程序不同部分的缓存。我们还有一个用于持久化非易失性数据的 cassandra 部署。
在 redis 上,我们的峰值接近 1k ops/sec (instantaneous_ops_per_sec)。预计负载会随着时间的推移而增加。在许多操作中,我们查询一个不存在的键以检查该键是否存在数据。
我想实现以下目标:
- 当一个 redis 节点出现故障时,写入应该故障转移到某处。
- 应该有一个备份,用于读取redis节点宕机时丢失的数据。
- 如果我们将来添加更多的 redis 节点(或者死节点重新出现),则应该一致地重新分配读取和写入。
我正在尝试找出合适的设计来处理上述情况。我想到了以下选项:
- 为现有节点创建热从节点,并在主节点宕机时交换它们。这不会涉及第三点。
- 编写一个应用程序层以在 redis 和 cassandra 中持久保存数据,从而在 redis 节点出现故障时允许读取的延迟加载路径。这种方法会产生写入两个存储的开销。
哪种方法更好?上述方法是否有合适的替代方案?
【问题讨论】:
标签:
caching
redis
cassandra
failover
【解决方案1】:
你在这里打开分布式数据库潘多拉魔盒。
我最好的建议是;不要这样做,不要实现自己的 Redis 集群,除非您可以承受丢失数据和/或需要一些停机时间。
如果您负担得起在尚未准备好生产的软件上运行,我的建议是查看官方的 Redis Cluster 实现;如果您的要求足够低,可以启动自己的集群实施,那么您有可能直接使用 Redis Cluster,这背后有社区支持。
您是否考虑过寻找与 Redis 不同的软件? Cassandra、Riak、DynamoDB、Hadoop 是成熟的分布式数据库的绝佳示例,可以满足您开箱即用的要求。
【解决方案2】:
1k ops/s 的负载远远低于 Redis 的能力。在接近超载之前,您需要增加多达两个或更多数量级。如果您不期望超过 50-70,000 次操作/秒并且不超过可用的单节点/0 节点内存,我真的不会为您的数据分片而烦恼,因为这比它值得付出更多的努力。
也就是说,我不会为这个客户端做分片。我会看看像 Twemproxy/Nutcracker 这样的东西来做你。这提供了通往 Redis 集群的路径以及扩展连接的能力,并证明了对故障转移场景的透明客户端支持。
要在客户端处理故障转移,您需要为每个插槽设置两个实例(在您的描述中为写入节点),其中一个被剃光到另一个。然后,您将运行 Sentinel Constellation 来管理故障转移。
然后您需要让您的客户端代码连接到哨兵以获取每个插槽的当前主连接。这也意味着客户端代码可以在发生故障转移时重新连接到新提升的主服务器。如果您有可用的负载均衡器,您可以将您的 Redis 节点放置在一个或多个(最好是两个具有故障转移功能的节点)之后,并消除客户端重新连接要求,但是您需要实施哨兵脚本或监视器以在故障转移时更新负载均衡器配置。
对于 Sentinel Constellation,标准的 3 节点设置可以正常工作。如果您使用您控制的节点中的软件进行负载平衡,最好在负载平衡器上至少有两个哨兵节点以提供自然连接测试。
根据您的描述,我将测试运行具有多个读取从属的单个主控,而不是在客户端代码中散列,将读取分配给从属并写入主控。这将在客户端提供更简单的设置和可能不太复杂的代码。扩展读取从站更容易和更简单,并且正如您所描述的那样,绝大多数操作将是读取请求,因此它完全符合您描述的使用模式。
您仍然需要使用 Sentinel 来管理故障转移,但这种复杂性仍然存在,从而导致代码和代码复杂性的净降低。对于单个主控,哨兵几乎是微不足道的,所以设置;注意事项是管理负载均衡器或虚拟 IP 或处理客户端代码中的哨兵发现的代码。