异步通讯
观察者模式:一个目标对象的状态发生改变,所有依赖对象/观察者都得到通知。
(狼来了的故事:山坡上的羊-在田地的农夫-狼-小孩,
topic1 农夫看一眼羊就是发了一个请求---->看羊的小孩1,传递情报给农夫。
topic2 水塘-牛-鳄鱼--小孩2)
subject:被观察者,目标对象,羊
observer:观察者,小孩
解决问题:解耦、频繁的访问服务器。
(糕点房/被观察者、顾客/订阅者、糕点好了服务员通知顾客/观察者发消息 )
生产者模式(面对过程的模式)
问题:耦合性大,前面流程影响后面的流程,前面流程太快,后面处理慢,就会造成流程阻塞。
解决问题:加缓冲区。缓冲区可以解耦、支持并发。无中间商赚差价;(数据单元的完整性)
缺点:缓冲没有数据处理能力;能保证数据的完整性。
缓冲区+观察者模式。(秒杀新款手机;饭店老板手机自动提示 美团开始接单了)
二、消息系统原理
2.1 点对点消息传递-push 对消费者来说是被动的推送
一个或多个消费者消费队列中的数据。但一条数据只能被消费一次。
当一个消费者消费了队列中的某条消息后,则该条消息需要从消息队列中删除。
点对点消息即使有多个消费者同时消费数据,也不能保证数据处理的顺序。
基于消息推送的消息系统,由消息代理记录消费状态。
(消息代理把消息推送都消费者后,只标记了该消息已被消费,但具体的消息处理情况不知道。)
2.2 发布订阅消息传递-pull 对消费者来说是主动的拉取
消息被持久化到了一个topic中。
消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会被立马删除。
在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。
kafka采取该模式-订阅-拉取模式,由自己控制消费速度,以及消费的进度,消费者可以按照自己的意愿处理消息。
kafka
kafka 也是由Apache开发的一个开源流处理平台,由scala和Java编写。kafka是高吞吐量的分布式-发布订阅消息系统。
kafka优点:
解耦:A-B-C(在消息中间插入一个接口层,方便两端独立扩展)
冗余:消息队列采用 插入-获取-删除 的模式,保证数据被安全的保存直到使用完毕。
拓展性:
灵活性/峰值处理能力:并发太多。
可恢复性:加缓存的好处。
缓冲:
异步通信:
kafka 系统架构
broker:节点-node-kafka集群
Topic:话题-partation
partation -repalication
Leader-floower
Producer 生产者
Comsumer 消费者
Sonsumer group
Offset 偏移量
zookeeper 管理者
另一个版本的理解
你在一台机器上安装了Kafka,那么这台机器就叫Broker
,KAFKA集群包含了一个或者多个这样的实例。这只是一个命名而已,并没有什么特定含义。
负责往KAFKA写入数据的组件就叫做Producer
,消息的生产者一般写在业务系统里。和我们的送奶工是一个维度。
发送到KAFKA的消息可能有多种,如何区别其分类?就是Topic
的概念。一个主题分布式化
后,可能会存在多个Broker上。
将Topic拆成多个段,增加并行度后,拆成的每个部分叫做Partition
,分区一般平均分布在所有机器上。
那些消费Kafka中数据的应用程序,就叫做Consumer
,我们给某个主题的某个消费业务起一个名字,这么名字就叫做Consumer Group
再看一下Kafka Server的配置文件,最重要的两个参数:partitions
和replication.factor
,其实就非常好理解了。
Broker: kafka 集群包含一个或多个服务器,服务器节点称为broker。
Topic:每条发布到kafka集群的消息都有一个类别,称为topic。
类似于数据库的表名或ES中的index。
物理上不同topic的消息分开存储。
逻辑上一个topic的消息虽然保存一个或多个borker上,但用户只需要指定消息的Topic就可以生产或消费数据,不会关注数据存在何处。
topic的创建流程
topic的删除流程
partition: topic中的数据分割为一个或多个partition。
每个topic至少有一个partion,当生产者产生数据的时候,根据分配策略,选择分区,然后将消息追加到指定的分区的队列尾部。
每条消息都会有一个自增的编号。(标识顺序。用于标识消息的偏移量。)
partition 中的数据是有序的,不同partition 中的数据是没顺序的。
如果topic有多个partition,消费数据时不能保证数据的顺序。需要保证消息数据时,需要将partition数目设置为1.
broker存储topic的数据。topic有N个partition,集群有N个broker,那么每个broker存储该topic的一个partition.
topic有 N个partition,集群有N+M个Borker,那么有N个Borker存储topic的一个哦partition,剩下的M个broker不存。
replication: 数据会存放到topic的partition中,但有可能分区会损坏。
所以需要对分区数据备份,备份多少份屈居于你对数据的重视程度。
我们将分区分为leader1 和 follow(N)。leader负责写入和读取数据。follow只负责备份。保证了数据的一致性。
被分数设置为N,表示主+备=N。
leader: 每个partition有过个副本,其中只有一个为leader,leader是当前负责数据读写的partition。
Producer:生产者即数据的发布者,将消息发布到kafka的topic中。
broker接收到生产者发送的消息后,broker将该消息追加到segment中。
生产者发送的消息,存储到一个partition中,生产者也可以指定数据存储的partition。
Consumer:消费者可以从broker中读取数据。消费者可以消费多个topic中的数据。
Consumer group:这个消费组共享一组偏移量数据,同组的消费者不能同时处理一个消息。
offset:可以唯一标识一条消息。
消息被消费后,不会马上被删除,可以设置删除消息的时间。
zookeeper: 存储集群的meta信息。来管理数据,管理的数据有consumer、offset.能保证数据的安全。
只消费只消费主节点leader数据,不会去读备份节点。
topic 在物理层面以partition 为分组,一个topic可分成若干个partition。
partition 还可细分为segment,一个partition物理层上由多个segment组成。
segment的参数有两个:
log.segment.bytes:单个segment 可容纳的最大数据量,默认为1GB
log.segment.ms: kafka在commit 一个未写满的segment前,所等待的时间(默认为7天)
logsegment文件由两部分组成,分别为.index 和 .log文件,分别表示为segment索引文件和数据文件。
partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。
数值大小为64位,20位数字字符长度,没有数字用0填充。
面试:如何保证kafka数据不会重复消费 或 不被丢失?
数据重复发送和数据缺失只能保证一个。
生产者产生数据向leader发送数据时
Producers 可以选择是否为数据的写入接收ack,有一下几种ack的选择:request.required.acks
acks=0 producer 在isr中的leader已成功收到数据并得到确认后发下一条message。
acks=1 producer 无需等待来自broker的确认而继续发送下一条。
acks=all prouducer 需要等待isr 中的所有follower 都确认接收到数据后才算一次发送完成,可靠性最高。
0:消息绝不会丢失,但可能重复。
1:消息可能会丢,但不会重复。
-1或all:每条消息肯定会被传输一次且传输一次。可靠性最高。
当生产者向leader发送数据时,可以通过request.required.acks
参数来设置数据可靠性的级别:
1(默认) 数据发送到Kafka后,经过leader成功接收消息的的确认,就算是发送成功了。在这种情况下,如果leader宕机了,则会丢失数据。
0 生产者将数据发送出去就不管了,不去等待任何返回。这种情况下数据传输效率最高,但是数据可靠性确是最低的。
-1 producer需要等待ISR中的所有follower都确认接收到数据后才算一次发送完成,可靠性最高。
ISR机制:
ISR:当主节点挂了,并不是去follow选择主,而是从isr中选择为主节点。
关键词:
AR:ASSIGNED REPLICAS 用来表示副本的全集
OSR:out-sync replicas 离开同步队列的副本
ISR:in-sync replicas 加入同步队列的副本
ISR=leader+没有漯河太多的副本;
AR=OSR+ISR;
我们备份数据就是防止数据丢失,当主节点leader挂掉时,可以启用备份节点。
producer--push--leader
leader--pull--follower(follower每间隔一定时间去leader拉取数据,来保证数据的同步)
Kafka解决副本之间的同步,采用的是ISR
,这是一个面试Kafka必考的点之一。
ISR全称"In-Sync Replicas",是保证HA和一致性的重要机制。副本数对Kafka的吞吐率是有一定的影响,但极大的增强了可用性。一般2-3个为宜。
从 0.9 版本开始,Kafka 的标语已经从“一个高吞吐量,分布式的消息系统”改为”一个分布式流平台“。
Kafka不仅仅是一个队列,而且是一个存储,有超强的堆积能力。
Kafka不仅用在吞吐量高的大数据场景,也可以用在有事务要求的业务系统上,但性能较低。
Kafka不是Topic越多越好,由于其设计原理,在数量达到阈值后,其性能和Topic数量成反比。
引入了消息队列,就等于引入了异步,不管你是出于什么目的。这通常意味着业务流程的改变,甚至产品体验的变更。
生产者:牛奶工。
消息:牛奶。
消息系统:奶箱。
一条消息队列:一个奶箱。
消费者:客户。
消息积压:客户一直不取走奶。
ACK:客户给你发消息,确认奶已经收到。
(-1 所有分区都需要确定收到消息。0只发出去,不需要收到回调。 1写的对应分区(不是备份分区)接收成功)
Kafka 集群(bocker1/bocker2/bocker2代表一个kafka的实例,一个bokcer部署在一台机器上)
一个bocker里面有很多分区partion1/partion2
Kafka的序列存储(最重要)
消费者消费后-offset
Resid--之前缓存
es--之前倒排索引
kafka--之前mq(异步通信)