小米Redis的K8s容器化部署实践

小米的redis使用规模很大,现在有数万个实例,并且每天有百万亿次的访问频率,支撑了几乎所有的产品线和生态链公司 。之前所有的Redis都部署在物理机上,也没有做资源隔离,给管理治理带来了很大的困难 。我们的运维人员工作压力很大,机器宕机网络抖动导致的Redis节点下线都经常需要人工介入处理 。由于没有做CPU的资源隔离,slave节点打RDB或者由于流量突增导致节点QPS升高造成的节点CPU使用率升高,都可能对本集群或其他集群的节点造成影响,导致无法预测的时延增加 。
Redis分片方式采用社区的Redis Cluster协议,集群自主分片 。Redis Cluster带来了一定的易用性的同时,也提高了应用开发的门槛,应用开发人员需要一定程度上了解Redis Cluster,同时需要使用智能客户端访问Redis Cluster 。这些智能客户端配置参数繁多,应用开发人员并无法完全掌握并设置这些参数,踩了很多坑 。同时,由于智能客户端需要做分片计算,给应用端的机器也带来了一定的负载 。

小米Redis的K8s容器化部署实践

文章插图
 
Why K8S
资源隔离当前的Redis Cluster部署在物理机集群上,为了提高资源利用率节约成本,多业务线的Redis集群都是混布的 。由于没有做CPU的资源隔离,经常出现某Redis节点CPU使用率过高导致其他Redis集群的节点争抢不到CPU资源引起时延抖动 。因为不同的集群混布,这类问题很难快速定位,影响运维效率 。K8s容器化部署可以指定 CPU request 和 CPU limit ,在提高资源利用率的同时避免了资源争抢 。
自动化部署自动化部署 。当前Redis Cluster在物理机上的部署过程十分繁琐,需要通过查看元信息数据库查找有空余资源的机器,手动修改很多配置文件再逐个部署节点,最后使用redis_trib工具创建集群,新集群的初始化工作经常需要一两个小时 。
K8s通过StatefulSet部署Redis集群,使用configmap管理配置文件,新集群部署时间只需要几分钟,大大提高了运维效率 。
How K8S
客户端通过LVS的VIP统一接入,通过Redis Proxy转发服务请求到Redis Cluster集群 。这里我们引入了Redis Proxy来转发请求 。
小米Redis的K8s容器化部署实践

文章插图
 
Redis Cluster部署方式Redis部署为StatefulSet,作为有状态的服务,选择StatefulSet最为合理,可以将节点的RDB/AOF持久化到分布式存储中 。当节点重启漂移到其他机器上时,可通过挂载的PVC(PersistentVolumeClaim)拿到原来的RDB/AOF来同步数据 。我们选择的持久化存储PV(PersistentVolume)是Ceph Block Service 。Ceph的读写性能低于本地磁盘,会带来100~200ms的读写时延 。但由于Redis的RDB/AOF的写出都是异步的,分布式存储带来的读写延迟对服务并没有影响 。
小米Redis的K8s容器化部署实践

文章插图
 
Proxy选型开源的Redis Proxy有很多,常见的开源Redis Proxy如下:
小米Redis的K8s容器化部署实践

文章插图
 
我们希望能够继续使用Redis Cluster来管理Redis集群,所以Codis和Twemproxy不再考虑 。redis-cluster-proxy是Redis官方在6.0版本推出的支持Redis Cluster协议的Proxy,但是目前还没有稳定版,暂时也无法大规模应用 。
备选就只有Cerberus和Predixy两种 。我们在K8s环境上对Cerberus和Predixy进行了性能测试,结果如下:
测试环境测试工具: redis-benchmark
Proxy CPU: 2 core
Client CPU: 2 core
Redis Cluster: 3 master nodes, 1 CPU per node
测试结果
小米Redis的K8s容器化部署实践

文章插图
 

小米Redis的K8s容器化部署实践

文章插图
 
在相同workload和配置下,Predixy的最高QPS要优于Cerberus,时延也比较接近 。综合来看,Predixy比Cerberus的性能要高33%~60%,并且数据的key/value越大,Predixy优势越明显,所以最后我们选择了Predixy 。
为了适应业务和K8s环境,在上线前我们对Predixy做了大量的改动,增加了很多新的功能,比如动态切换后端Redis Cluster、黑白名单、异常操作审计等 。
Proxy部署方式Proxy作为deployment部署,无状态轻量化,通过LB对外提供服务,很容易做到动态扩缩容 。同时,我们为Proxy开发了动态切换后端Redis Cluster的功能,可实现在线添加和切换Redis Cluster 。
Proxy自动扩缩容方式我们使用K8s原生的HPA(Horizontal Pod Autoscaler)来实现Proxy的动态扩缩容 。当Proxy所有pod的平均CPU使用率超过一定阈值时,会自动触发扩容,HPA会将Proxy的replica数加1,之后LVS就会探测到新的Proxy pod并将一部分流量切过去 。如果扩容后CPU使用率仍然超过规定的阈值,会继续触发扩容逻辑 。但是在扩容成功5分钟内,不论CPU使用率降到多低,都不会触发缩容逻辑,这样就避免了频繁的扩缩容给集群稳定性带来的影响 。


推荐阅读