kafka

消息以主题(Topic)来分类,主题数据由多个Partition分区共同存储,根据分区策略写入不同的分区,分区以文件追加形式顺序写入,单个Parition内是保证消息有序。
主题以消费组形式消费,一个主题可以被多个消费组消费,并且只会被组内某一个消费者消费,本质上是一个topic下的一个Partition只会被一个消费者消费,即分区是和消费组里的某个消费者绑定的!
所以,当组内消费者数量大于分区数时,多出来那个就不会收到任何消息,消费者数量的增减、分区数的增减都会触发重新绑定(Reblance)

同步策略 acks
ISR(in-sync replica 已同步的副本)列表含义就是,跟Leader始终保持同步的Follower有哪些
生产者生产消息的时候,通过 request.required.acks参数来设置数据的可靠性
0 发过去就完事啥也不管
1 写进leader就完事至于其他的副本能不能同步是不管的
-1 等待leader和所有副本都写完才成功,消息不会丢失
首先这个acks参数,是在KafkaProducer,也就是生产者客户端里设置的acks=-1 不能保证数据一定不会丢是,如果Partition只有一个副本,也就是一个Leader,任何Follower都没有,acks=-1没有卵用,起码得有一个副本

高可用性(可靠性)
高可用/可靠性是通过asks机制与Partition分片机制实现的,一个toipic可以有多个Partition,每个Partition可以有多个副本,只要有一个副本不挂数据就不会丢(不是绝对的,这个要配合asks机制,
如果asks是1,写入leader后leader没同步follwer,那么数据是会丢的)这个来保证生产可靠性。
消费可靠性依赖投递策略,主要两种 At most once:最多一次,消息可能会丢失,但不会重复 At least once:最少一次,消息不会丢失,可能会重复
当存在多副本的情况下,会尽量把多个副本,分配到不同的 Broker上,多个Partition中会选出其中一个作为leader,其他的作为follwer,即主从,之后只有leader对外交互,成功后再同步follower
leader也是要选举的,所以leader的选举需要有一个执行角色,所以kafka会根据注册在zk上的ISR列表,选择一个broker作为controller来做Partition的均匀分配与leader选举
Leader的容灾
一旦有Broker宕机,因Controller 在 ZK 的 /brokers/ids 节点上注册了Watch,它可以感知宕机行为。会给受到影响的Partition(broker上的主Partition)选出新Leader。
选出 Leader 后,更新 ZK,然后发送 LeaderAndISRRequest 给受影响的 Broker,让它们知道改变这事。

生产者幂等性
生产者productor初始化时都会对应一个ID,每生产一条消息都会为消息生成一个递增序列号,broker端会缓存生产者的最新序号,只有req_seq == broker_seq+1才通过

文件存储结构
同一个Topic下有多个不同的 Partition,每个 Partition 都对应一个目录,以Segment(片段)形式存储,Segment大小可设置,比如设置500M,当在这个topic里大量写数据时候,会有多个Segment文件,Segment文件由.index和.log组成,
命名为从0开始,后续每个Segment文件名为上一个Segment文件最后一条消息的唯一标记
| --topic1-0
| --00000000000000000000.index
| --00000000000000000000.log
| --00000000000000368769.index
| --00000000000000368769.log
| --topic2-0
| --topic2-1
index标注了消息的物理存储位置,消息体分为3个部分[消息唯一标记][消息数据长度][消息体]

1、零拷贝
绕过了一部分无用的数据读写操作
2、顺序写入,降低磁盘寻址开销
Partition其实都是一个文件 ,收到消息后Kafka会把数据插入到文件末尾这种方法有一个缺陷——没有办法删除数据 ,所以Kafka是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到了第几条数据 ,ffset是由客户端SDK负责保存的,Kafka的Broker完全无视这个东西的存在
3、内存映射文件读写,操作系统的支持,不直接读写硬盘因为不管怎样硬盘速度都是比内存慢,写入内存后,有两种机制写入磁盘,其实就是控制何时flush,一种是每次写完都flush这是同步,
还有写完直接返回,这是异步,这个机制速度快但不可靠,(与asks配置有关?)
4、批量数据压缩,生产数据时会攒一批数据并且进行压缩然后一起发送,拉取时也是批量拉。网络IO是MQ主要瓶颈,降低传输数据大小可以提高效率,kafka实际上是批量压缩,而不是每个消息都压缩(压缩也耗时)

消费者要从头开始消费某个topic的全量数据,需要满足2个条件(spring-kafka):
1)使用一个全新的"group.id"(就是之前没有被任何消费者使用过)
2)指定"auto.offset.reset"参数的值为earliest(默认是last)

消息的顺序性(分区策略)
第一种分区策略:给定了分区号,直接将数据发送到指定的分区里面去
第二种分区策略:没有给定分区号,给定数据的key值,通过key取上hashCode进行分区
第三种分区策略:既没有给定分区号,也没有给定key值,直接轮循进行分区
第四种分区策略:自定义分区
写入时需要指定topic、value、[key][partition]
其中key用来路由,如果加了key会根据key的hash路由到指定的partition上,且partition是顺序写入的,保证了顺序

消息保留策略:
1、保留一段时间的日志
2、保留特定大小的日志
当超过这些限制时,老的消息会被删除。也可以针对某个主题单独设置消息过期策略

leader脑裂问题,因网络问题leader不能与其他节点交互,至重新选出一个新leader,此时旧leader恢复,此时会产生两个leader
首先leader选举是得到了大多数follwer的投票,每当新leader产生时,会生成一个epoch纪元,这个epoch是递增的,followers会保存当前epoch,当旧leader向follwer发请求时会因epoch过低而被忽略,这里要注意,因为是大多数同意,所以可能有少部分节点不知道新leader的epoch,但这个终归是小部分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值