北京物流信息联盟

支持 redis 节点高可用的 twemproxy

2021-08-17 16:22:55

原生 twemporxy

twemproxy 支持一个 proxy 实例同时代理多个分布式集群(server pools),每个集群使用不同的网络端口实现数据流的隔离,下图中 port1 应用于 cluster1 代理,port2 应用于 cluster2 代理:

今天要介绍的是 twemproxy 对 redis 节点高可用的支持,拿上图的其中一个分布式集群进行示例,逻辑结构如下:

客户端 client 流入的请求,在 proxy 上进行路由分片,然后转发到后端的 redis 节点上存储或者读取。事实上,大家已经注意到后端的 redis 节点只有一个点,在云计算环境下,是很容易掉线的。按 twemproxy 的设计,它可以自动识别失效节点并将其剔除,同时落在原来节点上的请求会分摊到其余的节点上。这是分布式缓存系统的一种通用做法,但需要忍受这个失效节点上的数据丢失,这种情况是否可以接受?

在业内,redis 虽然被定位为缓存系统,但事实上,无论哪种业务场景(我们接触过的)都不愿意接受节点掉线带来的数据丢失,因为那样对他们系统的影响实在太大了,更有甚者在压力大的时候引起后端数据库被击穿的风险。所以,我们打算改造 twemproxy,前后总共有几个版本,下面分享给各位的是我们目前线上在跑的版本。

定制化改造

在上图的基础上,我们增加了与 manager 交互的模块、增加了与 sentinel(redis-sentinel)交互的模块,修改了 redis 连接管理模块,图中三个红色虚线框所示:

manager 交互模块

增加连接 manager 的客户端交互模块,用于发送心跳消息,从心跳应答包里获取 group 名称列表和 sentinel 列表(IP/PORT信息),即整个分布式集群的配置信息,其中心跳消息带有版本信息,发送间隔可配置。

sentinel 交互模块

增加与 sentinel 客户端交互模块(IP/PORT信息来自于 manager),发送 group 名称给 sentinel 获取 redis 主节点的 IP/PORT 信息,一个 group 对应一个主节点。取到所有主节点后,订阅主从切换频道,获取切换消息用于触发 proxy 和主节点间的连接切换。这里需要解析 sentinel 的响应消息,会比较繁琐一些。当 proxy 开始与 sentinel 节点的交互过程,需要启动定时器,用以控制交互结果,当定时器超时交互未结束(或者 proxy 未正常工作),proxy 将主动切换到下一个 sentinel 节点,并启动新的交互过程。考虑到 proxy 与 sentinel 之间网络连接的重要性(连接假死,proxy 收不到主从切换消息,不能正常切换),增加了定时心跳机制,确保这条 TCP 链路的可用性。

redis 连接管理模块

原先 redis 节点的 IP/PORT 信息来自于静态配置文件,是固定的,而改造以后这些信息是从 sentinel 节点获取。为了确保获取到的 IP/PORT 信息的准确性,需要向 IP/PORT 对应的节点验证是否是主节点的逻辑,只有返回确认是主节点,才认为是合法的。整个过程,按官方指导实现,不存在漏洞。

详细消息流

为了清晰的描述 proxy 的内部处理逻辑,制作了如下消息流图:

绿色为业务通道,用于透传业务层数据;

紫色为命令通道(红线的细化),用于初始化和节点主从切换:

箭头1:manager heartbeat req;

箭头2:manager heartbeat rsp;

箭头3:sentinel get-master-addr-by-name req;

箭头4:sentinel get-master-addr-by-name rsp;

箭头5:redis auth & role req;

箭头6:redis auth & role rsp;

箭头7:sentinel psubscribe +switch-master req;

箭头8:sentinel psubscribe +switch-master rsp;

箭头9:sentinel pmessage;

命令通道命令顺序按数字1-8进行,7/8是proxy与sentinel的心跳消息,9是主从切换消息;


高可用影响面分析

在 sentinel 节点切换的过程中,存在 proxy 正在对外提供业务服务的状态,这时候正在处理的数据将继续处理,不会受到影响,而新接入的客户端连接将会被拒绝,已有的客户端连接上的新的业务请求数据也会被拒绝。sentinel 节点切换,对系统的影响是毫秒级别,前面的设计对业务系统来讲会显得比较友好、不那么粗鲁;

而 redis 节点的主从切换对系统的影响,主要集中在 proxy 发现主节点异常到 sentinel 集群做出主从切换这个过程,这段时间内落在该节点上的业务都将失败,而该时间段的长度主要依赖在 sentinel 节点上的 down-after-milliseconds 配置字段。

经验总结

作为代理中间件,支持 pipeline 的能力有限,容易产生消息积压,导致客户端大量超时,所以慎用pipeline功能;

高负荷下容易吃内存,struct msg 和 struct mbuf 对象会被大量缓存在进程内(内存池化);

zero copy,对于多个连续请求(TCP粘包)进行拆分,拷贝是无法避免的,但是有优化空间;


↓↓↓ "阅读原文" 为开源链接(非蜂巢线上版本) 

友情链接

Copyright © 2023 All Rights Reserved 版权所有 北京物流信息联盟