每日一档之kafka

145 阅读4分钟
  • 用途

    • 解耦
    • 异步通信
    • 削峰填谷
  • 关系

    • topic(主题)
    • broker(可以理解为一台物理机)
    • record(一条消息)
    • parition(分区)
    • 总结
      kafka中消息是以topic为单位进行处理,topic中的record可以通过轮训或者hash或者取模(%partition数量)或者自定义,放到不同的parition中,同一个分区中消息遵循FIFO,不同分区的消息不能保证,每一个broker都是一个分区的leader,或者其他区分的flower
      
  • 角色划分

    • 消费者
    • 生产者
  • 角色分组

    • 消费者组
      任何一个消费者都是属于一个customer group的,这个组会把获取的消息均分到组内的消费者消费(即同一个组内的同一条消息,只能有一个消费者消费)
      一个topic可以有多个group进行订阅
      如果消费者组内的实例数量大于分区数据,那么超出的实例就会空闲
      
  • 方式

    • 点对点
    • 发布订阅
  • 日志

    • 日志的持久化时间默认事168(7 * 24),底层会定期删除以前的
    • 日志分区记录消息的唯一的offset,这个事有序不可变的,kafka==集群会记录==每个消费者读取到了那个offset,消费者也可以通过更改offset的值来决定从那进行读取
    • 每个消费者读取分区中的日志是相互独立的
    • 消费者消费完会让集群==记录下次==读取日志初始值的==offset==
      • 每次读取的位置(新加入组的消费者)
        auto.offset.reset = latest(最新的) / earliest(最早的) / none(未找到,抛出异常)
        
  • offset控制

    • 默认会定期提交
      • enable.auto.commit = true
      • auto.commit.interval.ms = 5000
    • 也可以自己控制,需要注意提交的offset要比本地消费的偏移量 ==+1==
  • Ack和Retry

    • Ack
      • 生产者发送完消息后,要求Broker在规定的时间Ack应答,如果没有会尝试n次重新发送
      • 取值
        1 : 只要写到leader就可以,但是如果失败,会导致所有丢失
        0 :不等任何服务器确认,性能高
        all/-1 : leader和flower(至少一个)确认
        
    • Retry
      • 规定时间没有应答
      • 参数设置
        requset.timeout.ms = 30000 默认
        retries = 2147483647 默认
        
    • 时序图 时序图
    • 没有及时应答,retry多次消息
      • 原因:ack应答设置为all,broker应答超时
      • 解决:幂等性(从生产者角度,保证不丢失不重复)(版本1.1.0以上)
        • 唯一标识
        • 记录消息是否处理
          enable.idempotence = true
          必须开启
          retries= true
          acks = all
          
        • 幂等性只能解决同一个分区的一条数据的不可重复
      • 事务
        • 解决多条记录的多分区的
        • 分类
          • 生产者事务Only
          • 消费者&生产者事务
          场景:
          topic1 --> 业务 --> topic2
          若业务再给topic2发送消息时,失败了,要回滚从topic1提交的offset,保证还能继续从topic1读数据
          
        • 参数设置
          消费者设置事务隔离级别read_committed
          生产者指定transactional.id
          
  • 数据同步机制

    • 概念
      • Topic被分为多个分区,分区按着Segments存储文件块(每个默认1G),有序的(根据offset能查到)
      • leader负责读取,follower负责同步
      • LEO(log end offset): 标识最后一条消息的下一个位置
      • HW(high watermarker): 高水位线,所有HW之前的数据都是已经备份的,当所有结点都备份成功,leader会更新水位线
      • ISR(in-sync-replicas,用于leader宕机后选出新的leader): leader会维护一份处于同步的副本集合,如果再规定的时间内(replica.lag.time.max.ms)没有发送fetch请求,或者发送了但是没有赶上限定时间,就会被leader从集合中剔除
    • HW(0.11版本之前)问题
      • 数据不一致或者丢失
      • 问题的原因 数据丢失 数据不一致
    • HW设计存在问题,在0.11+版本后引入Leader epoch概念(不在使用HW作为数据截断依据,但是没有废弃HW,而是只把HW作为同步的进度)
      leader_epoch 情形 数据丢失 数据不一致
  • 价值点

    • 高吞吐
    • 日志存在磁盘中,但是读取快的原因是:
      • 顺序写入
        • 硬盘的每次写都会寻址(机械动作,耗时) -> 写入,顺序写能省去内存开销和IO寻址时间
        • kafka数据不是实时写入到硬盘
      • Memory Mapped Files(mmap),内存映射文件
        • 分页存储(page cache),在磁盘中提前映射出一块要写入的地址,并把要写入的这块地址映射到操作系统的内核的内存中,程序只要把数据写到内核的空间中,就算写入成功,然后由OS自动刷新到磁盘
      • 读取使用ZeroCopy技术
        • 无需将数据拷贝到用户空间,而是将数据放到内核空间传递输出
        • DMA计算(协处理器)
        • 区分
          常规IO
          DMA 常规网络 零拷贝
  • kafka的监控

    • kafkaEagle