小米Redis容器化学习笔记

一、背景

1.1、现状

Redis有数万个实例,每天百万亿次Redis访问,支撑了几乎所有的产品线和生态链。

1.2、问题

Redis部署在物理机上,不同业务间没有做资源隔离:
1、当 机器宕机 或 网络抖动,导致Redis节点下线,需要人工介入运维处理,运维成本高。
2、没有做CPU资源隔离,当slave节点打RDB或流量激增导致节点QPS高,会造成节点CPU使用率增加,导致无法预测的延迟增加,影响其他业务。
3、Redis分片采用Redis Cluster协议,集群自主分片。问题:应用开发人员需要一定程度了解Redis Cluster,同事需要使用智能客户端访问Redis Cluster。这些智能客户端配置参数繁多,应用开发人员不易掌握。

二、为什么要用K8S

2.1、为了资源隔离

为了提升资源利用率,多个业务混合部署,当使用物理机时,混步的不同业务间会互相影响。一旦出现问题,不同业务间会互相影响,定位及解决问题需要花费一定时间,代价较高。

用K8S后,可以做资源隔离,不同业务不会互相影响。

2.2、自动化部署

部署到物理机时,需要人工介入:查找空余资源的机器,再手动修改配置文件,部署节点,在使用工具创建集群,新集群初始化需要1~2小时。

K8S通过StatefulSet部署K8S集群,部署新集群只需要几分钟,大大提高运维效率,降低了运维成本。

三、怎样使用K8S

客户端通过LVS(LinuxVirtualServer,一个虚拟的服务器集群系统)的VIP统一接入,通过Redis Proxy转发服务请求到Redis Cluster集群。这里引入了Redis Proxy来转发请求:
在这里插入图片描述

3.1、Redis Cluster部署方式

Redis部署为StatefulSet, 作为有状态服务。
对于持久化存储部分,如RDB/AOF,可持久化到分布式存储中,重启后读取,性能会低于本地磁盘,但好在RDB/AOF是异步的,延迟一点可接受(延迟为100~200ms)

在这里插入图片描述

3.2、Proxy部署方式

Proxy作为无状态服务,通过LB对外提供服务,很容器做到动态扩缩容。同时,为Proxy开发了动态切换后端Redis Cluster的功能,用于实现在线添加和切换Redis Cluster。

可以利用K8S对Proxy自动扩缩容

四、为什么使用Proxy

4.1、用于解决Redis Pod重启后IP变化的问题

Redis Cluster的Redis客户端,需要配置集群部分节点的IP和Port, 用于客户端重启时查找Redis Cluster的入口。这对于物理机不是问题,物理机重启后IP和Port不会变化。

但在K8S上的Pod, 重启后IP会变化,这样客户端就可能找不到Redis Cluster的入口了。

解决方案:在客户端和Redis Cluster之间加上Proxy,可对客户端屏蔽调Redis Cluster的信息,由Proxy动态感知Redis CLuster上的节点变化,客户端只需要将LVS的IP:Port最欧文入口,请求转发到Proxy上即可,这样就可以像使用单机版Redis一样使用Redis Cluster集群了,也不需要Redis只能客户端。

4.2、Redis处理连接负载高

在Redis 6.0版本之前,Redis都是单线程处理大部分任务的。当Redis节点连接较高时,Redis需要消耗大量的CPU资源处理这些连接,导致时延较高。有了Proxy智慧,大量连接都在Proxy上,而Proxy跟Redis实例之间只保持很少的连接,这样降低了Redis的负担,避免了连接增加而导致Redis时延升高。

4.3、集群迁移切换需要应用重启

集群迁移时,当前物理机的方案为:

  • 按需创建新集群
  • 使用同步工具,将数据从老集群同步到新集群
  • 确认数据无误后,跟业务沟通,重启服务切换到新集群

但有了Proxy,可以将后端的创建、同步、切换集群 对客户端屏蔽掉。新老集群同步完成后,由Proxy切换地址,使客户端无感知。

4.4、数据安全风险

Redis通过AUTH来做鉴权,客户端直连Redis,密码在客户端保存,存在安全风险。如果使用proxy, 密码保存在proxy,且proxy可限制flushdb, config set等操作,避免了客户端误用的情况。

proxy上增加了高危操作的日志保存功能,可以在不影响性能前提下提供审计能力。

4.5、Proxy代来的问题

1、多一跳的时延

多一跳会增加0.2~0.3ms的时延,不过通常这对业务来说是可以接受的。

2、Pod漂移造成IP变化

proxy部署在k8s上,重启IP也会变化,通过LVS感知proxy IP变化,可动态把LVS的流量且到重启后的proxy上。

3、LVS带来的时延

LVS带来的时延,总体小于0.1ms
在这里插入图片描述

五、K8S带来的好处

5.1、部署方便

5.2、解决端口管理问题

目前小米部署Redis实例,是通过端口来区分的,并且下线的端口不能服用,也就是说每个Redis实例都要有唯一的端口号,最多能用65535各。
通过K8S,每个Redis实例都有独立的IP,不存在端口数的限制了。

5.3、提高客户端性能

用户不必使用智能客户端,可降低客户端的负载。因为智能客户端需要再客户端对key进行hash以确定发送到哪个redis节点,在qps比较高的情况下回消耗客户端机器的CPU资源。

5.4、动态升级和扩缩容

Proxy支持动态添加和切换Redis Cluster,这样Redis Cluster在集群升级和扩容切换时,业务端无感知。

举例说明:业务方使用了30个节点的Redis Cluster集群,当需要扩容2倍节点时,在原来的物理机上过程如下:

  • 协调资源,部署60个节点的新集群
  • 手动配置迁移工具,将当前集群的数据迁移到新集群
  • 验证数据无误后,通知业务方修改Redis Cluster的连接地址,重启服务。

虽然Redis Cluster支持在线扩容,但扩容过程中slots迁移会对线上服务造成影响,同时迁移时间不可控,所以不采用线上扩容。

新的k8s集群扩容过程如下:

  • 通过API接口,一键创建60个节点的新集群
  • 通用通过API接口,一键创建集群同步工具,将数据迁移到新集群
  • 验证数据无误后,向Proxy发送命令,添加新集群信息并完成切换。

整个过程,业务无感知。

集群升级也很方便:如果业务方能接受一定的延迟毛刺,可在低峰时段通过StatefulSet滚动升级方式来实现;如果业务对延迟有要求,可以通过创建新集群迁移数据的方式实现。

5.5、提高服务稳定性和资源利用率

通过k8s自带的资源隔离能力,实现和其他不同类型的应用混步,在提高资源利用率的同时,也能保证服务稳定性。

六、遇到的问题

6.1、Pod重启导致数据丢失

K8s的Pod遇到问题重启时,由于重启速度过快,会在Redis Cluster集群发现并切主前,将Pod重启。如果Pod上的Redis是slave,不会有任何影响。如果是master,并且没有AOF,重启后原来内存中的数据被清空,Redis会reload之前存储的RDB文件,但RDB文件并不是实时的数据。之后slave也会跟着把自己的数据同步成之前的RDB文件中的数据镜像,会造成部分数据丢失。

StatefulSet是有状态服务,部署的Pod名是固定格式(StatefulSet名+编号)。我们在初始化Redis Cluster时,将相邻编号的Pod设置为主从关系,在重启Pod时,通过Pod名确定他的slave,在重启Poad前向从节点发送cluster failover命令,强制将或者的从节点且住,这样在重启后,该节点会自动以从节点方式接入集群。

6.2、LVS映射时延

Proxy的Pod事通过LVS实现负载均衡的,LVS读以后端IP:Port的映射生效有一定时延,Proxy节点突然下线,会导致部分连接丢失。

对于正常的Proxy Pod下线,例如集群缩容、滚动更新proxy版本,及其他k8s可控的pod下线,在pod下线前,会发消息给LVS,并等待171秒,这段时间足够LVS将这个pod的流量逐渐切到其他pod上,对业务无感知。

6.3、K8s StatefulSet无法满足Redis Cluster部署要求

k8s原生的StatefulSet不能完全满足Redis Cluster部署的要求:
1、Redis Cluster不允许同为主备关系的节点部署在同一台机器上。
2、Redis Cluster不允许机器超过一半的主节点失效。因为超过一半主节点失效,就无法有足够的节点投票来满足gossip协议的要求。因为Redis Cluster的主备是可能随时切换的,我们无法避免同一个机器上的所有节点都是主节点,所以在部署时,不能允许集群中超过1/4的节点部署在一台机器上。

为了满足上面的要求,原生StatefuleSet可以通过anti-affinity功能来保证相同集群在同一机器上只部署一个节点,但这样集群利用率很低。

因此,我们开发了基于StatefuleSet的CRD:RedisStatefulSet, 会采用多种策略部署Redis节点。同时,还在RedisStatefuleSet中接入了一些Redis管理功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值