Skip to main content

Kafka替代方案对比: AutoMQ vs. AWS MSK (serverless)

如果你需要一个低成本、高度弹性并且不会造成供应商锁定的Kafka服务,那么可以毫无顾虑地选择 AutoMQ

Background

What is AutoMQ

AutoMQ[1] 的诞生受到 Snowflake 的启发,是一款贯彻云优先理念来设计的 Kafka 替代产品。AutoMQ 创新地对 Apache Kafka 的存储层进行了基于云的重新设计,在 100% 兼容 Kafka 的基础上通过将持久性分离至 EBS 和 S3 带来了 10x 的成本降低以及 100x 的弹性能力提升,并且相比 Apache Kafka 拥有更佳的性能。

What is AWS MSK

AWS MSK [2]全称是Amazon Managed Streaming for Apache Kafka,是由 AWS 提供的Apache Kafka 托管云服务。AWS MSK 本质是开源Apache Kafka在云上的 rehost,但是 AWS 在开源版本的基础上额外提供了 tiered-storage的实现以及 Serverless 的版本。

流系统是重要的数据基础设施,选择适合自己的流系统对于构建一个现代化的数据栈具有重要意义。本篇文章将从多个维度对AutoMQ 和 MSK 进行全面对比,以便于读者在选择流系统时可以快速掌握他们的区别,选择适合自己的流系统。

TD;LR

AutoMQ 和 AWS MSK 以及 AWS MSK Serverless 的所有区别可用下图表示。如果关心其中对比的细节,则可以继续阅读后续的内容。

弹性 vs 非弹性 vs 伪弹性

云原生与 Serverless 的基石:弹性

经过多年的发展,云原生技术以及公有云已经浸润到各行各业成为现代化数据栈的基础。大家对云原生的概念主要来源于CNCF的定义 [4] 以及云厂商的定义 [5] 。无论是哪种定义,都强调了真正的云原生应用需要具备弹性的能力。具备弹性能力的应用可以根据工作负载快速、高效地调整自身实际所消耗的资源;而非原生的应用则需要根据应用的峰值负载进行繁琐的容量评估工作,并且面向峰值工作负载去过量预留资源。下面三幅图 [5] 很好地阐释了云原生应用与非云原生应用在使用资源上的差异。非云原生应用往往采用图 a 中 overprovisioning 的方式来做容量规划。以 Apache Kafka 为例,为了保证服务能够支持峰值吞吐的写入流量以及保证延迟,用户首先需要评估集群机器规格与可以支撑的写入流量的关系,然后得出支撑峰值吞吐所需要的集群规模。在该集群规模基础上再额外预留 30%~50% 的集群容量以避免产生一些预期外的“黑马”流量。这种 overprovisioning 的方式将会产生大量的计算、存储资源浪费。如果采用图 b 的 underprovisioning 方式来做容量规划,则无法支持负载较高的场景导致业务受到影响。真正的云原生需要做到像图 c 中的scale with elasticiy,即应用程序对资源的消耗是 pay-as-you-go 的。云最大的价值之一就是其近乎无限的资源以及快速的资源供应与销毁。当你不再使用这些云资源时,就一定要及时释放它们;当需要使用时则通过云API来快速供应这些资源。只有做到这种弹性,才可以将公有云的优势真正发挥出来。

弹性能力上的比较

结论:AutoMQ > MSK Serverless >>> AWS MSK

  • AutoMQ :AutoMQ 对 Apache Kafka 的存储层进行了彻底的云原生改造。基于云优先的理念,将持久性卸载至EBS、S3这样成熟的云存储服务。与 Apache Kafka 最大的不同在于整个计算层变成了无状态。由于计算层是无状态的,整个架构也变得极具弹性。在这种弹性架构下,AutoMQ 可以使用云的 Spot 实例、和自动弹性等技术来显著地降低成本,同时也可以在 Kubernetes 上工作得更好。是三者中唯一真正做到云弹性的产品,消除了所有Kafka 由于缺乏弹性所带来的成本、运维复杂性等问题。

  • AWS MSK Serverless :MSK Serverless 本质是一种伪弹性,因为其弹性能力本质还是通过由 AWS 自身提前帮助用户做好容量规划,给用户一种 Serverless 的假象。由于底层仍然是Apache Kafka存算一体的架构,技术上并没有什么突破。这种伪弹性提前预留的容量产生的费用最终都会反应到用户真实的账单上。多个客观事实可以证明 MSK Serverless 的伪弹性。

    • MSK Serverless 只能支持 200MB/s写入和400MB/s读取 [8] :显然是做了租户间集群的隔离,每个集群预留好峰值 400MB/s 的容量,从而营造 Serverless的假象。这种有限制的弹性是的 MSK Serverless应用在非常有限的场景。

    • 默认情况下分区数最多120个,每个分区最多250GB,数据保留时间1天 [9] : 这显然也是 AWS 为了控制成本而做的限制。由于 MSK Serverless 底层仍然是采用 Apache Kafka 的技术架构,根本没法实现自动弹性,因此只能通过配额限制和提前容量预留来达到所谓的 Serverless 效果。在这种默认限制下,用户只能将 MSK Serverless 用于一些流量非常小的业务场景,并且很难适应未来业务的发展。

  • AWS MSK :AWS MSK作为云托管的 Kafka 集群,在创建集群、监控整合方面确实相比用户自建带来了很多的便利,但是其云弹性能力与 Apache Kafka 一样仍然是非常弱的。用户需要提前面向峰值负载做好容量规划并且保留足够的预留容量,以保证工作负载增长后仍然可以正常工作。由于缺乏弹性,这种提前预留资源的方式将产生诸多副作用:

    • 容量评估显著增加TCO :AWS MSK是按照 Broker 规格来计费的。很多用户都忽视了容量评估带来的复杂性和挑战。为了保证生产系统的稳定,开发人员需要花费大量的时间针对不同的 Broker 规格测试性能,才可以准确评估出面向峰值吞吐所需要的集群容量。这里需要考虑副本数、读写比例、网络带宽、SSD IO带宽、保留时间等各种因素对能承载的写入吞吐的影响,大大增加了投产的成本。并且一旦未来需要扩缩容,则又需要进行重新的容量评估。容量评估是一个重人力介入、高成本的工作,会大大增加用户使用 AWS MSK的 TCO。

    • 预留容量导致资源浪费 :准确的评估和预测读写的吞吐是一件非常困难的事情。为了避免处理AWS MSK扩缩容时的效率问题,使用者只能按照峰值吞吐提前预留容量。并且为了避免一些没有被准确评估到的黑马流量(这在电商场景中很常见),需要额外预留30%~50%的容量。试想,如果一个用户平均的写入吞吐为 100MB/s,为了应对峰值吞吐 1GB/s,则需要准备一个可以承载 1.3GB/s~1.5GB/s 的集群,则有92%的集群容量都是浪费的。

    • 扩缩容影响业务读写,无法应对未来业务变化 :企业的业务是在不断的变化。即使采用提前容量预留的方式,仍然不可避免的在未来需要对集群容量进行调整。在 AutoMQ 服务的客户中,就有来自新能源车企和电商的真实案例。这类企业的特点就是其业务场景往往存在一些营销时刻,例如新车型发布或者电商的折扣促销活动,在该期间 Kafka 集群就需要承载比以往大数倍的流量,此时就需要对 Kafka 集群进行扩容,等到活动结束再将集群缩小至原来的规模。这对企业来说是一个非常高风险并且业务有损的操作。对于 AWS MSK 而言,扩缩容时期,会涉及 Broker 之间的大量数据复制。这个过程会耗时数小时至数天,更可怕的是,在分区数据迁移期间,这些挪动的分区的读写也会受到影响。每次扩缩容,负责运维 AWS MSK 的研发人员不仅自己要为容量调整的事情而担惊受怕,同时还需要做好业务方通知与协调,承担迁移期间影响生产消费所带来的潜在业务故障。此外,一旦由于扩缩容产生故障,AWS MSK 的使用者基本是没有任何止血手段的。笔者曾经在 AWS MSK 集群上执行了一个缩容操作,等待了3个多小时,在此期间你没法中断这个行为,只能等待它完成。

AWS MSK(Serverless) 不支持 Kubernetes

Kubernetes 是云原生技术领域中的重要创新也是云原生技术的集大成者。Kubernetes 充分利用了云原生的容器技术、弹性、IaC、声明式API 等云原生手段为企业提供了一个标准化的、通用的、高效的云原生技术底座。企业通过遵循云原生的最佳实践,将符合云原生技术理念的应用迁移部署在 Kubernetes 上,可以从其高效的自动化运维部署、资源管理、丰富的生态中获益。例如 Aliyun Cloud 上的核心服务基本都已经跑在K8s之上。使用 Kubernetes 在具有一定规模的企业中将会获得更大的益处。AutoMQ 的很多大型客户很多都在大量使用K8s或者正在将企业内的核心数据基础设施往K8s上迁移。

AutoMQ 对 K8s 有着绝佳的支持。Apache Kafka 社区在K8s生态中,也有像 Bitnami 和 Strimzi 这样优秀的产品。在他们的社区中也有开发者呼吁支持 AutoScaling 的声音 [10] [11],但是由于 Apache Kafka 本身存算一体的架构导致其在 K8s 上难以进行横向的伸缩。将Apache Kafka 部署到 K8s 上本质上只是将原本在 IDC 机房部署的 Kafka rehost 到K8s 上而已,难以将 K8s 的优势真正发挥出来。至于相反的是,AutoMQ 通过对 Kafka 存储层的云原生改造,支持了无状态的 Kafka Broker。你可以将 AutoMQ 部署到 AWS EKS 之上[12]并结合使用 Karpenter [13]、Cluster AutoScaler [14]等 K8s 生态产品支持 AutoMQ 的自动弹性。

AutoMQ 当前支持部署在用户自己的 K8s 之上,而 AWS MSK 以及 MSK Serverlesss 当前不支持部署在用户的 K8s 上。如果你未来希望将 Kafka 这类服务部署在 K8s 之上与自己的其他应用可以更好的协同工作,那么则更加推荐使用 AutoMQ。

价格优势

在价格这一块我们将不再 AWS MSK Serverless 的价格优势比较。AWS并没有在其价格计算器中提供 MSK Serverless 的价格,因为其本身不仅有着众多限制,比自家的 AWS MSK 都会昂贵许多。AWS MSK Serverless 与AutoMQ 和 AWS MSK 的定价模型不同是导致其价格昂贵的原因。除了固定的实例持有费用以外,其按照用户的流量来进行计费 [17], 入流量的费用是$0.1/GB,出流量的费用是 $0.05/GB,假设按照 1:1 生产消费,如果当天持续写入了100TB的数据,那么实际将消耗 $15360 每天,这都赶上 AutoMQ 一个月的订阅费了。 因此,这里我们还是将 AutoMQ 和 MSK 进行价格上的比较。

  • 计算层 :AWS MSK 本身底层采用的仍然是 Apache Kafka 的技术架构,因此其在做个方面都无法像 AutoMQ 一样去帮助用户降低成本。

    • Spot实例 :例如 aws cn-northwest-1 的 r6i.large 的on-demand价格为 ¥0.88313/hour,Spot实例的价格为 ¥0.2067/hour。在我们举例的这个case中,使用spot实例可以相比on-demand实例节约76%的成本。

    • AutoScaling :AutoMQ 由于其计算层是无状态的,因此有实现 AutoScaling 的基础。对于 AWS MSK来说,由于其本身缺乏弹性,扩缩容操作对于其来说是一个极其高风险和耗时的操作,普通的扩缩容操作都基本难以实施,更不要提实现 AutoScaling 这样的能力了。AutoMQ 可以通过快速地 AutoScaling 为用户提供与实际变化的负载相匹配的资源从而来减少资源浪费,降低成本。用户流量的波动越大,则通过 AutoScaling节约的费用则越多。

    • 相比 MSK,AutoMQ 可以用更少的机器承载更大的读写吞吐 :AWS 云上的机器,其网络带宽与其规格相关。只有规格更大的机型,才可以享用更大的网络带宽。假设是1:1的写入模型,针对1份写入流量,AutoMQ 的出流量会包含消费者消费的1份流量以及写入S3的1份流量。同样情况下采用分层存储的 AWS MSK,除了与 AutoMQ 相同的消费和写S3的出流量,Broker之间的 replication 复制还需要额外2份流量。综上分析,针对一个Broker,AutoMQ 只需选择可以承载 2份出流量网络带宽的 EC2既可满足诉求,而 MSK 需要承载 4份出流量的网络带宽的 EC2 才可以满足诉求,这使得 AutoMQ 可以使用比 MSK 规格小得多的机型既可承载相同的读写吞吐。

    • 无需容量评估,减少人力成本 :AutoMQ 企业版提供基于吞吐的计费。用户无需关心集群可以承载的流量与实际底层计算、存储、网络上的关系。AutoMQ的技术专家们耗费了大量时间帮助用户选择最优机型和最佳配置。无论是新建集群还是扩缩容,用户无需自己耗费大量时间和人力再次评估底层资源消耗与实际可承载的吞吐之间的关系。

  • 存储层 :MSK 通过分层存储在一定程度上降低了本地磁盘的存储开销,但是仍然不可避免的由于其存算一体化的架构带来如下几点成本上的劣势:

    • MSK本地磁盘占用空间不可控 :分层存储仍然要求分区的最后一个 LogSegment 在本地磁盘上,他的默认大小为 1GB。在实际生产环境中,MSK 很难控制一个 Broker 上具体应该有多少个分区,以及预测这些分区如何增长。集群维护者很难 做出准确的容量评估,例如每个 Broker 应该配置多少 GB 的本地磁盘。为了保证不影响读写,实际容量评估时对于应该配置的本地磁盘仍然需要预留30%~50%的本地存储空间。即使如此,未来因为数据倾斜,如果一个 Broker 上有大量的分区,仍然会因为磁盘I/O的争抢影响正常的读写流量。如果使用AutoMQ,由于其内置流量重平衡组件,可以秒级进行分区迁移,不会产生数据倾斜,而且只需要固定大小的10GB EBS大小作为 WAL即可。在AWS 使用 10GB GP3 卷,由于Free-Tier不会产生任何费用。

    • MSK在对象存储分层存储上溢价严重 :MSK 分层存储单价为 $0.06/GB/月,而AutoMQ 使用对象存储即使算上API的调用费,实际所需价格约为 $0.024/GB/月, MSK存储溢价高达 125% 之多。

    • MSK缺乏对S3的定制能力,在对象存储上降本潜力受限 :MSK的分层存储底层并没有向用户暴露S3,因此用户无法自行配置和使用其他成本更优的 S3 类型。以新加坡ap-southeast-1为例,500TB以后,Standard 的存储成本为 $0.023/GB,如果使用 AutoMQ 你可以选择 S3 Intelligent 类型,其 Archive Instant Access Tier 的访问成本为 $0.005/GB,仅需要 Standard Tier 22%的存储成本即可存储相同大小的数据。

    • 无需容量评估,减少人力成本 :如果使用 MSK 需要为每个 Broker 配置多少本地磁盘需要自行测试、验证和评估。与计算层相同,AutoMQ 无需用户自行进行集群容量评估。

  • 网络

    • MSK 强置多 AZ,测试费用高昂 :这是一块经常被忽略的隐形成本。除了生产环境以外,用户往往需要部署不同的测试环境、预发环境。MSK 强制用户使用多AZ部署。当用户在测试环境进行诸如一些压力测试时,AWS 将会向你写入的跨 AZ 流量收取大量的费用。例如测试环境一次压测写入了100 TB 的测试流量,跨 AZ 的流量费为 0.02 GB/s,你将额外会费 $2048。如果使用 AutoMQ,你可以选择在测试环境使用单可用区部署,这将为你节省大量的费用。

服务支持对比

AutoMQ > AWS MSK = AWS MSK Serverless

从服务支持和保证程度来说,AutoMQ 除了比 AWS MSK拥有高一点的 SLA [15] 以外,主要存在如下两个显著区别:

  • AutoMQ 商业版提供免费的技术专家直接支持 :几乎所有主流云厂商都不像客户提供和产品核心产研团队的直接交互。因为这将显著增加他们的成本。如果使用AWS MSK,你的工单请求将会经过多个人处理和转交才会最终交付到核心产研团队。AutoMQ 企业版提供更加友好的技术团队商业支持,你可以直接与AutoMQ核心产研团队进行问题咨询、排查和诊断以及在紧急情况下快速介入帮助用户及时止血。更短、更专业的支持人员意味着你的咨询问题将获得更佳优质的解答,你的工作人员将会花费更少的时间解决和处理问题,大大降低总体的TCO成本。值得注意的是,AutoMQ的这种商业版技术支持无需额外付费,包含在你的商业订阅中。
  • AWS MSK不对Apache Kafka自身的问题负责 :在AWS MSK SLA [16] 中明确指出其不会处理 Apache Kafka 引擎层面的内部问题。这对很多企业来说是难以接受的。企业采购商业产品目的本就是为了可以将这块服务能力完全交付给供应商托管。我们可以试想一种极有可能发生的场景,Apache Kafka 3.x 版本引入了一个非常 Critical 的 BUG,影响了消息的正常收发。MSK 经过诊断,识别该 BUG 由于 Apache Kafka 内部引擎导致,因此无法修复并且也不会对用户进行赔偿。用户唯一的选择就是自行确认哪一个 Apache Kafka 的版本没有引入该故障对此进行版本降低或者升级到修复该问题的版本。选择哪个版本升级或者降级,MSK是否提供该版本,调整后的版本是否会引入新的问题,这些所有的事情都需要用户自行判断和执行。而如果使用 AutoMQ,针对这种Critical的BUG,AutoMQ团队将在第一时间(发现社区该Critical问题后一周内)提供修复,并且协助和指导用户进行版本升级,并且为Apache Kafka引擎内部所产生的所有问题负责。如果你在重要的生产环境考虑使用AutoMQ,不妨问问自己如下几个问题 [7]

    • 如果您在使用 Amazon MSK 或 Amazon MSK Serverless 的项目中遇到 Kafka 问题,谁负责并承担风险?

    • 您对 Apache Kafka 开源项目相关的安全事件有何反应?

    • 如何解决性能或可扩展性问题(在客户端和服务器端)?

  • 更快的 Apache Kafka 社区跟进效率 :AutoMQ 作为专业的 Kafka 服务供应商,针对 Critical 的问题和修复会以周为单位提供修复版本。对于 Apache Kafka 社区的主要 Release 版本,AutoMQ 可以保证差距控制在一个月左右。根据我们对 AWS MSK 的一些了解,其跟进 Apache Kafka 主要 Release 版本的速度会慢很多,一般耗时在数个月甚至半年之久。

非云供应商锁定、多云支持

AutoMQ >> MSK=MSK Serverless

AutoMQ 没有供应商锁定问题。选择 AutoMQ,用户可以自由选择将 AutoMQ 部署在哪一个云供应商之上。不同的云供应商有各自不同的产品矩阵和核心优势。使用 AutoMQ 则可以让用户更加地充分利用多云的优势。当用户在各个云上具备多云部署能力时,在使用云厂商的云服务时除了可以充分利用多云优势,也将会拥有更强的议价权。例如,我们都知道 AWS 针对跨可用区的网络流量收取昂贵的费用。但是在 Azure 和 Alibaba Cloud 之上,云供应商不会向用户的跨可用区流量进行收费。用户如果将 AutoMQ 部署在 Azure 上,就可以充分利用 Azure 不收取跨可用区流量费的特性节约大量的成本。

从长远角度来看,选择非云供应商锁定的 AutoMQ,可以使得企业的技术架构保留足够的灵活性,更好适应未来不断变化的云环境。

参考资料

[1] AutoMQ: https://github.com/AutoMQ/automq

[2] AWS MSK(Serverless): https://docs.aws.amazon.com/msk/latest/developerguide/getting-started.html

[3] CNCF Cloud-Native: https://github.com/cncf/toc/blob/main/DEFINITION.md

[4] AWS What is Cloud-Native: https://aws.amazon.com/what-is/cloud-native/

[5] What Is Cloud Elasticity?: https://www.cloudzero.com/blog/cloud-elasticity/

[6] The Pro’s and Con’s of using AWS MSK Serverless: https://mantelgroup.com.au/the-pros-and-cons-of-using-aws-msk-serverless/

[7] When NOT to choose Amazon MSK Serverless for Apache Kafka?:https://www.kai-waehner.de/blog/2022/08/30/when-not-to-choose-amazon-msk-serverless-for-apache-kafka/

[8] Amazon MSK FAQs: https://aws.amazon.com/msk/faqs/

[9] Create more partitions and retain data for longer in your MSK Serverless clusters:https://aws.amazon.com/cn/blogs/big-data/create-more-partitions-and-retain-data-for-longer-in-your-msk-serverless-clusters/

[10] [bitnami/kafka ] Auto Scaling: https://github.com/bitnami/charts/issues/22733

[11] How to scaling up Kafka Broker: https://github.com/strimzi/strimzi-kafka-operator/issues/1781

[12]使用 AutoMQ 实现 Kafka 大规模成本及效率优化: https://aws.amazon.com/cn/blogs/china/using-automq-to-optimize-kafka-costs-and-efficiency-at-scale/

[13] Karpenter:https://karpenter.sh/

[14] autoscaler: https://github.com/kubernetes/autoscaler

[15] AutoMQ SLA: https://docs.automq.com/automq-cloud/support/service-level-agreement

[16] AWS MSK SLA:https://aws.amazon.com/msk/sla/

[17] AWS MSK and Confluent. Are they really Serverless?: https://upstash.com/blog/aws-msk-confluent-serverless

[18] AWS EC2 types: https://aws.amazon.com/ec2/instance-types/?nc1=h_ls