kafka高级特性及常见问题调优

  • 一、kafka高级特性
    • 1.1 producer发布消息机制
    • 1.2 Controller及partition选举机制
      • 1.2.1 Controller选举机制(zk控制)
      • 1.2.2 partition选举Leader机制
    • 1.3 Rebalance再平衡机制
      • 1.3.1 rebalance的前提
      • 1.3.2 什么情况下会发生rebalance
      • 1.3.3 Rebalance的过程
      • 1.3.4 Rebalance分配策略
    • 1.4 日志存储
    • 1.5 分区数如何选择
  • 二、kafka常见问题及调优
    • 2.1 kafka启动慢及消费者重新订阅慢
      • 2.1.1 kafka重启慢问题
      • 2.1.2 kafka消费者重启后重新订阅很慢
    • 2.2 kafka消息顺序性分析
    • 2.3 kafka如何保证不丢消息
    • 2.4 kafka能否保证消息幂等性
    • 2.4 kafka高性能的原因
  • 三、kafka集群的CAP问题
    • 3.1 一致性
      • 3.1.1 数据写一致性控制
      • 3.1.2 数据读一致性控制
    • 3.2 可用性
    • 3.3 分区扩展性

一、kafka高级特性

1.1 producer发布消息机制

  • 消息写入方式
    producer采用push模式将消息发送到broker,消息将被顺序写入对应的partition中,因为顺序写的极高,保证了kafka的吞吐效率。
  • 消息路由机制
    producer发消息到时,因为在多分区中只能写入唯一分区,所以消息写入分区号是需要计算的。

    • 指定分区号,则直接使用该分区

      public ProducerRecord(String topic, Integer partition, K key, V value)
      
    • 未指定分区,指定key[hash取模指定分区]
      public ProducerRecord(String topic, K key, V value)
      //对当前key进行hash,取模分区数
      Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
      
    • 分区号及key均未指定[RoundRobinPartitioner 轮询发送指定分区]
      public ProducerRecord(String topic, V value)
      //轮询RoundRobin
      int nextValue = nextValue(topic);
      List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
      if (!availablePartitions.isEmpty()) {int part = Utils.toPositive(nextValue) % availablePartitions.size();return availablePartitions.get(part).partition();
      } else {// no partitions are available, give a non-available partitionreturn Utils.toPositive(nextValue) % numPartitions;
      }
      
  • 消息写入过程

1.2 Controller及partition选举机制

1.2.1 Controller选举机制(zk控制)

kafka集群启动时,所有broker向zookeeper发送创建**/Controller临时节点的请求,由zookeeper来保证只有1个broker节点能创建成功,该broker则当选为kafka集群中的Controller,负责管理集群分区和副本状态信息。
当controller节点的broker宕机,则zookeeper中的
/Controller**临时节点消失,所有存活的broker将再次竞争创建临时节点,由zookeeper保证唯一的新broker成为Controller。

具备控制器身份的broker需要比其他普通的broker多一份职责,负责监听整个集群所有分区和副本的状态。具体细节如下:

  • 监听broker相关的变化。为Zookeeper中的/brokers/ids/节点添加BrokerChangeListener,用来处理broker增减的变化。

  • 监听topic相关的变化。为Zookeeper中的/brokers/topics节点添加TopicChangeListener,用来处理topic增减的变化;为Zookeeper中的/admin/delete_topics节点添加TopicDeletionListener,用来处理删除topic的动作。

  • 从Zookeeper中读取获取当前所有与topic、partition以及broker有关的信息并进行相应的管理。对于所有topic
    所对应的Zookeeper中的/brokers/topics/[topic]节点添加PartitionModificationsListener,用来监听topic中的分区分配变化。

  • 更新集群的元数据信息,同步到其他普通的broker节点中。

1.2.2 partition选举Leader机制

  • unclean.leader.election.enable=false 不选非Isr集合中的broker
    选择Isr集合中,第一个broker作为leader。(第一个broker最先放进ISR列表,可能是同步数据最多的副本)
  • unclean.leader.election.enable=true 如果Isr列表为空,将选择AR中可用的broker作为partition的lerder

副本进入ISR列表有两个条件:

  • 副本节点不能产生分区,必须能与zookeeper保持会话以及跟leader副本网络连通
  • 副本能复制leader上的所有写操作,并且不能落后太多。(与leader副本同步滞后的副本,是由
    replica.lag.time.max.ms 配置决定的,超过这个时间都没有跟leader同步过的一次的副本会被移出ISR列表)

1.3 Rebalance再平衡机制

1.3.1 rebalance的前提

消费者通过subscribe不指定分区消费的情况下会发生rebalance,assign这种指定分区消费的方式则不会再平衡。

1.3.2 什么情况下会发生rebalance

  • 消费者组的consumer数量发生增减(重启某台消费者服务器时势必也会造成rebalance)
  • 动态给topic增加分区
  • 消费者组订阅了更多的topic

1.3.3 Rebalance的过程

  • 第一阶段:选择组协调器(选小组长)
  • 第二阶段:加入消费组Join Group
  • 第三阶段:Sync Group

1.3.4 Rebalance分配策略

rebalance共有3中再平衡策略:range、round-robin、sticky

  • range(范围分配) 假设有10个分区,消费者组内有3个消费者,则:

    消费者0被分配:partition-0、partition-1、partition-2、partition-3

    消费者1被分配:partition-4、partition-5、partition-6

    消费者2被分配:partition-7、partition-8、partition-9

  • round-robin(轮询分配) 假设有9个分区,消费者组内有3个消费者,则:

    消费者0被分配:partition-0、partition-3、partition-6

    消费者1被分配:partition-1、partition-4、partition-7

    消费者2被分配:partition-2、partition-5、partition-8

  • sticky(稳态分配)

    sticky与round-robin的分配方案比较类似,但显著的区别时,sticky尽可能保证本次分配与上次相同。

    即原有分配方案,尽可能不变。

    sticky发生rebalance的两个原则:

    • 1)分区分配尽可能均匀
    • 2)再平衡尽可能与上次保持相同

1.4 日志存储

kafka消息存储在指定的log.dir目录下,topic对应的日志信息以Topic+分区号命名。

  • 为避免日志文件过大,kafka为.log文件指定分段大小,以避免文件过大影响读写效率

    单个日志分段大小

    log.segment.bytes: The maximum size of a single log file

    Default: 1073741824 = 1GB

  • 存储文件消息内容的文件.log文件

  • 为提高查询效率,.log文件的内容以每次4K(可配置)的offset作为索引值记录到.index文件中。存储索引offset的文件,可以快速定位消息的offset进而查找到.log真是消息内容的位置。

  • .timeindex索引文件,同样在.log文件中每次以4K发送一次来到.timeindex中。

1.5 分区数如何选择

bin/kafka-producer-perf-test.sh --topic my_local_topic --num-records 1000000 --record-size 1024 --throughput -1 --producer-props bootstrap.server=192.168.149.128:9092 acks=1

二、kafka常见问题及调优

2.1 kafka启动慢及消费者重新订阅慢

2.1.1 kafka重启慢问题

  • kafka-server-start.sh 修改默认初始化堆内存及最大堆内存
#原值
if [ "x$KAFKA_HEAP_OPTS" = "x" ]; thenexport KAFKA_HEAP_OPTS="-Xmx1G -Xms1G"
fi
#根据物理内存情况32G内存可置为16G
export KAFKA_HEAP_OPTS="‐Xmx16G ‐Xms16G ‐Xmn10G ‐XX:MetaspaceSize=256M ‐XX:+UseG1GC ‐XX:MaxGCPauseMillis=50 ‐XX:G1He apRegionSize=16M"
#最大STW50ms,使用G1垃圾回收器,单元格大小16M,元空间256M,初始化内存16G.最大内存16G,年轻代10G
  • 修改启动实例或关闭实例时梳理日志文件线程数
    在启动kafka时,需要后台线程将log.dir目录中topic的分区segment log读取到内核空间,当partition分区中的数据很多(或许日志删除hour过大,保留日志量很大),后台默认的num.recovery.threads.per.data=1将忙不过来,可以试着将该线程数放大

2.1.2 kafka消费者重启后重新订阅很慢

当有消费者宕机或重启,这是生产中非常常见的状态,将导致coordinator认为分区与消费者的对应关系发生变化,需要重新平衡消费者于分区关系。

  • session.timeout.ms 根据服务需求,可大可小,当该值更小时,更容易触发rebalance,当该值更大时,可能消费者已宕机而broker未发现。
  • max.poll.interval.ms 如果消费者处理消息的时间,超过该设置值,将视为消费者处理能力差,或被踢出ConsumerGroup
  • rebalance策略,可以选择sticky以减少已有稳定分区的重新分配。

2.2 kafka消息顺序性分析

能否保证所有消息有序?不能,只能保证分区内有序(局部有序)

2.3 kafka如何保证不丢消息

1、kafka能否保证消息不丢? 不能 why?什么情况下会丢消息?
2、消息丢失及处理(消息保障)
3、消费确认机制等

2.4 kafka能否保证消息幂等性

是否支持消息幂等?
消息生产端可调整配置支持幂等,消费者端需要业务自行实现(服务端需要有异常补偿,基于Corgi准实时补偿 + 异常表补偿等)

2.4 kafka高性能的原因

  • 磁盘顺序读写
    kafka消息不能修改及不会在文件中间删除内容,保证了每次写内容都是在文件末尾的追加,从而保证写文件的顺序行;每次读内容时有.index文件的索引查找,及.log文件的分段,又能极大结合磁道读取内容的顺序行,从而提高读取效率。

  • 数据传输零拷贝

  • 读写数据的批量batch处理及压缩传输

三、kafka集群的CAP问题

什么是CAP,当分布式系统同时涉及读写时,需要保证一致性(Consistence)、可用性(Availabiliy)、分区容错性(Partition Tolerance)的平衡。成熟的分布式系统一般是在一致性、可用性方面找到平衡点,依据服务的需求设计出更贴近使用的CAP系统。

当强调一致性时,需保证所有的ISR必须完成数据的同步才算完成生产者数据的写入,而此时从可用性来看,只要Leader存活,是可以保证可用性的。除非Leader宕机,Follower才需要从ISR中靠前的broker选择接替Leader,短时间出现不可用。
当强调可用性时,也可以通过保证最终一致性(如ack=-1,> nums/2个副本完成数据同步),使集群其他节点最终数据一致性,从而实现可用性和一致性得以兼得。

3.1 一致性

分布式系统一般存在多个副本,Leader副本和多个Follower副本,如果系统能够保证线性一致性当然极好,但如果不能保证线性一致,进而保证顺序一致性也能满足需要。

  • 什么是线性一致性?
    线性一致性(Linearizability),也称原子一致性(atomic consistency)、强一致性(strong consistency)。从字面意思就可以理解,多个副本之间的同步状态像是集群只有1个副本。所有的操作都是原子的,当针对leader进行更新时,多个follower副本的状态也需要同步更新完成才能让该条更新结果对客户端可见。
    显而易见,线性一致性对消费者客户端是十分友好的,我和朋友小张分别拿着手机看NBA总决赛最后10s,当小张看到Ray Allen三分绝杀比赛结束时,我看到的却还是比分持平,等待发球,我的内心是无法接收的。
    但做到线性一致性是需要付出更多代价的,比如在kafka中消息生产者可以将 ACKS=ALL或-1,同时 min.insync.replicas(最少同步副本数量)设置为AR(所有副本数),此时生产者发送消息必须所有副本写入完成才算成功。但这毫无疑问将导致集群可用性的降低。
  • 什么是顺序一致性(Sequence Consistency)
    假设分布式系统中,X的原值为0,ClientA对X的值修改为1,那么因为网络的延迟等原因,虽然B0、C1的执行事件与A0存在先后顺序,但在服务端真正执行的顺序却是不确定的。所以B0、C1由于与A0存在并行关系,所以B0、C1得到X=0或X=1都是可能的。
    顺序一致性,需要保证的就是:当一个Client从服务端得到最新的结果后,后续其他Client得到的结果也必须是最新的。既:当B0如果读到X=1,那么C1也只能得到X=1。这样就保证了有序的一致性。

    我们从kafka的角度再详细的看读写一致性问题。

3.1.1 数据写一致性控制

更新的数据只能由Leader写入,然后同步超过半数以上副本算写入成功,其他未立即同步的副本会在后续完成写入,可得数据写入是线性一致、强一致的。

Acks=-1 或Acks=All
min.insync.replicas >= num/2+num%2 (保证同步副本超过半数)

3.1.2 数据读一致性控制

kafka官网中介绍,Consumer客户端连接不同的Partition分区,虽然有了HW高水位的存在保证消费者能读取到的消息水位是相同的,但由于不同分区的log-end-offset偏移量是不同的(显然Leader的最大偏移量是最大的),当有ClientA、B分别读取Follower1和Follower2,此时X=3尚未同步到Follower2。

如果此时出现Rebalance,则可能出现ClientA、B再平衡到Follower2、Follower1,但由于zookeeper的存在,客户端和Zookeeper分别维护了zxid和lastZxid值(下面细讲),当客户端的zxid>zookeeper维护节点的lastZxid时,也就是ClientA连接到Follower2,但是Follower的lastZxid尚未更新到3,此时如果连接将导致消息丢失。所以zk将保证重连时ClientA不会连接到Follower2。

上面两幅图的动态过程,大致讲解了zk在保证消息顺序一致性所做的事。那么什么是zxid?

  • zxid
    就是事务id,由64位二进制数组成,是为了保证事务的顺序一致性,zookeeper采用了递增的事务id号(zxid)来标识事务。
    其中高32位为epoch值(eopch值主要用来区分leader的版本,当前leader宕机选出下个leader时则需要epoch+1,以此区别leader朝代的更迭),低32位则是当前leader通知下依次递增的计数号码。

    看到这个zxid有没有让你联想到什么?我的感受是:
  • 从外形上看类似java对象头Object Header中Markword,甚至在偏向锁中也有epoch值概念。
  • 从高低位搭配上看,酷似ReentrantReadWriteLock的sync内部类中用高16位表示共享锁状态,低16位表示独占写锁状态。

3.2 可用性

可用性指的是在集群中,一部分节点故障后,集群整体是否还能响应客户端的读写请求。
提到可用性,势必会和一致性做兼容。

  • WARO(Write All Read One)
    所有副本写入完成才算成功,读取数据只从一个节点读。当Write All时保证了原子性、强一致性,所以读取节点时无疑会读取最新数据。但此时可用性并不高。
  • Quorum(NWR) 权衡一定的一致性和可用性。
    • N:总的副本数
    • W:更新数据需要保证完成写入的节点数
    • R:读取数据时,需要读取的副本节点数
  • N=5,W=5,R=1(追求强一致性,需要保证所有节点均写入成功,读取时数据是最新的)
  • N=5,W=3,R=3(写入时需要保证超过半数节点写入成功,读取超过半数节点的数据,未完成同步的节点可以通过zxid比较事物号大小,保证读取时顺序一致性)
  • N=5,W=3,R=1(当追求可用性更高时,该种配置可以在存在2个节点故障时仍然可用,且可以保证顺序一致性。)

3.3 分区扩展性

由于kafka是分布式部署在不同机器上的,并且由于网络不可靠,Leader也可能存在网络异常的场景,当Controller认为当前Leader不可用,broker将会再次选举(broker首先会推选自己为leader,再经由与其他broker投票生成新的leader),若老的leader恢复后,新leader也生成了,将出现新旧Leader并存的问题。此时zookeeper将再次通过上述的epoch值比较,控制版本保证数据一致性。

分布式-MQ-07 kafka高级特性及常见问题调优相关推荐

  1. Redis基础用法、高级特性与性能调优以及缓存穿透等分析

    目录 一.Redis介绍 二.Redis数据结构及常用的命令 三.Redis持久化策略选择 四.内存管理与数据淘汰机制 五.Redis过期策略及实现原理 1  说明 2  设置过期时间 3  三种过期 ...

  2. Redis 宝典 | 基础、高级特性与性能调优

    转载:Redis 宝典 | 基础.高级特性与性能调优 本文由 DevOpsDays 本文由简书作者kelgon供稿,高效运维社区致力于陪伴您的职业生涯,与您一起愉快的成长. 作者:kelgon 链接: ...

  3. Redis 基础、高级特性与性能调优 | 高薪必备

    来源:http://c7.gg/fxqAK 本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护 ...

  4. redis scan 效率太慢_Redis 基础、高级特性与性能调优(下)

    数据淘汰机制 Redis提供了5种数据淘汰策略: volatile-lru:使用LRU算法进行数据淘汰(淘汰上次使用时间最早的,且使用次数最少的key),只淘汰设定了有效期的key allkeys-l ...

  5. 高薪必备|Redis 基础、高级特性与性能调优

    点击▲关注 "数据和云"   给公众号标星置顶 更多精彩 第一时间直达 本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍. ...

  6. redis decr 防止超卖_Redis基础、高级特性与性能调优——一篇文章搞定

    本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍.之后概览Redis提供的高级能力,并在部署.维护.性能调优等多个方面进行更深入的介绍和指导. ...

  7. Redis基础、高级特性与性能调优

    点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Life is too short to spend time r ...

  8. 搞定Redis高级特性与性能调优

    阅读文本大概需要15分钟. 本文适合使用 Redis 的普通开发人员,以及对 Redis 进行选型.架构设计和性能调优的架构设计人员: Redis 的数据结构和相关常用命令 数据持久化 内存管理与数据 ...

  9. 4.2.4 Kafka高级特性解析(物理存储、稳定性:事物,控制器,可靠性,一致性,_consumer_offsets、延时队列、自定义重试队列)

    Kafka高级特性解析 文章目录 Kafka高级特性解析 2.5 物理存储 2.5.1 日志存储概述 2.5.2 日志存储 2.5.2.1 索引 2.5.2.1.1 偏移量 2.5.2.1.2 时间戳 ...

最新文章

  1. Ubuntu画图工具
  2. linux验证cuda安装成功_Linux环境CUDA 4.0入门:验证安装
  3. 【英语学习】【English L06】U07 Jobs L5 Work overtime
  4. 写一个function,清除字符串前后的空格。(兼容所有浏览器)
  5. Linux 系统 nohup 命令详解
  6. 1156 Sexy Primes – PAT甲级真题
  7. 聊一聊在Airtest自动化中如何清除iOS后台应用
  8. thon中的全局变量
  9. mysql secure file_mysql secure-file-priv选项问题的解决方法
  10. 前后端分离实现上传图片的功能
  11. Oracle 11g R2 RSF(Recurive Subquery factoring)
  12. Ubuntu18.04
  13. 动力工程及工程热物理推免真题(凭个人记忆整理)
  14. Zxing.jar下载
  15. [CSCCTF 2019 Qual]FlaskLight SSTI注入
  16. 【程序员股民系列】如何用python, pandas, numpy, matplotlib绘制每日个股成交额图
  17. 前端性能分析—前端优化
  18. html判断按键状态,javascript判断鼠标按键和键盘按键的方法
  19. msn登陆不上,显示默认网关为脱机!
  20. Content root being added Content entries should not intersect.

热门文章

  1. 中国移动互联网设置和中国移动WAP设置有什么区别?
  2. 运用c++与easyx图形库实现消灭星星最基本的消除功能、掉落功能以及判断死锁的方式
  3. android 10.0 SystemUI导航栏默认背景色的修改
  4. 出行即服务MaaS精华主题汇总(至2022年12月06日)
  5. 计算机键盘特点,市面上的笔记本键盘优缺点解析,看完秒懂!
  6. 能源系统建模:configuring carbon market in GCAM
  7. 友盟社会化分享微信登录签名错误
  8. 一周快讯【第57期】|机智云CEO黄灼获评“广州城市形象国际传播大使”
  9. DiffUtil的使用
  10. 小米9.0系统机器最完美激活Xposed框架的步骤