Kafka
依赖zookeeper
kafka4.0才完全删除zk
Kafka如何保证消息不丢失
生产者:设置重试次数retries = 3
消费者:手动提交offset
Kafka不丢消息
acks = all
副本数replication.factor >= 3
最少写入几个副本min.insync.replicas > 1
replication.factor = min.insync.replicas + 1
Kafka 如何保证消息不重复消费
消费消息服务做幂等校验
拉取到消息即提交,会有消息丢失的风险,通过定时任务同步数据兜底
kafka消费端重试
DEFAULT_MAX_FAILURES = 10
间隔为0
RabbitMQ
Exchange Types(交换器类型)
- fanout:它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。
- direct:它会把消息路由到那些Bindingkey与RoutingKey完全匹配的Queue中。
- topic:将消息路由到 BindingKey 和 RoutingKey 相匹配的队列中,通配符匹配
- headers:不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的 headers 属性进行匹配。
死信队列
DLX,全称为 Dead-Letter-Exchange
导致的死信的几种原因:
- 消息被拒(Basic.Reject /Basic.Nack) 且 requeue = false。
- 消息 TTL 过期。
- 队列满了,无法再添加。
延迟队列
RabbitMQ 本身是没有延迟队列的,通过 RabbitMQ 本身队列的特性来实现,需要使用 RabbitMQ 的死信交换机(Exchange)和消息的存活时间 TTL(Time To Live)。
使用rabbitmq-delayed-message-exchange插件
RabbitMQ高可用
- 普通集群模式:你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据。
- 镜像集群模式:在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。
RabbitMQ消息不丢失
- 生产者到交换机,confirm确认,判断ack是否为true,投递失败增加补偿措施
- 交换机到队列,开启return返回模式,根据返回码判断是否投递成功
- 队列数据不丢失,交换机、队列、消息持久化,集群高可用
- 消费者消费消息,手动确认,增加重试次数,丢入死信队列
RabbitMQ保证幂等性
- 生成者发送消息,增加全局唯一id
- 消费者消费时,使用redis setnx命令
百万消息堆积
- 提前预防,做好压测预估
- 应急处理,临时增加消费者数量,先写入其他设备,现在生产者发送速度
- 事后优化,增加消费速度
Zookeeper
zk是什么
ZooKeeper 是一个开源的分布式协调服务,通常被用于实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
znode
- 持久(PERSISTENT)节点:一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
- 临时(EPHEMERAL)节点:临时节点的生命周期是与 客户端会话(session)绑定的,会话消失则节点消失。并且,临时节点只能做叶子节点,不能创建子节点。
- 持久顺序(PERSISTENT_SEQUENTIAL)节点:除了具有持久(PERSISTENT)节点的特性之外,子节点的名称还具有顺序性。比如/node1/app0000000001、/node1/app0000000002。
- 临时顺序(EPHEMERAL_SEQUENTIAL)节点:除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性
集群角色
- Leader:为客户端提供读和写的服务,负责投票的发起和决议,更新系统状态。
- Follower:为客户端提供读服务,如果是写服务则转发给 Leader。参与选举过程中的投票。
- Observer:为客户端提供读服务,如果是写服务则转发给 Leader。不参与选举过程中的投票,也不参与“过半写成功”策略。在不影响写性能的情况下提升集群的读性能。此角色于 ZooKeeper3.3 系列新增的角色。
ZAB协议
ZAB(ZooKeeper Atomic Broadcast,原子广播) 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。
- 崩溃恢复:当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的 Leader 服务器,同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。其中,所谓的状态同步是指数据同步,用来保证集群中存在过半的机器能够和 Leader 服务器的数据状态保持一致。
- 消息广播:当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。 当一台同样遵守 ZAB 协议的服务器启动后加入到集群中时,如果此时集群中已经存在一个 Leader 服务器在负责进行消息广播,那么新加入的服务器就会自觉地进入数据恢复模式:找到 Leader 所在的服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。
zk选举
epoch大直接胜出,再比较zxid,再比较myid
- 优先选择拥有最新数据的节点(epoch 和 zxid)
- 若数据一样,优先选 myid 较大的服务器
选举阶段
- 初始状态
- 所有节点启动时都认为自己是 Leader(LOOKING 状态)
- 每个节点会发出一条 选票,选自己为 Leader,附带自己的 epoch 和 zxid 信息(数据事务号)
选票内容:<myid, epoch, zxid>
- 互相发送选票
- 所有节点将自己的选票广播给集群中其他所有节点
- 收到他人选票后,和自己的选票进行对比
- 投票规则
对于每台节点来说,会维护一个“当前投票选的 Leader 候选人”(可能是自己或别人),当它接收到其他投票后,会根据以下规则判断是否更新自己的投票人:新选票的 (epoch, zxid) 更大,则更新自己的投票人
若 (epoch, zxid) 相同,选择 myid 更大的作为 Leader - 达成多数票
当某个候选人获得了超过半数节点的投票,选举成功:- 被选中的节点状态变为 LEADING
- 其他节点变为 FOLLOWING
- 整个集群进入正常工作状态