近年来,我行互联网金融业务发展迅速,网上银行、手机银行业务量成倍增加,井喷式增长的客户在线访问量和大数据高并发的访问需求,给电子银行相关系统带来了很大的挑战。比如在互联网金融业务场景中,常见的营销模式:秒杀,经常会出现的问题包括:并发太高导致程序阻塞;库存无法有效控制,出现超卖的情况。我们采用异步、缓存这两种手段来解决系统压力问题。前者,例如说内存队列(例如说 JDK Queue 、 Disruptor 等)、分布式队列(例如说 RabbitMQ 、 RocketMQ 、 Kafka ),更多适合写操作。后者,例如说内存缓存(例如说 JDK Map 、 EhCache 等)、分布式缓存(例如说 Redis 、 Memcached 等),更适合读操作。本文重点谈论后者中的 Redis ,目前我行已经有很多系统采用了 Redis 集群作为数据缓存层和消息队列,采用三主三从 6 节点的架构。多个 Redis 集群的运维管理,主要有以下三个方面的问题:
版本管理难: Redis 之前是直接部署在物理机上,各个版本的 Redis 非常分散而且不容易维护。
新集群部署慢:需要手动修改很多配置文件再逐个部署节点,初始化工作需要较长时间。
资源隔离差:当前的 Redis 集群部署在物理机集群上,多业务线的 Redis 集群有混布的情况。由于没有做 CPU 的资源隔离,经常出现某 Redis 节点 CPU 使用率过高导致其他 Redis 集群的节点争抢不到 CPU 资源引起时延抖动。因为不同的集群混布,这类问题很难快速定位,影响运维效率。
为了简化大规模 Redis 集群的运维管理工作,我行对新的技术手段展开调研。容器镜像天然支持标准化,与硬件无关,可以解决版本的问题, K8 通过 StatefulSet 部署 Redis 集群,使用 configmap 管理配置文件,新集群部署时间只需要几分钟,大大提高了运维效率。 Redis 容器化的好处非常多,但是结合到我行具体应用场景还有一些问题需要验证,我们希望在测试 Redis 数据库容器云应用(大数据平台领域)时了解以下方面:
1 Redis 容器化以后与原来相比,性能读写,响应时间,网络流量有多大差距。
2 访问 Redis 采用 ip 和端口,并且主从不能在一台宿主机上,如何解决以上问题?
3 Redis 的配置文件和数据持久化如何在容器环境中保存?
4 主节点宕机时, Redis 会自动将从节点转换为主节点,此时若 k8s 将原来主节点拉起会导致数据冲突。
测试环境的设计,我们真实模拟生产环境,采用了典型的三主三从 6 节点的架构,用 6 台虚拟机,每台机器作为 OpenShift Container Platform ( OCP )集群的一个 worker 节点,每个 worker 只启动一个 pod 实例,最大利用主机资源,同时 Redis 集群的架构与生产环境完全一致。生产环境的 Redis 集群是在应用层面对集群的各个节点做负载均衡和路由,集群运维难度大、成本高,所以在测试环境设计上,我们做了优化,采用中间件 haproxy 自动负载均衡,这样 Redis 集群对于前端应用来说透明,维护会比较简单。
容器云平台的选型,我行经过调研,最终决定选用浪潮 K1 Power 与红帽 OpenShift 推出的容器云平台联合解决方案,该方案面向企业级客户在容器平台部署方面的需求,是可伸缩的,简化的以及快速的一个部署环境,经过浪潮和红帽严格的环境测试和官方认证,在使用这样一个软硬件环境的情况下,可以明显减少本次测试工作部署方面投入的时间和成本。
OCP 集群信息
软件版本:
集群说明:
OCP 集群部署在 K1 Power Linux 服务器 FP5290G2 创建的虚机上。
Redis 集群采用三主三从模式,六个 Redis 容器实例 pod 分别部署在 OCP 集群的六个 worker 节点上。
Redis 作为有状态服务,通过 statefulset 统一部署集群 6 个 pod 。
Redis 集群持久化采用 PVC 实现远程文件存储( nfs )到 Console 节点。
基于 Redis cluster 集群内部数据请求重定向后会新建 tcp 连接,所有 pod 的 ip 外部需要访问到,这里实现 pod 的网络模式为 hostnetwork, 共用宿主机 worker 的网络接口和 ip 。
集群前端搭建 haproxy 实现负载均衡。
架构拓扑图如下:
1) ssh 登录 OCP 集群 console 节点。
2) 创建 project
oc new-project Redis-cluster-test
3) 创建 PV
进到工作目录(自行创建)
oc create -f pv.yaml
pv.yaml 参考文件: https://github.com/powerlsr/redis-on-ocp/blob/main/pv.yaml
共创建 6 个 PV , Redis 集群 6 个节点会各分配一个,其中:
server: 10.152.20.31
path: /home/share/Redis-cluster-test/n{0-5}
server 表示 nfs server ip ,这里设置为 console 节点 ip
path 需要手动创建
4) Console 节点主机设置启动 nfs 服务
yum install –y nfs-utils
cat >> /etc/exports << EOF
/home/share/Redis-cluster-test/n0 *(insecure,rw,async,no_root_squash)
/home/share/Redis-cluster-test/n1 *(insecure,rw,async,no_root_squash)
/home/share/Redis-cluster-test/n2 *(insecure,rw,async,no_root_squash)
/home/share/Redis-cluster-test/n3 *(insecure,rw,async,no_root_squash)
/home/share/Redis-cluster-test/n4 *(insecure,rw,async,no_root_squash)
/home/share/Redis-cluster-test/n5 *(insecure,rw,async,no_root_squash)
EOF
service nfs restart
service rpcbind restart
5) 在 project Redis-cluster-test 中创建 ConfigMap
Console 节点主机执行命令:
oc create -f configmap.yaml -n Redis-cluster-test
configmap.yaml 参考: https://github.com/powerlsr/redis-on-ocp/blob/main/configmap.yaml
如果对 Redis 配置有要求,可以修改这个文件中的 Redis.conf 项
6) 在 project Redis-cluster-test 中配置安全策略
Console 节点主机执行命令:
oc adm policy add-scc-to-user anyuid -z default -n Redis-cluster-test
oc adm policy add-scc-to-user privileged -z default -n Redis-cluster-test
oc adm policy add-cluster-role-to-user cluster-reader -z default -n Redis-cluster-test
7) 在 project Redis-cluster-test 中创建 statefulset
oc create -f sts.yaml
sts.yaml 文件参考: https://github.com/powerlsr/redis-on-ocp/blob/main/sts.yaml
8) 查看已创建的 Redis 集群对象
oc get pods -n Redis-cluster-test
oc get pv -n Redis-cluster-test
oc get pvc -n Redis-cluster-test
9) 登录 web 界面确认创建对象
登录后查找 statefulset:
点击 Redis-cluster 后选择 Pods 标签:
可以看到有 6 个 pod 已经 running ,分别分布到 6 个 worker 节点,点击其中任意一个,查看 POD_IP :
可以看到 pod ip 使用的是宿主机 worker 节点的 ip , 说明集群外部网络是可以直接通过 IP 访问 pod 的。
10) 启动 Redis 集群
登录 Console 主机:
Redis-cli --cluster create 10.152.20.41:6379 10.152.20.42:6379 10.152.20.43:6379 10.152.20.44:6379 10.152.20.45:6379 10.152.20.46:6379 --cluster-replicas 1
11) 验证集群功能
登录 Console 主机:
Redis-cli -h 10.152.20.41 –c
12) 在压力主机上搭建 haproxy
主机 ip: 10.152.15.42
yum install –y haproxy
/etc/haproxy/haproxy.cfg 参考:
Harpoxy 监听端口 4306.
启动 haproxy:
haproxy -f /etc/haproxy/haproxy.cfg
验证:
Redis-cli -h 10.152.15.42 -p 4306 -c
1) Redis 容器 VS 非容器性能对比
使用 Redis-benchmark 工具进行压力测试, Console 节点安装 Redis:6.0.5 版本, Console 节点部署 Docker 容器 Redis:6.0.5 版本:非容器 Redis 端口 6379 , Redis-Docker 映射本机端口 6380.
客户端主机 ip:10.152.15.42
非容器化 Redis 集群压力测试结果:
模拟 100 并发, 100000 个请求
登录 10.152.15.42 :
Redis-benchmark -h 10.152.20.31 -c 100 -n 100000 :
容器化 Redis 集群压力测试结果:
测试结果显示, Redis 集群在 K1 Power 容器化和非容器化场景下性能差异不大。
2) 集群节点独立部署
根据测试目标,参照第四章节把 Redis 集群的三主三从节点部署到容器云平台不同的 worker 节点上面,实现了 Redis 集群主从节点的独立部署。
3) 数据持久化
Redis 集群的持久化使用容器云平台 nfs 远程存储,共创建 6 个 PV , Redis 集群 6 个节点会各分配一个, path 需要手动创建。
4) failover 测试
查看当前 Redis cluster 集群 master slave 分布情况:
登录 console 节点,执行命令:
Redis-cli -h 10.152.15.42 -p 4306 -c
查看pods分布情况:
模拟删掉master节点10.152.20.45:6379所在pod Redis-cluster-1,目前Redis集群检查心跳时间为2秒(cluster-node-timeout 2000,小于pod自动拉起时间),检查slave节点10.152.20.41:6379是否自动升级为master节点,原有master节点下降为slave节点:
主动切换正常。
从测试结果可以看到,删除 Redis 集群中一个 master 对应的 pod ,相当于该 master 节点不能提供服务,这个 master 对应的 slave 自动升级成 master 节点, OCP 把挂掉的 pod 拉起来,自动成为 slave 。
本次测试,模拟生产环境 Redis 集群架构,实现了高可用集群实例在容器云平台 worker 节点上的独立部署,外部应用节点可以通过 IP 和端口访问 Redis 高可用集群;并使用容器云平台 nfs 存储为 Redis 集群提供了配置信息等关键信息的持久化;并验证通过主从节点的 failover 自动快速切换。浪潮 K1 Power 与红帽 OpenShift 容器云平台联合方案,为本次测试提供了性能卓越、稳定的运行平台,其中 Redis 集群容器化部署表现出与非容器部署接近的性能, 达到了预期的效果 。 OpenPOWER 生态系统为我们的测试提供了各种开放的软硬件选择,简单顺畅的完成整体方案部署。 K1 Power Linux FP5290G2 服务器采用 POWER9 处理器,相比于 x86 平台提供更快的内核和更多的线程,处理器有 22 个核心,支持 SMT4 ;具有更宽更快的内存接口,支持 8 个内存通道,内存容量支持 2TB 。在测试中表现出更高的吞吐和更低的延迟,运行的容器实例密度更高,性能更好,整体方案性价比高。
如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!
赞13
添加新评论6 条评论
2021-06-30 10:28
2021-06-29 11:10
2021-06-29 10:02
2021-06-29 09:50
2021-06-24 14:35
2021-06-24 11:35