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. bzoj4332;vijos1955:JSOI2012 分零食

    描述 这里是欢乐的进香河,这里是欢乐的幼儿园. 今天是2月14日,星期二.在这个特殊的日子里,老师带着同学们欢乐地跳着,笑着.校长从幼儿园旁边的小吃店买了大量的零食决定分给同学们.听到这个消息,所有同 ...

  2. 用gcc编译c语言程序以及其编译过程

    对于初学c语言编程的我们来说,学会如何使用gcc编译器工具,对理解c语言的执行过程,加深对c语言的理解很重要!!! 1.预编译 --> 2.编译 --> 3.汇编 --> 4.链接- ...

  3. Kafka监控安装

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  4. 4层板的pcb创建

    四层板的制作可以在原先的二层板上增加层,(软件为AD17)方法如下: 一.单击Design->Layer Stack Manager菜单(快捷键为DK),将弹出以下的界面: 二,选择上图中的Ad ...

  5. [国嵌攻略][160][SPI驱动程序设计]

    SPI Flash驱动 1.打开/drivers/mtd/devices/m25p80.c驱动文件.找到初始化m25p80_init函数,其中通过spi_register_driver来注册spi设备 ...

  6. docker运行dubbo-admin

    一:简介 dubbo-admin是dubbo框架的管理平台. 二: 创建继续镜像 Dockerfile FROM fangjipu/jdk8:8 RUN yum -y install epel-rel ...

  7. 从零开始学习前端JAVASCRIPT — 4、JavaScript基础Math和Date对象的介绍

    Math对象的介绍 1:Math对象 Math 对象用于执行数学任务.并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math().您无需创建它,通过把 Math 作为对象使用就 ...

  8. 如何完成域名和ip地址的绑定

    首先,我们要知道什么是域名绑定,所谓域名绑定就是是指已选定的域名与服务器主机的空间绑定,实在是在域名注册查询上设置或者WEB服务器上设置,使一个域名被指导向一特定空间,从而使访问者访问你的域名的时候就 ...

  9. ios 继承关系图

  10. Android带有粘性头部的ScrollView

    前言,一天在点外卖的时候,注意到饿了么列表页的滑动效果不错,但是觉得其中的手势滑动还是挺复杂的,正好又碰到了在熟悉Touch事件的理解当中,所以就抽空对着饿了么的列表页面尝试写写这个效果 1.先贴一个 ...