-
-
解耦、异步通信、削峰、冗余、异常处理,分布式事务的最终一致性。
-
消息不丢
-
微秒级,这是 RabbitMQ 的一大特点,延迟最低
-
-
消息队列有什么优点和缺点?
-
系统可用性降低,过度依赖mq
-
系统复杂度提高:
-
顺序:在消费者中解决顺序问题
-
重复:消息幂等。
-
丢失:系统保证,本地发消息,消息到消息中心,再到交换机,队列。均采用日志的形式。
-
-
一致性问题:mq是异步,弱一致性,强最终一致性的工具。 非必要消息,和可延迟的用mq。
-
-
Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?
-
消息丢失怎么办?
-
-
生产者丢消息:
-
同步:用事务控制,影响性能。
-
异步:/confirm/i模式:每个消息一个id ,发送方ack确认。
-
-
RabbitMQ丢消息:
-
开启持久化:
-
队列持久化,
-
消息持久化,deliverMode = 2
-
-
如果还没有持久化mq挂了,ack 机制发送者能感知到。
-
-
消费端丢消息: 还没消费,进程挂了。
-
关闭自动ACK,处理后,进行手动ack
-
-
-
RabbitMQ的高可用
-
实现:主从(非分布式)
-
模式:
-
单机、
-
普通集群:队列只在一台机器,一个挂了就挂了。
-
镜像集群:主从,但是一个机器会包含所有数据。没有扩展性。
-
-
-
如何保证消息顺序性:
-
场景:一个queue多个消费者,
-
解决方式:一个消费者,内存自己排序后,调用worker处理。
-
-
如何解决消息队列的延时以及过期失效问题:
-
队列积压:
-
先解决消费卡脖子问题。
-
考虑是否扩容。
-
增加消费速率。
-
-
失效大量ttl::
-
写脚本,拉出来,塞进队列
-
开发mq后台,进行持久化后,
-
-
-
设计一个消息队列。
-
发送者:
-
建立channel Tcp连接
-
信道的原理是一条线程一条信道,多条线程多条信道共同使用一条TCP连接。一条TCP连接可以容纳无限的信道,及时每秒造成成千上万的请求也不会造成性能瓶颈
-
发送消息 + 处久化 + ack回应
-
-
服务器 broker 代理:
-
交换机:(binding key) xxx_direct xxx_topic
-
-
直接(Direct):直接交换机通过消息上的路由键直接对消息进行分发。
-
扇出(Fanout):一个扇出交换机会将消息发送到所有和它进行绑定的队列上。
-
主题(Topic):这个交换机会将路由键和绑定上的模式进行通配符匹配。
-
-
持久化消息:必须和队列一起被持久化
-
ack应答
-
消息分发到queue:
-
-
消费者:
-
轮询拉取队列里的消息
-
Ack 应答
-
消费中挂掉了,broker 收不到ack怎么办? broker 会判断是否断开连接,重新
-
-
HA:
-
普通模式:同步节点所以信息,不包含message
-
镜像模式: 副本
-
-
-
KafKa:
-
设计:
-
以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能保证常数时间的访问性能。
-
高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100K条消息的传输。
-
支持Kafka Server间的消息分区,及分布式消费,同时保证每个partition内的消息顺序传输。
-
同时支持离线数据处理和实时数据处理。
-
Scale out:支持在线水平扩展
-
-
-
producer 流程:
-
producer 根据 broker 拿到对应存储的paritition地址。
-
broker会根据paritition机制选择一个存储。
-
broker通过ZooKeeper找到该Partition的Leader返回
-
-
producer向Partition发消息
-
Leader 写到本地 log
-
follower 从 leader pull数据,pull到 发ack给leader ,然后写到本地log
-
-
Partition leader发ack给producer
-
-
consumer 流程:
-
consumer注册到zookeeper上
-
Consumer 去pull partition 数据
-
服务器会记录每个consumer的在每个topic的每个partition下的消费的offset,然后每次去消费去拉取数据时,都会从上次记录的位置开始拉取数据
-
offset() + 全局消息id
-
通过offset 二分法找到 segment
-
通过offset 二分法 index 中 大概位置
-
通过全局消息id 二分法 找到log中 消息位置。
-
-
一个group的consumer 和 partition 数量最好一致。
-
consumer 消费后会发commit 给zookeeper 更新偏移量
-
-
存储:
-
每一个partition 都是一个文件,包含2部分,稀疏索引,log查找根据2分发
-
.index文件:offset, 物理偏移量
-
.log文件:全局消息id + 数据
-
Segment:partition物理上由多个segment组成。
-
-
-
Kafka性能为什么快:
-
分区
-
为什么要有paritition:负载均衡,消除机器io的性能瓶颈。
-
consumer group 设定
-
-
网络传输上减少开销
-
批量发送:先缓存到内存中,超过一定大小或时间发送
-
端到端压缩:数据从发送到服务器上 都是压缩,不解压,频繁压缩和解压会降低性能。到消费者手上也是压缩的。
-
-
顺序读写:
-
顺序 和随机 差6000倍
-
-
零拷贝技术:
-
传统 文件到socket 中需要
-
从磁盘co 到 内核缓冲区
-
切换内核到用户 co 到 用户缓冲区
-
应用程序讲数据写到内核的socket缓冲区
-
*** 作系统, co到 网卡接口缓冲区 发出去
-
-
调用linux sendfile系统实现0拷贝,java调用FileChannel.transferTo
-
从磁盘通过DMA引擎复制到内核缓冲区直接放到网卡接口
-
-
优秀的文件存储机制
-
稀疏索引、文件采用偏移量,利用二分法查找。
-
-
-
主从复制机制:
-
Broker 的 主从,读写和备份分离,leader选举
-
完全同步:follower 都复制了才算commit
-
完全异步:leader 写入log 才算
-
kafka:有一个复制到内存就算commit
-
leader的ISR列表:从落后太多会剔除,默认10000
-
-
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)