Skip to main content

AutoMQ vs. Apache Kafka 成本对比

Apache Kafka 集群的成本主要包括计算和存储两部分。计算成本涵盖 Kafka Broker 运行所需的服务器,如 AWS EC2;存储成本则涉及数据保存所需的存储设备,如 AWS EBS

AutoMQ 全新的云原生架构针对计算和存储进行大幅优化,使集群总成本在相同流量下降低至原来的十分之一。

本报告将从存储和计算两方面详细介绍 AutoMQ 在成本上的优化,并计算潜在的成本节约。最后,我们在一个典型场景中部署了一个 AutoMQ 集群,并将其成本与不支持分层存储的 Apache Kafka(低于 3.6.0 版本)进行了比较。

若无特别说明,以下定价均基于 2023 年 10 月 31 日的亚马逊云科技宁夏区域 (cn-northwest-1)。

存储方案:充分利用高可靠、低成本的云存储

在云计算时代,各大云服务提供商均提供了高可靠性的云存储解决方案。针对不同的使用场景,用户可以选择适合自己需求的产品,例如 AWS EBSAWS S3AWS EFS

为了最大程度地利用云存储,AutoMQ 将主要数据存储在对象存储中,并仅使用少量的块存储作为缓冲。这种方式既确保了性能和可靠性,又显著降低了数据存储成本。

基于 EBS 无副本冗余

云厂商提供的 EBS 服务具备高可靠特性,基于云盘上层再次构建多副本在提高可靠性方面效果微弱,但存储成本会显著增加。

AutoMQ 仅使用小容量云盘用作数据在上传到对象存储之前的持久化缓冲区,无需进行额外的数据复制;同时 AutoMQ 可以保障在各种场景下依然具备高高可靠特性。

充分利用对象存储

对象存储是云服务中成本最低且容量几乎无限的存储选项之一。AutoMQ 通过将大部分数据转移到对象存储,显著降低了存储成本。对于存储大量数据的场景,这种方法尤为有效。

以 AWS 为例, AWS S3 Standard Storage 的单价为 0.1755 CNY/(GiB*month)AWS EBS gp3 的单价为 0.5312 CNY/(GiB*month),使用 S3 将节约 67.0% 的存储成本。

对比 AutoMQ 与 Apache Kafka 的存储成本,AutoMQ 使用 S3 Standard Storage 存储 10 TiB 数据每月的花费为:


10 TiB * 1024 GiB/TiB * 0.1755 CNY/(GiB*month) = 1797.12 CNY/month

而 3 副本 Apache Kafka 使用 EBS gp3 存储 10 TiB 数据每月的花费为(令磁盘水位为 80%):


10 TiB * 1024 GiB/TiB ÷ 80% * 3 * 0.5312 CNY/(GiB*month) = 20398.08 CNY/month

Apache Kafka 存储成本理论上是 AutoMQ 的 20398.08 / 1797.12 ~= 11.4 倍。

计算方案:充分利用按量计费、任意扩缩的云计算

在云计算时代,云服务提供商提供高度弹性的云计算服务。用户可以根据需求随时购买或释放云服务器,并且按使用量计费。这样用户可以在服务器闲置时释放,以节约成本。

AutoMQ 采用存算分离的架构,充分利用云计算的弹性能力。无论是分区迁移还是扩缩容,AutoMQ 均可在分钟级时间内完成。

按需扩缩,没有闲置

AutoMQ 可以实现秒级分区迁移和持续流量重平衡,因此在缩容或扩容时,都能在分钟内完成。

AutoMQ 的快速扩缩容能力使得 AutoMQ 可根据实时流量变化调整集群容量,避免资源浪费。相比之下,Apache Kafka 需要根据最大预估流量进行部署,以避免业务受损。在流量波动明显的场景下,这种灵活性能够显著降低成本。

对于流量峰值比为 10:1、持续 4 小时的集群,AutoMQ 与 3 副本 Apache Kafka 所需实例数的理论比例如下。


(1 * (24 - 4) + 10 * 4) : (10 * 24 * 3) = 1 : 12

竞价实例,灵活便宜

当前各个主流云厂商均提供了竞价实例(又称“抢占式实例”)的服务,其相较于按需付费的实例,其有如下特点:

竞价实例具有随时被强制释放的特点,其管理可能会比按需实例更具挑战性。AutoMQ 可有效解决这一问题。

  • 当接收到实例即将释放的信号时,AutoMQ 可以迅速将该 Broker 上的分区迁移到其他 Broker,实现优雅下线。

  • 即使在极端情况下,分区未完全迁移即实例被释放,AutoMQ 仍能从该实例的数据盘中恢复并上传数据,确保数据不会丢失。

在 AutoMQ 集群中,所有 Broker 都可以作为竞价实例,这样可以显著降低成本。

AWS r6i.large 机型为例,按需售价为 0.88313 CNY/hour,竞价售价为 0.2067 CNY/hour,使用竞价实例可以节约 76.6% 的成本。

带宽用在刀刃上

针对不同的实例类型,云服务提供商设定了网络带宽上限,这会影响单个 Kafka Broker 可处理的流量。优化 Broker 的网络带宽利用有助于提升单机流量上限,降低成本。

在集群生产消费比为 1:1 的情况下,AutoMQ 的 Broker 承载流量上限是 Apache Kafka 的 1.5 倍。

  • AutoMQ 的 Broker 在收到 1 份流量消息时,其出流量包括 1 份发送给消费者的流量和 1 份上传至对象存储的流量,合计 2 份。

  • 而 3 副本的 Apache Kafka 的 Broker 在收到 1 份流量消息时,其出流量包括 1 份发送给消费者的流量和 2 份进行副本间复制的流量,合计 3 份。

测试数据:线上实际场景

为验证 AutoMQ 在成本上的优势,在 AWS 上部署一个 AutoMQ 集群,并模拟消息的发送和接收。使用 AWS CloudWatch 和 AWS Cost Explorer 监控集群容量和成本变化,最后与 Apache Kafka 的成本进行比较。这样可以更清楚地了解 AutoMQ 在成本效益方面的优势。

测试方案

为模拟真实场景下的集群流量,对 OpenMessaging Benchmark Framework 做了少量修改,使其支持在指定时间段变化收发消息的流量。测试时使用的流量曲线为:

  • 常时流量为 80 MiB/s。

  • 从 00:00 到 01:00 流量上升至 800 MiB/s, 到 02:00 流量下降至 400 MiB/s, 到 03:00 流量回归至 80 MiB/s。

  • 从 13:00 到 13:45 流量上升至 800 MiB/s, 到 14:30 流量回归至 80 MiB/s。

  • 从 18:00 到 19:00 流量上升至 1200 MiB/s, 到 20:00 流量回归至 80 MiB/s。

其他配置详见附录一。

运行结果

在 AWS 宁夏区域 (cn-northwest-1) 运行上述负载 24 小时,获得以下结果。

动态扩缩容

通过 AWS CloudWatch 可以获得在对应时间内,broker 数量与集群总流量随时间的变化关系。如下图:

说明:

  • 图中蓝色曲线为集群中生产消息的总流量(即每秒生产的消息总大小),由于生产消费比为 1:1, 这同时也是消费消息的总流量。其单位为 byte/s, 左 Y 轴中标识的单位是以 10 为底数的指数,例如,1M = 1,000,000, 1G = 1,000,000,000。

  • 由于开启了 AWS Auto Scaling group重平衡,以及竞价实例释放,在集群流量维持稳定时,依然可能发生短时间内 Broker 数量的增减。

从图中可以看出:

  • AutoMQ 可以实时随流量的增减进行扩缩容,仅存在分钟级延迟,这将节约大量的计算成本。

  • AutoMQ 在扩缩容的过程中,仅会带来短时间、小幅度的流量波动,不会影响集群可用性。

成本组成

通过 AWS Cost Explorer 可以获得在对应时间内,集群总成本及其组成。见下表:

类型
成本 (CNY)
占比
EC2 - 按需实例
64.450
34.3%
EC2 - 竞价实例
19.446
10.4%
S3 - 标准存储费
93.715
49.9%
S3 - API 调用费
7.692
4.1%
EBS - gp3
2.431
1.3%
合计
187.734
100.0%

说明:

  • 表中列出的成本统计周期为 2023-11-01 00:00 至 2023-11-01 23:59, 总计 24 小时。

  • 为保证集群稳定性,AutoMQ 会使用 3 台按需实例作为 Controller(同时,其也会作为 Broker 承担一小部分流量),其成本为 0.88313 CNY/hour * 3 * 24 hour = 63.59 CNY, 与表中“EC2 - 按需实例”项基本一致。

  • 由于 AWS Cost Explorer 对于“S3 - 标准存储费”的统计存在延迟,故表中所列成本为估算值 0.1755 CNY/(GiB*month) * 16242 GiB / 730 hour/month * 24 hour = 93.715 CNY。 其中 16242 GiB 为前述流量在 24 小时中产生的数据量。

  • “S3 - API 调用费”包括调用以下 API 产生的费用: GetObject, PutObject, InitiateMultipartUpload, UploadPart, CopyPart 和 CompleteMultipartUpload。

  • 表中没有列出花费未超过 0.001 CNY 的费用,例如 CreateBucket, ListBucket, DeleteBucket 等 API 调用费。

从表中可以看出:

  • 由于 AutoMQ 中所有 Broker 都使用了竞价实例,且实例按需扩缩,大幅降低了计算成本。

  • AutoMQ 将绝大多数数据都保存在对象存储(S3)中,仅有少部分数据保存在作为缓冲区的块存储(EBS)中,大幅降低了存储成本。

与 Apache Kafka 对比

我们还估算了在同样场景下,Apache Kafka (低于 3.6.0 版本,无分层存储) 所需成本。

为该 Apache Kafka 集群做出以下预设:

  • 根据集群流量峰值 (1200 MiB/s) 购买按需实例,使用同样的 r6i.large 机型(其按需售价为 0.88313 CNY/hour,竞价售价为 0.2067 CNY/hour,基准带宽为 100MiB/s),同时网络水位为 80%;此外,额外购买 3 台按需实例作为 Controller。

  • 根据集群总存储量 (16242 GiB) 购买块存储,使用 gp3 (其售价为 0.5312 CNY 每 GiB 每月),使用 3 副本存储,同时存储水位为 80%。

估算如下:


单 broker 承载流量上限:100 MiB/s * 80% / (1 + 2) = 26.67 MiB/s
集群中 broker 的数量:1200 MiB/s ÷ 26.67 MiB/s = 45
所需实例数量:45 + 3 = 48
每日计算成本:48 * 24 hour * 0.88313 CNY/hour = 1017.366 CNY

所需存储大小:16242 GiB * 3 / 80% = 60907.5 GiB
每日存储成本:60907.5 GiB * 0.5312 CNY/(GiB*month) / 730 hour/month * 24 hour = 1063.695 CNY

总成本:1017.366 CNY + 1063.695 CNY = 2081.061 CNY

将其与 AutoMQ 对比:

成本类别
Apache Kafka (CNY)
AutoMQ (CNY)
倍率
计算
1017.336
83.896
12.13
存储
1063.695
103.838
10.24
合计
2081.061
187.734
11.09

AutoMQ 充分利用云的弹性能力和对象存储,相比于 Apache Kafka,显著降低了计算和存储成本,节约超过 10 倍的费用。

附录一:测试配置

AutoMQ 安装器的配置文件 kos-config.yaml:


kos:
installID: xxxx
vpcID: vpc-xxxxxx
cidr: 10.0.1.0/24
zoneNameList: cn-northwest-1b
kafka:
controllerCount: 3
heapOpts: "-Xms6g -Xmx6g -XX:MetaspaceSize=96m -XX:MaxDirectMemorySize=6g"
controllerSettings:
- autobalancer.reporter.network.in.capacity=60000
- autobalancer.reporter.network.out.capacity=60000
brokerSettings:
- autobalancer.reporter.network.in.capacity=100000
- autobalancer.reporter.network.out.capacity=100000
commonSettings:
- metric.reporters=kafka.autobalancer.metricsreporter.AutoBalancerMetricsReporter,org.apache.kafka.server.metrics.s3stream.KafkaS3MetricsLoggerReporter
- s3.metrics.logger.interval.ms=60000
- autobalancer.topic.num.partitions=1
- autobalancer.controller.enable=true
- autobalancer.controller.anomaly.detect.interval.ms=60000
- autobalancer.controller.metrics.delay.ms=20000
- autobalancer.controller.network.in.distribution.detect.threshold=0.2
- autobalancer.controller.network.in.distribution.detect.avg.deviation=0.05
- autobalancer.controller.network.out.distribution.detect.threshold=0.2
- autobalancer.controller.network.out.distribution.detect.avg.deviation=0.05
- autobalancer.controller.network.in.utilization.threshold=0.8
- autobalancer.controller.network.out.utilization.threshold=0.8
- autobalancer.controller.execution.interval.ms=100
- autobalancer.controller.execution.steps=1024
- autobalancer.controller.load.aggregation=true
- autobalancer.controller.exclude.topics=__consumer_offsets
- autobalancer.reporter.metrics.reporting.interval.ms=5000
- s3.network.baseline.bandwidth=104824045
- s3.wal.capacity=4294967296
- s3.wal.cache.size=2147483648
- s3.wal.object.size=536870912
- s3.stream.object.split.size=8388608
- s3.object.block.size=16777216
- s3.object.part.size=33554432
- s3.block.cache.size=1073741824
- s3.object.compaction.cache.size=536870912
scaling:
cooldown: 10
alarmPeriod: 60
scalingAlarmEvaluationTimes: 1
fallbackAlarmEvaluationTimes: 2
scalingNetworkUpBoundRatio: 0.8
scalingNetworkLowerBoundRatio: 0.8
ec2:
instanceType: r6i.large
controllerSpotEnabled: false
keyPairName: kafka_on_s3_benchmark_key-xxxx
enablePublic: true
enableDetailedMonitor: true
accessKey: xxxxxx
secretKey: xxxxxx

说明:

  • 机型统一使用 r6i.large, 其网络基准带宽为 0.781 Gbps, 故将 s3.network.baseline.bandwidth 设置为 104824045 (Byte)。

  • 为了模拟生产场景,将 controller 的数量配置为 3 个,同时 controller 使用的是按需实例。

  • 为了快速感知流量变化并及时扩缩容,开启了 AWS EC2 detailed monitoring, 同时将 kos.scaling.cooldown 设置为 10 (s), 将 kos.scaling.alarmPeriod 设置为 60 (s)。

  • 为了充分发挥 AutoMQ 的弹性优势,将 kos.scaling.scalingNetworkUpBoundRatio 和 kos.scaling.scalingNetworkLowerBoundRatio 均设置为 0.8。

OpenMessaging Benchmark Framework 配置如下:

driver.yaml:


name: AutoMQ
driverClass: io.openmessaging.benchmark.driver.kafka.KafkaBenchmarkDriver

# Kafka client-specific configuration
replicationFactor: 3
reset: false

topicConfig: |
min.insync.replicas=2

commonConfig: |
bootstrap.servers=10.0.1.134:9092,10.0.1.132:9092,10.0.1.133:9092

producerConfig: |
acks=all
linger.ms=0
batch.size=131072
send.buffer.bytes=1048576
receive.buffer.bytes=1048576

consumerConfig: |
auto.offset.reset=earliest
enable.auto.commit=false
auto.commit.interval.ms=0
max.partition.fetch.bytes=131072
send.buffer.bytes=1048576
receive.buffer.bytes=1048576

workload.yaml:


name: 1-topic-128-partitions-4kb-4p4c-dynamic

topics: 1
partitionsPerTopic: 128
messageSize: 4096
payloadFile: "payload/payload-4Kb.data"
subscriptionsPerTopic: 1
consumerPerSubscription: 4
producersPerTopic: 4
producerRate: 19200
producerRateList:
- [16, 0, 20480]
- [17, 0, 204800]
- [18, 0, 102400]
- [19, 0, 20480]
- [ 5, 0, 20480]
- [ 5, 45, 204800]
- [ 6, 30, 20480]
- [10, 0, 20480]
- [11, 0, 307200]
- [12, 0, 20480]
consumerBacklogSizeGB: 0
warmupDurationMinutes: 0
testDurationMinutes: 2100

此外,使用两台 c6in.2xlarge 实例作为 worker,其网络基准带宽为 12.5 Gbps(即 1600 MiB/s),可以满足峰值流量时收发消息的需求。