三种使用Kafka的最佳实践方法 - antonmry


Apache Kafka于2011年初由LinkedIn开源。尽管存在所有最初的限制,但它还是取得了巨大的成功,并成为了流数据的事实上的标准。性能,重播事件的可能性以及独立的多个用户是其领先流媒体竞技场的一些功能。
但是,卡夫卡也因其学习困难和操作困难而著称。以我的经验,在过去几年中,这两个方面都得到了很大的改进,但是原始的陷阱仍然存在:

  • Kafka从一开始就为提高性能而创建,因此默认情况下,它不是为了可靠性,而是为了性能,以提高低延迟/吞吐量。
  • Kafka背后的主要思想之一是将部分责任推给生产者和消费者。这个简单的想法使卡夫卡拥有了传奇般的表现。但这使卡夫卡对客户而言变得更加复杂:您需要做出一些决策,它们将对经纪人和整个通道产生巨大影响。
  • Kafka可以用于许多不同的用例,这最终意味着需要针对每个用例进行调整……而且还有很多需要调整的地方。使用Kafka所需的大多数决策和知识都是基于经验,并通过Internet在博客文章和讲座中进行传播。更糟糕的是,一种模式对于用例可能是完全有效的,而对其他情况则完全是灾难。

 
1.小消息
卡夫卡不喜欢大消息。默认情况下,限制为1Mb。您可以在代理中修改message.max.bytes以允许更大的消息,但这通常不是一个好主意。它需要对客户端和代理进行微调,这将使整个集群的性能降低。不仅如此,您不能为特定主题更改此设置,也不能为整个群集更改此设置,这会使容量规划变得更加困难。
在Kafka中,一条消息的理想大小是1Kb。我有性能很好的管道,消息比这小得多。当它们很小时,没什么太大的关系。Kafka生产者将把它们放在一起并分批发送。经纪人broker将批量存储它们,而消费者将批量读取它们。您可以独立于消息大小(吞吐量的交易等待时间)配置批处理大小,因此小消息就可以,大消息就不能。
大消息的另一个问题是,如果您想在某个时候迁移到托管服务,它们可能不支持它们。案例: Confluent Cloud(6 Mb), Azure EventHub(1 Mb) or Google PubSub(10 Mb).
我不得不多次宣布这个坏消息,并应对开发人员的悲伤面孔。幸运的是,经过一些讨论,我们始终找到了无需修改message.max.bytes即可解决此问题的方法。让我们回顾三个不同的选项:
  1. 将消息分成几条消息:即使一开始并不容易看到,这几乎总是可能的。查看模式,看看如何将其拆分为具有各自意义的消息。在它们之间重复信息(通常是元数据)是完全可以的。正如我们之前提到的,Kafka将批量发送它们,并且几乎总是压缩它们(提示:不要在Kafka上使用E2E压缩几乎总是一个坏主意),因此重复副本不会对整体大小产生太大影响的批次。
  2. 将消息移到不同的存储中:当消息太大并且无法拆分(图像,PDF等)时,通常最好将它们发布为S3,然后将其存储在URI中,并将其发送到Kafka中信息。甚至有一些库允许自动执行此操作:当消息太大时,序列化程序将写入S3;当反序列化程序接收到URI时,反序列化程序将从S3下载有效负载。
  3. 使用Kafka以外的不同方法:几乎所有消息传递代理都存在大消息问题,但Kafka的下限较低。可以选择Apache Pulsar,它的默认情况下的最大消息量为10 Mb,它具有将其拆分为较小的消息并在需要时在生产者中重新加入的功能。这不是针对特定用例的解决方案,但是,如果您知道要处理很多大消息,那么选择一种或另一种技术可能是一个重要因素。

如果有任何效果,请增加message.max.bytes。这不是世界末日,但请注意,可能需要进行一些微调,这需要Kafka的专业知识。
 
小Toptic
卡夫卡的另一个相当成问题的是大Topic话题。这往往是有机发生的。您可以使用一个具有相同使用者的存在项,而不是为不同类型的信息创建一个新Topic主题。这种方法存在几个问题:
  1. 对数据的某些部分感兴趣的消费者必须阅读所有内容并进行过滤以选择所需的数据。那是非常低效的。有一些技巧可以避免对不需要的消息进行反序列化,但是使用者必须阅读它们并反正消耗网络带宽。
  2. 一个大话题通常意味着很多分区。Kafka的工作方式是:将一个主题划分为不同经纪人的分区。如果需要更高的吞吐量,则增加数量。很好,但是有一些警告:您不能减少分区的数量。另外,添加分区时,消费者会受到影响,并且会发生一些滞后。另外,Kafka必须完成一些与分区数成比例的协调。
  3. 大话题意味着大集群。稍后我们将介绍大型集群,但是在不同集群之间分配负载是很平常的。如果主题较小,则将主题移至其他群集很容易。如果没有,这可能是不可能的。
  4. Kafka中有一些操作需要创建该主题的新版本:通常减少分区数或在消息架构中引入重大更改。在这种情况下,您将需要一个V2主题。这是非常常见的情况,自动化是确保迁移过程顺利进行的关键。当您的主题较小时,此过程会更简单,因为受影响的消费者较少。

小topic主题也存在一些问题,例如,如果消费者需要阅读所有消息很麻烦,Kafka可以解决此问题:订阅主题列表非常容易。您还可以指定一个正则表达式模式,这样即使以后创建主题,也可以对其进行动态分配。
 
小集群
即使对于拥有最丰富卡夫卡经验的公司来说,大型集群也很难维护。您可以在此线程中看到许多推荐小型集群的最重要的公司,而Netflix撰写了一篇有关该集群的文章(Kafka部署策略部分)。
大型群集的另一个问题是在群集级别完成配置(message.max.bytes,auto.create.topics.enable(对于CDC用例),压缩/保留线程等),这些配置可能取决于用例能够针对特定负载对其进行优化很有趣。
小型集群的另一个好处是使升级更容易,这在Kafka中非常重要。该社区非常活跃,Kafka在过去几年中发展了很多。能够运行Kafka的最新稳定版本几乎是强制性的,以实现弹性并节省云成本。一个很好的例子就是Confluent Cloud,它仅支持最新版本的候选清单。如果使用它,则有时需要升级到较新的版本。
云中的小型集群特别方便。我知道一家公司(游戏)的流量高峰非常短。对于Kafka来说,这是有问题的,因为您无法轻松地增加/减少分区数。因此,对于这些情况,我们自动创建了一个具有更多资源的新集群,并将所有流量动态迁移到新集群。一旦峰已经过去,我们将以相反的顺序重复相同的操作。这不是很常见,但是可以很好地了解集群拆分后在云中可以做什么,它们易于管理,并且您可以控制生产者和消费者。
小型集群的问题之一是当您想要联接来自不同主题的数据时。当主题位于不同的集群中时,可能会非常复杂。因此,通常适合按业务域或负载的类型/要求划分集群,因此您无需在集群之间复制(过多)数据。