Kafka_核心

kafka集群

image.png

Kafka的设计都是为了实现kafak消息队列消费数据的语义
Kafka消息队列中数据消费的三种语义:

  • at-most-once:至多一次
    会出现数据丢失的问题
  • at-least-once:至少一次
    会出现数据重复的问题
  • exactly-once:有且仅有一次
    只消费处理成功一次
    所有消息队列的目标

kakfa卡只能保证局部有序,如何实现全局有序

image.png

kafka中每个分区内有offset保证局部有序
1.如果topic只有 一个分区可以实现全局有序
2.写数据的时候指定分区编号,只想一个分区内写数据

Kafka如何保证自身数据安全

多副本机制
生产者和消费者跟leader副本进行读写
follower副本跟leader副本同步数据
且读写的内容只能在hw高水位线之前

副本同步机制
为什么会存在同步?因为读写只跟leader副本打交道。所以follower副本需要同步数据。
副本集合概念:

  • AR 该分区的所有副本 ALL

  • ISR 所有副本中处在同步状态的 健康良好的 IN Sync
    只有ISR中的副本才有选举资格 成为新的leader 优先顺序 从左往右

    谁来负责leader副本选举? kafka中主角色controller
    谁来kafka主角色controller选举呢? 通过zk集群选举。【临时节点 监听 唯一性】

  • OSR 非同步状态的 Out Sync
    正常情况下 OSR集合中应该是空的 每个副本都应该处于健康的状态
    ISR同步超时 就会被打入OSR

          AR=ISR+OSR
          
      名词:
          LSO  start  每个副本的第一个消息offset 正常是0。如果开启了删除清理 之前的数据就会被删除
          LEO  end    每个副本的【下一个待写入】的offset值 
          HW  高水位线  只有它之前的消息才能被消费者拉取消费
              hw=min(leo)  类似于木桶效应
    

Producer生产者如何保证生产的数据不丢失\不重复

  • 如何保证kafka数据不丢失
    ack校检和重试机制

    • ACK级别
      0 不管ack 只发送数据
      1 当leader副本保存成功 返回ack给生产者
      -1|all 当所有的ISR副本都保存同步成功 返回ack 【最安全 最慢】
    • 重试机制
      因为网络质量等偶发因素导致的消息发送失败 可以通过重试机制
      如果因为代码问题 集群环境问题 重试一百万次有没有意义
  • 如何保证数据写入kafka不重复?
    为什么会重复?
    1_重试机制,如果前一个ack还没有返回 生产者认为失败了基于重试机制重新发了一遍
    2_ack结果延迟 丢失
    实际上kafka已经存储成功了 只不过生产者没有正确准确的收到ack

    内部设计了什么机制?
    1_幂等性机制 操作一次和操作多次 效果是一样的。 不跟次数有关。 重复支付 重复提交 常量函数。
    2_给每个生产者发送的消息内部编号 自增id
    kafka在保存数据的时候 就会判断编号 如果已经有了 不保存了直接返回ack

生产者写入数据分区规则

当Producer生产者向Topic队列中发送数据时,如何确定发送到哪个分区Partition呢?

  • 1.如果用户指定了分区,就向指定分写入数据

  • 2.如果用户不指定分区,看是否有自定义分区规则

    • 2_1 如果没有指定自定义分区规则,按照默认的规则分区规则
      如果有key,根据 key的hash值%分区个数

    Utils.murmur2(keyBytes) % numPartitions
    计算key哈希值,对partition分区个数进行取模操作 结果就是分区编号。
    只要key一样,一定到同一个分区。

    如果没有key:

    a_老版本 采用轮询策略
    b_新版本 stickyPartition 黏性策略
    if (keyBytes == null) {
    return stickyPartitionCache.partition(topic, cluster);
    }

    什么叫做黏性策略呢?
    首先判断当前有没有partition的连接 如果连接有效 直接使用这个连接
    Integer newPart = oldPart;
    如果没有分区连接,那就随机选择一个分区创建连接 把数据都写入这个分区
    random

    • 2_2 如果有自定义分区规则,按照自定义分区规则分配

Consumer消费者如何保证数据不重复不丢失

Kafka记录了每次消费者消费后的消费记录
当消费者来消费的时候,只需消费上一次offset+1的数据就可以了

  • 消费者消费数据的三种方式
    指定topic     ~~~~ ~~~~ ~~~~读取的是指定topic下所有分区的数据
    指定topic partition ~~~~ ~~~~ 读取的是指定topic下的某个分区的数据
    指定topic partition offset ~~~~读取的是指定topic下 指定分区的 某个offset开始

订阅主题 subscribe 消费该主题的所有分区数据
订阅主题指定分区 assign 消费指定主题分区的数据
精准消费 定位消费 seek 消费指定主题分区 指定偏移量消费
需要先订阅topic 和 分区,然后才能seek 偏移量


消费者开始消费数据时,从哪里开始消费

  • step1: 第一次消费规则 由属性决定
    lastest 从0开始
    earliest 从最新的开始(默认)
      //设置消费的位置 从哪里开始消费  合法参数:latest |  earliest
      props.setProperty(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");
  • step2:第二次及以后 从上一次消费完的offset +1位置开始消费

  • 以上成为消费记录,那么kafka如何保存消费记录的呢?
    ~~~~消费者内存中 自己维护 程序不断 不重启的情况下 【优先使用】。
    ~~~~持久化存储在磁盘、存储介质: 【重启程序的依据】
    ~~~~ ~~~~存储kafka中(默认) 自创了主题_consumer_offsets
    ~~~~ ~~~~ 存储zk/mysql/redis

内存消费记录:kafka自己记录的非常标准,但是程序重启之后就没有了,需要从文件当中读

文件消费记录:kafka自己有一个topic 专门用来存储每个消费者消费的offset


image.png

offset偏移量管理
消费者消费完的记录需要提交,怎样提交?

  • 自动提交
    • 根据时间周期提交下一下的消费的offset,默认每五秒提交一次
    • 风险:
      数据丢失
      数据重复


      image.png

为了防止数据丢失,或者重复消费我们选择手动提交

  • 手动提交offset
    先消费数据,然后再提交offset
    风险:如果此时我已经消费了两个分区的数据,第三个分区还没有消费完,程序崩溃了,offset没有提交,就会导致,下次程序启动的时候 重复消费数据
  • 手动提交--基于分区提交offset
    offsets.put(partition,new OffsetAndMetadata(consumerOffset+1));
    把当前分区消费的最后一条日志的offset +1,提交上去。
  • 手动提交分区offset探秘


    image.png

消费者在自己的内存中维护了消费记录
当内存中有记录的时候,程序之间从内存当中读取消费记录,这个消费记录是自己维护的正确的

而磁盘中的消费记录,只有在程序重启 内存中的消费记录丢失了 才会根据磁盘去消费


消费者消费数据分配策略

问题:Kafka 消费组Consumer Group中多个消费者Consumer如何消费Topic队列中数据?
前提-kafka中同一个消费组中的消费者规则:
一个分区只能被一个消费者消费
一个消费者可以消费多个分区

另 一个分区的内容,可以被不同消费组内的消费者消费
最理想的状态:消费者和分区 一对一
策略:
范围分配
轮询分配
粘性分配

1_RangeAssignor 分配策略-范围分配

  • Kafka中默认的分配规则
  • 一个topic中所有的分区按照消费者的个数平均分,多的就分配给编号小的消费者
    优点:适用于消费topic比较少的情况,分配会比较平均
    ex: 一个topic内有七个分区 有三个消费者c1 c2 c3
    c1 (0,1,2) c2(3,4) c3(56)
    缺点: 不适应于多个消费者消费多个topic,会造成编号小的负载压力大的情况
    列如:三个消费者 消费三个topic 每个topic有7个分区会导致
    c1 -t1(0,1,2) t2(0,1,2) t3(0,1,2)

c2 -t1(3,4) t2(3,4) t3(3,4)
c3 t1(5,6) t2(5,6) t3(5,6)

2_RoundRobinAssignor 分配策略-轮询策略

  • 给每个Topic和其分区编号,轮询分配给消费者
    一个消费者分配一个 轮询分配
    适合:所有消费者都订阅相同的主题。
    缺点:如果有消费者故障 或者加入新的消费者 之前全推倒 重新分配

image.png

缺点: c1、c2消费第一个topic,c2、c3消费第二个Topic、c3消费第三个Topic,指定消费者消费Topic
会导致c3 (t2-p2,t3-p1-p2-p3)负载过大
3_StickyAssignor 分配策略-粘性策略(推荐)
粘性策略注意针对的是消费过程者,如果有消费者挂掉了.该如何分配其正在消费的分区.
不出故障的时候跟轮询一样,出故障之后正常的都不动,轮询的分配故障后的分区

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容