传统的消息队列在顺序保存消息到服务器时,如果有多个消费者从队列中读取消息,服务器会顺序发送消息。但是,尽管服务器是顺序发送消息的,但是消费者是异步接收消息的,因此消费者接收到的消息可能并不是顺序的,但消费者并不知道消息是乱序的。为避免这种情况,传统的消息队列通常只允许一个进程读取消息,这也就意味着消息的处理是单向的,而不是并行的。
Kafka在这方面有更好的处理方式,它通过在主题中使用分区完成了并行处理。Kafka既保证了顺序输出又实现了消费者之间的平衡。通过给主题分配分区,将消息分给同组内的消费者,确保每一分区内的消费者是唯一的,并且是顺序读取消息。由于是通过分区来实现多个消费者对象的负载均衡,所以同一消费者组的消费者是不能超过分区的。
Kafka仅仅实现了消息在一个分区内的排序,而不是同一主题不同分区内的排序。对于大多数应用而言,数据分区和分区内数据排序就足够了。如果你想要所有的消息都是顺序排列的,那就只能有一个分区,这意味着只能有一个消费者在一个消费者组内。这种情况下,消息的处理就不是并行的。
可靠性
消息会以生产者发送的顺序追加到主题的分区。例如,一个生产者发送同一个消息两次分别称为M1,M2,M1先发,那么M1将会有一个更小的偏移量,并且也会比M2早出现在日志中。
消费者以存储在日志中的顺序看见消息。
对于复制N倍的主题,即便N-1台服务器出错,都不会使已经提交到日志的消息丢失
使用场景
消息代理
Kafka可以替代一些传统的消息代理。消息代理有很多使用场景,比如与数据处理程序解耦,缓存未处理的消息等等。和大多数消息处理系统相比,Kafka有更好的吞吐量,内建的分区,复制和容错能力,这使得Kafka能够很好的处理大规模消息应用。
活动追踪
Kafka最初用来提供实时追踪网站用户行为的相关数据的能力,例如统计PV,UV等。
监控统计
Kafka经常被用来操作监控数据,比如从分布式的应用中汇总统计数据。
日志收集
我们的服务通常部署在多台计算机上,服务器的运行日志也会分散打在各个机器上。Kafka通常被用来从各个服务器上收集日志,然后统一打到HDFS或者其他离线存储系统,比如Facebook的Scribe在收集日志时就是用了Kafka。
流处理
很多用户完成原始数据的阶段性汇总,加工等处理后,将操作结果转换为新的topic写入Kafka来进行更深入的处理。 比如,文章推荐程序完首先是用爬虫从RSS中爬取用户订阅的文本内容,然后把这些内容发布到articles topic下。接下来的处理程序,将articles topic下的内容格式化后,发布到format topic下。最终的处理程序尝试将这些格式化的内容推荐给合适的用户。Storm和Samze是处理这种业务的流行框架。
事件采集
业务状态的变化被按照时间顺序记录下来,这种程序设计方式被成为事件采集。Kafka支持大规模的日志数据存储,这使得Kafka成为事件采集程序理想的后端模块。
相关阅读: