十.Kafka

Kafka特点

  1. 高吞吐量:每秒可生产25w消息(50MB),每秒可处理55w消息(110MB)
  2. 可持久化。将消息持久化到磁盘,因此可用于批量消费
  3. 分布式系统,易于向外扩展
  4. 消息被处理的状态都在consumer维护,而不由broker维护:消息是否被处理是由consumer提交消费进度给broker,而不是broker消息被consumer拉去后,就标记为已消费

设计要点

高吞吐

  1. 数据磁盘持久化:消息不在内存中缓存,直接写入磁盘,利用磁盘的顺序读写性能
  2. zero-copy:减少IO操作
    1. 传统的数据发送需要4次上下文切换
    2. 采用sendfile系统调用后,数据可以直接在内核态交互,系统上下文切换减少为2次,提高百分60的数据发送性能
  3. 数据批量发送
  4. 数据压缩
  5. Topic划分为多个partition,提高并行度
    1. kafka以topic来进行消息管理,每个topic包含多个partition,每个partition对应一个逻辑log,有多个segment文件组成
    2. 每个segment中存储多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射
    3. 每个partition在内存中对应一个index,记录每个segment中的第一条消息偏移量
    4. 发布者发到某个topic的消息会被均匀的分布到多个partition上,broker 收到发布消息往对应partition的最后一个segment上添加该消息
    5. 当segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment文件

负载均衡

  1. producer根据用户指定的算法,将消息发送到指定partition中
  2. topic存在多个partition,每个分区都在不同的broker节点上
  3. 相同的topic的多个partition会分配给不同的consumer进行拉取消息,消费

拉取系统

  1. 可以根据consumer消费能力自主控制消息拉去速度
  2. 可以根据consumer自身情况选择消费模式,例如:批量、重复、从尾端开始消费

可扩展性

通过zookeeper管理broker和consumer的动态加入与离开

  1. 当需要增加Broker节点时,新增的broker会向zookeeper注册,而producer和注册在zookeeper上的watcher感知这些变化,并及时做出调整
  2. 当新增和删除consumer节点时,相同topic的多个partition会分配给剩余的consumer

Kafka架构

分布式架构,主要包括producer、broker、consumer

  1. Producer,consumer实现kafka注册的接口
  2. 数据从producer发送到broker中,broker承担一个中间缓存和分发的作用
  3. broker分发注册到系统中的consumer。broker的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存

基本概念:

  1. Topic:kafka处理的消息源的不同分类
  2. Partition:topic物理上的分组(分区),一个topic可以分为多个partition。每个partition都是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)
    1. replicas:partition的副本集,保障partition的高可用
    2. leader:replicas中的一个角色,producer和consumer只跟leader交互
    3. follower:replicas中的一个角色,从leader中复制数据,作为副本,一旦leader挂掉,会从它的followers中选举出一个新的leader继续提供服务
  3. Message:消息,每个producer可以向一个Topic发布一些消息
  4. Producers:消息和数据生成者,向Kafka的一个Topic发布消息的过程
  5. Consumers:消息和数据消费者,订阅Topic,并处理其发布的消息的过程
    1. consumer group:每个consumer都属于一个consumer group,每条小只能被consumer group中的一个consumer消费,但是可以被多个consumer group消费
  6. Broker:缓存代理
    1. Controller:Kafka集群中,通过zookeeper选举某个broker作为controller,用来进行leader election 以及各种failover
  7. Zookeeper:Kafka通过Zookeeper来存储集群的Topic、Partition等元信息

Kafka为什么要将Topic进行分区?

为了负载均衡,水平扩展

  1. Topic只是逻辑概念,面向的是producer和consumer,而partition则是物理概念。如果Topic不进行分区,而将Topic内的消息存储于一个Broker,那么关于该Topic的所有读写请求都将由一个Broker处理,吞吐量容易陷入瓶颈
  2. 有了Partition概念后,可以把流量分布到不同的服务器上
  3. 当Producer发布消息时,Producer客户端可以采用random、key-hash及轮询算法选定目标Partition
  4. 当Consumer拉取消息是,Consumer客户端可以采用随机、轮询算法分配partition,从不同的Broker拉取对应的Partition的leader分区

应用场景

  1. 消息队列
  2. 行为跟踪:跟踪用户浏览页面、搜索及其他行为,以及发布订阅的模式实时记录到对应的Topic里
  3. 元数据监控
  4. 日志手机
  5. 流处理
  6. 持久性日志

Kafka消息发送和消费的流程

  1. Producer,根据指定的partition方法,将消息发布到指定Topic的Partition里面
    Producer采用push模式将消息发布到Broker
    每条消息都被append到Patition,属于顺序写磁盘。
    Producer发送消息到Broker时
    会根据分区算法选择将其存储到哪一个Partition中
    其路由机制:
    	1. 指定Partition
    	2. 未指定Partition,但指定了key,通过对key进行hash
    	3. Partition和key都未指定,使用轮询选出
    写入流程:
    	1. 与zookeeper进行交互,在brokers/topic/state节点找到该partition的leader
    	2. Producer将消息发送给该leader
    	3. leader将消息写入本地log
    	4. followers从leader pull消息,写入本地log后向leader发送ack
    	5. leader收到所有ISR中的replica的ACK后,增加HW并向Producer发送ACK
    
  2. Kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长,而不关注消息是否被消费
    存储的信息有:
    	1. 具体的日志文件	000000.log
    	2. 索引文件				000000.index
    	3. 时间索引文件		000000.timeindex
    
    每个Partition分区又对应多个segment(分段)文件
    每个segment文件都包含一组以上的存储文件
    
  3. Consumer,从Kafka集群pull数据并控制获取消息的offset。至于消费的进度,可手动或者自动提交给Kafka集群
    consumer group 一个消息只能被group内的一个consumer所消费
    且consumer消费信息时不关注offset
    最后一个offset由zookeeper保存,下次消费时直接从记录的offset开始
    1. 如果消费者线程大于Patition数量,则有些线程将收不到消息
    2. 如果Patition数量大于消费线程数,则有些线程多收到多个Patition的消息
    3. 如果一个线程消费多个Patition,则无法保证你收到的消息的顺序,而一个Patition内的消息是有序的
    
    Consumer采用pul模式从Broker中读取数据
       push模式,很难适应消费速率不同的消费者,因为发送速率由Broker决定
       这样会造成consumer来不及处理消息
       典型的表现为拒绝服务以及网络拥塞
    

Kafka Producer有哪些发送模式

  1. 同步
  2. 异步:以batch的形式push数据,默认是16kb,一定时间内若未满16kb也会发送,若在时间内满了16kb直接发送

Kafka的网络模型是怎么样的?

  1. KafkaClient ,单线程Selector模型(NIO)
  2. KafkaServer,Kafka Broker
    1. Broker内部的实现实际上为NettyServer的NIO方式
    2. Accept Thread负责与客户端建立连接链路,然后把Socket轮转交给Process Thread(相当于Netty的Boss EventLoop)
    3. Process Thread负责接收请求和响应数据,Process Thread每次基于Selector事件循环,首先从Response Queue读取响应数据,向客户端回复响应,然后接收到客户端请求后,读取数据放入Request Queue。(相当于Netty的Worker EventLoop)
    4. Work Thread负责业务逻辑、IO磁盘处理等,负责从Request Queue读取请求,并把处理结果放入Response Queue,待ProcessThread 发送出去(相当于业务线程池)

Kafka的副本机制

多个Broker节点对其他节点的Topic分区的日志进行复制。当集群中的某个节点出现故障,访问故障节点的请求会被转移到其他正常节点,Kafka每个主题的每个分区都有一个主副本和0个或多个副本,副本和主副本保持数据同步

在Kafka中并不是所有的副本都能来替代主副本,Kafka的Leader节点中维护着一个ISR(活跃组):
1. 节点必须与zookeeper保持连接
2. 在同步的过程中这个副本不能落后主副本太多

AR(副本全集),OSR(不活跃的副本),ISR(活跃的副本)
1. AR = OSR + ISR
2. ISR = leader+没有落后太多的副本

HW:consumer能够看到此partition的位置
LEO:每个partition的log最后一条message的位置

Producer向Leader发送数据时,可以设置 request.required.acks参数来设置数据可靠性级别:
1. 参数1(默认):只要Leader成功接收到则可以发送下一条message。若此时Leader宕机了,数据丢失
2. 参数0:不需要等待Broker的确认继续发送,数据可靠性最低
3. 参数-1:Broker需要等待ISR中所有的Follower都去人接受才发送下一条

Zookeeper在Kafka中的作用

  1. Broker在zookeeper中注册
  2. Topic在zookeeper中注册
  3. Consumer在zookeeper中注册
  4. Producer负载均衡
  5. Consumer负载均衡
  6. 记录消费进度Offset
  7. 记录Partition与Consumer的关系

Kafka如何实现高可用

  1. zookeeper部署2N+1节点,形成zookeeper集群,保证高可用
  2. kafka broker部署集群
  3. kafka consumer部署集群

Kafka是否会弄丢数据

  1. 消费端丢失数据
    唯一可能导致消费者丢失数据的情况,你消费了这条消息,然后消费者自动提交了offset,让broker以为你已经消费好了这个消息,实际上你猜刚准备处理这个消息,但是还没处理完就挂了。此时肯定会重复消费一次,需自己保重幂等性

  2. Broker丢失数据
    kafka某个broker宕机,重新选举partition的leader,此时其他的follower刚好还有些没有同步,结果此时的leader挂了,选举某个follower改成leader,丢失了一些数据
    方案:

    1. 给Topic设置replication.factor 参数:这个值必须大于1,要求每个partition必须有至少2个副本
    2. 在kafka服务端设置min.insync.replicas参数:这个值必须大于1,这个是要求一个leader至少感知到有一个follower还跟自己保持联系
    3. 在producer端设置acks=all:要求每条数据,必须是写入所有replica之后才认为是写入成功
    4. 在producer端设置retries=max:这个是要求一旦写入失败就无限重试,卡在这里
  3. 生产者丢失数据
    如果按照之前的思路设置acks=all,一定不会丢失数据,保持leader所有的follower都同步消息成功才保证本次写入成功

Kafka消息的顺序性

  1. consumer对每个partition内部单线程消费
  2. consumer拉去到消息后,写到N个内存queue,具有相同key的数据都到同一个内存queue。然后对于N个现场,每个线程分别消费一个内存queue即可
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值