作者: 京东研发工程师 钟厚
关于京东
京东(JD.com),又称京东商城,是一家领先的电子商务公司。京东的业务已扩展至零售、技术、物流、健康、保险、房地产开发、工业、自有品牌和国际业务。京东在《财富》全球 500 强中排名第 52 位,是中国收入最高的零售商。京东服务近 6 亿客户,通过对质量、真实性和具有竞争力的价格的承诺,树立了电子商务的标准。京东运营着中国任何电子商务公司中最大的履约基础设施,使 90%的零售订单能够在当日或次日送达。京东还通过向合作伙伴、品牌和各个行业提供其尖端技术和基础设施,促进了生产力和创新。
JDQ 平台介绍
京东内部使用基于 Apache Kafka 构建的 JDQ 来支持其平台业务。JDQ 是京东集团大数据平台统一的实时数据总线,赋能集团内部京东零售、物流、科技、健康、安联等 40 多个一级部门,搜索推荐、广告、点击流、实时大屏等 1400+ 的业务线。JDQ 当前集群规模多达 6000 多个节点,每天产生的记录数达 15 万亿,峰值出带宽达到 1TB/s。
JDQ 平台采用 Kubernetes 进行有状态服务编排,通过 StatefulSet 控制器管理整个集群,支持多种存储方案和服务访问方式。该平台可部署在私有云、公有云以及京东内部的 Kubernetes 平台上。随着公司整体技术架构向基于 Kubernetes 的云原生架构演进,JDQ 在 Kubernetes 上的运行效率、成本和弹性都面临新的挑战。
CubeFS 介绍
CubeFS 是一款新一代云原生开源存储系统,由京东内部自研的 ChubaoFS 系统捐赠至云原生计算基金会(CNCF),支持 S3、HDFS 和 POSIX 等访问协议。CubeFS 广泛适用于各种场景,如大数据、AI/LLMs、容器平台、数据库和中间件的存储与计算分离、数据共享和保护等。
CubeFS 由 元数据子系统(Metadata Subsystem) ,数据子系统(Data Subsystem) 和 资源管理节点(Master) 以及 对象网关(Object Subsystem) 组成,可以通过 POSIX/HDFS/S3 接口访问存储数据。
京东大规模应用 Kafka 时带来的挑战
存储、网络带宽浪费导致成本上升
京东 JDQ 底层存储采用支持 S3 协议的 CubeFS 对象存储。CubeFS 通过多副本机制来保证数据持久性,而 Kafka 则使用 ISR 多副本机制实现相同目的。Apache Kafka 诞生于十几年前,其架构专为 IDC 物理机部署而设计。Kafka 将数据存储在本地磁盘上,并通过多副本的 ISR 机制来确保数据持久性。这种设计在当时是合理的。然而,随着云计算时代的到来,基于 S3 等对象存储的共享存储架构逐渐兴起,Kafka 的传统架构显得不够优化。以京东为例,当 Kafka 直接部署在 CubeFS 上时会产生大量数据冗余:针对 Kafka 的一份写入数据,由于 ISR 需要进行副本复制,真正存储到 CubeFS 上以后,考虑到 CubeFS 内部的多副本机制,实际存储了 9 份数据,其中约 66.67%(6/9)的存储空间被不必要的数据冗余占用,造成了严重的资源浪费。
此外,Kafka 层面的副本复制以及写远程 CubeFS 还会消耗额外的网络带宽。这导致在当前架构下,Kafka 的 ISR 机制反而造成了存储和网络带宽资源的过度使用,最终增加了总体成本。下图展示了 Kafka 部署在 CubeFS 上时,冗余数据是如何产生的。其中虚线的数据块则是冗余的数据副本。
Apache Kafka 架构不是 Kubernetes 云原生
Kubernetes 为企业带来了诸多益处,尤其是通过容器化和 Pod 抽象显著提升了硬件资源利用率,并降低了成本。在全面 Kubernetes 化的背景下,像 Apache Kafka 这样的核心基础软件也需要部署在 Kubernetes 上,以充分利用其资源优化优势。京东内部已将 50% 的物理节点上的 Kafka 集群迁移至 Kubernetes,在这个过程中我们深切体会到了 Kafka 本身架构在 Kubernetes 上运行所带来的挑战。Apache Kafka 采用存算一体的 Shared-Nothing 架构,其计算节点 Broker 与本地存储紧密耦合,这使得其难以在 Kubernetes 上实现灵活的扩缩容。
以扩容为例,Apache Kafka 扩容时必须经历如下几个过程:
-
仔细制定分区迁移策略,确保各个 Broker 之间的整体流量保持均衡
-
评估迁移影响,制定预案,提前通知 Kafka 上下游应用
-
在业务低峰期执行扩容操作,进行分区数据迁移(根据数据量大小,可能耗时数分钟到数小时)
-
分区迁移完毕后,检测集群状态,确保流量在 Broker 之间保持均衡
由于 Kafka 的架构不符合 Kubernetes 原生设计理念,其扩缩容操作在 Kubernetes 上成为了一个需要人工介入的高风险操作。在这种限制下,Apache Kafka 只能作为与 Pod 绑定的静态资源部署。Kubernetes 无法根据集群资源利用率来自动扩缩容节点和调度 Pod,因此也就无法发挥其优势。
AutoMQ 如何解决京东 Kafka 挑战
在寻求解决京东内部 Kafka 挑战的调研过程中,我们发现了 AutoMQ[1] 这一优秀产品。AutoMQ 采用计算与存储分离的共享存储架构,在确保与 Apache Kafka 完全兼容的同时,可将数据存储到兼容 S3 协议的对象存储之上,从而显著降低成本并提升效率。
具体而言,AutoMQ 通过技术创新解决了京东内部 JDQ 云原生化过程中的主要挑战:
-
S3 API 协议兼容适配 CubeFS:AutoMQ 兼容标准的 S3 API 协议,不仅可适配标准云对象存储服务,还支持 MinIO、Ceph 以及 CubeFS 等兼容 S3 API 的对象存储介质。这使得 AutoMQ 能够与京东内部的 CubeFS 服务自然整合。
-
100% 完全兼容 Kafka,利于迁移:鉴于京东内部拥有大规模的 Kafka 集群及其周边基础设施,AutoMQ 的完全兼容性确保了现有业务无需任何代码改造和配置修改即可无缝迁移,同时可充分利用现有 Kafka 生态系统。
-
数据卸载至云存储,显著降低存储、带宽资源:AutoMQ 基于 WAL 和对象存储构建的共享存储架构实现了计算与存储的完全分离。不同于 Apache Kafka 的 ISR 多副本机制,AutoMQ 将数据持久性直接委托给 S3/CubeFS 等对象存储服务。这种设计使得写入 Broker 的数据在 CubeFS 层面仅产生 3 份副本,大幅降低了存储资源消耗。由于采用单一 Leader Partition 设计,AutoMQ 还节省了传统 Kafka Replica 写入远程 CubeFS 产生的网络带宽开销。
- 极速弹性、自动平衡:AutoMQ 架构无需像 Kafka 那样迁移分区数据就能完成扩缩容。迁移分区只需更新元数据,在 1 秒左右即可完成。AutoMQ 内置的 Self-Balancing 组件持续监控集群状态,实时进行业务无感知的分区迁移和调度,确保集群流量和 QPS 始终保持均衡。凭借这种弹性优势,AutoMQ 能与 Kubernetes 平台的 Autoscaler、Karpenter 等工具完美配合,根据负载自动进行集群扩缩容,充分发挥 Kubernetes 的潜力。
AutoMQ 基于 CubeFS 在京东的优化实践
1、CubeFS Object Node 服务部署:CubeFS 支持 S3 协议的请求访问,在架构实现层面是通过提供了 Object Node 对外服务,S3 协议的客户端将请求发送给 Object Node 服务,并从 Object Node 服务获取到相关相应,整个请求响应的过程 S3 SDK 并不与 CubeFS 后端的 Meta Node 和 Data Node 通信。京东 CubeFS 的 Object Node 服务对外统一通过 Load Balance 提供域名访问,如果京东 Kafka 所有的流量请求都经过 Load Balance 进行负载均衡,则 Load Balance 服务经过估算需要上千台机器才能支撑访问,这种成本开销是无法接受的。后面京东经过方案验证与优化,将 Object Node 服务与 AutoMQ 服务部署在同一个 Pod 中,Object Node 和 AutoMQ 在 Pod 中处于同一个网络 namespace,可以直接给 AutoMQ 提供 Localhost 的访问能力,从而直接绕过了 Load Balance 服务并节省了相应的成本开销。
2、CubeFS 单目录下文件数过多优化:CubeFS 同时兼容 S3 和 Posix 协议访问,使用 AutoMQ 通过 S3 协议往 CubeFS 写入大量数据后,单个目录下可能会产生大量的子目录和文件,而这些大量的子目录为了兼容 Posix 协议访问,会对 CubeFS 后端集群的元数据管理造成较大压力;并且 AutoMQ 在执行 compaction 时使用 KEEP_DATA 策略,从 kraft 中删除 metadata,但是底层 object 文件依然存在,这些文件会使得 CubeFS 单目录下存在过多的子目录;京东优化调整了 AutoMQ 的 MINOR_V1 参数后,将 compaction 操作通过物理合并,能将存储在 CubeFS 的 object 文件数量降低 90%,从而降低 CubeFS 后端集群的元数据管理压力。
3、CubeFS 空目录优化:CubeFS 在创建对象文件时,会将文件前缀转换成目录,AutoMQ 在创建数据主存对象文件时,也会在 CubeFS 集群上创建对象文件的前缀目录,而对象文件删除后,相应的前缀目录存在没有删除的情况,这样造成了 CubeFS 上面存在大量未清理的空目录;在通过优化 Object Node 对前缀目录的元数据标记后,能级联删除对象文件相应的前缀目录,从而消除了 AutoMQ 基于 CubeFS 产生的空目录问题。
4、CubeFS S3 请求接口兼容扩展:CubeFS 目前兼容 S3 协议的读写请求访问,但是也有个别 S3 SDK 的接口目前还没有兼容支持,比如 AutoMQ multipart object 在超过 32MB 之后调用的 S3 UploadPartCopy 接口,目前还没有兼容支持,后续京东规划会根据业务场景的需求进行兼容支持;
AutoMQ 在京东生产应用的效果
当前,京东采用的是 AutoMQ S3 WAL [2] 的模式。AutoMQ 的架构设计中对于 WAL 进行了高度的抽象,可以将不同的存储介质作为 WAL。在京东的场景中,我们将 CubeFS 本身作为了 WAL,不再依赖本地存储,整体的架构变得十分的简洁、高效。
下图展示了京东内部一个 AutoMQ 生产集群的核心指标。这个集群在采用 AutoMQ 新架构后,取得了以下成效:
-
集群存储成本降低 50%,带宽成本降低 33%:得益于 AutoMQ 的云原生架构,显著降低了 Kafka 集群在存储和网络带宽方面的资源需求,大幅节省了成本。
-
集群在 Kubernetes 上扩容效率由小时级别提升到分钟级别:使用 AutoMQ 后,部署在 Kubernetes 上的 Kafka 扩缩容不需要大量的拷贝迁移数据,将扩缩容的时效提升到了分钟级别。AutoMQ 集群能够快速动态调整容量,从容应对大促、秒杀等电商场景,不仅减轻了运维负担,还避免了为应对峰值而过度配置资源的浪费。
未来展望
AutoMQ 作为一款以“云优先”理念设计的新一代 Kafka 与京东业务全面上云、云原生化的步调一致。在未来,我们将在保证集群稳定、高可用的前提下,进一步推广和深化 AutoMQ 在京东的应用,促进数据基础设施全面云化、云原生化并且进一步降低数据基础设施的成本、提升效率。
参考资料
[1] AutoMQ: https://www.automq.com/
[2] AutoMQ WAL Storage: https://docs.automq.com/automq/architecture/s3stream-shared-streaming-storage/wal-storage
共同学习,写下你的评论
评论加载中...
作者其他优质文章