JDQ 平台介绍
京东内部使用基于 Apache Kafka 构建的 JDQ 来支持其平台业务。JDQ 是京东集团大数据平台统一的实时数据总线,赋能集团内部京东零售、物流、科技、健康、安联等 40 多个一级部门,搜索推荐、广告、点击流、实时大屏等 1400+ 的业务线。JDQ 当前集群规模多达 6000 多个节点,每天产生的记录数达 15 万亿,峰值出带宽达到 1TB/s。
JDQ 平台采用 Kubernetes 进行有状态服务编排,通过 StatefulSet 控制器管理整个集群,支持多种存储方案和服务访问方式。该平台可部署在私有云、公有云以及京东内部的 Kubernetes 平台上。随着公司整体技术架构向基于 Kubernetes 的云原生架构演进,JDQ 在 Kubernetes 上的运行效率、成本和弹性都面临新的挑战。
JDQ Architecture
CubeFS 介绍
CubeFS(原名 ChubaoFS)是一款新一代云原生开源存储系统,是云原生计算基金会(CNCF)的毕业项目。该开源项目由社区和 OPPO 等多家公司共同维护和发展,持续在云存储、高性能计算等领域优化演进。京东作为该项目的早期发起者,在内部大规模应用,支撑了海量离在线业务的稳定运行。
CubeFS 支持 S3、HDFS 和 POSIX 等访问协议,广泛适用于大数据、AI/LLMs、容器平台、数据库和中间件等场景,提供存储与计算分离、数据共享和分发等能力。
CubeFS 由 元数据子系统(Metadata Subsystem) ,数据子系统(Data Subsystem) 和 资源管理节点(Master) 以及 对象网关(Object Subsystem) 组成,可以通过 POSIX/HDFS/S3 接口访问存储数据。
CubeFS Architecture
京东大规模应用
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 上时,冗余数据是如何产生的。其中虚线的数据块则是冗余的数据副本。
Waste of Storage and Network Bandiwith of Kafka
Apache Kafka 架构不是 Kubernetes 云原生
Kubernetes 为企业带来了诸多益处,尤其是通过容器化和 Pod 抽象显著提升了硬件资源利用率,并降低了成本。在全面 Kubernetes 化的背景下,像 Apache Kafka 这样的核心基础软件也需要部署在 Kubernetes 上,以充分利用其资源优化优势。京东内部已将 50% 的物理节点上的 Kafka 集群迁移至 Kubernetes,在这个过程中我们深切体会到了 Kafka 本身架构在 Kubernetes 上运行所带来的挑战。Apache Kafka 采用存算一体的 Shared-Nothing 架构,其计算节点 Broker 与本地存储紧密耦合,这使得其难以在 Kubernetes 上实现灵活的扩缩容。
以扩容为例,Apache Kafka 扩容时必须经历如下几个过程:
由于 Kafka 的架构不符合 Kubernetes 原生设计理念,其扩缩容操作在 Kubernetes 上成为了一个需要人工介入的高风险操作。在这种限制下,Apache Kafka 只能作为与 Pod 绑定的静态资源部署。Kubernetes 无法根据集群资源利用率来自动扩缩容节点和调度 Pod,因此也就无法发挥其优势。
Kafka Scaling on Kubernetes
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 产生的网络带宽开销。
Offload Kafka Data Durability to Object Storage
极速弹性、自动平衡:AutoMQ 架构无需像 Kafka 那样迁移分区数据就能完成扩缩容。迁移分区只需更新元数据,在 1 秒左右即可完成。AutoMQ 内置的 Self-Balancing 组件持续监控集群状态,实时进行业务无感知的分区迁移和调度,确保集群流量和 QPS 始终保持均衡。凭借这种弹性优势,AutoMQ 能与 Kubernetes 平台的 Autoscaler、Karpenter 等工具完美配合,根据负载自动进行集群扩缩容,充分发挥 Kubernetes 的潜力。
Partition Reassignment in Seconds
AutoMQ 基于 CubeFS
在京东的优化实践
The optimization of ObjectNode deployment
AutoMQ 在京东生产应用的效果
当前,京东采用的是 AutoMQ S3 WAL [2] 的模式。AutoMQ 的架构设计中对于 WAL 进行了高度的抽象,可以将不同的存储介质作为 WAL。在京东的场景中,我们将 CubeFS 本身作为了 WAL,不再依赖本地存储,整体的架构变得十分的简洁、高效。
AutoMQ Deployment on Kubernetes in JD.com
下图展示了京东内部一个 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