文章目录
kafka理论
kafka介绍
kafka是一个基于发布/订阅的消息队列,生产者发布消息到topic,消费者采用拉的模式,轮询的去问kafka有没有消息,好处在于消费的速度可以自己控制,坏处在于需要消费者需要一直维护一个长轮询
发布/订阅模式 还有一种是主动向消费者推送消息的,这种模式会出现消费者集群,但是有的服务消费的很慢,有的服务消费的很快,那么就会造成有的服务资源不够用,有的服务资源浪费,因为不管客户端的消费速度怎么养,消息队列都是同样的速度去推送消息
还有另一种模式就是点对点,生产者发送一条消息到queue,只有一个消费者能收到。
生产者消费者和kafka的连接对象
kafka会用到zookeeper,作用是帮助kafka组建集群信息,存储kafka的topic的信息,有几个topic,下面有几个partition,Leader是谁,每个partition有几个replicas,还有ISR,
消费者在0.9版本之前是把offser存在zookeeper,之后是存在kafka里面
生产者不依赖zookeeper,依赖的是broken-list,就是kafka集群
zookeeper作用
帮助kafka存储信息,保存kafka集群信息
kafka下面各个角色的作用
Broker:集群中的一台kafka服务器
Topic:消息的主题,对消息做分类
Partition:主题下面的真实存储消息的,对一个Topic的消息做负载均衡,提高并发
Leader:主Partition
replicas/follower:副Partition,可以有多个,对消息做备份,Leader挂掉的时候提升为主,集群状态下Leader和follower不在同一个broken
消费者
消费者主要就是一个消费者组,同一个消费者组下面的消费者订阅同一个Topic,只能有一个人收到消息
假如一个Topic下面有三个Partition,两个消费者是同一个消费者组的,监听的都是这个Topic,会有一个分区策略,把Partition里的消息分配两个消费者
但是如果有另外一个消费者组也是订阅的这个Partition,那么这个消费者组也可以收到消息
同理,生产者发送消息的时候也会有策略决定发到Topic下的哪个Partition
生产者
当生产者发送消息到一个不存在Topic的时候,会自动创建这个Topic,一个Partition,一个replicas,这个值在server.proertits里面设置
生产者发送消息怎么保证kafka一定收到了消息
采用ack机制,一共有两种方案
1.半数以上的Partition完成的消息同步就发送ack给生产者
优点: 效率高,较短的时间可以响应生产者
缺点: 选举新的leader时,容忍一半节点挂掉,如果大于半数的节点挂掉了那么有可能有消 息没有同步过来
2.全部Partition完成同步,才发送ack
缺点: 1.响应时间相比较久一点,
2.要是再发送消息的时候是有10个节点,再同步的时候一个节点挂掉了只剩9个,那 么永远都不会同步到第10个节点,生产者就收不到ack
优点: 允许全部节点-1个数量挂点,至少有一个节点还在,消息不会丢失
kafka采用的是第二种方式,用了一个ISR的机制来优化这个方案
ISR机制
Leader维护了一个动态的in-sync replica Set(ISR), 意思是和Leader保持同步的Follower集合,当Leader和ISR集合里面的Follower完成数据同步之后就给生产者发送消息,但这个集合不是所有Follower都可以加进来的,如果该Follower长时间没有向Leader同步消息,那么就会被踢出集合,这个时间值默认是10s,在replica.lag.time.max.ms设置 Leaser故障之后也会再ISR里面选取新的Leader,而不会去找其他的节点
生产者允许消息丢失的时候怎么处理
kafka提供了三种可靠级别,在生产者这边配置
acks:0 不等待Broker的ack,提供了最低的延迟,不管kafka有没有收到消息,反正发送出去了,但是消息是最容易丢失的
acks:1 等待Broker的ack,但是只要Leader收到消息之后就返回了,不等其他Follower同步,包括也不等ISR里的,要是Leader这时候挂掉了,就可能丢失消息
acks-1或者ALL 等待Broker的ack,等Partition的Leater和ISR里的Follower全部同步消息了才返回ack,但是在Follower同步完成后,Leader没有来得及把ack发送出去,生产者就以为kafka没有收到消息,可能造成消息重复