存储机制
持久化的消息和非持久化的消息都可以被写入到磁盘。
持久化的消息一开始就会写入磁盘,如果可以,也会在内存中保存一部分以提高性能,当内存吃紧时会从内存中清楚。
非持久化的消息一般存储在内存中,内存吃紧时会换入到磁盘中,以节省内存空间。
这两种类型的消息的落盘处理都在RabbitMQ的”持久层“完成。
持久层
持久层是一个逻辑概念,包含队列索引和消息存储。
- 队列索引(每个队列一个):rabbit_queue_index 负责维护队列中落盘消息的信息,包括消息的存储地点、是否己被交付给消费者、是否己被消费者 ack 等。
rabbit_queue_index 中以顺序(文件名从0开始累加)的段文件来进行存储,后缀为" . idx " ,每个段文件中包含固定的 SEGMENT_ENTRY_COUNT 条记录,SEGMENT-ENTRY-COUNT 默认值为 1638 。每个 rabbit_queue_index 从磁盘中读取消息的时候至少要在内存中维护一个段文件,所以设置 queue_index_embed_msgs_below(存储在哪个结构的临界值) 值的时候要格外谨慎 一点点增大也可能会引起内存爆炸式的增长。
- 消息存储(每个节点有且只有一个):rabbit_msg_store 以键值对的形式存储消息,它被所有队列共享。
经过 rabbit_msg)store 处理的所有消息都会以追加的方式写入到文件中,当这个文件的大小超过指定的限制(file_size_limit)关闭这个文件再创建一个新的文件以供新
的消息写入。文件名(文件后缀是". rdq") 开始进行累加 因此文件名最小的文件也是最老的文件。在进行消息的存储时, bb 会在 ETS(Erlang Term Storage)表中记录消息
在文件中的位置映射(Index)和文件的相关信息( FileSummary)。
消息可以存储在rabbit_queue_index中,也可以存储在在rabbit_msg_store中。最佳的配备是较小的消息存储在 rabbit queue index 中而较大的消息存储在rabbit_msg_store 中。
队列的结构
队列通常由rabbit_amqqueue_process和backing_queue两部分组成
- rabbit_amqqueue_process:负责协议相关的消息处理
- backing_queue:消息存储的具体形式和引擎
惰性队列
尽可能地将消息存入磁盘中,在消费者消费到相应消息时才被加载到内存中。
内存和磁盘告警
内存或者磁盘低于配置的阈值时,RabbitMQ会暂时阻塞客户端的连接直至恢复正常。blocking:对应消费者关联的connection,这时候并不阻塞。blocked:对应发送消息的Connection,这时候阻塞。
流控
RabbitMQ从2.8版本以后还引入了流控来保证系统的稳定性。内存和磁盘告警相当于全局流控,一旦触发会阻塞集群中所有Connection,本流控是针对单个Connection的。
五、RabbitMQ高阶
原文:https://www.cnblogs.com/fcb-it/p/13079545.html