kafka基础知识回顾

kafka基础知识回顾

1. 消息引擎系统

消息格式 :

二进制  (常见消息格式 : 结构化的 xml json )

传输协议:

​ (常见的传输协议 amqp webservice soap)

消息模型 :

​ p2p (point to point 点对点) topic(发布订阅)

2. kafka概要设计

​ kafka设计之初要考虑的问题: 吞吐量/延迟 消息持久性 负载均衡和故障转移 伸缩性?

吞吐量/延迟

  1. 什么是吞吐量 ?

     是处理某种能力的最大值,对于kafka而言,它的吞吐量就是 每秒能够处理的消息数或者每秒能够处理的字节数;吞吐量和延迟是一对矛盾体.提高吞吐量需要做消息小批量发送,会增加延迟时间.
    
  2. kafka时如何做到高吞吐量,低延时?

    写入 (生产):

    • kafka的写入操作很快,得益于磁盘使用方法不同,虽然kafka会持久化所有数据到磁盘,但本质每次写入操作其实都只是把数据写入操作系统的页缓存,然后由操作系统自行决定什么时候把页缓存中的数据写回磁盘

      磁盘随机读写慢,顺序读写很快,甚至比内存的随机读写要快.

      鉴于这一事实,kafka在设计时采用了追加写入消息的方式,即只能追加写入新的消息,且不允许修改已写入的消息,因此它属于典型的顺序访问型操作.

      这样设计的优势:

      • 操作系统页缓存是在内存中分配的,所以消息写入的速度非常快

      • kafka不必直接与底层的文件系统打交道,所有繁琐的I/O操作都由操作系统来处理

      • kafka写入操作采用追加写入的方式,避免了磁盘随机写操作.

    读取(消费):

    ​ kafka在读取消息时会尝试从操作系统页缓存中读取,而且页缓存命中率很高,直接读取磁盘的

    ​ 磁盘io读取:使用以sendfile为代表的零拷贝技术加强网络间的数据传输效率.

消息持久化

​ 支持消息持久化到磁盘,消息重演,持久化格式

负载均衡和故障转移

​ 负载均衡:

​ 故障转移:

​ 当服务器意外终止时,整个集群可以快速的检测到改失效,并立即将该服务器上的应用和服务自动转移到其他服务器上,故障转移通常以 “心跳”,"会话"的机制来实现的. kafka服务器支持故障转移的方式是会话机制,每台kafka都向zookeeper注册,kafka服务器出现问题时,与zookeeper的会话就不能维护,从而超时失效,集群会选举新的服务器继续提供服务.

伸缩性

​ 伸缩性表示向分布式系统中增加额外的计算资源时吞吐量提升的能力.

​ 阻碍线性扩容的一个很常见的因素就是状态的保存,无论哪类分布式系统,集群中每台服务器一定维护很多内部状态,如果服务器自己来保存这些状态信息, 则必须处理一致性的问题. 相反,如果服务器是无状态的,状态的保存和管理交与专门的协调服务来做(比如zookeeper),扩容集群节点只需简单地启动新的节点机器进行自动负载均衡就可以了.

​ kafka正式采用这样的思想: 每台kafka服务器上的状态统一交由zookeeper保管.kafka只保存了很轻量级的内部状态,扩容kafka集群只需要启动新的kafka服务即可.

3. kafka基本概念

消息: topic partition offset 副本 leader flower broker

ISR : in-sync replica, 与leader replica保持同步的replica集合

kafka对于没有提交成功的消息不做任何交付保证,它只保证在ISR存活的情况下, "已提交"的消息不会丢失

4. 参数设置

broker

broker.id : kafka使用唯一的一个整数来标识每个broker

log.dirs : kafka持久化消息的目录

zookeeper.connect : 配置zk的连接信息

delete.topic.enable : 是否允许kafka删除topic

log.retention.{hours|minutes|ms} : 消息的保存时间,默认7天

num.network.threads : broker处理(只负责转发请求)网络请求的线程数,默认3

num.io.threads : broker端实际处理(真正干活)网络请求的线程数,默认8

message.max.bytes :kafka broker能够接收的最大消息大小,默认977kb

topic

delete.retention.ms : 每个topic可以设置自己的日志留存时间以覆盖全局默认值

max.message.bytes : 覆盖全局的max.message.bytes

retention.bytes : 覆盖全局的log.retention.bytes

gc / jvm

kafka是运行再jvm,推荐 java8 g1进行垃圾回收

os

topic需要打开很多文件,文件描述符限制:ulimit -n 1000000

设置更长flush时间: 页缓存写入物理磁盘的时间间隔,默认5秒,建议增大该值,linkedin 公司设置为 2分钟

5. producer开发

  1. 如何确定消息发到哪个分区?

    kafka producer提供了一个默认的分区器(partitioner) ,对于每条消息,如果指定key,那么该partitioner会根据key的hash值选择分区,没有指定key 则轮询选择分区。 producer也可以指定目标分区。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ll4eGK5-1587889232653)(C:\Users\admin\AppData\Local\Temp\1586908279192.png)]

  1. 发送消息:send方法

    通过java提供的Future同时实现了同步发送和异步发送+回调两种发送方式。

    send() : 异步

    ​ 将消息放到缓冲区,有一个专属的I/O线程负责从缓冲区中提取消息并封装到batch中,然后发送出去,存在数据丢失的窗口。

    send().get() :同步

  2. 异常类型:

    可重试异常和不可重试异常,可重试异常为 RetriableException子类

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6IEWm77T-1587889232657)(C:\Users\admin\AppData\Local\Temp\1586910467172.png)]

  1. 关闭producer

    close():等待消息发送结束后关闭

    close(timeout): 等待超时,然后强制关闭,不推荐

  2. producer参数设置

bootstrap.servers : kafka连接地址,多个broker时写部分即可,例 ip1:9092,ip2:9092,ip4:9092

key.serializer : 被发送到broker端的任何消息的格式都必须是 字节数组。该值无默认参数必须配置,对key进行序列化

value.serializer : 对消息体进行序列化,将其转化为字节数组,必须配置

acks: 该参数非常重要,可以设置为 0 1 -1/all

​ 0 : 不需要等待broker处理结果,此时回调无效,无法保证消息发送成功,优点是吞吐量高、

​ -1或all:需要leader broker将消息写入本地日志(持久化到磁盘),并且还会等待isr其他副本都写入各自日志,才发送响应结果给producer

​ 1 : 默认的参数值,需要leader broker将消息写入本地日志,然后便发送响应结果给producer,无需等待ISR中其他副本写入消息,为上述两种的折中方案。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SOOwodEH-1587889232659)(C:\Users\admin\AppData\Local\Temp\1586913520947.png)]

buffer.memeory : 异步发送的缓冲区大小

compression.type : 压缩算法,默认为none 支持 : gzip snappy 和lz4压缩算法

retries : producer 内部实现了重试功能,该配置可能会引入: 消息重复 和消息乱序问题,需注意

batch.size : 前文提到的kafka的发送吞吐量很大,是在延迟和吞吐量中权衡选择小批量的发送的方式,该配置可以配置批量大小,默认为16kb. 需要注意的是, producer不是等batch满了才发送,这和linger.ms有关

limger.ms : 该参数控制消息发送的延时行为的,超过该延时时间 , producer就会发送改消息.

max.request.size : producer 端能够发送的最大消息大小.

request.timeout.ms : producer发消息和broker的最大响应时间,超过该值则超时

思考?

如何通过配置实现数据无丢失,数据乱序,数据重复消费 ?

producer配置

无丢失:

acks = all, retries = Integer.MAX_VALUE,

使用带回调的send方法,如果消息失败可以得到通知。

乱序问题?

max.in.flight.requests.per.connection = 1 : 这个参数的实际效果其实限制了producer在单个broker连接上能够发送的未响应请求的数量,因此,如果设置为1 , 则producer在某个broker发送响应之前将无法再给该broker发送produce请求。

在回调方法callback里,显式调用KafkaProducer.close(0). 这样是为了处理消息的乱序问题,若不使用close(0),默认情况下,producer 会被允许将未完成的消息发送出去,这样可能导致乱序。

boker端配置

unclean.leader.election.enable = false: 不允许非ISR中的副本被选举为leader,从而避免broker端因日志水位截断而造成的消息丢失。

replication.factor >=3 多副本

min.insync.replicas > 1 : 用于控制某条消息至少被写入到ISR中的多少个副本才算成功。 只有在acks = -1或者all时候生效。

推荐配置: replication.factor = min.insync.replicas + 1

kafka 0.11.0.0 之后版本支持 idempotent producer。支持事务和幂等.broker可以去重

消费端需要自己实现.

在生产者方面,Kafka 0.11.0 支持幂等和事务性能力。幂等传递确保消息在单个生产者的生命周期内仅给特定的主题分区传递一次。事务交付允许生产者给多个分区发送数据,这样所有的消息都会被传递成功或失败。这些功能使Kafka符合“恰好一次语义”。

6. consumer 开发

消费者组

​ 消费者使用一个消费者组名来标记自己,topic的每条消息都只会发送到每个订阅他的消费者组的一个消费者实例上。即 1. 一个消费者组可能有若干个消费者实例 2. 对于一个group而言,topic的每条消息只能被发送到group下的一个consumer实例上 3. topic消息可以被发送到多个group中

offset 偏移量

该值指向消费者组对应的消费位置,offset信息在新版本里存放在broker的__consumer_offsets topic里。

手动提交或者自动提交

重平衡(rebalance)

重平衡指的是:broker的协调者为消费者组的消费者重新分配分区。 对于每个组而言,kafka的某个broker会被选举为组协调者(group coordinator),coordinator 负责对组的状态进行管理,他的主要职责就是为消费者组分配分区,即coordinator负责对组执行rebalance操作。

rebalance触发条件

  • 组成员变更,比如新的consumer加入组,已有的consumer离开组,或者已有consumer崩溃
  • 组订阅topic数发生变更,比如基于正则表达式的订阅,匹配到新的topic时
  • 组订阅topic分区数发生变更,比如使用命令行修改了订阅topic的分区数

常见触发条件:

comsumer崩溃,这里的崩溃不是指consumer进程“挂掉,“宕机”。当comsumer无法在指定的时间内完成消息的处理,那么coordinator就认为该comsumer已经崩溃,从而触发新一轮的rebalance.

rebalance开销很大,需要对consumer调优减少rebalance , request.timout.ms max.poll.records 和 max.poll.interval.ms

rebalance分配策略 :

  • range
  • round-robin
  • sticky

rebalance generation :

从0开始记录,每次重平衡 + 1 , 可以防止无效的offset提交,比如上一代的comsumer成员延迟提交了offset,但rebalance之后该group产生了新一代group成员,而此次延迟提交的offset是旧的generation信息,因此这次提交会被consumer group

kafkaProducer : 线程安全 kafkaConsumer : 线程不安全。

7. kafka设计原理

nd-robin

  • sticky

rebalance generation :

从0开始记录,每次重平衡 + 1 , 可以防止无效的offset提交,比如上一代的comsumer成员延迟提交了offset,但rebalance之后该group产生了新一代group成员,而此次延迟提交的offset是旧的generation信息,因此这次提交会被consumer group

kafkaProducer : 线程安全 kafkaConsumer : 线程不安全。

7. kafka设计原理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值