caching - Redis 故障转移和分区?

标签 caching redis cassandra failover

我在 4 节点 redis 设置上使用客户端分区。写入和读取分布在节点之间。 Redis 用作 volatile 数据的持久层以及应用程序不同部分的缓存。我们还有一个用于持久化非 volatile 数据的 cassandra 部署。

在 Redis 上,我们的峰值接近 1k ops/sec (instantaneous_ops_per_sec)。负载预计会随着时间的推移而增加。在许多操作中,我们查询不存在的键以检查该键的数据是否存在。

我想实现以下目标:

  • 当 redis 节点出现故障时,写入应该故障转移到某个地方。
  • 应该有一个备份来读取当redis节点宕机时丢失的数据。
  • 如果我们在未来添加更多的 redis 节点(或者死节点重新出现),读取和写入应该一致地重新分配。

我正在尝试找出合适的设计来处理上述情况。我想到了以下选项:

  • 为现有节点创建热从节点,并在主节点宕机时交换它们。这不会解决第三点。
  • 编写一个应用层以在 redis 和 cassandra 中持久保存数据,从而在 redis 节点出现故障时为读取提供延迟加载路径。这种方法会有写入两个存储的开销。

哪种方法更好?是否有合适的替代上述方法?

最佳答案

1k ops/s 的负载远远低于 Redis 的能力。在接近重载之前,您需要增加两个或更多数量级。如果您不期望超过 50-70,000 次操作/秒并且不超过可用的单节点/0 节点内存,我真的不会为数据分片而烦恼,因为它比它值得付出更多的努力。

也就是说,我不会为这个客户端做分片。我会看看像 Twemproxy/Nutcracker 这样的东西来帮你做。这提供了通往 Redis 集群的路径以及扩展连接的能力,并证明了对故障转移场景的透明客户端支持。

要处理客户端中的故障转移,您需要为每个插槽设置两个实例(在您的描述中为写入节点),其中一个实例与另一个实例共享。然后您将运行 Sentinel Constellation 来管理故障转移。

然后您需要让您的客户端代码连接到 sentinel 以获得每个槽的当前主连接。这也意味着客户端代码可以在发生故障转移时重新连接到新提升的主服务器。如果您有可用的负载均衡器,您可以将您的 Redis 节点放在一个或多个节点后面(最好是两个具有故障转移功能的节点)并消除客户端重新连接的要求,但是您随后需要实现哨兵脚本或监视器以在故障转移时更新负载均衡器配置。

对于 Sentinel Constellation,标准的 3 节点设置可以正常工作。如果您使用您控制的节点中的软件进行负载平衡,最好在负载平衡器上至少有两个哨兵节点以提供自然连接测试。

根据您的描述,我将测试运行一个主服务器和多个读取从服务器,而不是在客户端代码中进行哈希处理,而是将读取分发给从服务器并将写入分发给主服务器。这将在客户端提供更简单的设置和可能不太复杂的代码。扩展读取从属更容易和更简单,正如您所描述的那样,绝大多数操作将是读取请求,因此它完全符合您描述的使用模式。

您仍然需要使用 Sentinel 来管理故障转移,但这种复杂性仍然存在,从而导致代码和代码复杂性的净减少。对于单个 master,sentinel 几乎是微不足道的设置;注意事项是管理负载均衡器或虚拟 IP 或处理客户端代码中的哨兵发现的代码。

关于caching - Redis 故障转移和分区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25255773/

相关文章:

swift - 删除数据和缓存 wkwebview swift 4

database - Redis 4.0混合AOF+RDB

cassandra - Apache Cassandra 是否提供可以用来防止数据破坏(恶意节点)的测量方法?

Cassandra:如何在 super 列族中创建列?

java - Spring Redis 在使用@Cacheable 或@CachePut 时将 POJO 保存为不同的类型

cassandra - cassandra 3.0.x 和 3.11.x 版本之间的差异

java - 使用 Spring 3.2 和 EHCache 缓存父类(super class)方法

azure - Azure 上的 Redis - 键突然停止增加,命中和未命中为零

html - 只有在过去访问过的网站才会出错

node.js - socket.io + redis - 幽灵套接字 - 这可能吗?