【Kafka】

Kafka概念

概念理解

kafka是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统。

特性

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
  • 可扩展性:kafka集群支持热扩展
  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
  • 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
    高并发:支持数千个客户端同时读写

场景应用

  • 日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。
  • 消息系统:解耦和生产者和消费者、缓存消息等。
  • 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
  • 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告

设计思想

  • Consumergroup:各个consumer可以组成一个组,每个消息只能被组中的一个consumer消费,如果一个消息可以被多个consumer消费的话,那么这些consumer必须在不同的组。
  • 消息状态:在Kafka中,消息的状态被保存在consumer中,broker不会关心哪个消息被消费了被谁消费了,只记录一个offset值(指向partition中下一个要被消费的消息位置),这就意味着如果consumer处理不好的话,broker上的一个消息可能会被消费多次。
  • 消息持久化:Kafka中会把消息持久化到本地文件系统中,并且保持极高的效率。
  • 消息有效期:Kafka会长久保留其中的消息,以便consumer可以多次消费,当然其中很多细节是可配置
  • 批量发送:Kafka支持以消息集合为单位进行批量发送,以提高push效率
    push-and-pull :Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管从broker pull消息,两者对消息的生产和消费是异步的。
  • Kafka集群中broker之间的关系:不是主从关系,各个broker在集群中地位一样,我们可以随意的增加或删除任何一个broker节点。
  • 负载均衡方面: Kafka提供了一个 metadata API来管理broker之间的负载(对Kafka0.8.x而言,对于0.7.x主要靠zookeeper来实现负载均衡)。
    同步异步:Producer采用异步push方式,极大提高Kafka系统的吞吐率(可以通过参数控制是采用同步还是异步方式)。
  • 分区机制partition:Kafka的broker端支持消息分区,Producer可以决定把消息发到哪个分区,在一个分区中消息的顺序就是Producer发送消息的顺序,一个主题中可以有多个分区,具体分区的数量是可配置的

架构原理

基础架构名词解释

  • Producer:Producer即生产者,消息的产生者,是消息的入口。
  • Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等……
  • Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。
  • Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的物理表现形式就是一个一个的文件夹!
  • Message:每一条发送的消息主体。
  • Consumer:消费者,即消息的消费方,是消息的出口
  • Consumer Group:我们可以将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
  • Zookeeper:kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。

分区

分区的目的

  • 方便扩展:因为一个topic可以有多个partition,所以我们可以通过扩展机器去轻松的应对日益增长的数据量。
  • 提高并发:以partition为读写单位,可以多个消费者同时消费数据,提高了消息的处理效率。

分区的策略

在这里插入图片描述

  • 在指明partition的情况下,直接将指明的值作为partition
  • 没有指明partition的值,但是有key值的情况下,将Key的hash值和topic的partition数进行取余得到``partition`值
  • 在既没有partition的值有没有key值的情况下,Kafka采用了Sticky partition粘性分区器,随机选择一个分区,并尽可能一直使用该分区,待该分区的batch已满或者已经完成,kafka会随机选择另外一个分区进行使用

分区结构

在这里插入图片描述

每个topic都可以分为一个或多个partition,如果你觉得topic比较抽象,那partition就是比较具体的东西了!Partition在服务器上的表现形式就是一个一个的文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。

工作流程

  1. 先从集群获取分区的leader
  2. producter将消息发送给leader
  3. leader将消息写入本地文件
  4. followers从leader pull 消息
  5. followers 将消息写入本地后向leader发送ACk
  6. leader收到所有副本的ACk后向produc发送ACK

数据可靠(ACK确认)

数据可靠是靠ACK应答来保证的,三种ACK应答方式存在的漏洞

应答策略
  • 0:生产者发送过来的数据,不需要等带数据落盘就应答。
    因为leader不需要应答producer,此时如果leader挂掉了,那么producer并不知情,依然进行数据的发送,就会导致后续发出的数据丢失。

  • 生产者发送过来的数据,leader收到数据落盘后应答
    leader接收数据后没有同步给其他Follower,此时leader挂掉,会从其他Follower选举出来一个leader,新的leader并没有之前的数据。造成数据丢失

  • -1(ALL):所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份
    leader正在同步数据,此时一个follower挂掉了。但是leader要一直等待着follower的应答,系统就会一直卡着,leader不会给producer应答。

为了解决这个问题:
leader里面维护了一个动态的in-sync replica set (ISR),意为和leader保持同步的Leader—Follower集合(leader:0, ISR:0,1,2)。
如果Follower长时间未向leader发送通信或者同步数据则该Follower将被踢出ISR。
时间的阈值由replica.lag.time.max.ms参数设定,默认时间30s。例如2超时(leader:0, ISR:0,1)
这样就不用等待长期联系不上或者已经故障的节点

如果分区副本设置为1,ISR里应答的最小副本数量设置为1,和ack=1的效果是一样的,仍然有丢失数据的危险。

数据完全可靠性

公式

== 数据完全可靠条件 = (ACK级别为-1) + (分区副本数大于等于2)+ (ISR里应答的最小副本数量大于等于2)==

数据重复分析

如果数据同步已经成功,leader正在应答时,leader挂掉了。

就会选出新的leader。由于Producer没有收到应答,会将之前的数据再发一份给leader,导致数据重复。

代码中设置acks
props.put("acks","1");
//重试的次数 0不允许重试
props.put("retries",0);

数据去重

  • 至少一次(At Least Once)= (ACKS级别设置为-1)+ (分区副本大于等于2) + (ISR里应答的最小副本数量大于等于
  • 最多一次(At Most Once)= Ack级别设置为

At Least Once 可以保证数据不丢失,但是不能保证数据不重复
At Most Once 可以保证数据不重复,但是不能保证数据不丢失

  • 精确一次(Exactly Once)=幂等性+至少一次(At Least Once)
    重复数据的判断标准:具有**<PID,Partition,SeqNumber>**相同主键的消息提交时,Broker只会持久化一条数据。

PID:kafka每次重新启动都会分配一个新的PID
Partition:表示分区号
Sequence Number:序列化号,是单调递增的

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值