云原生热度持续攀升,这一趋势也延伸了到中间件领域。借助云原生技术,中间件正在解决了自身的弹性、韧性、运维、交付等问题。同时,开发者使用中间件方式也越来越云原生化。
那么,在云原生时代,中间件应该如何完成自己的技术“进化”呢?5 月 30 日,网易数帆云原生首席架构师冯常健做客《极客有约》,与我们一起探讨了这一话题。以下内容根据直播内容整理,并做了不改变原意的删减,完整内容可点击查看回放视频。
中间件为什么要云化
Q:冯老师 12 年加入网易,已经有十多年的研发经验。您是什么时候开始关注云原生的?
A:我大概做了十多年的开发和架构设计工作,比较幸运的是,我正好完整地赶上了云原生从萌芽、发展,再到目前逐渐成熟,在生产环境里可以大规模创新落地的整个过程。在 2014 年的时候,Kubernetes1.0 版本还没有出来,我们就基于 Docker、Kubernetes 开发容器云平台。目前,我在公司里面也一直在做云原生相关的微服务、容器化、服务网格、中间件以及 DevOps 等云原生工程大规模落地实践方面的事情。
Q:您觉得,云原生从最开始到现在发生了哪些重大进展?
A:最直观的感受还是云原生对研发运维过程产生了很大的影响。5、6 年前,DevOps 还没有太多比较具体的落地路径,更多还是在强调 DevOps 开发运维一体化的理念。随着云原生各项技术的发展,大家慢慢发现 DevOps 理念倡导的敏捷、灵活和快速,都可以通过云原生技术落地。可以说,云原生技术真正重塑了企业开发和运维的整个过程。
Q:那中间件云化的必要性体现在哪里?
A:首先,云的根本特征就是具备资源弹性,可以应对突发性的流量波动,而弹性的背后就是资源的池化,即把所有的计算、网络、存储等做成一个资源池,我们可以充分地调度,来提升资源利用率。
第二方面,我觉得自动化运维方面是绕不过去的。在传统领域,如果不做云化和平台化,按照我们的工程经验,通过脚本或半自动化方式可以搞定三五十个集群。但当数量达到互联网业务常见的三五百个集群规模后,传统脚本或半自动化方式是很难掌控这么多实例稳定运行的。云化的必要性在于,它可以很好地解决自动化运维的问题。
第三方面,标准化也是云化必要性的一个体现。假如不考虑云原生化,我们实际上会面临特别多的版本,特别是中间件领域,同一个中间件的选型会有很多版本,另外还有很多不同的部署架构,自动化各方面能力也难以统一。
而云化就意味着相对标准化,有助于技术栈的统一。我们可以把整个技术栈聚焦到少数几个选型上,还可以进一步做企业级的技术规范化,大家约定使用某个版本后会便于后续的维护和统一升级。
还有一点,云化意味着中间件服务供给方式的变化。规模化组织里,微服务架构除了应用外,还需要缓存、消息队列等中间件。这样的中间件要做微服务,首先要申请流程,如果运维团队和业务团队不是一个成本中心,还需要提前做容量规划、采购计划等等。这个过程涉及了多方大量的流程性交互。
云化的中间件平台提供了一个技术中台,或者说是一个门户,可以自主申请,经过一些必要的审批之后,各业务部门自己可以按需采用,大大缩短了流程,使整个资源管控效率更高。
Q:什么样的中间件可以称之为云原生的中间件?
A:我认为运行在 K8s 上面,用 K8s 原生的方式设计架构的中间件服务,就是云原生的中间件。
Q:云原生中间件和本地 PaaS 中间件之间是否有本质上的不同?
A:差异来源是云原生中间件基于 K8s。中间件的很多基础能力都下沉到了 K8s,大量常规的高频运维操作都被抽象成 K8s 上面一个个资源的定义,运维人员经常碰到的扩缩容、迁移、重建、故障恢复等高频动作都可以通过 kubectl 或其他对应的白屏化操作统一操作,极大降低了运维门槛和工作量,这是标准化带来的一个好处。
另外,因为有 Kubernetes 这一层抽象,云原生中间件天然可以做跨云或者跨异构基础设施的部署交互,所以用户体验可以在整个过程中保持完全一致。也就是说,在云计算时代,我们可以选择不同的国内外主流云厂商,把中间件服务完全跑在云上,而且可以随时迁移。这些理论上就是基于 Kubernetes 这一层的解耦。
中间件的云化路径
Q:云原生中间件的技术栈主要涵盖了哪些?又如何通过对企业发展起到降本增效的作用?
A:我们整个技术栈主要基于 K8s 以及 K8s 上面的框架,比如 Operator 等。
对于怎么降本增效,其实就是效率和成本的问题。效率上,更多是在流程和自动化两个方面提升。我们可以做很多自动化、故障根因分析、故障治愈,甚至可以做提前故障感知、稳定性巡检等事情。
成本也是云计算一直以来的问题。云计算一直在提降本增效,但多年实践下来发现,用了云计算以后成本反而处于不可控的状况。我认为,企业还是要更精细化去管控、合理地使用资源。
Q:你们内部会对云原生的中间件进行分类吗?
A:会有,主要还是按状态去分,即有状态和无状态。我们说负责负载均衡的,如 Nginx、API 网关,属于无状态的中间件,像消息缓存这种就是弱状态的中间件。
Q:对于有状态的中间件,比如 Kafka,它们的云原生路径是什么的?其中的难点又是什么?
A:云原生中间件是构建在 K8s 下面的定义,中间件包括本身的运行时、像 Redis 这样的引擎,以及配套的管控系统。我觉得它们云化的主要路径主要包括通用的技术框架和一些差异化的管控流程这两个方面。
目前,K8s 上管理有状态的主流方案就 Operator 框架及其托管平台 OLM,负责管控中间件集群的生命周期,这个过程中也会涉及到 K8s 上像 CPU 内存、磁盘网络这样的资源管理调度。此外,中间件统一访问路口的问题也非常重要。这需要结合企业里复杂的网络架构,涉及集群内外的访问,需要考虑很多细节。
接下来,我们还要做相对高级一点的能力,比如自动化的弹性扩缩容、实例迁移、一些动态的配置下发等,来实现更高层次的高可用等特性,最后还会涉及到配套相关的可观测性方面的内容。
生命周期管理、调度、访问方式,以及可观测性这些都是通用的,即 Kafka、Redis 等其他各种中间件都绕不开的这些设计。
此外,还有一些差异化的管控流程。“差异化”意味着需要在通用的基础框架上来实现不同的资源依赖管理。比如各种中间件,有些是磁盘密集型的,有些是内存密集型,有些是网络密集型,那么不同中间件对不同的资源就有不同的要求,也就需要不同的技术方案。
另外,中间件高可用的方案也是五花八门的,即它们的集群拓扑管理方式不一样,比如 Kafka 依赖 ZK 的管理集群,相对比较容易自动化,而 Redis 需要在整个集群启动之后再进行角色分配的,相对来说管控面就会重一些。
整体来说,还是通过一些通用的技术框架和差异化管理去实现各个品类中间件的云化。
运维之难
Q:轻舟有专门的运维稳定性管控产品,为什么会做专门运维产品?运维难点体现在哪些方面?
A:云原生中间件的优势在于重塑了技术供给方式,但如果稳定性问题不解决,就无法体现出这个优势。中间件运维需要消耗很大的精力。影响稳定性的因素非常多,我举几个例子后大家可能会非常能理解。
比如典型的资源水位问题,我们很难去做容量规划。资源水位的风险大概有两类,一类是实时流量带来的带宽风险,像 CPU、磁盘 IOPS、网卡带宽等;还有一种是逐步增长和堆积的容量型风险,主要体现在磁盘空间和内存水位,影响容量相关的风险很多,比如应用的业务流量、中间件内在的支撑机制等。
中间件都是多副本的集群,一个挂了后往往会有自身重建的过程,但重建过程会给剩余的一些存活节点带来负载压力,这个时候它们很不可控,有时甚至会放大。现在一个节点挂了后要先恢复,这个节点恢复过程中会从存活的节点拉数据,这就会对资源水位造成影响,进而引发其他问题。其他比如像均衡性、热点资源,硬件故障、配置参数异常等都会引起稳定性问题。
我们刚才说网易数帆专门的稳定性管控产品是我们运维团队十多年经验的沉淀,为用户提供监控告警、稳定性容量、日常排障等方面的服务。另外,我们也试着建立一种稳定性的改进循环。思路就是发现问题、分析整改,然后再把沉淀的经验加到规则引擎里来,避免下次发生同样的问题,如此循环下去,逐步将企业的运维经验沉淀到平台里。中间件的稳定性管理需要非常资深的人和经验,我们希望这个平台可以把这部分经验固化下来。
Q:看到朋友问,一人多岗的小公司如何做运维?
A:我觉得这样的企业反而更有必要去做云原生的转型。因为现在各种各样的中间件都有各自的应用场景和擅长解决问题的领域。所以运维人员每天都要学习业务侧提交的对中间件的需求。
Redis、Kafka 都是很常见的中间件,还有一些比如图数据库或者时序数据库,有时候也会被归到中间件的领域里来。对没有多少运维人员的小公司或者是“一人多搞”这样的公司来说,运维反而很容易失控,结果就是不再提供这些中间件,出现技术选型受限问题。
那么,有这么一套中间件平台有什么好处?我们前面讲到的云化必要性或者说云原生中间件的根本特征,其中一条就是足够的标准化。所有运维人员的必要技能是理解 K8s、理解声明式 API、理解 CRD 对资源定义,这样无论是 Kafka 还是 Redis,运维人员的学习路径、技术理解等方面都是一致的。比如,Kafka 和 Redis 的扩容操作都可以声明为一个同样的 CR,这样哪怕有十个中间件,他们都可以用几乎同样的运维方式去应对。
这就是云原生很大的一个优势,它可以解耦,将很多技术细节沉淀到 Operator 里。对运维人员来说,工作界面就是一个 K8s 的命令行,有助于解放他们的生产力。
中间件云化的技术选型
Q:轻舟具体什么时候开始做云原生中间件的?
A:我们做云化中间件比较早。整个网易互联网业务从 2012 年就开始做私有云,当时是基于 OpenStack 提供云主机、网络、硬盘,同时基于 OpenStack 的虚拟化环境提供基于虚拟机的 PaaS 中间件。所以,我认为真正做云化中间件是从 2012 年就开始了,我们大概用了一两年的时间把网易 95%的互联网业务迁移到了云平台上,并使用我们的云主机和一些云化的中间件。
14、15 年左右,网易进入了云原生阶段。我们开始尝试做无状态应用的容器化,让集团的一些无状态业务跑在 K8s 上面,还做服务网格。到了 19 年左右,企业该容器化的基本都完成了容器化,大量的核心业务都在服务网格平台上运行。
从 18 年下半年开始,我们开始真正意义上基于 Operator 做云原生的中间件。经过三年多时间,逐步建立了一些深度的产品能力,我们从早期专注中间件生命周期管理,即创建、删除、扩缩容等能力,慢慢发展到现在更多地去考虑做多机房、多集群的高可用,以及国产化异构软硬件平台的适配等。
去年年初,我们逐步做刚才提到的稳定性巡检产品化,另外也开始做“两地三中心”以及多活能力的建设。现在我们已经经过了生命周期管理阶段,慢慢做更加深度的能力。
Q:我们现在是全部的业务都上云吗?
A:我们互联网业务基本上都是云化,无状态应用全部容器化,有状态的目前在慢慢迁移。像消息队列、缓存这样的可能会快一些,数据库类的相对来说会慢一些。
Q:前边您提到了很多次 Operator 框架,为什么当时会选择这个框架?企业如何去做技术选型?
A:K8s 上的应用交付有两种方式,一种是基于 Helm,另一种就是基于 Operator。
Helm 更多适合一些无状态应用,它依赖 K8s 原生资源控制器去保证各项 K8s 资源的自愈、扩缩容能力,但管控能力比较弱,不能保证 K8s 原生资源之间的关联性。比如我们在做中间件的时候,涉及到某个 Pod 下面的一些状态变化互相之间是有依赖的,就是说某个 Pod 会依赖另外一个 Pod 的结果,我需要把这个信息注入到对应的 Kubernetes 里去,这其中有一些复杂的业务逻辑,这是 Helm 控制器搞不定的。
另外就是基于 Operator 用户可自定义资源的管理方式。如果我们现在把 Kubernetes 理解成硬件上面的一个分布式操作系统,Operator 就是在这个操作系统上面开发云原生应用的一套框架,它比较适合做中间件应用,或者说有状态应用。
中间件有两个核心特征,一是状态,这个状态表现为存储、网络 IP 等;还有就是中间件集群之间各个副本都是有关系的,比如 Redis 两个副本之间有主从关系,这样就不能把他们两个同等对待。Operator 是一种封装了一些特定领域的运维知识经验的抽象,可以自定义做很多事情,选择用 Operator+CRD 的方式管理中间件是非常匹配的。
Q:随着业务规模不断扩大,云原生的中间件如何保证自身的高性能和高稳定?
A:这个也是很多企业把有状态应用容器化时的一个顾虑,性能和稳定性是中间件最看重的。可以说下我们在这方面的具体思路和解决办法。
在性能方面,首先会涉及到负载均衡,可以把更多分布式处理能力利用起来,需要一些负载均衡组件、代理组件。还有就是考虑弹性的快速扩容,可以是一种水平扩展或提升整个集群性能容量的方式。另外,如果对 IO 或磁盘要求特别高的话,可以考虑用更加高性能的本地盘方式。当然最重要的,可以对中间件在云原生场景下面做一些参数级的调优。这些都是我们提升性能的一些方案。
稳定性方面也有很多方式。一种是利用稳定性巡检平台,可以更合理地使用整个平台的资源,确保资源水位保持健康的状态。另外,我们采用了一些像 Operator 这样的自动化开发框架,使中间件可以有治愈能力,并配和一些可观测性方式和混沌工程。如果我们把这些故障都能有效地解决,那大家对这个系统就会比较放心。
Q:整个云原生框架是越来越复杂的,大家现在都越来越关注可观测性。目前业内在可观测性方面发展得如何?
A:可观测性也是大家先有各自的标准,一些主流厂商主导,慢慢再在基层社区形成共识,进而产生新的业界标准。
现在,很多五花八门的应用在可观测性方向的指标、链路、日志都遵循社区标准。比如,链路方面有 OpenTelemetry 这样的社区标准,目前整个社区向好。大量开源的云原生软件都会号称至少遵循这样的社区关系标准。这样大家不用太考虑兼容性和互操作性方面的问题。目前来说,已经发展到这个阶段了。
Q:网易数帆在可观测行上做了哪些探索?
A:我们自己也做了一个一体化监控的可观测性产品。微服务的场景需要以应用为中心,我们需要把散落在各个组件里应用的各种指标和信息收集起来,在一个屏幕上有逻辑地显示出来。
所以,我们通过一些语言数据系统,把监控系统和各子产品,比如说服务框架、服务网格、涉及流量入口的一些 API 网关,以及中间件的日志、链路等数据全部会聚在这个立体化监控平台上,然后将数据打通。
数据统一采集是第一步,下面还有很多想象空间,比如可以做进一步的根因分析。以前的根因分析可能仅在某个纬度,比如东西流量调用、南北流量调用,或者某个中间件。现在,根因定位过程能够串联起整个过程。比如访问慢了可以直接定位到容器层或者更往下的网络内存等。
另外,我们在一些小的领域,比如日志领域,也做了很多事情。我们以前也用了 Fluentd 等开源的日志采集工具,但在一些大规模的互联网场景下,性能还是不够,像日志丢了很难查出来这个日志到底有没有采集上来、丢没丢。由于痛点一样,所以我们跟中国工商银行联合共建,发布了开源日志采集软件 Loggie。
落地实践
Q:网易目前落地了哪些中间件的云化?
A:在我们集团的互联网业务中,Redis、Kafka、RocketMQ、ES、ZK 这些已经落地,MySQL 这块也在推进落地。上面几个相对比较成熟,新业务也大都会使用云原生。
Q:之前看到介绍说,网易云音乐在引入了轻舟中间件的 Redis 后,成本节约了 30%以上。具体都做了哪些工作来达到这个效果?
A:首先我们在 2012 年后做了一个基于 KVM 虚拟化的 PaaS 中间件服务,到后面应用容器化后,相比虚拟化开销天然就有 10%以上的成本节省。
其次,我们研发了一个在 K8s 上的管控系统,主要负责离在线业务混部。比如在水位较低的时候,把音乐典型的转码等离线计算服务调度到 Redis 上。通过系统混部能够把资源利用率提高到 60%以上,而一般情况下可能是百分之一二十,甚至更少。当然还有其他的混部尝试,比如将 Redis 和其他中间件混部等。
第三方面就是资源超售,这也是云平台基本都会做的事情,就是对 K8s 进行资源超售,比如合理设计 requests 与 limit 的超售比等,尽量把测试环境里数据实例密度提上来。我们线上和线下的整个应用规模大概 1:1 左右,我们对线下做了更加极端些的操作。
Q:云原生的中间件更适合在哪些场景下应用?
A:其实,云原生中间件就是对传统中间件的替代。比如缓存类中间件就是数据缓存、需要快速访问的场景,消息队列类中间件就是用于解耦、削峰填谷场景,API 网关就是用在流量均衡的场景。在场景方面,没有说云原生特别适合、传统中间件不适合的,只不过本地化 PaaS 或者传统中间件,已经不适应现在微服务架构的一些要求了,这些就可能需要云原生中间件去提供。
比如金融行业都需要做多活架构,服务框架具备这样的功能了,但中间件数据库无法支持,这就没办法继续推进整个架构发展,逼着你一定要用云原生化的中间件去支撑它的云化架构。
Q:整个落地过程中会面对哪些困难或者挑战?
A:从业界来看,要么自研,要么外部采购,或者两个结合。网易主要还是自主开发为主。自研肯定基于开源的技术框架等,但没有开源社区会真正为稳定性兜底,也很少有专业的支持,可能都是靠大家价值观或技术热情驱动,一般企业的个性化需求不见得能响应。总的来说,还是场景化程度比较低,企业级管控能力比较弱。这些都是基于开源做自主开发可能会碰到的,企业要点对点地解决这些高可用、稳定性和大规模应用等问题。
外采是一个很快捷的路径,但这块的困难主要是采购方没有形成对中间件完整的掌控能力,毕竟是外面买来的,缺乏掌控的技术能力。这种时候,培训是很重要的,需要确保能够对这个产品日常使用
归根到底,还是需要人了。自研也好,或者外采也好,就都需要懂云原生、懂 K8s 的技术人才,去构建整个生态。
Q:需要开发人员去理解业务吗?
A:中间件的开发是需要的,理解业务后才能更好的设计,因为你的东西设计出来是给别人用的,甚至给业务人员使用的。
但是这里可以从两方面理解。一方面是要理解企业的 IT 流程,比如了解各种各样技术平台各自的定位、不同平台之间的职能到底是什么、边界在哪里、平台间是怎么协同的。
另一方面就是了解一些业务场景下的最佳实践。为支撑大规模应用需要沉淀一些最佳实践,这时就需要中间件开发人员理解业务的使用方式。比如 API 网关的业务流量模型是什么样的、流量趋势是随机的还是固定的,Kafka 或 Redis 对数据分片、性能、扩展性和高可用的要求,都会涉及到固有架构和它依赖资源的选型,我们只有了解了它的业务类型,才能做出合理的评估。比如在做异地多活或者单元化架构的时候,对于一些不重要的业务,就没必要做复杂的架构,同城架构就可以。我觉得这些都需要理解业的,很难说有一种很通用的协议可以在所有场景使用。
Q:汪源老师曾在分享中表示,同样一个中间件,基于 K8s 研发代码量减少了 50% 到 80%。这是如何做到的?
A:我觉得这可能是我们最早基于 Operator 或者容器化去做中间件带来的最直观的一个收益。
当时,我们基于 KVM 虚拟机的 PaaS 中间件也好几个团队,刚才列举了大概六七个这样的中间件是六七个团队去做的,所有人都要去理解中间件的整个管控过程,尤其是高可用、容灾方面的。整个管控过程是缺少这种抽象的、代码也很难复用,使得研发效率比较低,一个中间件 PaaS 服务从开始的立项、开发、测试到上线,大概需要两三个月,这还是比较快的,还不包括企业级的能力,如计费计量、权限控制、资源池等。
我们用了 Operator 框架以后,代码量减少可能是最终结果,那我们过程中做了哪些事情?前面讲过,Operator 可以分为通用部署和差异化部署,通用部分体现在设计规范上,包括设计原则、最佳实践、CRD 响应设计。
那时候,我们大量转型到用 Golang 作为开发语言,就是用的 Operator SDK 作为开发框架,遵循声明式 API 设计规范。所以我们从设计规范、开发规范、部署规范、运维规范、测试规范等研发过程中的各种规范,以及线上稳定性管理、对中间件的高可用要求等方面,去制订标准和约束,最终结果就是有 50%以上代码量的减少。
做云原生中间件不一定是为了减少代码量,但这确实是个副产品。我们当时做第一代 PaaS 中间件大概是五六万行代码,容器化以后大概只有两万行左右。其他也类似,Kafka 原先大概是五万行,后来是两万多行。
未来发展
Q:云原生中间件未来还有哪些想象力?
A:现在大家对中间件的定义都有自己的理解,但我认为一些有状态应用都是可以云原生化的,包括现在看比较过时的一些中间件。
举个例子,我们集团在使用一个早期的缓存中间件 Memcached,可能在很多业务看来它是一个已经快要被淘汰的中间件,但是在我们的某个业务里面它还被一些应用大量使用,因为它在一些特定场景中还有很多应用。我们基于 Operator 的 SDK 框架快速实现了对 Memcached 的 Operator,用云原生化的 Memcached 替代。
我们真正开始基于 K8s 去做这些标准化的能力,包括前面说到的各种各样规范,开发和实现替代是很快的。如果我们没有这样的框架沉淀和技术储备,这些可能就是历史负债,下又下不掉,甚至有些可能都没法替换,还需要有人持续维护。我们把这些看起来快要过时的中间件云原生化,同时花很小的成本就可以统一维护。
这只是举个例子,我想说的是,很多有状态的中间件都可以通过云原生化的方式来提升运维效率。
当然对应的还有一个成本的优势。现在公有云 IaaS 在资源层面的竞争已经非常激烈,有各种同质化的应用,毛利非常低。相反,PaaS 中间件是有比较大的利润空间的,它会想尽办法让业务用它的 PaaS 服务。如果关注成本,人们会在公有云的 IaaS 上自建中间件平台,这相对来说整个成本就会低很多。由于大家都是基于标准的 K8s 底座,所以这件事情就比较可行。
Q:未来,轻舟在中间件云化方面有哪些规划?
A:技术方面,我们跟进了云原生,我们的多集群、多活等都还在持续建设中。虽然我们有很多技术层面的积累,但还需要在产品层面进一步做场景化验证。整个业界都一样,都在持续进化。
另外,对于大家现在提的比较多的中间件的网格化,虽然目前还没有特别实际的生产场景需求,但它描绘的愿景确是非常美好:进一步提升开发效率和运维效率,我们也会持续关注。
此外,我们希望可以实现更多支撑微服务架构中间件的云原生化。对于开源开放的技术栈,我们希望能够实现对核心中间件的国产化替代,除了网易自己的互联网场景外,希望能在金融、制造、能源等各个行业做技术输出。
评论