Kafka API很棒; 现在让我们快速

2021-02-24 21:27:30

这篇博客文章代表了几个月的工作和超过400个小时的实际基准测试,我们将Redpanda和最新的2.7 Kafka版本进行了比较。我们使用了Confluent在CNCF开放式消息传递基准测试中的推荐的生产设置和环境。

在开始之前,完整的实际结果以及完整的工作负载分布,饱和度,延迟和吞吐量位于此交互式博客文章的底部。

Kafka API已成为流工作负载的通用语言。开发人员喜欢生态系统,并且能够在一夜之间转换复杂的产品。就像Apache和Nginx有自己的HTTP实现一样,gccgo和Go编译器为语言指定了解析器,MySQL和Postgres实现了SQL,Redpanda和Kafka实现了Kafka API。 Redpanda旨在为现有的最先进系统的现有压倒性复杂性带来操作简便性。这体现在最低水平,不再需要在数据安全性和性能之间进行选择。

让我们清楚一点,在大数据世界中尾部延迟很重要的原因是因为Redpanda并不是孤立存在的。它通常位于您的Web服务器,数据库,内部微服务,数据湖等之间。Redpanda控制着如何,何时何地存储,传输,访问,变异和最终交付事物的信息流。我们之所以担心尾部延迟,是因为消息传递系统中的p99.99经常发生-这是交换消息的简单功能。随着使用Kafka API的系统之间的交互和消息的数量增加,单个用户操作或API调用受99.99thpercentile以上的延迟影响。

我们在下面介绍18个工作负载。两个系统的所有工作负载均将数据复制到3个节点,没有任何延迟(在仲裁系统中手动验证)。唯一的区别是Apache Kafka在内存内复制(使用页面缓存)中运行,并在每个消息后刷新。 Redpanda仅可在acks = all的安全模式下(每批后冲洗)运行。下面的基准与Alok Nikhil& Confluent的Vinoth Chandar使用相同的CNCF Open Messaging Benchmark套件将Pulsar和Kafka扩展速度为1.2GB / s进行了比较。

首先,我们注意到我们只能复制Confluent的前6个结果。对于其他三个工作负载,数据显示,在i3en.2xlarge实例上的AWS上,要实现300MB / s以上的持续网络吞吐量实际上是不可能的。有关详细说明,请参见最后的“基准附录”部分。我们还将默认的1分钟预热时间更改为30分钟,以解决虚拟机基准测试实践中的常见缺陷,并完全专注于稳定状态性能,然后将每个工作负载再运行60分钟,记录结果并重复步骤,以使每个系统都能最佳运行。也就是说,每次我们运行基准测试时,都要花54个小时以上才能完成。

对于所有工作负载,我们为客户端使用了两个m5n.8xlarge,具有32核,并具有25Gbps的保证网络吞吐量和128GB内存,以确保瓶颈在服务器端。基准测试使用了三个i3en.6xlarge 24核心实例,这些实例具有192GB内存,25Gbps保证网络连接和两个NVMe SSD设备。

我们注意到经过几百小时的基准测试,我们占用了Confluent的Kafka设置,以跟上较大的instancesto num.replica.fetchers = 16,message.max.bytes = 10485760,supplica.fetch.max.bytes = 10485760, num.threads = 16,num.io.threads = 16,log.flush.interval.messages = 1。否则,Redpanda和Kafka的Gapbetween将要大得多。这具有艰的效应,对于较低百分位,Kafka的延迟比使用一半的线程,以便使用指定的Github Repo指定的一半。

下面的所有延迟都是端到端P99.999延迟,16个Producers和16个消费者在一个主题上有100个分区。 EveryMessage代表1KB的数据。我们注意到,By和大Kafka是Ableto,除了几个与Acks = Allwhere Redpanda更好的工作负载之外。有意义的差异在延迟:每个系统都可以去。

在Kafka的内存复制中(页面缓存&没有显式刷新)vs. redpanda fsync() - 每批次后

我们已经说过这个adauseam:硬件是theplatform.modern硬件能够为您提供低延迟和没有数据档(fsync)。让我们谈谈大部分有意义的低级建筑差异,让我们在那里

在我们深入了解详细信息之前,我们鼓励您注册我们的Twitch Stream,我们将通过每一个索赔制作本文,并且很乐意回答您的问题。它会备注,emacs,你和问题。完美的。

当我们开始建立Redpanda时,主要的驱动因子是可理解的。上面的性能,我们想要一个简单的心理模型,它意味着在3次复制品中有2个,我们如何用筏结束 - 一种具有数学证明的协议&日志完整性和重点关注可用性,作为其指定目标的一部分。

但是,一旦您获得复制模型集,产品的其余部分都花在了可预测性上,以及大数据和amp;实时系统,这意味着可以理解,扁平的尾随延迟。它是快速的。这是不够的安全性。当尝试使用每天流的Terabytes时,您只需在网络分区,磁盘等的情况下的产品中断的方式中只需要预测,而且还要在性能如何降低作为函数饱和度的函数。这是在运行简单的系统的核心。

现代硬件让我们终于有好东西。它不再是您必须在安全性(无数据丢失)andspeed(低延迟)之间进行选择。此外,这种可预测性为产品发布提供了您准确的规划。作为用户,我了解如何运输硬件。我将执行一个“FIO`测试”,并有一个特定硬件可以做的事情的折磨。 RedPanda让您提供这些硬件饱和度号,并为您提供了一个合理的机会,预测开发新产品的成本如何。

页面缓存是Linux内核中的对象。它与全球锁定语义保持繁华。这是一种尝试和真实的,具有来自各种生产的启发式的易懂机制,该机制推动和将设计推向一个非常好的中间地面。如果你需要做io,那就不能成为一个糟糕的选择。但是,对于我们特种用例 - 日志 - 我们可以做得更好。我们一直到用户应用程序的解释,下一步需要多少数据,其中大多前进,更新频道,后台操作和高速缓存优先级的访问模式。

对我们来说,页面缓存引入了延迟和非法确定的iobehavior。例如,当加载Kafka Fetch请求的数据时,Thelinux内核将触发通用读取的启发式,AndCache它读取的字节,拍摄全局锁定,并更新indexes.redpanda不进行常规IO。它是一个日志,仅附加,具有Wellunderstood访问模式。我们将数据添加到终端文件并收缩写作背后的策略。当我们读取数据时,RedPanda读取InOrder,这意味着我们可以在理论上具有完美的读取前方和objerMaterialization,它位于PageCache等字节数组样式API之上。

更基本上,绕过内核的页面缓存允许我们对故障语义和尾部延迟进行遗嘱。 WeCan检测并测量IO的速率和延迟并相应地调整我们的缓冲池。我们可以对低记忆压力情况做出反应,并且了解我们的存储器足迹的整体视图。我们有可预测的是每个文件系统操作,该文件实际上可以影响正确性 - PostgreSQL团队与未检测到20年未被发现的FSYNC()错误所证明的。

通用启发式机构是一生的启发式聚合比编程师,几十年的生产系统经验,用于渗透到几乎每层内核的IO。此外,还有页面缓存,带有捆绑在自动调谐器中的RedPandacomes,RPK,将常规Linux框转换为设备:

通过设置Nomergesin / Sys / Block / *禁用IO的Linux Block-IO自动合并,禁用昂贵的检查,但对Redpanda确定型存储器占用期间,请讨价还价。

对I / O执行中断关联,使得最初派出请求的内核不足的核心。

这些设置在NVMe SSD设备中特别有用,该设备最多可以有64K队列,每个队列最多有64K插槽。但是,尽管这些设置确实可以提供10%到30%的改进,但是实质性的改进来自于我们的体系结构。

首先,我们的自适应分配在Linux内核(用于更新大小的全局操作)中分摊文件元数据争用。通过消除文件大小更新来减少元数据争用,当磁盘操作接近饱和时,Redpanda的拖尾延迟性能提高了20%以上。与其在每次写入文件时都改变全局对象,不如说让内核给我们更多的数据块并将它们与特定的文件描述符相关联,因为我们知道我们将要写入它们。因此,现在当我们将数据追加到日志中时,没有全局元数据更新。

if(next_committed_offset()+ n> _fallocation_offset){返回do_next_adaptive_fallocation()。然后([this,buf,n] {return do_append(buf,n);}); }

如我们之前所写,我们的日志段编写器使用直接内存访问(DMA),这意味着我们根据文件系统的布局手动对齐内存,并花费了大量的精力来确保尽可能少地刷新到实际的物理设备,并尝试花费尽可能多的时间进行dma_write()来减少序列化点。

当流从append_entries()Raft RPC读取流时,我们使用文件系统alignedbuffers的线程本地缓冲池从分配的内存池中连续调度当前缓冲区。这是与页面缓存的根本区别,不仅因为我们根本不使用它,还因为我们可以精确控制在线程本地池上分配了多少内存,并将其用作所有打开文件句柄之间的共享资源。这意味着在出现尖峰的情况下,允许最苛刻的分区借用最多数量的缓冲区。

这项技术的真正灵感来自于指令流水线技术。对于我们这些凡人,硬件专家已经弄清楚了,在可能的情况下,我们从他们的书中借书了几页:)在为Raft解码一组操作时,我们人为地将写操作反跳了几毫秒。 。这使我们可以跳过许多fdatasync()操作,不仅节省了使用较少的IOP的时间,而且还避免了在文件上引入全局障碍-刷新防止在后台进行任何其他写操作,因为fsync()是同步点。

管道,批处理,后写,无序执行,内核调整是Redpanda中每核心线程架构的情况下实质性性能提升的基础。我们甚至还没有在磁盘上深入研究过预读策略,后写缓冲,分段缓冲区解析,整数解码,流压缩器,对缓存友好的查找结构的影响等。

我们已经简要介绍了利用Redpanda使用的现代硬件的基本技术,并且,如果您到目前为止已经做到这一点,则可能希望加入我们的实时Twitch流中,我们将通过这些基准测试。如果您想进行实时聊天,请加入我们的团队,打个招呼。

我们凭经验显示,在AWS中的i3en.2xlargeinstances上无法交付超过持续负载300MB / s的第3个工作负载。我们在原始i3en.2xlarge实例上运行了4次不同的500MB / s和1GB / s工作负载,这些实例是原始基准测试集指定的,而原始设置是由Confluent产生的,因此我们无法持续产生300MB / s以上的速度。不可能由于任何软件限制而无法达到高于300MB / s的稳定状态,而是因为在这些实例类型上基础AWS架构将您的速度限制在300MB / s左右。

我们增加了工作负载基准测试时间,因为在使用Kafka进行30分钟的预热后,我们无法获得延迟稳定性,并且我们仅想展示两个系统的稳态性能。

对于较小的测试持续时间,我们表明您可以达到原始基准所规定的1GB /吞吐量,并且急剧下降到300MB / s。

此外,正如在引言部分中提到的那样,我们无法使用默认数量的IO线程来饱和更高的盒子(8)。我们使用8个线程将这些基准测试运行了100个小时,我们无法在1GB / s和1.25GB / s的吞吐量下达到饱和。我们不得不将线程数增加到16个,这导致Kafka的平均延迟有所增加,但是我们最终设法使Kafka在大多数情况下使硬件饱和以提高吞吐量。请参阅下面的交互式图表。

开放消息基准的最后一个重大变化是将消费者和生产者的数量增加到16,这在技术上是原始数量4的四倍。否则,我们将无法可靠地产生和消费来自基准的足够数据。 16是不可思议的数字,它使我们能够在客户端获得稳定的性能。