Kafka/flume知识概要

一、Kafka

1、原理架构

kafka是一个分布式消息系统。具有高性能、持久化、多副本备份、横向扩展能力。消息保存在磁盘中,以顺序读写方式访问磁盘,避免随机读写导致性能瓶颈。生产者往队列里写消息,消费者从队列里取消息进行业务逻辑。

Kafka集群包含一个或多个服务器,服务器节点称为broker,broker存储topic的数据。broker可分为ControllerfollowerController管理集群broker的上下线,所有topic的分区副本分配和leaderPartition选举等工作

每条发布到Kafka集群的消息都有一个类别Topic,Topic像一个消息队列。Kafka分配的单位是partition,一个topic包含一个或多个partition,一个partition在磁盘上对应一个文件夹,一个partition会有多个副本,其中有且仅有一个partition作为Leader,Leader是当前负责数据的读写的partition,其他partition为flower作为备用选主。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。

offset:消费者在对应分区上已经消费的消息数(位置),kafka0.8 版本之前offset保存在zookeeper上。a0.8 版本之后offset保存在kafka集群上。

2、kafka的文件存储机制

一个topic,有多个不同的partition,每个partition为一个目录。partition命名的规则是,topic的名称加上一个序号,序号从0开始。

每一个partition目录下的文件,被平均切割成大小相等的数据文件(每一个数据文件都被称为一个段(segment file);每一个segment段消息,数量不一定相等,使得老的segment可以被快速清除。默认保留7天的数据,每次满1G后,在写入到一个新的文件中。

每一个partition只需要支持顺序读写就可以,也就是说它只会往文件的末尾追加数据,这就是顺序写的过程,生产者只会对每一个partition做数据的追加(写操作)。

在partition目录下,有两类文件,一类是以log为后缀的文件,一类是以index为后缀的文件,每一个log文件和一个index文件相对应,这一对文件就是一个segment file,也就是一个段。log文件:就是数据文件,里面存放的就是消息, index文件:是索引文件,记录元数据信息。

元数据指向,对应的数据文件(log文件)中消息的物理偏移地址。log文件达到1个G后滚动重新生成新的log文件。

kafka高效文件存储设计特点

  • Kafka把topic中一个parition大文件分成多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。
  • 通过索引信息可以快速定位message
  • 通过index元数据全部映射到memory,可以避免segment file的IO磁盘操作。
  • 通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。

3、producer

3.1、消息分区策略

kafka的分区策略,决定了producer生产者产生的一条消息最后会写入到topic的哪一个分区中

  • 1、指定具体的分区号, 数据就会写入到指定的分区中
producer.send(new ProducerRecord<String, String>
("test", 0,Integer.toString(i), "hello-kafka-"+i));
  • 2、不给定具体的分区号,给定key的值(key不断变化),这里使用key的 hashcode%分区数=分区号
producer.send(new ProducerRecord<String, String>
("test", Integer.toString(i), "hello-kafka-"+i));
  • 3、不给定具体的分区号,也不给对应的key,这个它会进行轮训的方式把数据写入到不同分区中
producer.send(new ProducerRecord<String, String>
("test", "hello-kafka-"+i));
  • 4、自定义分区

    • 定义一个类实现接口Partitioner
3.2、ack(acknowledgement 确认收到)
  • 1) 高可用型,配置:acks = -1(all), producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盘成功后才返回 ack。 At Least Once 语义。

优点:保证了producer端每一条消息都要成功,如果不成功并将消息缓存起来,等异常恢复后再次发送。
缺点:这样保证了高可用,但是这会导致集群的吞吐量不是很高,因为数据发送到broker之后,leader要将数据同步到fllower上,如果网络带宽、不稳定等情况时,ack响应时间会更长

  • 2) 折中型,配置:acks = 1 ,:producer 等待 broker 的 ack,partition 的 leader 落盘成功后返回 ack

优点:保证了消息的可靠性和吞吐量,是个折中的方案;缺点:性能处于2者中间

  • 3)高吞吐型,配置:acks = 0,producer 不等待 broker 的 ack。 At Most Once 语义。

优点:可以相对容忍一些数据的丢失,吞吐量大,可以接收大量请求;缺点:不知道发送的消息是否成功

3.3、Exactly Once 语义

ACK =-1(all),可保证 Producer 到 Server 之间不会丢失数据,即 At Least Once 语义。

ACK =0,可以保证生产者每条消息只会被发送一次,即 At Most Once 语义。

在 0.11 版本以前的 Kafka,对此是无能为力的,0.11 版本的 Kafka,引入了一项重大特性:幂等性

幂等性指 Producer 不论向 Server 发送多少次重复数据,Server 端都只会持久化一条。幂等性实现,其实就是将原来下游需要做的去重放在了数据上游。

幂等性结合 At Least Once 语义,就构成了 Kafka 的 Exactly Once 语义。
即:At Least Once + 幂等性 = Exactly Once

启用幂等性,只需要将 Producer 的参数中 enable.idompotence 设置为 true 即可。开启幂等性的 Producer 在 初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而 Broker 端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker 只 会持久化一条。

幂等性:就是用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因为多次点击而产生了副作用。
解决幂等性的方案有:

  1. mysql中设置业务ID,并设置为主键,且唯一
  2. 使用redis或者zk的分布式锁
3.4、producer消息发送原理流程

Kafka 的 Producer 发送消息采用的是异步发送的方式。

在消息发送的过程中,涉及到main 线程和 Sender 线程两个线程,以及一个线程共享变量RecordAccumulator。main 线程将消息发送给 RecordAccumulator,Sender 线程不断从 RecordAccumulator 中拉取消息发送到 Kafka broker。

main 线程中

  • 1)通过一个拦截器ProducerInterceptors,对发送的数据进行拦截,(这个功能其实没啥用)

  • 2)通过序列化器Serializer 对消息的key和value进行序列化

  • 3)通过使用分区器作用在每一条消息上,实现数据分发进行入到topic不同的分区中

RecordAccumulator 中

  • 1)RecordAccumulator收集消息,实现批量发送。( 它是一个缓冲区,可以缓存一批数据,把topic的每一个分区数据存在一个队列中,然后封装消息成一个一个的batch批次,最后实现数据分批次批量发送。)

Sender线程

  • 1)Sender线程从RecordAccumulator获取消息

  • 2)构建ClientRequest对象

  • 3)将ClientRequest交给 NetWorkClient准备发送

  • 4)NetWorkClient 将请求放入到KafkaChannel的缓存

  • 5)发送请求到kafka集群

  • 6)调用回调函数,接受到响应

3.5 、Producer 事务

Kafka 从 0.11 版本开始引入了事务支持。事务可以保证 Kafka 在 Exactly Once 语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。

为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer获得的PID 和Transaction ID 绑定。这样当Producer 重启后就可以通过正在进行的 TransactionID 获得原来的 PID。

为了管理 Transaction,Kafka 引入了一个新的组件 Transaction Coordinator。Producer 就是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。

Transaction Coordinator 还负责将事务所有写入 Kafka 的一个内部 Topic,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。

3.6、调优,提升消息吞吐量
 //准备配置属性
 Properties props = new Properties();
 //kafka集群地址
 props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
 //acks它代表消息确认机制   // 1 0 -1 all
 props.put("acks", "all");
 //重试的次数
 props.put
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值