Kafka 消费者及消费者分区策略
消费方式:
consumer 采用 pull(拉)模式从 broker 中读取数据。
push(推)模式很难适应消费速率不同的消费者,因为消息发送速率是由 broker 决定的。
它的目标是尽可能以最快速度传递消息,但是这样很容易造成 consumer 来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。而 pull 模式则可以根据 consumer 的消费能力以适 当的速率消费消息。
pull 模式不足之处是,如果 kafka 没有数据,消费者可能会陷入循环中,一直返回空数 据。针对这一点,Kafka 的消费者在消费数据时会传入一个时长参数 timeout,如果当前没有 数据可供消费,consumer 会等待一段时间之后再返回,这段时长即为 timeout。
一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及 到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。
Kafka 有三种分配策略,
RoundRobinAssignor分配策略
RangeAssignor(默认)
StickyAssignor分配策略
一、 RoundRobinAssignor:
第一种例子 所有分区是一个主题

0-6一共7个分区,轮询给消费者组种的消费者消费。
第二个例子 消费者消费多个主题

例如T1三个分区,T2主题也有3个分区,我们的消费者组里有2个消费者。2个消费者都订阅了主题T1\T2, RoundRobin中 会把两个主题中当作一个整体, 将分区对象(TopicAndPartition)的hash值排个序,分别给2个消费者。
但是这种策略存在问题:

如果,同一个消费者组中的A、B两个消费者,A订阅T1、T2; B订阅T2、T3,那么会把T1\T2\T3当作一个整体,就会导致B未订阅T1也会收到T1的分区;或者同一个消费者组 A订阅T1,B订阅T2,也有可能导致A消费T2....会有问题。所以kafka中默认的消费分区策略是range策略。
二、RangeAssignor:先看订阅的消费者,再看组。
7/3 = 2;第一个给三个,后面每个给两个。
存在的问题:可能会导致不均衡。因为range分区策略是按主题来划分。
例如:一个消费者组中A、B两个消费者,订阅了主题T1和T2. range是按主题来分别分区的。那么A消费T1的0,1分区,消费T2的0 1分区,随着主题增多,这里消费者之间消费的分区数将不均衡。
再来看一个例子:

A、B消费者属于同一个消费者组,C是另一个消费者组。A、B订阅了T1主题,B订阅了T2主题。C订阅了T1主题:
如果是RoundRobin 分区策略,把T1、T2的6个对象作为一个整体,往A\B分组发,可能导致A收到T2主题的数据;
所以要用range分区策略:range分区要按主题划分,C单独消费T1; T1的0、1分区给A , 2分区给B;
对于T2主题,按主题划分需要先看是谁订阅了这个主题,然后才考虑组。
消费者分区策略触发执行时机:
当消费者数量变化时:例如启动消费者时,或者添加或者减少消费者个数。
当消费者组里的消费者个数发生变化,都要重新分配分区。
三、StickyAssignor分配策略
Kafka从0.11.x版本开始引入这种分配策略,它主要有两个目的:
1、分区的分配要尽可能的均匀;
2、分区的分配尽可能的与上次分配的保持相同。
当两者发生冲突时,第一个目标优先于第二个目标
假设消费组内有3个消费者:C0、C1和C2,它们都订阅了4个主题:t0、t1、t2、t3,并且每个主题有2个分区,也就是说整个消费组订阅了t0p0、t0p1、t1p0、t1p1、t2p0、t2p1、t3p0、t3p1这8个分区。最终的分配结果如下:
消费者C0:t0p0、t1p1、t3p0
消费者C1:t0p1、t2p0、t3p1
消费者C2:t1p0、t2p1
这样初看上去似乎与采用RoundRobinAssignor策略所分配的结果相同,但事实是否真的如此呢?再假设此时消费者C1脱离了消费组,那么消费组就会执行再平衡操作,进而消费分区会重新分配。
如果采用RoundRobinAssignor策略,那么此时的分配结果如下:
消费者C0:t0p0、t1p0、t2p0、t3p0
消费者C2:t0p1、t1p1、t2p1、t3p1
如分配结果所示,RoundRobinAssignor策略会按照消费者C0和C2进行重新轮询分配。而如果此时使用的是StickyAssignor策略,那么分配结果为:
消费者C0:t0p0、t1p1、t3p0、t2p0
消费者C2:t1p0、t2p1、t0p1、t3p1
可以看到分配结果中保留了上一次分配中对于消费者C0和C2的所有分配结果,并将原来消费者C1的“负担”分配给了剩余的两个消费者C0和C2,最终C0和C2的分配还保持了均衡。
如果发生分区重分配,那么对于同一个分区而言有可能之前的消费者和新指派的消费者不是同一个,对于之前消费者进行到一半的处理还要在新指派的消费者中再次复现一遍,这显然很浪费系统资源。StickyAssignor策略如同其名称中的“sticky”一样,让分配策略具备一定的“粘性”,尽可能地让前后两次分配相同,进而减少系统资源的损耗以及其它异常情况的发生。
Kafka 消费者及消费者分区策略的更多相关文章
- kafka的topic和分区策略——log entry和消息id索引文件
Topic在逻辑上可以被认为是一个在的queue,每条消费都必须指定它的topic,可以简单理解为必须指明把这条消息放进哪个queue里. 为了使得Kafka的吞吐率可以水平扩展,物理上把topic分 ...
- kafka Poll轮询机制与消费者组的重平衡分区策略剖析
注意本文采用最新版本进行Kafka的内核原理剖析,新版本每一个Consumer通过独立的线程,来管理多个Socket连接,即同时与多个broker通信实现消息的并行读取.这就是新版的技术革新.类似于L ...
- Kafka 生产者、消费者与分区的关系
背景 最近和海康整数据对接, 需要将海康产生的结构化数据拿过来做二次识别. 基本的流程: 海康大数据 --> kafka server --> 平台 Kafka 的 topic 正常过车 ...
- Kafka 消费组消费者分配策略
body { margin: 0 auto; font: 13px / 1 Helvetica, Arial, sans-serif; color: rgba(68, 68, 68, 1); padd ...
- Apache Kafka 0.9消费者客户端
当Kafka最初创建时,它与Scala生产者和消费者客户端一起运送.随着时间的推移,我们开始意识到这些API的许多限制.例如,我们有一个“高级”消费者API,它支持消费者组并处理故障转移,但不支持许多 ...
- kafka 服务端消费者和生产者的配置
在kafka的安装目录下,config目录下有个名字叫做producer.properties的配置文件 #指定kafka节点列表,用于获取metadata,不必全部指定 #需要kafka的服务器地址 ...
- kafka学习(三)kafka生产者,消费者详解
文章更新时间:2020/06/14 一.生产者 当我们发送消息之前,先问几个问题:每条消息都是很关键且不能容忍丢失么?偶尔重复消息可以么?我们关注的是消息延迟还是写入消息的吞吐量? 举个例子,有一个信 ...
- Kafka技术内幕 读书笔记之(四) 新消费者——新消费者客户端(二)
消费者拉取消息 消费者创建拉取请求的准备工作,和生产者创建生产请求的准备工作类似,它们都必须和分区的主副本交互.一个生产者写入的分区和消费者分配的分区都可能有多个,同时多个分区的主副本有可能在同一个节 ...
- kafka生产者和消费者流程
前言 根据源码分析kafka java客户端的生产者和消费者的流程. 基于zookeeper的旧消费者 kafka消费者从消费数据到关闭经历的流程. 由于3个核心线程 基于zookeeper的连接器监 ...
随机推荐
- Linux最常用的命令大全
Linux最常用的命令大全 按功能索引 目录处理命令 ls mkdir pwd cd rmdir cp mv rm 文件处理命令 touch cat tac more less head tail l ...
- 物联网wifi模块
物联网wifi模块 物联网wifi模块 是上海卓岚推出的MQTT+JSON转Modbus物联网WiFi核心模块.支持以MQTT的方式连接云端服务器,支持可以界面话配置,自主采集Modbus仪表/645 ...
- 联赛%你测试10T2:漫无止境的八月
题意: 思路: 有几个特殊的性质: 在不考虑q里面的单点修改,我们先只判断一个序列是否Yes. 我们注意到每次操作都是对一个长度为k的区间进行区间加减1的操作,所以我们如果将序列里面的数按%k分组,把 ...
- 如何使用懒加载 - umi
.umirc.js文件 plugins: [ dynamicImport: true,
- JetBrains-CLion永久激活教程
前言 JetBrains Clion 是一款专为 C/C++ 开发所设计的跨平台 IDE.本文适用 JetBrains CLion v2019.3/3.1/3.2/3.3 永久激活,附破解补丁和激活码 ...
- 【Azure Redis 缓存 Azure Cache For Redis】Redis出现 java.net.SocketTimeoutException: Read timed out 异常
问题描述 在使用Azure Redis时,遇见Read Timed out异常, Redis的客户端使用的时jedis.问题发生时,执行redis部分指令出错,大部分get指令,set指令能正常执行. ...
- Unity实现代码控制音频播放
前言 很久没说过Unity了,现在说一下Unity用代码控制音频播放 准备工作 1.需要播放的音频 2.给需要加声音的对象加Audio Source组件 3.新建Play脚本,并绑定需要播放声音的对象 ...
- 51node1256 乘法匿元(扩展欧几里得)
#include<iostream> using namespace std; int gcd(int a,int b,int &x,int &y){ if (b==0){ ...
- deploy.php
<?php namespace Deployer; require 'recipe/common.php'; // Project name set('application', 'tp_web ...
- Qlik Sense学习笔记之Mashup开发(二)
date: 2019-01-26 11:28:07 updated: 2019-01-26 11:28:07 Qlik Sense学习笔记之Mashup开发(二) 1.Mobile SPA UI Fr ...