提交新活动

谢谢!您的提交已收到!
糟糕!提交表单时出错。

提交新闻报道

谢谢!您的提交已收到!
糟糕!提交表单时出错。

订阅新闻邮件

谢谢!您的提交已收到!
糟糕!提交表单时出错。
2017年10月10日

关于Python中Kafka的说明

作者

摘要

我最近调查了Kafka的Python库的现状。这篇博文包含了我的发现。

PyKafka 和 confluent-kafka 都有成熟的实现,并由投入的公司维护。Confluent-kafka 通常更快,而 PyKafka 在 Python 可用性方面可以说设计和文档更好。

现在两者都有 Conda 包可用。我希望扩展其中一个或两个,以支持使用 Tornado 的异步工作负载。

免责声明:我不是该领域的专家。我与这些项目没有任何紧密联系。这是一份基于我过去几周经验的报告。我不鼓励任何人从这项工作中得出结论。我鼓励大家自行研究。

引言

Apache Kafka 是流式架构中常见的数据系统。它管理字节消息的滚动缓冲区,并提供一种可扩展的机制来实时发布或订阅这些缓冲区。虽然 Kafka 最初设计用于 JVM 领域,但它只管理字节的事实使其易于从 C/C++ 和 Python 等原生代码系统访问。

Python 选项

目前 Python 中有三种独立的 Kafka 实现,其中两种可以选择性地由 C 实现 librdkafka 提供支持以提高速度

  • kafka-python:第一个出现,是一个纯 Python Kafka 客户端,文档完善,API 与原始 Java API 相当一致。该实现是 GitHub 上标星最多的,拥有最活跃的开发团队(按提交者数量计算),但也缺乏与快速 C 库的连接。我承认,正因为如此,我没有花足够的时间在这个项目上对其进行充分评价。
  • PyKafka:按时间顺序是第二个实现。该库由 Parse.ly 维护,Parse.ly 是一家广泛使用流系统和 Python 的网络分析公司。PyKafka 的 API 更具创意,旨在遵循常见的 Python 习语而非 Java API。PyKafka 既有纯 Python 实现,也连接到低级 librdkafka C 库以提高性能。
  • Confluent-kafka:按时间顺序是最后一个实现。它由 Confluent 维护,Confluent 是主要支持和维护 Kafka 的营利性公司。这个库速度最快,但从 Python 的角度来看可访问性也最低。该实现用 CPython 扩展编写,文档很少。但是,如果您熟悉 Java API,那么这种体验是完全一致的,因此文档可能足够了。

性能

Confluent-kafka 的消息消费带宽比 PyKafka 高约 50%,消息生产带宽高约 3 倍,两者都明显高于 kafka-python。这些数字我引用自这篇博文,其中提供了对这三个库的基准测试。主要的数值结果如下:

注意:值得注意的是,这篇博文是在处理大约 100 字节的小消息。我希望当消息大小适中时,Kafka 的性能会更好(更接近网络带宽)。

生产者吞吐量

时间(秒) MB/秒 消息/秒 confluent_kafka_producer 5.4 17 183000 pykafka_producer_rdkafka 16 6.1 64000 pykafka_producer 57 1.7 17000 python_kafka_producer 68 1.4 15000

消费者吞吐量

时间(秒) MB/秒 消息/秒 confluent_kafka_consumer 3.8 25 261000 pykafka_consumer_rdkafka 6.1 17 164000 pykafka_consumer 29 3.2 34000 python_kafka_consumer 26 3.6 38000

注意:我在 parsely/pykafka #559 上发现了这篇文章,其中对这三个库有很好的讨论。

我在这些情况下对 PyKafka 进行了性能分析,看来这些代码路径尚未优化。我预计适度的努力可以显著缩小差距。这种差异似乎更多是由于缺乏兴趣,而不是任何硬性的设计限制。

目前尚不清楚这些速度有多关键。据 Parse.ly 的 PyKafka 维护者称,他们实际上并未在其内部流水线中开启 librdkafka 优化,而是使用了慢速的纯 Python 实现,这对于一般用途来说显然已经足够快了。将消息从 Kafka 中取出并不是他们的瓶颈。可能是这些 250,000 条消息/秒的限制在大多数应用中并不重要。我怀疑这在批量分析工作负载中比在线应用中更重要。

Pythonic API 对比 Java API

我花了点时间才让 confluent-kafka 工作起来。不清楚需要向构造函数传递什么信息来连接到 Kafka,当我提供错误信息时,没有收到任何错误提示。Docstrings 和文档都很少。相比之下,PyKafka 的 API 和错误消息很快引导我走向正确行为,我一分钟内就启动并运行了。

然而,我坚持使用了 confluent-kafka,找到了正确的Java 文档,最终还是让它运行起来了。一旦成功,一切都水到渠成,我能够轻松地使用 Confluent-kafka 构建简单又快速的应用程序。

开发体验

我想为其中一个或两个库添加异步支持,以便它们能够以非阻塞方式读写数据,并与 Tornado 或 Asyncio 等其他异步系统良好协作。我已经在 GitHub 上开始调查这两个库。

开发者

这两个库都有一个响应迅速的维护者,他们的时间由母公司资助。这两位维护者似乎每天都很活跃,并处理外部开发者的贡献。

这两个库都很活跃,常见的模式是由一个主要开发者合并许多不太活跃的开发者的工作。过去六个月的提交分布看起来相似

confluent-kafka-python$ git shortlog -ns --since "six months ago"
38 Magnus Edenhill
5 Christos Trochalakis
4 Ewen Cheslack-Postava
1 Simon Wahlgren

pykafka$ git shortlog -ns --since "six months ago"
52 Emmett Butler
23 Emmett J. Butler
20 Marc-Antoine Parent
18 Tanay Soni
5 messense
1 Erik Stephens
1 Jeff Widman
1 Prateek Shrivastava
1 aleatha
1 zpcui

代码库

关于代码库,我发现出于几个原因,PyKafka 更容易修改:

  1. PyKafka 大部分是用 Python 编写的,而不是 C 扩展,因此对更广泛的开发者基础更易于访问。我发现 Python C 扩展使用起来并不愉快,即使你熟悉 C 语言。
  2. PyKafka 似乎经过了更广泛的测试。PyKafka 实际上会启动一个本地 Kafka 实例来执行全面的集成测试,而 Confluent-kafka 似乎只测试 API,而没有真正针对实际的 Kafka 实例运行。
  3. 顺便说一句,PyKafka 的维护者对 Tornado 的一个问题快速做出了回应。Confluent-kafka 的维护者仍然没有回复关于现有 Tornado 问题的评论,尽管该评论包含了更多内容(一个可工作的原型)。

需要说明的是,任何维护者都没有义务回答我在 GitHub 上的问题。他们可能正忙于与他们特定职责更相关的事情。

Conda 包

我已在 conda-forge 上提交/更新了这两个软件包的 recipes。您可以按如下方式安装它们:

conda install -c conda-forge pykafka # Linux, Mac, Windows
conda install -c conda-forge python-confluent-kafka # Linux, Mac

在这两种情况下,它们都针对快速的 librdkafka C 库构建(Windows 除外),并且也安装了该库。

未来计划

我最近开始为Dask 开发流系统和流水线,所以我可能会继续调查这个领域。我仍然在这两种实现之间犹豫不决。它们都有很强的理由被使用。

从文化上讲,我更喜欢 Parse.ly 的 PyKafka 库。他们显然是为 Python 用户编写的 Python 开发者。然而,这里使用非 Pythonic 系统的成本并不高(Kafka 的 API 很小),而且 Confluent 的利益与长期投资 Kafka 更为一致,而不是 Parse.ly。