sharetwitterlinkedIn

Pulsar 和 Kafka 基准测试报告 2020报告(完整版)

November 9, 2020
head img

为了更全面地了解 Pulsar 和 Kafka,我们“复现”了 Confluent 对 Pulsar 和 Kafka 基准测试。重复这一基准测试的原因有两个,一是 Confluent 的测试方法存在一些问题;二是 Confluent 的测试范围和测试场景不够全面。为了更准确地对比 Pulsar 和 Kafka,我们在测试中不仅修复了 Confluent 测试中的问题,还扩大了测试范围,纳入更多性能衡量标准,模拟更多实际场景。

和 Confluent 的测试相比,我们的测试主要有三项改进:

  • 包含 Pulsar 和 Kafka 支持的所有持久性级别。在同等持久性级别下,对比二者的吞吐量和延迟。
  • 引入影响性能的其他因素和测试条件,如分区数量、订阅数量、客户端数量等。
  • 测试的混合负载同时包含写入、追赶读和追尾读,模拟实际使用场景。

本节将详述测试结果和结论。

最大吞吐量测试

测试目标:观测在处理发布和追尾读工作负载时 Pulsar 和 Kafka 可实现的最大吞吐量。

测试设置:通过调整分区数量,观测分区数量对吞吐量的影响。

测试策略:

  • 将所有消息都复制三次,确保容错;
  • 改变 ack 数量,测试在不同持久性保证下,Pulsar 和 Kafka 的最大吞吐量;
  • 启用 Pulsar 和 Kafka 的批处理,为不超过 10 ms 的响应延迟设置最大批处理为 1 MB 数据;
  • 改变分区数量(1、100、2000 个分区),分别测试最大吞吐量;
  • 当分区数量为 100 和 2000 时,使用 2 个 producer 和 2 个 consumer;
  • 当分区数量为 1 时,改变 producer 和 consumer 的数量,观测吞吐量变化;
  • 消息大小为 1 KB;
  • 在所有测试场景中,改变持久性级别,观测最大吞吐量。

测试结果:

#1 100 个分区,1 个订阅,2 个生产者/2 个消费者

分区数量为 100,改变持久性保证,分别观测 Pulsar 和 Kafka 的最大吞吐量。在 Pulsar 和 Kafka 中,都使用 1 个订阅、2 个生产者和 2 个消费者。测试结果如下。

  • 在 1 级持久性保证(同步复制持久性,异步本地持久性)下,Pulsar 的最大吞吐量约为 300 MB/s,达到日志磁盘带宽物理极限。Kafka 的最大吞吐量约为 420 MB/s。值得注意的是,在持久性为 1 级时,Pulsar 配置一个磁盘为日志磁盘进行写入,另一个磁盘为 ledger 磁盘进行读取;而 Kafka 同时使用两个磁盘进行写入和读取。尽管 Pulsar 的设置能够提供更好的 I/O 隔离,但单个磁盘最大带宽(〜300 MB/s)会限制吞吐量。
  • 将持久性(同步复制持久性和异步本地持久性)配置为 2 级时,Pulsar 和 Kafka 的最大吞吐量均可达到约 600 MB/s 。两个系统都达到了磁盘带宽的物理极限。

图 1 为 100 个分区,同步本地持久性下,Pulsar 和 Kafka 的最大吞吐量。

图1· 有 100 个分区时,Pulsar 和 Kafka 的最大吞吐量(同步本地持久性)

图 2 为 100 个分区,异步本地持久性下,Pulsar 和 Kafka 的最大吞吐量。

图2· 100 个分区时,Pulsar 和 Kafka 的最大吞吐量(异步本地持久性)

#2 2000 个分区,1 个订阅,2 个生产者/2 个消费者

分区数量从 100 增加到 2000,持久性保证不变(acks = 2),分别观测 Pulsar 和 Kafka 的最大吞吐量。在 Pulsar 和 Kafka 中,都使用 1 个订阅、两个生产者和两个消费者。测试结果如下。

  • 在 1 级持久性保证下,Pulsar 的最大吞吐量保持在约 300 MB/s,在 2 级持久性保证下则增加到约 600 MB/s;
  • 单独为每条消息刷新数据时(kafka-ack-all-sync),Kafka 的最大吞吐量从 600MB/s (100 个分区) 降到了 300MB/s 左右;
  • 使用系统默认的持久性设置(kafka-ack-all-nosync)时,Kafka 的最大吞吐量从约500 MB/s(100 个分区)下降到约 300 MB/s。

为了了解 Kafka 吞吐量下降的原因,我们绘制了 Kafka 和 Pulsar 在每一持久性保证下的平均发布延迟图。图 3 表明,分区数量增加到 2000 时,Kafka 的平均发布延迟增加到 200 毫秒,P99 发布延迟增加到 1200 毫秒。

图3· 2000 个分区时,Pulsar 和 Kafka 的最大吞吐量

发布延迟通常会对吞吐量造成显著影响。但由于 Pulsar 客户端充分利用了 Netty 强大的异步网络框架,Pulsar 的吞吐量没有受到影响。而 Kafka 客户端使用同步实现,Kafka 的吞吐量的确受到影响。把 producer 数量增加一倍可以提高 Kafka 的吞吐量。如果生产者数量增加到 4 个,Kafka 的吞吐量能达到约 600 MB/s。

图 4:2000 个分区时,Pulsar 和 Kafka 的发布延迟

图4· 2000 个分区时,Pulsar 和 Kafka 的发布延迟

#3 1 个分区,1 个订阅,2 个生产者/2 个消费者

增加更多 broker 和分区有助于提高 Pulsar 和 Kafka 的吞吐量。为了更深入地了解这两个系统的效率,我们把分区数量设为 1,观测 Pulsar 和 Kafka 的最大吞吐量。在 Pulsar 和 Kafka 中,都使用 1 个订阅、2 个生产者和 2 个消费者。

测试结果如下:

  • 在所有持久性级别,Pulsar 的最大吞吐量都达到了约 300 MB/s;
  • 在异步复制持久性下,Kafka 的最大吞吐量达到了约 300 MB/s,但在同步复制持久性下只有约 160 MB/s。

图 5:在 1 个分区,同步本地持久性下,Pulsar 和 Kafka 的最大吞吐量

图5· 1 个分区时,Pulsar 和 Kafka 的最大吞吐量(同步本地持久性)

图 6:在 1 个分区,异步本地持久性下,Pulsar 和 Kafka 的最大吞吐量

图6· 1 个分区时,Pulsar 和 Kafka 的最大吞吐量(异步本地持久性)

#4 1 个分区,1 个订阅,1 个生产者/1 个消费者

分区数量为 1,订阅数量为 1(与上个测试相同),分别观测 Pulsar 和 Kafka 的最大吞吐量。在 Pulsar 和 Kafka 中,只使用 1 个生产者和 1 个消费者。

测试结果如下:

  • 在所有持久性级别,Pulsar 的最大吞吐量都保持在约 300 MB/s;
  • 在异步复制持久性下,Kafka 的最大吞吐量从约 300 MB/s(测试#3中)下降到约 230 MB/s;
  • 在同步复制持久性下,Kafka 的吞吐量从约 160 MB/s(测试#3中)下降到约 100 MB/s。

图 7 为在同步本地持久性,一个分区、一个生产者和一个消费者的情况下,Pulsar 和 Kafka 的最大吞吐量

图7· 一个分区、一个生产者和一个消费者时,Pulsar 和 Kafka 的最大吞吐量(同步本地持久性)

为了了解 Kafka 吞吐量下降的原因,我们绘制了 Kafka 和 Pulsar 在不同持久性保证下的平均发布延迟图(图8)和端到端延迟图(图9)。从下图中可以看到,即使只有一个分区,Kafka 的发布延迟和端到端延迟也从几毫秒上升到了几百毫秒。减少生产者和消费者数量会对 Kafka 吞吐量造成显著影响。相比之下,Pulsar 的延迟始终保持在几毫秒。

图8· 一个分区、一个生产者和一个消费者时,Pulsar 和 Kafka 的发布延迟(同步持久性)

图9· 一个分区、一个生产者和一个消费者时,Pulsar 和 Kafka 的端到端延迟(同步持久性)

发布和端到端延迟测试

测试目标:观测在处理发布和追尾读工作负载时 Pulsar 和 Kafka 可实现的最低延迟。

测试设置:通过调整订阅数量和分区数量,观测订阅数量和分区数量对发布延迟和端到端延迟的影响。

测试策略:

  • 将所有消息都复制三次,确保容错;
  • 改变 ack 数量,测试在不同持久性保证下,Pulsar 和 Kafka 吞吐量的差异;
  • 改变订阅数量(从 1 到 10),分别测试延迟;
  • 改变分区数量(从 100 到 10000),分别测试延迟;
  • 消息大小为 1KB;
  • 生产者以 200000/s(约 200MB/s)的固定速度发送消息,追尾读消费者在生产者持续发送消息时处理消息。

各项测试结果如下。

#1 100 个分区, 1 个订阅

我们从 100 个分区、1 个订阅开始,在所有不同持久性保证下,对 Pulsar 和 Kafka 能实现的最低延迟进行了基准测试。

测试证明,在所有持久性级别上,Pulsar 的发布延迟和端到端延迟都比 Kafka 低,是 Kafka 的 1/5 到 1/2。

发布延迟 - 同步本地持久性

使用两种复制持久性设置(分别为 ack-1 和 ack-2)和同步本地持久性时,Pulsar 和 Kafka 发布延迟的差异如图 10。表 2 为每种情况下的精确延迟数值。在异步复制持久性(ack-1)下,Pulsar P99 延迟是 Kafka 的 1/3; 在同步复制持久性(ack-2)下是 Kafka 的 1/5。

图10· Pulsar 和 Kafka 的发布延迟(数据同步)

表2· Pulsar 和 Kafka 的实际发布延迟测试结果(数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 3.23 3.21 4.23 4.73 5.89
pulsar-ack-2 3.64 3.42 4.47 10.37 32.74
kafka-ack-1 2.54 1.99 3.78 11.37 18.71
kafka-ack-all 9.84 5.71 19.7 58.83 164.20

为了更深入地了解延迟如何随时间变化,我们绘制了 Pulsar 和 Kafka 采取不同复制持久性设置时的 P99 延迟图。如图 11 所示,Pulsar 的延迟比较稳定(约 5 毫秒),但 Kafka 的延迟波动较大。对于关键任务服务(mission-critical services)来说,稳定、持续的低延迟至关重要。

图11· Pulsar 和 Kafka 的 P99 延迟

端到端延迟--同步本地持久性

使用两种复制持久性设置(分别为 ack-1和 ack-2)和同步本地持久性时,Pulsar 和 Kafka 端到端延迟的差异如图 12。表 3 为每种情况下的精确延迟数值。在异步复制持久性(ack-1)下,Pulsar P99 端到端延迟是 Kafka 的 1/3,在同步复制持久性(ack-2)下是 Kafka 的 1/5。

图12· 1 个订阅时,Pulsar 和 Kafka 的端到端延迟(数据同步)

表3· 1 个订阅时,Pulsar 和 Kafka 的实际端到端延迟测试结果(数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 4.32 4.41 5.35 5.86 7.65
pulsar-ack-2 4.72 4.65 5.60 11.64 33.90
kafka-ack-1 6.23 4.91 9.08 18.75 91.74
kafka-ack-all 12.89 7.53 23.07 64.62 169.83

发布延迟 - 异步本地持久性

使用两种复制持久性设置(分别为 ack-1 和 ack-2)和异步本地持久性时,Pulsar 和 Kafka 发布延迟的差异如图 13。表 4 为每种情况下的精确延迟数值。在异步复制持久性(ack-1)下,Kafka 性能更优,但 Pulsar P99 发布延迟更稳定(低于 5 毫秒),增加复制持久性保证(从 ack-1 到 ack-2)并未影响延迟。在同步复制持久性(ack-2)下,Kafka P99 发布延迟是 Pulsar 的 2 倍。

图13· Pulsar 和 Kafka 的发布延迟(无数据同步)

表4· Pulsar 和 Kafka 的实际发布延迟测试结果(无数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 2.81 2.79 3.8 4.21 5.45
pulsar-ack-2 2.99 2.97 3.96 4.47 6.19
kafka-ack-1 1.74 1.62 2.60 3.06 9.91
kafka-ack-all 3.01 2.77 3.97 8.47 15.57

为了更深入地了解发布延迟如何随时间变化,我们绘制了 Pulsar 和 Kafka 在不同复制持久性设置下的 P99 发布延迟图。如图 14 所示,Pulsar 的延迟始终保持在较低的水平(低于 5 毫秒),而 Kafka 的延迟始终是 Pulsar 的 2 倍。

图14· 不同复制持久性设置下,Pulsar 和 Kafka 的 P99 发布延迟

端到端延迟--异步本地持久性

使用两种复制持久性设置(分别为 ack-1 和 ack-2)和异步本地持久性时,Pulsar 和 Kafka 端到端延迟的差异如图 15。表 5 为每种情况下的精确延迟数值。在所有情况下,Pulsar 的性能都优于 Kafka。Pulsar P99 端到端延迟保持稳定(约 5 毫秒),改变复制持久性设置对其并无影响。对于 ack-1,Kafka 的 P99 端到端延迟比 Pulsar 高;对于 ack-2,Kafka 的 P99 端到端延迟是 Pulsar 的 2 倍。

图15· 1 个订阅时,Pulsar 和 Kafka 的端到端延迟(无数据同步)

表5· 1 个订阅时,Pulsar 和 Kafka 的实际端到端延迟测试结果(无数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 3.96 3.99 4.90 5.33 7.93
pulsar-ack-2 4.06 4.17 5.08 5.55 8.52
kafka-ack-1 4.26 4.10 5.39 6.94 17.24
kafka-ack-all 4.22 3.96 5.19 10.43 18.95

#2 100 个分区, 10 个订阅

了解 Pulsar 和 Kafka 只有一个订阅时的性能后,我们想知道更改订阅数量会如何影响发布延迟和端到端延迟。于是我们把订阅数量从 1 增加到 10,并为每个订阅分配了 2 个消费者。

从如下数据中可以看出,我们的测试结果表明:

  • Pulsar P99 发布延迟和端到端延迟保持在 5 到 10 毫秒之间。
  • 增加订阅数量会对 Kafka 的 P99 发布和端到端延迟产生巨大影响,导致延迟增加到几秒。

发布延迟 - 同步本地持久性

使用两种复制持久性设置(分别为 ack-1和 ack-2)和同步本地持久性时,Pulsar 和 Kafka 发布延迟的差异如图 16。表 7 为每种情况下的精确延迟数值。在异步复制持久性(ack-1)下,Pulsar P99 发布延迟仍然是 Kafka 的 1/3。但在同步复制持久性(ack-2)下,Pulsar 的发布延迟是 Kafka 的 1/160(1 个订阅时,Pulsar 的发布延迟是 Kafka 的 1/5)。

图16· 10 个订阅时,Pulsar 和 Kafka 的发布延迟(数据同步)

表7· 10 个订阅时,Pulsar 和 Kafka 的实际发布延迟测试结果(数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 3.24 3.20 4.26 4.89 10.31
pulsar-ack-2 3.67 3.47 4.56 9.94 31.31
kafka-ack-1 3.14 2.39 4.39 15.07 61.29
kafka-ack-all 290.51 176.82 724.26 1593.46 2686.41

端到端延迟--同步本地持久性

使用两种复制持久性设置(分别为 ack-1和 ack-2)和同步本地持久性时,Pulsar 和 Kafka 端到端延迟的差异如图 17。表 8 为每种情况下的精确延迟数值。在异步复制持久性(ack-1)下,Pulsar P99 延迟是 Kafka 的 1/20,在同步复制持久性(ack-2)下是 Kafka 的 1/110 。

图17· 10 个订阅时,Pulsar 和 Kafka 的端到端延迟(数据同步)

表8· 10 个订阅时,Pulsar 和 Kafka 的实际端到端延迟测试结果(数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 4.79 4.83 6.03 7.12 15.36
pulsar-ack-2 5.34 5.12 6.43 14.65 39.90
kafka-ack-1 11.36 6.65 17.12 145.10 914.19
kafka-ack-all 296.45 171.32 731.67 1599.79 2696.63

发布延迟 - 异步本地持久性

使用两种复制持久性设置(分别为 ack-1 和 ack-2)和异步本地持久性时,Pulsar 和 Kafka 发布延迟的差异如图 18。表 9 为每种情况下的精确延迟数值。Pulsar 的性能显著优于 Kafka。Pulsar 的平均发布延迟约为 3 毫秒,P99 延迟在 5 毫秒以内。Kafka 在异步复制持久性(ack-1)下性能令人满意,但在同步复制持久性(ack-2)下性能差了很多。在同步复制持久性下,Kafka 的 P99 发布延迟是 Pulsar 的 270 倍。

图18· 10 个订阅时,Pulsar 和 Kafka 的发布延迟(无数据同步)

表9· 10 个订阅时,Pulsar 和 Kafka 的实际发布延迟测试结果(无数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 2.86 2.82 3.86 4.46 11.18
pulsar-ack-2 3.05 3.00 4.03 4.73 10.39
kafka-ack-1 2.11 1.89 3.02 6.35 14.74
kafka-ack-all 158.04 17.63 526.91 1281.25 1956.71

端到端延迟--异步本地持久性

使用两种复制持久性设置(分别为 ack-1 和 ack-2)和异步本地持久性时,Pulsar 和 Kafka 端到端延迟的差异如图 19。表 10 为不同情况下的精确延迟数值。在所有情况下,Pulsar 的性能始终优于 Kafka。Pulsar 的端到端延迟始终保持在 4~7 毫秒之间,改变复制持久性设置对其并无影响。对于 ack-1,Kafka 的 P99 端到端延迟是 Pulsar 的 13 倍;对于ack-2,则是 187 倍。

图19· 10 个订阅时,Pulsar 和 Kafka 的端到端延迟(无数据同步)

表10· 10 个订阅时,实际端到端延迟测试结果(无数据同步)

Average P50 P90 P99 P999
pulsar-ack-1 4.51 4.47 5.60 6.84 15.77
pulsar-ack-2 4.61 4.61 5.76 6.94 14.21
kafka-ack-1 8.01 5.90 9.38 89.80 532.68
kafka-ack-all 212.77 87.72 537.85 1295.78 1971.03

#3 100, 5000, 8000, 10000 个分区

了解更改订阅数量会如何影响 Pulsar 和 Kafka 的发布延迟后,我们想更改分区数量,看看会产生什么效果。于是,我们把分区数量从 100 个累加到 10000 个,观察发生了什么变化。

测试结果表明:

  • 分区数量增加时,Pulsar P99 发布延迟稳定在 5 毫秒内。
  • Kafka 的 P99 发布延迟受分区数量累加影响很大,延迟上升到几秒。
  • 分区数量超过 5000 后,Kafka 的消费者就跟不上发布吞吐量了。

Ack = 1,同步本地持久性

使用同步本地持久性和异步复制持久性 (ack = 1) 更改分区数量时,Pulsar 和 Kafka 发布和端到端延迟的差异分别如图 20 和图 21。

图20· 分区数量不同,ACK=1 时的发布延迟(数据同步)

图21· 分区数量不同,ACK=1 时的端到端延迟(数据同步)

表 12 显示了分区数量不同,ACK=1 时的实际发布延迟测试结果。表 13 显示了分区数量不同,ACK=1 时的实际端到端延迟测试结果。

表12· 分区数量不同,ACK=1 时的实际发布延迟测试结果(数据同步)

Average P50 P90 P99 P999
kafka-100 2.54 1.99 3.78 11.37 18.71
kafka-5000 3.50 4.41 9.21 29.26 44.39
kafka-8000 8.37 5.11 20.18 40.70 69.72
kafka-10000 11.14 6.57 26.81 52.24 82.07
pulsar-100 3.23 3.21 4.23 4.73 5.89
pulsar-5000 3.35 3.30 4.34 5.03 13.96
pulsar-8000 3.67 3.67 4.89 5.61 16.07
pulsar-10000 3.42 3.37 4.48 5.36 19.20

表13· 分区数量不同,ACK=1 时的实际端到端延迟测试结果(数据同步)

Average P50 P90 P99 P999
kafka-100 6.23 4.91 9.08 18.75 91.74
pulsar-100 4.32 4.41 5.35 5.86 7.65
pulsar-5000 4.52 4.53 5.55 6.26 17.78
pulsar-8000 4.89 4.99 6.11 6.86 23.83
pulsar-10000 4.49 4.62 5.70 6.67 27.25

图 22 给出了分区数量不同,ACK=1 时 Pulsar 端到端的延迟。图 23 给出了分区数量不同,ACK=1 时 Kafka 端到端的延迟。

图22· 分区数量不同,ACK=1 时 Pulsar 的端到端延迟(数据同步)

图23· 分区数量不同,ACK=1 时 Kafka 的端到端延迟(数据同步)

从以上图表可以看出:

  • Pulsar P99 发布延迟稳定在 5 毫秒左右,更改分区数量对其并无影响。
  • Pulsar P99 端到端延迟稳定在 6 毫秒左右,更改分区数量对其并无影响。
  • Kafka 的 P99 发布延迟随着分区数量增加而逐渐拉长,在 10000 个分区时,其延迟增加了 5 倍(与 100 个分区时相比),比 Pulsar 的延迟高出 10 倍。
  • Kafka 的 P99 端到端延迟随着分区数量增加而逐渐拉长,在 10000 个分区时,其延迟高出 10000 倍(与 100 个分区时相比),增加到 180 秒,是 Pulsar 的 280000 倍。

Ack = 2,同步本地持久性

使用同步本地持久性和同步复制持久性(ack = 2)更改分区数量时,Pulsar 和 Kafka 发布延迟的差异如图 24。表 14 为每种情况下的精切延迟数值。

图24· 分区数量不同,ack=2/all 时的发布延迟(数据同步)

表14· 分区数量不同, ack=2/all 时的实际发布延迟测试结果(数据同步)

Average P50 P90 P99 P999
kafka-100 9.84 5.71 19.7 58.83 164.20
kafka-5000 154.50 36.86 468.75 1259.82 2017.15
kafka-8000 283.50 124.82 784.69 1742.27 2729.79
kafka-10000 259.50 96.15 731.85 1718.09 2684.28
pulsar-100 3.64 3.42 4.47 10.37 32.74
pulsar-5000 3.84 3.57 4.69 12.81 42.83
pulsar-8000 4.15 3.97 5.23 11.90 42.19
pulsar-10000 4.04 3.71 5.03 13.54 46.73

图 25 和图 26 分别显示了更改分区数量如何影响 Pulsar 和 Kafka 端到端的延迟。

图25· 分区数量不同,ack=2 时 Pulsar 的端到端延迟(数据同步)

图26· 分区数量不同,ack=2 时 Kafka 的端到端延迟(数据同步)

从以上图表可以看出:

  • Pulsar P99 发布延迟稳定在约 10 毫秒,增加分区数量对其并无影响。
  • 随着分区数量增加,Kafka 的 P99 发布延迟逐渐拉长;有 10000 个分区时,其延迟是 100 个分区的 30 倍,增加到 1.7 秒,是 Pulsar 的 126 倍。
  • Pulsar P99 端到端延迟稳定在约 10 毫秒,增加分区数量仅对 Pulsar P99 端到端延迟产生轻微影响。但即使有 10000 个分区,延迟仍相对较低,约为 50 毫秒。
  • 随着分区数量增加,Kafka 的 P99 端到端延迟逐渐拉长。有 10000 个分区时,Kafka P99 端到端延迟增加到 200 秒,是 Pulsar 的 14771 倍。

Ack = 1, Async 本地持久性

使用异步本地持久性和异步复制持久性(ack = 1)更改分区数量时,Pulsar 和 Kafka 发布延迟的差异如图 27。表 15 为不同情况下的精切延迟数值。

图27· 分区数量不同,ack=1 时的发布延迟(无数据同步)

表15· 分区数量不同,ack=1 时的实际发布延迟测试结果(无数据同步)

Average P50 P90 P99 P999
kafka-100 1.74 1.62 2.60 3.06 9.91
kafka-5000 4.13 3.05 5.20 25.32 33.86
kafka-8000 6.84 4.32 16.51 34.19 46.34
kafka-10000 8.95 5.32 22.75 41.83 59.32
pulsar-100 2.86 2.79 3.8 4.21 5.45
pulsar-5000 2.98 2.95 3.89 4.51 7.85
pulsar-8000 3.26 3.27 4.50 5.14 15.21
pulsar-10000 3.06 2.97 4.15 5.23 19.47

图 28 和图 29 分别显示了更改分区数量如何影响 Pulsar 和 Kafka 端到端的延迟。

图28· 分区数量不同,ack=1 时,Pulsar 端到端的延迟(无数据同步)

图29· 分区数量不同,ack=1 时,Kafka 端到端的延迟(无数据同步)

从以上图表可以看出:

  • Pulsar P99 发布延迟稳定在约 4~5 毫秒之间,增加分区数量对其并无影响。
  • Kafka P99 发布延迟随着分区数量增加而逐渐拉长,有 10000 个分区时,延迟增加到 41 毫秒,是有 100 个分区时的 13 倍,是 Pulsar 的 8 倍。
  • Pulsar P99 端到端延迟稳定在约 4~6 毫秒之间,增加分区数量仅对 Pulsar P99 端到端延迟产生轻微影响,但即使有 10000 个分区,它也保持在相对较低的水平(24 毫秒以内)。
  • 随着分区数量增加,Kafka P99 端到端延迟逐渐拉长。有 10000 个分区时,Kafka P99 端到端延迟高达 180 秒,是 Pulsar 的 34416 倍。

Ack = 2,异步本地持久性

使用异步本地持久性和同步复制持久性 (ack = 2)更改分区数量时,Pulsar 和 Kafka 发布延迟的差异如图 30。表 16 为每种情况下的精确延迟数值。

图30· 分区数量不同,ack=all/2 的发布延迟(无数据同步)

表16· 分区数量不同,ack=all/2 的实际发布延迟测试结果(无数据同步)

Average P50 P90 P99 P999
kafka-100 3.01 2.77 3.97 8.47 15.57
kafka-5000 19.33 10.16 40.40 121.40 336.21
kafka-8000 138.19 42.52 385.86 1164.90 2008.28
kafka-10000 266.66 102.55 752.95 1717.83 2797.51
pulsar-100 2.99 2.97 3.96 4.47 6.19
pulsar-5000 3.13 3.10 4.17 4.98 9.45
pulsar-8000 3.44 3.44 4.64 5.36 12.92
pulsar-10000 3.32 3.24 4.39 6.18 23.10

图 31 和图 32 分别显示了更改分区数量如何影响 Pulsar 和 Kafka 端到端的延迟。

图31· 分区数量不同,ack=2 时 Pulsar 的端到端延迟(无数据同步)

图32· 分区数量不同,ack=2 时 Kafka 的端到端延迟(无数据同步)

从以上图表可以看出:

  • Pulsar P99 发布延迟稳定在约 4~5 毫秒之间,增加分区数量对其并无影响。
  • 随着分区数量增加,Kafka P99 发布延迟逐渐拉长,有 10000 个分区时,其延迟增加到 1.7 秒,是 100 个分区时的 202 倍,是 Pulsar 的 278 倍。
  • Pulsar P99 端到端延迟稳定在约 4~6 毫秒之间,增加分区数量仅对其造成轻微影响,延迟仍保持在相对较低的水平(28 毫秒以内)。
  • 随着分区数量增加,Kafka P99 端到端延迟逐渐拉长。有 10000 个分区时,Kafka P99 端到端延迟增加到 200 秒,是 Pulsar 的 32362 倍。

追赶读测试

测试目标:观测在处理仅包括追赶读工作负载时 Pulsar 和 Kafka 可实现的最大吞吐量。

测试策略:

  • 将所有消息都复制三次,确保容错;
  • 改变 ack 数量,测试在不同持久性保证下,Pulsar 和 Kafka 的吞吐量变化;
  • 启用 Pulsar 和 Kafka 的批处理,为不超过 10 ms 的响应延迟设置最大批处理为 1 MB 数据;
  • 在 100 个分区的情况下,对两个系统进行基准测试;
  • 共运行四个客户端--两个生产者和两个消费者;
  • 消息大小为 1 KB。

测试一开始,生产者开始以 200K/s 的固定速率发送消息。队列中积累了 512GB 数据后,消费者开始处理数据,首先从头读取累积数据,然后在数据到达时继续处理传入数据。在测试期间,生产者持续以相同速率发送消息。

我们评估了每个系统读取 512GB 累积数据的速度,在不同持久性设置下对 Kafka 和 Pulsar进行了比较。各项测试结果如下:

#1 启用 Pulsar 绕过 Journal 写入的异步本地持久性

本项测试中,我们在 Pulsar 和 Kafka 上使用了同等的异步本地持久性保证。我们启用了新的 Pulsar 绕过 Journal 写入,来匹配 Kafka 默认 fsync 设置中的本地持久性保证。

下图 33 给出了测试结果:

  • 只处理追赶读时,Pulsar 的最大吞吐量达到了 370 万条信息/秒(3.5 GB/s)。
  • Kafka 的最大吞吐量只达到 100 万条消息/秒(1GB/s)。
  • Pulsar 处理追赶读的速度比 Kafka 快 75%。

图33· Pulsar 和 Kafka 的追赶读吞吐量(绕过 Journal 写入)

#2 未启用 Pulsar 绕过 Journal 写入的异步本地持久性

本项测试中,我们在 Pulsar 和 Kafka 上使用了异步本地持久性保证,但并未启用 Pulsar 绕过 Journal 写入。

下图 34 给出了测试结果:

  • 处理追赶读时,Pulsar 的最大吞吐量达到 180 万条信息/秒(1.7 GB/s)。
  • Kafka 的最大吞吐量仅达到 100 万条消息/秒(1GB/s)。
  • Pulsar 处理追赶读的速度是 Kafka 的两倍。

图34· Pulsar 和 Kafka 的追赶读吞吐量(数据同步)

#3 同步本地持久性

本项测试中,我们在同等同步本地持久性保证下对 Kafka 和 Pulsar 进行了比较。

下图 35 给出了测试结果:

  • 只处理追赶读时,Pulsar 的最大吞吐量达到 180 万条/秒(1.7 GB/s)。
  • Kafka 的最大吞吐量只达到 100 万条消息/秒(1GB/s)。
  • Pulsar 处理追赶读的速度是 Kafka 的两倍。

图35· Pulsar 和 Kafka 的追赶读吞吐量(无数据同步)

混合工作负载测试

测试目标:评估追赶读对混合工作负载中的发布和追尾读的影响。

测试策略:

  • 将所有消息都复制三次,确保容错;
  • 启用 Pulsar 和 Kafka 的批处理,为不超过 10 ms 的响应延迟设置最大批处理为 1 MB 数据;
  • 在 100 个分区的情况下,对两个系统进行基准测试;
  • 在不同耐久性设置下对 Kafka 和 Pulsar 进行比较;
  • 共运行四个客户端--两个生产者和两个消费者;
  • 消息大小为 1 KB;

测试一开始,两个生产者均开始以 200K/s 的固定速率发送数据,两个消费者中有一个立即开始处理追尾读。队列中积累了 512GB 数据后,另一个(追赶读)消费者开始从头读取累积数据,然后在数据到达时继续处理传入数据。在测试期间,两个生产者持续以相同的速率发布,而追尾读消费者继续以相同的速率消费数据。

测试结果如下:

#1 启用 Pulsar 绕过 Journal 写入的异步本地持久性

本项测试中,我们在同等异步本地持久性保证下对 Kafka 和 Pulsar 进行了比较。我们启用了新的 Pulsar 绕过 Journal 写入,来匹配 Kafka 默认 fsync 设置的本地持久性保证。

下图 36 显示,追赶读对 Kafka 写入造成显著影响,但对 Pulsar 影响很小。Kafka 的 P99 发布延迟增加到 1-3 秒,而 Pulsar 的延迟则稳定在几毫秒到几十毫秒间。

图36· 追赶读对 Pulsar 和 Kafka 发布延迟的影响(绕过 Journal 写入)

#2 未启用 Pulsar 绕过 Journal 写入的异步本地持久性

本项测试中,我们在 Pulsar 和 Kafka 上使用了异步本地持久性保证,但未启用 Pulsar 绕过 Journal 写入。

下图 37 显示,追赶读对 Kafka 写入造成显著影响,但对 Pulsar 影响很小。Kafka 的 P99 发布延迟增加到 2-3 秒,而 Pulsar 的延迟则稳定在几毫秒到几十毫秒之间。

图37· 追赶读对 Pulsar 和 Kafka 发布延迟的影响(数据同步)

#3 同步本地持久性

本项测试中,我们在同等同步本地持久性保证下对 Kafka 和 Pulsar 进行了比较。

下图 38 显示,追赶读对 Kafka 写入造成显著影响,但对 Pulsar 影响很小。Kafka P99 发布延迟增加到约 1.2 至 1.4 秒,而 Pulsar 的延迟则稳定在几毫秒到几十毫秒之间。

图38· 追赶读对 Pulsar 和 Kafka 发布延迟的影响(无数据同步)

结论

基于基准测试结果,我们得出以下结论:

  • 纠正配置和调优错误后,Pulsar 与 Kafka 在 Confluent 有限测试用例中实现的端到端延迟基本一致。
  • 在同等持久性保证下,Pulsar 在模拟实际应用场景的工作负载上性能优于 Kafka。
  • 以上测试中,改变了持久性保证设置、订阅、分区和客户端数量,结果表明 Pulsar 在延迟和 I/O 隔离方面均明显优于 Kafka。
© StreamNative, Inc. 2022Apache, Apache Pulsar, Apache BookKeeper, Apache Flink, and associated open source project names are trademarks of the Apache Software Foundation.TermsPrivacy