REDIS 云原生实战

摘要

本次以Redis为范例,阐述了有道基础架构团队在基础设施容器化道路上的实践,主要将从声明式管理,Operator工作原理,容器编排,主从模式,集群模式,高可用策略,集群扩缩容等方面展开。

 

背景

Redis 是业务系统中较为常用的缓存服务,常用于流量高峰数据分析、积分排序等场景,并且通过中间件可以实现系统之间的解耦,提升系统的可扩展性。

传统物理机部署中间件,需要运维人员手动搭建,启动时间较长,也不利于后期维护,无法满足业务快速发展的需求。

云原生相较于传统IT,可以助力业务平滑迁移、快速开发、稳定运维,大幅降低技术成本,节约硬件资源。

云原生中间件是指依托容器化、服务网格、微服务、Serverless等技术,构建可扩展的基础设施,持续交付用于生产系统的基础软件,在功能不变的前提下,提高了应用的可用性与稳定性。

在这种大趋势下,有道基础架构团队开始了云原生中间件的实践,除了本文介绍的 Redis,还包括 Elasticsearch、ZooKeeper 等。

 

面临的挑战

利用云原生技术可以解决当前Redis部署缓慢,资源利用率低等问题,同时容器化 Redis 集群也面临着一些挑战:

• Kubernetes 如何部署 Redis 有状态服务

• 容器 Crash 后如何不影响服务可用性;

• 容器重启后如何保证Redis 内存中的数据不丢;

• 节点水平扩容时如何做到 slots 迁移时不影响业务;

• pod ip变化后集群的状态如何处理。

声明式管理

对于一个 Redis 集群,我们的期望是能够 7×24 小时无间断提供服务,遇故障可自行修复。这与Kubernetes API的声明式特点如出一辙。

所谓“声明式”, 指的就是我们只需要提交一个定义好的 API 对象来“声明”我所期望的状态是什么样子,Kubernetes中的资源对象可在无外界干扰的情况下,完成当前状态到期望状态的转换,这个过程就是Reconcile过程。例如,我们通过yaml创建了一个Deployment ,Kubernetes将“自动的”根据yaml中的配置,为其创建好Pod,并拉取指定存储卷进行挂载,以及其他一系列复杂要求。

因此,我们的Redis集群是否可以使用一个类似的服务去完成这个过程呢?即我们需要定义这样的对象,定义服务Reconcile的过程。Kubernetes的Operator刚好可以满足这个需求,可以简单的理解Operator由资源定义和资源控制器构成,在充分解读集群和Operator的关系后,我们将整体架构图设计如下
REDIS 云原生实战
Operator集群本身采用Deployment部署,由ETCD 完成选主,上层与Kubernetes的Api Server 、Controller Manager等组件进行通信,下层持续调和Redis集群状态。

哨兵模式中Redis服务用一套哨兵集群,使用StatefulSet部署,持久化配置文件。Redis server也采用 StatefulSet部署, 哨兵模式的实例为一主多从。

集群模式中的每个分片使用StatefulSet部署,代理采用Deployment部署。原生Pod、StatefulSet、Service、调度策略等由Kubernetes本身负责。

Redis的资源定义在ETCD中存储一份即可,我们只需要预先提交自定义资源的 yaml配置。如下所示为创建三个副本的Redis主从集群

其中,kind定义使用的CR名称,size为副本数,resources定义资源配额,config对应Redis Server的config,该定义存储在Kubernetes的ETCD数据库中,后续的具体资源申请与使用由Operator的Controller完成。

Operator工作原理

Operator 是 Kubernetes 的扩展模式,由CRD、Controller构成。它利用定制资源管理特定应用及其组件,Operator 遵循 Kubernetes 的理念。

Operator 无需任何修改,即可从 Kubernetes 核心中获得许多内置的自动化功能,如使用 Kubernetes 自动化部署和运行工作负载, 甚至可以自动化 Kubernetes 自身。

Kubernetes 的 Operator 模式可在不修改 Kubernetes 自身的代码基础上,通过控制器关联到一个以上的定制资源,即可以扩展集群的行为。Operator 是 Kubernetes API 的客户端,核心功能是充当定制资源的控制器。
REDIS 云原生实战

CRD: Custom Resource Definition, 在Kubernetes中一切皆是资源,资源就是CRD,用户自定义的Kubernetes资源是一个类型 ,比如默认自带的由Deployment,Pod ,Service等。

CR: Custom Resource 是实现CRD的具体实例。

用户创建一个CRD自定义资源,ApiServer把CRD转发给webhook,webhook 进行缺省值配置 验证配置和修改配置,webhook处理完成后的的配置会存入ETCD中 ,返回给用户是否创建成功信息。Controller 会监测到CRD,按照预先写的业务逻辑,处理这个CRD,比如创建Pod、处理新节点与旧集群关系等,保证运行的状态与期望的一致。

容器编排

Redis 集群在 Kubernetes 中的最小部署单位为 Pod,因此在架构设计之前,需预先考虑Redis特性、资源限制、部署形态、数据存储、状态维护等内容,为不同类型的Redis集群配置合适的部署方式。

资源限制

Kubernetes 采用 request 和 limit 两种限制类型来对资源进行分配。

• request(资源需求):即运行Pod的节点必须满足运行Pod的最基本需求才能启动。
\
• limit(资源限制):即运行Pod期间,可能内存使用量会增加,那最多能使用多少内存,这就是资源限额。

Redis 基本不会滥用 cpu,因此配置1-2个核即可。内存根据具体业务使用分配,考虑到部分场景下会fork较多的内存,例如 aof 频繁刷写,aof 重写过程中,Redis 主程序称依旧可以接收写操作,这时会采用 copy on write (写时复制)的方法操作内存数据,若业务使用特点为“写多读少”,那么刷写期间将产生大量的内存拷贝,从而导致 OOM,服务重启。

一个有效的解决方式为减少刷写次数,将刷写操作放在夜间低流量时段进行。减少刷写次数的方法为适当增加auto-aof-rewrite-min-size的大小,可配置使用内存的5倍甚至更大的最小刷写量;其次可以主动触发刷写,判断内存使用达到的配额两倍时进行刷写,实际部署时一般也会预留50%的内存防止OOM。

部署的基本形态

依据数据是否需要持久化或是否需要唯一标识区分服务为无状态和有状态的服务,Redis集群需要明确主从、分片标识,大部分场景也需要数据持久化,Kubernetes使用StatefulSet来满足这一类需求。StatefulSet的顺序部署、逆序自动滚动更新更能提高Redis集群的可用性。

具体的:

• Redis Server 使用 StatefulSet 启动,为标识为{StatefulSetName}-0的Pod设置Master角色,给其他Pod设置为该Master的从节点。

• Proxy无需存储任何数据,使用Deployment部署,便于动态扩展。

配置文件
Redis Server 启动时需要一些配置文件,里面涉及到用户名和密码,我们使用 Configmap 和 Secret 来存储的。Configmap 是 Kubernetes的Api 对象,常用于存储小于1MB的非机密键值对。而 Secret 可以用于存储包含敏感信息的密码、令牌、密钥等数据的对象。

两种资源均可以在 Pod 运行的时候通过 Volume 机制挂载到 Pod 内部。

存储
存储使用的是 PVC(PersistentVolumeClaim) 加 PV (Persistent Volumes),PV为Kubernetes集群中的资源,由存储类StorageClass来动态供应,PV支持多种访问模式:ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany,通过PV定义存储资源,PVC申请使用该存储资源。另外通过根据存储的 StorageClass 字段 可抽象不同的存储后端,如Cephfs、Cephrbd、Openebs、LocalStorage 等。

主从模式

主从拓扑图

Redis容器化后建立的每个 CR 表示一个完整的Redis服务,具体的服务模式包括哨兵模式和集群模式两种,在进行容器化过程中,除覆盖裸服务器部署结构外,也对架构进行了一定程度的优化。

原生哨兵模式

原生哨兵模式为每套实例配一组哨兵。
REDIS 云原生实战

共用哨兵模式

所有实例共用一组哨兵将进一步提高实例启动速度,并在一定程度上可提高硬件资源利用率,实测单组哨兵可轻松应对百规模的主从集群。
REDIS 云原生实战

调和原理

Reconcile 实现持续监测并对主从集群进行修复的功能。
REDIS 云原生实战

  1. 检查是否按照预期启动了全部的Pod,比如创建3个Server,那么需要按照预期启动三个才能继续进行后面的操作。
  2. 检查Master的数量,确保该实例仅有一个主节点(数量为0主动选一个;数量大于1手动修复)。
  3. 检查哨兵:(1)所有的哨兵是否监控了正确的Master;

    (2)所有的哨兵均知道相同的Slave;

    (3)再次检查哨兵的数量,确保哨兵均可用。

  4. 检查 Service,使Service 的Endpoints指向正确的Master。
  5. 检查Redis config是否有做修改,有则对所有节点重写config参数。

集群模式

集群拓扑图

Redis Cluster + Proxy模式

通过在传统Redis Cluster架构中引入代理功能,实现动态路由分发,并基于Kubernetes原生动态扩缩容特性,更易应对突发流量,合理分配使用资源。

代理基础转发规则如下

• 对于操作单个Key的命令,Proxy会根据Key所属的Slot(槽)将请求发送给所属的数据分片。

• 对于操作多个Key的命令,如果这些Key是储存在不同的数据分片,Proxy会将命令拆分成多个命令分别发送给对应的分片。

服务部署前,也对代理的部分功能进行了补充,例如移除不可用节点等。

REDIS 云原生实战

调和原理

reconcile实现持续监测并对Redis Cluster进行修复功能。
REDIS 云原生实战

确保集群健康的步骤

  1. 等待所有 Pod 状态变为 Ready 且每个节点相互识别后,Operator 会在每个 StatefulSet 的 Pod 中挑选一个作为 Master 节点,其余节点为该 Master 的 Slave。
  2. 获取实例集群所有Pod的ip、所有Pod的cluster info(包含nodeIP,主从关系等)。
  3. 进入恢复流程(1)处理失败节点, 对部分节点重启后的无效ip、状态为noaddr的僵尸节点进行forget操作;

    (2)处理不可信节点 (所有handshake状态的节点),发生于某一个节点被移除(由forget node触发),但试图加入集群时,即该Pod在Operator角度下存在,但实际集群节点并不需要该节点,处理方式为删掉这个Pod,并再次做forget操作直到Pod被删除。

  4. 任选一个节点,使用CLUSTER MEET给该节点加入所有已知节点。
  5. 为StatefulSet中的Pod建立主从关系,同时给其分配Slots。若当前Master数量同预期不一致,则对应扩缩容操作,具体见’集群扩缩容’的横向扩缩容小节。
  6. 检查Redis config是否有做修改,有则对所有节点重写config参数。

确保代理健康的步骤

  1. 获取所有Running状态代理的Pod ip。
  2. 从代理获取Redis Server信息,将集群信息同步到所有的代理上,代理中不存在的Server ip做移除操作。
  3. 若代理中无可用Redis Server, 表示被全部移除,则添加一个,代理可自动发现集群其他Redis节点。

高可用策略

Kubernetes保证的高可用

(1) 容器部署保证高可用:

Redis部署最小资源对象为Pod,Pod是Kubernetes创建或部署的最小/最简单的基本单位。

当启动出错,例如出现“CrashLoopBackOff”时,Kubernetes将自动在该节点上重启该Pod,当出现物理节点故障时,Kubernetes将自动在其他节点上重新拉起一个。
Pod未出问题,但程序不可用时,依托于健康检查策略,Kubernetes也将重启该Redis节点。

(2) 滚动升级:

节点纵向扩容时,使用StatefulSet的滚动升级机制,Kubernetes将逆序重启更新每个Pod,提高了服务的可用性。

(3) 调度的高可用:

Kubernetes本身不处理Redis 多个Pod组建的集群之间的部署关系,但提供了部署策略,为保证特定场景下的高可用,如因物理节点导致所有Redis节点均宕机,CRD在设计中加入了亲和与反亲和字段。
默认使用 podAntiAffinity 做节点打散,如下所示实例instance1的所有 Pod 将被尽可能调度到不同的节点上。

Redis集群的高可用

Redis 服务运行期间不可避免的出现各种特殊情况,如节点宕机、网络抖动等,如何持续监测这类故障并进行修复,实现 Redis 集群的高可用,也是 Operator 需解决的问题,下面以哨兵模式模式为例描述集群如何进行故障恢复。

主节点宕机:因物理节点驱逐、节点重启、进程异常结束等导致的Redis主节点宕机情况,哨兵会进行切主操作,然后Kubernetes会在可用物理节点上重新拉起一个Pod。

从节点宕机:哨兵模式的Redis集群未开启读写分离,从节点宕机对服务无影响,后续Kubernetes会重启拉起一个Pod,Operator会将该Pod设置为新主节点的从节点。

集群全部节点宕机:发生概率极小,但基于持久化可将服务影响降至最低,集群恢复后可继续提供服务。

节点网络故障:主从模式下配置了三个哨兵用于集群选主操作,哨兵集群的每一个节点会定时对 Redis 集群的所有节点发心跳包检测节点是否正常。如果一个节点在down-after-milliseconds时间内没有回复Sentinel节点的心跳包,则该Redis节点被该Sentinel节点主观下线。

当节点被一个 Sentinel 节点记为主观下线时,并不意味着该节点肯定故障了,还需要Sentinel集群的其他Sentinel节点共同判断为主观下线才行。

该 Sentinel 节点会询问其他Sentinel节点,如果 Sentinel 集群中超过 quorum 数量的 Sentinel 节点认为该 Redis 节点主观下线,则该 Redis 客观下线。

如果客观下线的 Redis 节点是从节点或者是Sentinel节点,则操作到此为止,没有后续的操作了;如果客观下线的Redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。

集群模式故障转移与上述类似,不过不需要哨兵干预,而是由节点之间通过PING/PONG实现。

监控观测

Redis 的监控采用经典的 Exporter+Promethus 的方案,Exporter 用于指标采集,数据存储在 Prometheus 或其他数据库中,最终 Grafana 前端将服务状态可视化。

集群扩缩容

(1)纵向扩缩容

纵向扩缩容主要指Pod的CPU、内存资源的调整,基于Kubernetes的特性,只需修改实例对应的spec字段,Operator的调和机制将持续监测参数变化,并对实例做出调整 。当修改cpu 、内存等参数时,Operator同步更新StatefulSet的limit、request信息,Kubernetes将逆序滚动更新Pod,滚动更新时,若停掉的是主节点,主节点的preStop功能会先通知哨兵或者集群进行数据保存,然后做主从切换操作,从而将服务的影响降至最低。更新后的主从关系建立以及哨兵monitor主节点功能也由Operator一并处理,全过程对客户端无感知。主从版、集群版在该场景下均支持秒级断闪。

(2)横向扩缩容

横向扩缩容主要指副本数或节点数的调整,得益于 Kubernetes 的声明式 API,可以通过更改声明的资源规模对集群进行无损弹性扩容和缩容。

Redis Server扩容操作时,主从版本中Operator将获取新节点ip, 新启动节点将在下一轮调和时触发slaveof 主节点操作,且同步过程中,哨兵不会将该节点选为主节点。集群版本中Operator将在同步节点信息后进行分片迁移,保证所有节点上的Slots尽可能均匀分布。

Redis Server缩容操作时,主从版本中Operator将逆序销毁Pod,销毁时会先询问哨兵,自己是否为主节点,若为主节点则进行先failover操作再退出。集群版本中Operator中会先进行分片迁移,再对该节点做删除操作。

代理的扩缩容,更易实现,根据流量波峰波谷规律,可手动定期在波峰到来时对 Proxy 进行扩容,波峰过后对 Proxy 进行缩容;也可根据HPA实现动态扩缩容,HPA也是Kubernetes的一种资源,可以依据Kubernetes 的Metrics API的数据,实现基于CPU使用率、内存使用率、流量的动态扩缩容。

总结与展望

本次以 Redis 为范例,阐述了有道基础架构团队在基础设施容器化道路上的实践,Redis上云后将大幅缩短集群部署时间,支持秒级部署、分钟级启动、启动后的集群支持秒级自愈,集群依托于哨兵和代理的特性,故障切换对用户无感知。

有道架构团队最终以云的形式提供中间件能力,用户无需关注基础设施的资源调度与运维,重点关注具体业务场景,助力业务增长。未来,将进一步围绕Redis实例动态扩缩容、故障分析诊断、在线迁移、混合部署等内容展开探索。

Redis 容器化后有哪些优势?
\
Kubernetes 是一个容器编排系统,可以自动化容器应用的部署、扩展和管理。Kubernetes 提供了一些基础特性:

部署:部署更快,集群建立无需人工干预。容器部署后可保证每个的Redis节点服务正常,节点启动后将由Operator持续监测调和Redis集群状态,包括主从关系、集群关系、哨兵监控、故障转移等。

资源隔离:如果所有服务都用同一个集群,修改了Redis集群配置的话,很可能会影响到其他的服务。但如果你是每个系统独立用一个Redis群的话,彼此之间互不影响,也不会出现某一个应用不小心把集群给打挂了,然后造成连锁反应的情况。

故障恢复

(1)实例的重启:容器化后的健康检查可以实现服务自动重启功能;
(2) 网络故障:因宿主机网络故障带来的实例延迟高,哨兵可进行主从切换,而为了保证集群的健康,将由Operator负责同步集群信息。

扩缩容:容器部署可根据limit和request限制实例的cpu和内存,也可以进行扩缩容操作,扩容后的故障恢复由Operator处理。

节点调整:基于Operator对CRD资源的持续调和,可在Operator的Controller中为每个Redis实例进行状态维护,因此,节点调整后带来的主副关系建立、集群Slots迁移等均可自动完成。

数据存储:容器化可挂载Cephfs、LocalStorage等多种存储卷。

监控与维护:实例隔离后搭配Exporter、Prometheus等监控工具更容易发现问题。

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。商机网仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 tenspace2022@163.com 举报,一经查实,本站将立刻删除。 本文链接:https://www.315965.com/n/53341.html 聚才发 母婴好物

(0)
上一篇 2023年12月16日 上午1:54
下一篇 2023年12月16日 上午2:04

相关推荐

  • 我的世界新手教程手机(我的世界手机新手入门攻略)

    1.Minecraft Minecraft是一个沙盘游戏,是一个高度自由的游戏。整个游戏没有终点,你可以在世界里任意发挥你的想象力和能力。 生存模式:你需要不断地收集资源,探索世界,寻找食物来生存下来,整个生存模式没有最终目标。死后可以选择复活。 创造模式:你可以飞行,你拥有无限的资源,能够尽情的创造建筑等,甚至是大型红石设备。 冒险模式:你不能破坏与放置方…

    2023年7月31日
    365
  • 推荐几个可以免费使用的ChatGPT工具

    在ChatGPT相关API推出之后,各种工具如雨后春笋一般层出不穷,这篇文章就列举一些日常使用到的工具。 工具列表 myreader.io myReader主页 这款工具的作者是@madawei2699,github主页地址为t.co/adJBYWbjkF,… 在线读取任意网页内容包括视频(YouTube),并根据这些内容回答你提出的相关问题或总结相关内容 …

    2023年12月18日
    358
  • 强烈推荐的微信小程序开发总结

    遇到过的坑 小程序页面栈最多十层 问题:假设小程序内有12个问题页面,答完上一个问题后wx.navigateTo到下一个问题页面,那么到第十题时,你会发现wx.navigateTo跳转不到下一个页面。这是因为使用wx.navigateTo跳转会把当前页面保存到页面栈中,而小程序页面栈最多十层。 require的路径不支持绝对路径 问题:在嵌套比较深的目录层级…

    2023年12月17日
    158
  • cad教程入门基础免费(cad入门基础知识教程)

    CAD入门这个范围实在是太广了,如果简单理解为,掌握大部分绘图、修改命令的用法,这个倒是可以考虑去整理。 那今天,我们就一点点,从最简单的命令开始学起。 1、直线命令,快捷键L 执行命令后鼠标左键确定起点,再次点击鼠标左键确定终点。 注意:确定起点后,命令行提示了另外两种方式确定终点,角度A和长度L,就是说你可以通过输入A利用指定角度画出你要的直线,或者长度…

    2023年7月30日
    267
  • 电子琴初学教程(电子琴初学教程手指法)

    今天重点学习下 弹琴前的最后准备功课正确的姿势以及大小调和弦 级数是罗马数字 分别表示1234567 之前教程具体讲过和弦的定义,在大调里面,不是说所有和弦都必须是大三和弦。 我们以大调前6个常用级数来看,1级4级5级是大三和弦,2级3级6级是小三和弦。 通过这种布局可以得出一个自己总结的概念 在大调里面常用级数的大小三和弦分别是: 1 4 5为大,2 3 …

    2023年7月31日
    216
  • 花束包装教程图解(简单鲜花包装教程)

    DIY 的花太多了,不知道如何存放?8 种花艺包装给你选择 (附教程) 今天的主题就是 花束包装 教程1 这次的教程总共分为8个教程 不管是对于鲜花 还是我们自己制作的手工花 包装包装的手法大体一致 主要的区别就是 鲜花需要做保鲜处理 而我们的手工花 只需要负责美美哒! 教程2 在包装材料的选取这一块 我们也尽量遵循着纸艺的原则 所以在材料准备上面 大家只需…

    2023年7月30日
    304
  • “超级充电宝”蓄势待发 还面临哪些挑战?

    装机规模增长、技术装备提升、应用成本下降……近年来,包括抽水蓄能、新型储能等技术在内的储能技术和装备,为促进新能源的开发消纳、提高电力系统的灵活性,发挥了积极作用。 未来,还需通过进一步发力技术研发、健全市场机制、保障安全水平等,循序渐进,推进储能高效应用和高质量发展。 山间峡谷,国网新源安徽桐城抽水蓄能电站加紧施工,超过21亿千瓦时的设计年发电量,可满足安…

    2023年12月22日
    157
  • 预测2024年之后的前端开发模式

    最近AIGC(AI Generated Content,利用AI生成内容)非常热,技术圈也受到了很大冲击。目前来看,利用LLM(Large Language Model,大语言模型)辅助开发还停留在非常早期的阶段,主要应用是辅助编码,即用自然语言输入需求,模型输出代码。更近一步的探索也仅仅是在此基础上的一层封装(比如copilot X、cursor)。 但即…

    2023年12月16日
    156
  • 剪纸教程图解步骤(剪纸教程图解步骤简单)

    今天给大家带来的是——简单枫叶剪纸教程。有多简单呢?只需要一张纸,一把剪刀,而且只需要剪一下就可以了。有没有一丝心动,感兴趣的话就快来试试吧!这个枫叶剪纸作为装饰非常不错哦! 枫叶剪纸教程图解 先上图 我们需要准备的材料有:一张正方形的纸,我用的是10厘米正方形纸,供大家参考。除此之外还有剪刀。 取出正方形纸,沿着中间对折。 然后按如图所示,再次向中间折叠。…

    2023年7月30日
    328
  • 如何制作精美的ppt(如何制作精美的ppt教程)

    PPT在我们的生活和工作当中经常会被用到,很多人都在羡慕为什么别人的PPT做出来都非常好看,然而自己做的却很平常,今天就来教大家5个与众不同的PPT实用技巧,让你的PPT更高级! 一、墨迹笔刷效果 平时在制作PPT时,一直用的都是形状,时间久了就会感觉到没有欣赏度,赶快试试这个墨迹笔刷效果吧!首先需要准备一些笔刷素材,然后插入到PPT,点击右键「填充」-「图…

    2023年7月31日
    377