IT评测·应用市场-qidao123.com技术社区

标题: 是否应在 Kubernetes上运行Redis?快手这样做! [打印本页]

作者: 徐锦洪    时间: 2024-11-9 04:08
标题: 是否应在 Kubernetes上运行Redis?快手这样做!
导读:针对无状态服务,业界已拥有成熟解决方案,但对于有状态服务(如数据库、Redis)是否适合容器化与K8s托管,仍存在争议。本文将基于快手在 Redis 云原生化实践中的经验,探究有关有状态服务的云原生化思索及应对方案。
一、背景

随着行业技术的不断演进,快手的基础办法顺应技术潮流逐步迈向云原生化。在各业务团队的支持下,容器云成为服务与基础办法的新界面,目前在快手无状态服务已基本全面实现 Kubernetes (K8s) 的云原生化。然而,有状态服务的云原生化之路却仍然充满了挑衅:

以 Redis 为例,它是快手广泛使用的有状态服务之一,超大规模是其明显特性。即使微小的优化在云云庞大的规模下也能为企业带来巨大的收益。在面向未来的长期规划中,快手高度承认 Redis 云原生化带来的潜在代价,尤其是资源使用率提升带来的成本优化。本文基于快手 Redis 云原生化实践中的经验,深入分析有状态服务的云原生化思索及应对策略。
二、有状态服务是否适合运行在K8S上?

有状态服务运行在K8S上的风险与收益

将有状态服务运行在 Kubernetes 上的收益显而易见:


尽管有状态服务运行在 Kubernetes 上的收益明显,但潜在风险也需认真评估,尤其是对数据库等有状态服务,其重要性和稳定性要求极高。这里的主要风险包罗:
1. 性能降落风险:容器化部署增加了一层抽象,是否会导致服务性能降落?
2. 稳定性影响:将数据库体系构建在K8S体系上,有状态服务稳定性是否会受到影响?
3. 运维复杂度增加?标题发生时,是否必要同时具备数据库和云原生技术的专家才能有效定位息争决标题?


针对上述风险,下文将睁开探究。
有状态服务运行在K8S上的可能性


在探究有状态服务时,我们首先必要明确“状态”的具体含义:
数据状态:单个实例生存的、区分其他实例的数据。每个实例负担差别角色,存储独特的数据状态。因此,任何实例不可随意抛弃;同时,在实例生命周期管理过程中,也需额外对数据进行处理(如备份、恢复、数据重平衡等)。
拓扑状态:差别角色实例之间的关系状态信息;且这种关系在实例运行过程中通常是动态变革的。
综上,有状态服务的云原生化相比无状态服务面对新的挑衅:怎样包管数据的可用性、管理数据生命周期,以及建立和维护拓扑关系并实现基于拓扑结构的服务发现和灰度发布等能力。K8S 社区目前的应对步伐包罗:
方案一:StatefulSet Workload:

方式二:自定义Workload + Operator:

综上所述,有状态服务部署在 Kubernetes 上相比无状态业务来说必要更多风险考量,且实现的成本和难度相对较高。然而,这种投入每每是一次性的,而云原生化带来的收益则是一连性的,可以为企业未来发展提供坚实基础。因此,企业在决策时应充实衡量这些因素,以做出更具战略性的选择。
三、快手怎样将Redis运行在K8S上?

快手的 Redis 采用的是经典的主从架构,包罗三个组件(Server、Sentinel 和 Proxy)。


迁移单个Redis集群上K8S


快手 Redis 云原生化思路

基于以上分析,Redis 的云原生化实现无法基于 Kubernetes 社区现有 Workload 实现,具体而言:

针对上述挑衅,我们提出了如下解决思路:



KubeBlocks 解决方案

颠末调研,KubeBlocks 项目成为我们重点关注的解决方案之一,其贴合我们的思路与需求。作为一个开源 K8S Operator,KubeBlocks 抽象了管理各种数据库的 API,支持在 Kubernetes 上运行和管理多种范例的数据库。其愿景是“在 Kubernetes 上运行任何数据库”。
颠末与 KubeBlocks 社区深度合作,我们通过如下方式实现一个 Redis 集群的编排:



1. InstanceSet Workload

2. Component、Shard 、Cluster Workload:

迁移大规模Redis集群上K8S


前面提到,超大规模是快手 Redis 的明显特性,其实例规模远超单个 K8S 集群的容量。因此,我们不得不基于多个 Kubernetes 集群来支持业务。与传统模式下所有主机平铺的方式差别,因为 K8S 单个集群的容量限定,我们必须将主机资源池切分到多个 K8S 集群中。如果将多个 K8S 集群的复杂度直接袒露给 Redis 业务方,上云成本势必会被大幅增加。
联邦集群架构

在快手,我们通过基于联邦集群能力提供相应的同一调理和同一视图能力,降低业务方的复杂度,使其更专注于焦点业务。


而怎样将上述基于 KubeBlocks 的方案落地到联邦集群架构呢?以下是整体架构:


1. KubeBlocks Operator 拆分:
将 KubeBlocks 拆分为多个部分,此中:

2. Fed-InstanceSet控制器:
在联邦集群和成员集群之间,快手扩展自研了 Fed-InstanceSet 控制器组件,其主要职责为:

Fed-InstanceSet 控制器

针对 Fed-InstanceSet 控制器,有两个关键标题必要解决:

针对第一个标题,我们与社区合作,设计了 Ordinals 字段,答应指定编号的索引值。在多集群下发场景下,Fed-InstanceSet 控制器可以为每个子集群的 InstanceSet 设置差别的索引值,从而包管实例在多 K8S 集群中的全局唯一性和有序性。


针对第二个标题,我们必要联合全局顺序、角色关系、灰度变更策略、并发度管控和角色变更策略等因素,构建全局变更的有向无环图(DAG)。该图结构将用于包管多 K8S 集群范围内的全局变更管控。
应对Redis上K8S的风险


性能

Redis 基于云原生架构部署模式下,相较于传统主机部署增加了一层容器抽象。但根据业界分享和快手内部测试效果,这种架构带来的性能差距通常在 10% 以内,很多情况下基本持平。这种性能变革每每在可接受范围内。企业也可根据自身实际情况进行性能测试与评估,以确保满足业务需求。
稳定性

迁移有状态服务上 K8S 后,尽管 K8S 带来的主动化能力大幅提升了运维服从,但这也导致实行流程变得黑盒化,且微小的设置变更会影响大范围的业务实例。因此,为了有效应对非预期内的运维操作(如K8S 发生实例驱逐、集群运维人员误操作、Operator 逻辑非常等场景)给业务带来的稳定性风险,我们必要在如下工作上做出努力:

针对标题一,答案显而易见:是否由运维人员主动发起可作为唯一的判断标准。基于此,我们可以为业务团队生成指定的 ServiceAccount 证书,并通过请求中的用户信息来区分变更发起泉源;
针对标题二,沿着标题一的思路,我们可以使用 K8S APIServer 的 Admission Webhook 机制,对所有变更请求进行拦截和校验,从而直接拒绝非预期的变更操作;基于快手多 K8S 集群的场景,我们必要实现跨集群和多可用区(AZ)的变更管控能力。为此,快手内部研发了一套风险变更阻断系统:kube-shield,关于该系统的更多细节,本文将暂时不做深入探究,筹划未来会单独撰写一篇文章进行具体先容
另外,值得一提的是,在快手内部,通过加强对细粒度打散调理能力的支持,以及基于资源使用率的负载均衡调理等功能,进一步提升了业务的高可用性与稳定性。
运维复杂度

将基于主机的运维体系迁移至基于 K8S 的运维体系,并支持后续的运维工作,这必要对 Redis 和容器云两个领域具备深入的理解,若仅依靠 Redis 团队或容器云团队独立支持都将非常困难。而公道的分工,不仅可以提高生产服从,也能充实发挥各团队在各自领域的专业性。
以快手的 Redis 云原生方案为例:



四、总结

“有状态服务云原生化”是一个必要慎重思量利弊且充满挑衅的过程,但对于快手来说,其代价显而易见。我们以 Redis 为出发点,与 KubeBlocks 社区深度合作,低成本完成 Redis 的云原生化方案落地。未来,快手将基于以上经验,继续推动更多有状态服务,如数据库和中间件的云原生化,从而获得技术和成本的双重收益。
附注:在本年 8 月份的香港 KubeCon 上,快手与 KubeBlocks 团队进行了联合演讲,如果您对此感兴趣,可以查看演讲的回首内容。

本文作者:刘裕惺

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4