如何知道Apache Kafka是否适合您
在过去的几年中,Apache Kafka的功能和覆盖范围已经有了很大的提高。“财富”500强中有三分之一用于生产,其中包括十大全球银行中的七家,十大保险公司中的八家,以及美国十大电信公司中的九家。
本文快速浏览卡夫卡提供的核心功能。我将介绍很多示例来帮助您了解常见的使用模式。希望你会发现与你自己的工作流程有一定的关联,这样你就可以开始利用卡夫卡的力量。我们先看看卡夫卡提供的两个核心功能。
1.Kafka作为消息系统
消息广泛用于两种方式:
排队(SQS,celery等):排队消费者充当一个工作组。每条消息只会转到其中一个工作进程,从而有效地分配工作。
发布 - 订阅(SNS,PubNub等):订阅者通常彼此独立。每个用户都会得到每封邮件的副本。它就像一个通知系统。
这两种都是有用的范例。排队划分工作,对于容错和规模来说非常有用。发布 - 订阅允许多用户,这可以让你分离你的系统。Kafka的美妙之处在于它将排队和发布 - 订阅范例结合到一个强大的消息传递系统中。
我强烈建议阅读解释底层设计的文档,以及在主题,分区和消费者组的帮助下如何实现这种组合。使用RabbitMQ或SNS-SQS组合也可以实现此功能。
2.Kafka用于流处理
一旦你有一个健壮的,可扩展的消息系统,你所需要的只是一个简单的方法来处理消息流。Stream API提供了这一点。它是一个Java客户端库(现在也是Scala),它提供比生产者和消费者 API 更高级别的抽象。
它使得它易于执行:
无状态操作,如过滤和转换流消息
有状态的操作,如时间窗口上的连接和聚合
流API处理消息的序列化/反序列化,并维护有状态操作所需的状态。
示例
以下是Stream API示例,它可以读取输入流上的纯文本,计算每个单词的出现次数,并将计数写入输出流。
通过窗口化,很容易在一段时间范围内进行聚合,并跟踪当天的前N个单词。
// Serializers/deserializers (serde) for String and Long types
final Serde<String> stringSerde = Serdes.String();
final Serde<Long> longSerde = Serdes.Long();
// Construct a `KStream` from the input topic "streams-plaintext-input", where message values
// represent lines of text (for the sake of this example, we ignore whatever may be stored
// in the message keys).
KStream<String, String> textLines = builder.stream("streams-plaintext-input",
Consumed.with(stringSerde, stringSerde);
KTable<String, Long> wordCounts = textLines
// Split each text line, by whitespace, into words.
.flatMapValues(value -> Arrays.asList(value.toLowerCase().split("\W+")))
// Group the text words as message keys
.groupBy((key, value) -> value)
// Count the occurrences of each word (message key).
.count()
// Store the running counts as a changelog stream to the output topic.
wordCounts.toStream().to("streams-wordcount-output", Produced.with(Serdes.String(), Serdes.Long()));
Kafka的典型用例
想象一下,你运行一个旅游网站。酒店和航班的价格一直在变化。需要将系统的一些组件(价格警报,分析)告知这些更改。您将更改发布在Kafka主题上,并且需要通知的每个组件都充当订户。单个订户系统的所有节点形成单个消费者组。给定的消息仅发送给消费者组中的一个节点。通过这种方式,每个组件都获得消息的副本,并且每个组件内部的工作都得到有效分配。
可以通过Kafka跟踪和分析网站活动(网页浏览量,搜索或用户可能采取的其他行动)。事实上,这是卡夫卡在LinkedIn发明的原始用例。网站活动发布到每个活动类型有一个主题的中心主题。Feed可以实时处理,以深入了解用户参与,下架,页面流等等。
想象一下,您有来自GPS信标或智能手机设备的位置数据,并且您想要实时处理它以显示车辆路径,行驶距离等。传入的数据可以在Kafka主题上发布并使用Stream API进行处理。当您需要在特定时间段内提取和处理给定用户的所有位置数据时,使用窗口进行状态处理非常方便。
何时不使用Kafka
如果你不能或不想迁移到Java / Scala上与Kafka集群交谈的服务,那么你将错过Kafka Streams提供的所有更高级别的抽象。Streams API本质上是一个与Kafka集群交谈的客户端库。Kafka背后的公司Confluent目前专注于Java。流行的语言如Python 对于流式支持已经有了一个开放的问题,现在已经超过了1.5年。
如果您只需要一个任务队列,请考虑RabbitMQ。通过Kafka,每个分区只能由单个消费者使用。你必须在将任务放入队列时决定分区。因此,给定分区上的大量任务可能会导致饥饿,您无法做任何事情,因为添加消费者无助于此。
如果你每天只处理几千条消息,那么卡夫卡可能是过度杀伤。Kafka的确是为处理大规模流处理而建造的,所以如果你没有/预计规模,建立和维护它并不值得。