Push VS Pull

An initial question we considered is whether consumers should pull data from brokers or brokers should push data to the consumer. In this respect Kafka follows a more traditional design, shared by most messaging systems, where data is pushed to the broker from the producer and pulled from the broker by the consumer.

Kafka遵循传统设计,也是被大多数消息系统所采用的,即,producer push数据到broker,consumer从broker那里pull数据。

A push-based system has difficulty dealing with diverse consumers as the broker controls the rate at which data is transferred. The goal is generally for the consumer to be able to consume at the maximum possible rate; unfortunately, in a push system this means the consumer tends to be overwhelmed when its rate of consumption falls below the rate of production.

基于push的系统在面对不同的消费者的时候需要控制数据传输的速率这是很困难的,一般消费者都是以最大速率去消费的,不幸的是这对于push系统来说意味着当消费的速率低于生产的速率时消费者有崩溃的倾向。而基于pull的系统就有很好的属性,消费者可以简单的落后,并且在可能的时候迎头赶上。在消费者感觉快要崩溃的时候可以缓和一下,获取传输速率完全靠消费者机灵。

基于pull的系统的另一个优势在于broker可以将自己的数据批量的发送给消费者。而基于push的系统必须选择是立即发送请求还是累积更多的数据再发请求,而且发送以后它不知道消费者是否能很快的处理它。基于pull的系统就能够很好的解决这个问题,因为消费者总是拉取在当前日志的位置之后的所有可用的消息。

基于pull的系统有一个缺陷就是如果broker没有数据,消费者会一直循环等待,有效的繁忙的等待直到有数据到达。为了避免这个问题, 我们可以让消费者在请求的时候以“长轮询”的形式阻塞,直到有数据到达。

Consumer Position

大部分的消息系统在broker中维护关于消息是否已经被消费的元数据。因此,一个消息被分发给消费者以后broker可以理解处理或者等到消费者确认。

或许你还没有意识到让broker和consumer就消息是否已经被消息达成一致是一个很重要的问题。如果每次消息被分发出去以后broker就立即将这条消息标记为consumed,这个时候如果消费者处理消息失败了(可能是因为它宕机了或者请求超时了或者其它的原因),那么这条消息就丢失了。为了解决这个问题,许多消息系统增加一个确认特性,这就意味着在消息被发送以后只能将它们标记为sent而不是consumed,broker会等待来自消费者的确认,之后才会将这条消息标记为consumed。这个策略虽然解决了丢失消息的问题,但是又带来了新的问题。首先,如果消费者已经处理完消息,但是在它发送确认之前它失败了,那么这种情况下会导致消息被消费两次。第二个问题跟性能有关,现在broker对于每条消息必须维护多个状态(首先锁定它以至于它不会被分发第二次,然后永久的标记它为consumed以至于它肯能会被删除)。棘手的问题必须被处理,比如消息发送后没有确认。

Kafka handles this differently. Our topic is divided into a set of totally ordered partitions, each of which is consumed by exactly one consumer within each subscribing consumer group at any given time. This means that the position of a consumer in each partition is just a single integer, the offset of the next message to consume. This makes the state about what has been consumed very small, just one number for each partition. This state can be periodically checkpointed. This makes the equivalent of message acknowledgements very cheap.

Kafka对这些问题的处理不同,主题被划分为一系列有序的分区,在任意时刻,一个分区只能被订阅这个主题的每个消费者组中的一个消费者消费。这就意味着,消费者的位置在每个分区中仅仅是一个整数,这个整数就是即将要消费的下一个消息的offset(偏移量)。这使得标记关于消息是否已经被消费的状态变得很简单,每个分区仅仅一个数。这个状态可以周期性的被检查。这跟消息确认是等价的,而且也是非常廉价的。

消费者可以故意倒回到一个旧的offset去重新消费数据。当然,这一点违反了队列的公共契约,但事实上这是许多消费者的一个基本特性。例如,如果消费者的代码有bug,并且在一些消息被消费以后才发现,那么消费者可以重新消费这些消息以修复这个bug。

参考 http://kafka.apache.org/documentation/#design

Kafka Consumer的更多相关文章

  1. 【原创】Kafka Consumer多线程实例

    Kafka 0.9版本开始推出了Java版本的consumer,优化了coordinator的设计以及摆脱了对zookeeper的依赖.社区最近也在探讨正式用这套consumer API替换Scala ...

  2. Kafka设计解析(四)- Kafka Consumer设计解析

    本文转发自Jason’s Blog,原文链接 http://www.jasongj.com/2015/08/09/KafkaColumn4 摘要 本文主要介绍了Kafka High Level Con ...

  3. 【原创】kafka consumer源代码分析

    顾名思义,就是kafka的consumer api包. 一.ConsumerConfig.scala Kafka consumer的配置类,除了一些默认值常量及验证参数的方法之外,就是consumer ...

  4. Understanding Kafka Consumer Groups and Consumer Lag

    In this post, we will dive into the consumer side of this application ecosystem, which means looking ...

  5. Kafka consumer处理大消息数据问题

    案例分析 处理kafka consumer的程序的时候,发现如下错误: ERROR [2016-07-22 07:16:02,466] com.flow.kafka.consumer.main.Kaf ...

  6. 【原创】Kafka Consumer多线程实例续篇

    在上一篇<Kafka Consumer多线程实例>中我们讨论了KafkaConsumer多线程的两种写法:多KafkaConsumer多线程以及单KafkaConsumer多线程.在第二种 ...

  7. 读Kafka Consumer源码

    最近一直在关注阿里的一个开源项目:OpenMessaging OpenMessaging, which includes the establishment of industry guideline ...

  8. kafka consumer 配置详解

    1.Consumer Group 与 topic 订阅 每个Consumer 进程都会划归到一个逻辑的Consumer Group中,逻辑的订阅者是Consumer Group.所以一条message ...

  9. kafka consumer 0.8.2.1示例代码

    package test_kafka; import java.util.ArrayList; import java.util.HashMap; import java.util.List; imp ...

  10. Kafka consumer group位移0ffset重设

    本文阐述如何使用Kafka自带的kafka-consumer-groups.sh脚本随意设置消费者组(consumer group)的位移.需要特别强调的是, 这是0.11.0.0版本提供的新功能且只 ...

随机推荐

  1. [bzoj1223] [HNOI2002]Kathy函数

    首先由题解可得TAT,f(i)=i当且仅当i在二进制下为回文串. 那么问题就变成了1~n中有多少个二进制下的回文串. 把m转成2进制后就是正常的统计了= =. f[i]表示二进制下,有多少个i位的回文 ...

  2. ECharts 环形饼图 动态获取json数据

    ECharts  环形饼图 动态获取json数据 效果图如下: 一.html部分 <div id="secondPieChart" style="width:100 ...

  3. parseInt原来是这样用的

    今天在群里无意中看到了这样一个问题,突然发现不会,结果运行一看,懵逼了,不知道为什么???(结果是啥?自己去试试看) 现在我们还是先来复习一下parseInt()这个知识点吧! parseInt() ...

  4. dede表前缀不定时,查询表#@__archives

    $query = "SELECT arc.*,tp.typedir,tp.typename,               tp.isdefault,tp.defaultname,tp.nam ...

  5. channelartlist|频道文档:

    http://help.dedecms.com/v53/archives/tag/global/channelartlist/ {/dede:channelartlist} 参数说明: typeid ...

  6. Struts2与Ajax数据交互

    写在前面: ajax请求在项目中常常使用,今天就平时掌握的总结一下,关于使用ajax请求到Struts2中的action时,前台页面与后台action之间的数据传递交互问题. 这里我主要记录下自己所掌 ...

  7. H5+混合移动app应用开发——坑我太甚

    用了MUI之后,才发现,那坑比我想象之中的要多得多,有些是H5的坑,有些是plus的坑,接下来我一一来吐槽一番. IOS下面,上拉的时候,速度稍微快一点,表头自动隐藏,等你不拉的时候又自动显示 这种情 ...

  8. mysq开启慢查询

    1 将未建立索引的sql放到慢查询日志中 查看 log_queries_not_using_indexes 是否为on show variables like 'log%'; 将 log_querie ...

  9. 什么是bgp线路

    https://www.douban.com/note/319956581/ BGP(边界网关协议)主要用于互联网AS(自治系统)之间的互联,BGP的最主要功能在于控制路由的传播和选择最好的路由.中国 ...

  10. mysql超出最大连接数解决方法

    遇到mysql超出最大连接数,相信不少人第一反应就是查看mysql进程,看有没有慢查询,当然这个做法是完全正确的!但是很多时候真正的问题不在这里.今天有遇到同样的问题,一味查看mysql进程和慢查询日 ...