vlambda博客
学习文章列表

Pipy + Sentinel 实现 Redis 的高可用

Pipy[1] 是面向云、边缘和 IoT 的开源的可编程代理。Pipy 的灵活多变使其可以用于很多场景。本文的主要目的是演示通过 Redis 的主从同步的前置代理,提供 TCP 的负载均衡来保持客户端/应用程序的连接性。

目标

当 Redis 主节点在由于进程停止、硬件故障、网络中断或者其他未知原因导致无法响应时,我们希望可以实现自动的故障转移,同时 Sentinel 会自动将主节点转移至某个从节点。我们希望故障转移机制不会影响客户端和应用程序的连接。我们希望故障转移机制是完全透明的,不需要客户端和应用程序的任何配置。我们希望所有的写(比如 SET 或其他用户指定的命令)请求可以正常被主节点处理,客户端和应用程序不会感知到拓扑的变化。我们希望所有的请求被均衡的调度到所有的可用节点,充分利用资源并提高吞吐。......

负载均衡、代理 TCP 连接、确保 SET(或其他用户配置的) 命令始终路由到主节点、健康探测、记录的控制台输出、指标输出等都由 Pipy 实现。

Redis 部署的高可用性(包括主从节点)是通过 Redis Sentinel 来实现的,如果主节点未响应,它会持续监控、通知以及自动故障转移。

使用技术介绍

Pipy[2] 是面向云、边缘和 IoT 的开源的可编程代理。Redis[3] 是开源的被评为世界上最快的内存数据存储。Redis 为前沿应用提供强力支持,在增强实时分析、快速大容量事务、应用内社交功能、应用程序作业管理、排队和缓存等场景有着很高的知名度。Redis Sentinel[4] 在不使用 Redis 集群功能时,为 Redis 提供高可用。

部署架构

作为 TCP 负载均衡器的 Pipy 服务器,同时还会持续跟踪 Redis 服务器的可用性。主从同步模式的 3个 Redis 服务器。用于稳健部署的 Sentinel 实例。

环境搭建

为了演示方便,使用实例代码中附带 Docker Compose 脚本启动容器。

所有的实例代码都可以从 https://github.com/flomesh-io/pipy-demos/tree/main/pipy-redis-sentinel 下载。

先决条件

Docker[5]docker-compose[6]redis-cli[7]从 Pipy Demo 仓库[8]克隆代码,或者从 pipy-redis-sentinel[9] 直接获取代码启动 Pipy 代理、Redis、Sentinel 容器

 $ docker-compose up -d

测试

1.确保所有的容器正常运行

docker ps

CONTAINER ID   IMAGE                       COMMAND                  CREATED         STATUS         PORTS                                                 NAMES
0db7eba4f91d   sentinel                    "sentinel-entrypoint…"   6 seconds ago   Up 6 seconds   6379/tcp, 26379/tcp                                   redis_sentinel_3
e4a7b6b99074   sentinel                    "sentinel-entrypoint…"   6 seconds ago   Up 6 seconds   6379/tcp, 26379/tcp                                   redis_sentinel_2
4ec87846b1e3   naqvis/pipy-pjs:0.22.0-31   "/docker-entrypoint.…"   6 seconds ago   Up 5 seconds   6000/tcp, 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp   pipy-proxy
8e81ddc5eb07   sentinel                    "sentinel-entrypoint…"   6 seconds ago   Up 4 seconds   6379/tcp, 26379/tcp                                   redis_sentinel_1
f1a533de6d41   redis:alpine                "docker-entrypoint.s…"   8 seconds ago   Up 6 seconds   6379/tcp                                              redis-slave2
a522c208b236   redis:alpine                "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   6379/tcp                                              redis-slave1
8065dec93c3d   redis:alpine                "docker-entrypoint.s…"   8 seconds ago   Up 7 seconds   6379/tcp                                              redis-master

Pipy 监听 docker 主机上的 TCP 端口 6379 (这是 Redis 的默认端口),并在 3个 Redis 容器(一主二从)之间进行负载均衡。三个 Sentinel 容器为 Redis 提供高可用性。

1.执行命令检查 Pipy 服务是否将请求均衡路由到所有 Redis 节点。无需提供 docker 的宿主机 IP 和端口信息,因为 Pipy 监听在 Redis 的默认端口。

redis-cli info replication | grep role
role:master
redis-cli info replication | grep role
role:slave
redis-cli info replication | grep role
role:slave

Pipy 提供了多种负载均衡算法,演示脚本中使用 RoundRobinLoadBalancer[10]。就如上面所示的,Pipy 以轮询的方式将请求路由到所有节点。

1.现在尝试更多 Redis 命令。

redis-cli set hello world
OK

redis-cli get hello
"world"

redis-cli set foo bar
OK

我们已经将代理设置为轮询算法,但是所有的 SET 操作都执行成功。如果我们只是简单地遵循轮询算法,所有请求被平等地转发给各个节点,但是 SET 却没有被转发给从节点出现如下错误:

(error) READONLY You can't write against a read only slave.

故障转移测试

1.让我们暂停 Redis 的主节点来测试自动故障转移。

docker pause redis-master

Sentinel 会监测到主节点丢失,然后会选择一个从节点将其提升为主节点。Pipy 代理中的健康检查感知到主节点停止,会将该节点标记为不健康并在路由中忽略该节点知道其变为可用。同时 Pipy 会感知到新的主节点并将所有 SET 请求转发到新的主节点。

1.再次执行一些 Redis 命令,检查是否可以正常访问 Redis。

redis-cli set abc 1234
OK

redis-cli get abc
"1234"

1.恢复暂停的容器,Sentinel 会将其设置为从节点。

docker unpause redis-master

就这样,即使不使用 Redis 集群模式,仍然为 Redis 提供容错和高可用性。

性能测试

我们使用 Pipy、Haproxy、Twemproxy 以及单节点 Redis 进行了各种测试,得出在使用代理后在吞吐上的损耗。

下面的是在 M1 Max上的运行 Ubuntu 20.04.4 LTS (Focal Fossa) 的 4C8G 虚拟机中获得的测试结果。

从图中可以很明显地看出,Redis 在使用了代理之后性能出现了明显的下降,这也是受益于代理提供的功能时所需付出的代价。

总结

通过结合基础设施服务和软件配置,可以实现 Redis 的高可用,并在故障和灾难发生时为 Redis 的同步提供最大程度的保护。通过恰到好处的基础设置配置,可以通过使用不同的可用区来实现主从之间的 Redis 复制的高可用性。Redis Sentinel 监控并执行故障转移时的主从切换。

Pipy[11] 是一个开源的[12]、速度极快、轻量级网络流量处理器,可被用于各种场景,包括边缘路由器、负载均衡和代理(转发/反向)、API 网关、静态 HTTP 服务器、服务网格边车、以及其他许多应用程序。Pipy 正处于活跃的开发中,并由全职开发者贡献和维护。尽管仍是早期版本,但它经过了多个商业用户生产环境的实战验证。

引用链接

[1] Pipy: https://flomesh.io/
[2] Pipy: https://flomesh.io/
[3] Redis: https://redis.io/
[4] Redis Sentinel: https://redis.io/docs/manual/sentinel/
[5] Docker: https://www.docker.com/
[6] docker-compose: https://docs.docker.com/compose/install
[7] redis-cli: https://redis.io/topics/rediscli
[8] Pipy Demo 仓库: https://github.com/flomesh-io/pipy-demos.git
[9] pipy-redis-sentinel: https://github.com/flomesh-io/pipy-demos/tree/main/pipy-redis-sentinel
[10] RoundRobinLoadBalancer: https://flomesh.io/docs/en/reference/api/algo/RoundRobinLoadBalancer
[11] Pipy: https://flomesh.io/
[12] 开源的: https://github.com/flomesh-io/pipy