一、目录
1、MQ基础概念
2、Kafka数据存储设计
3、Kafka生产者设计
4、Kafka消费者设计
5、Kafka提交与移位
6、Kafka消息保留策略
二、MQ概念
????????MQ 是message queue ,消息队列,也叫消息中间件。消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有ActiveMQ,RabbitMQ,Kafka,RocketMQ。
????????MQ,是一种跨进程的通信机制,用于上下游传递消息。 画外音:这两个进程,一般不在同一台服务器上。?
????????在互联网架构中,MQ经常用做“上下游解耦”:? ????????消息发送方只依赖MQ,不关注消费方是谁;? ????????消息消费方也只依赖MQ,不关注发送方是谁; ?? ??? ?画外音:发送方与消费方,逻辑上和物理上都不依赖彼此。?
什么时候不使用MQ?? ????????当调用方需要关心消息执行结果时,通常不使用MQ,而使用RPC调用。
三、MQ常见使用场景
典型场景一:数据驱动的任务依赖 举个例子,互联网公司经常在凌晨进行一些数据统计任务,这些任务之间有一定的依赖关系,例如: task3需要使用task2的输出作为输入; task2需要使用task1的输出作为输入; 这样的话,tast1, task2, task3之间就有任务依赖关系,必须task1先执行,再task2执行,载task3执行。
典型场景二:上游不关心执行结果 举个例子,互联网的消息通知,发短信,发邮件等
典型场景三:上游关注执行结果,但执行时间很长 举个例子,微信支付,跨公网调用微信的接口,执行时间会比较长,但调用方又非常关注执行结果 一般采用“回调网关+MQ”方案来解耦: ? 1.调用方直接跨公网调用微信接口; ? 2.微信返回调用成功,此时并不代表返回成功; ? 3.微信执行完成后,回调统一网关; ? 4.网关将返回结果通知MQ; ? 5.请求方收到结果通知;
四、基础架构
????????Kafka 是一种高吞吐量、分布式、基于发布/订阅的消息系统 常用于系统间的异步交互、大数据的实时分析场景
五、核心概念
1. ?broker:一个单独的Kafka server就是一个Broker,主要工作是接收生产者发送的消息,分配offset,之后保存到磁盘中;同时,接收消费者、其他Broker的请求,根据请求类型进行相应处理并返回响应。 2. ?topic:存储消息的逻辑概念,可以看作是一个消息集合。每个Topic可以有多个生产者向其中push消息,也可以任意多个消费者消费消息。 3. ?Partition:每个Topic可以划分成多个分区,同一Topic下的不同分区包含的消息是不同的。一个消息被添加到Topic时,会分配唯一的一个offset,Kafka通过offset保证消息在分区内时顺序的。即:Kafka保证一个分区内的消息是有序的;同一Topic的多个分区的消息,Kafka并不保证其顺序性。 4. ?offset:消息在日志中的位置,可以理解是消息在 partition 上的偏移量,也是代表该消息的唯一序号 5. ?Producer:主要工作是生产消息,将消息按照一定的规则推送到Topic的分区中。如:根据消息key的Hash值选择分区、或者按序轮询全部分区。 6. ?Consumer:主要工作是从Topic拉取消息进行消费。某个消费者消费Partition的哪个位置(offset)是由Consumer自己维护的。 7. ?Consumer Group:Kafka中可以让多个Consumer组成一个 Consumer Group(下面简称CG),一个Consumer只能属于一个CG。Kafka保证其订阅的Topic的每个Partition只会分配给此CG的一个消费者进行处理。如果不同CG订阅了同一个Topic,CG之间是不会互相影响的。 8. ?Zookeeper:Broker注册、Topic注册、生产者负载均衡、消费者负载均衡、记录分区与消费者组的关系、offset的记录、消费者注册。
六、Kafka数据存储设计-partition
partition 1、每个Partition只会在一个Broker上,物理上每个????????对应的是一个文件夹. 2、Kafka默认使用的是hash进行分区,所以会出现不同的分区数据不一样的情况 3、Partition包含多个Segment,每个Segment对应一个文件,Segment可以手动指定大小, 当Segment达到阈值时,将不再写数据,每个Segment都是大小相同的。
partition在broker上的分配原则: 1、保证所有的分区以及副本可以均衡在分布上所有的broker上。 2、保证同一个分区及其副本尽量不要分布在同一个broker上。
?
?七、Kafka数据存储设计-segment
数据文件分段 segment( 顺序读写、二分查找 ) partition 物理上由多个 segment 文件组成,每个 segment 大小相等,顺序读写。每个 segment数据文件以该段中最下的 offset 命名,文件扩展名为.log和.index。这样在查找指定 offset 的 Message 的时候,用二分查找就可以定位到该 Message 在哪个 segment 数据文件索引中。 1、segment file组成:由2大部分组成,分别为index file和data file,此2个文件一一对应,成对出现,后缀”.index”和“.log”分别表示为segment索引文件、数据文件. 2、segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。
?
数据文件索引(分段索引、 稀疏存储 ) Kafka 为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩展名为.index。index 文件中并没有为数据文件中的每条 Message 建立索引,而是采用了稀疏存储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以将索引文件保留在内存中。
八、Kafka生产者设计
负载均衡(partition 会均衡分布到不同 broker 上) 由于消息 topic 由多个 partition 组成,且 partition 会均衡分布到不同 broker 上,因此,为了有效利用 broker 集群的性能,提高消息的吞吐量,默认的round-robin方式来在partition间负载均衡,也可以指定一个partition function实现自定义的均衡方法,将消息平均发送到多个 partition 上,以实现负载均衡。
异步&批量发送提高吞吐率 异步和批量发送是提高消息吞吐量重要的方式,Producer 端可以在内存中合并多条消息后,以一次请求的方式发送了批量的消息给 broker,从而大大减少 broker 存储消息的 IO 操作次数。但也一定程度上影响了消息的实时性,相当于以时延代价,换取更好的吞吐量。
压缩( GZIP 或 Snappy ) Producer 端可以通过 GZIP 或 Snappy 格式对消息集合进行压缩。Producer 端进行压缩之后,在Consumer 端需进行解压。压缩的好处就是减少传输的数据量,减轻对网络传输的压力,在对大数据处理上,瓶颈往往体现在网络上而不是 CPU(压缩和解压会耗掉部分 CPU 资源)。 ?
九、Kafka消费者设计
消费者组 每个消费者都属于一个消费者组。不指定会有一个默认组。一个消费者组中默认有多个消费者。kafka消费消息使用pull方式进行消费。
十、Kafka提交与移位
提交与移位 当我们调用poll()时,该方法会返回我们没有消费的消息。 当消息从broker返回消费者时,broker并不跟踪这些消息是否被消费者接收到;Kafka让消费者自身来管理消费的位移,并向消费者提供更新位移的接口,这种更新位移方式称为提交(commit)。
自动提交 默认方式让消费者来管理位移,应用本身不需要显式操作。当我们将enable.auto.commit设置为true,那么消费者会在poll方法调用后每隔5秒(由auto.commit.interval.ms指定)提交一次位移。和很多其他操作一样,自动提交也是由poll()方法来驱动的;在调用poll()时,消费者判断是否到达提交时间,如果是则提交上一次poll返回的最大位移。
手动提交 1、同步提交 ? ? ? 提交失败,会进行重试直到提交成功或最终抛出异常到应用服务。 ? ? ? 2、异步以交 ? ? ? 提交失败,不会进行重试,原因是异步提交容易造成移位覆盖的问题。 3、混合提交 ? ? ? 先异步提交,若提交失败,则使用同步提交补充提交。 ?
十一、Kafka消息保留策略
无论消费者是否消费过消息,Kafka为了保证磁盘不被占满,会配置相应的“保留策略”,以实现周期性地删除陈旧的消息。
kafka有2种保留策略: 1.根据消息保留的时间,当消息在kafka中保存的时间超过指定时间,就会被删除。 2.根据Topic存储的数据大小,当Topic所占日志文件大于一个阈值时,则可以开始删除最旧的消息。
kafka会启动一个后台线程,定期检查是否有可以删除的消息。“保留策略”可以有全局配置,也可以针对某个Topic覆盖全局配置。 ?
|