Internal Implementation of RabbitMQ

Source: Internet
Author: User

Internal Implementation of RabbitMQ
Communication Protocol of RabbitMQ

Message sending process:

<AMQP
> 10, 10: Connection. start
<10, 11: Connection. start_ OK
> 10, 30: Connection. tune
<10, 31: Connection. tune_ OK
<10, 40: Connection. open
> 10, 41: Connection. open_ OK
<20,10: Channel. open
> 20, 11: Channel. open_ OK
<85, 10: Confirm. select
> 85,11: Confirm. select_ OK
<60,40: Basic. publish
<Message
> 60, 80: Basic. ack
<20,40: Channel. close
> 20, 41: Channel. close_ OK
<10, 50: Connection. close
> 10, 51: Connection. close_ OK

Message receiving process:

<AMQP
> 10, 10: Connection. start
<10, 11: Connection. start_ OK
> 10, 30: Connection. tune
<10, 31: Connection. tune_ OK
<10, 40: Connection. open
> 10, 41: Connection. open_ OK
<20,10: Channel. open
> 20, 11: Channel. open_ OK
<60,10: Basic. qos
> 60, 11: Basic. qos_ OK
<60,20: Basic. consume
> 60, 21: Basic. consume_ OK
> 60, 60: Basic. deliver
> Message
<60, 80: Basic. ack
...

Implementation of multicast assurance in RabbitMQ

RabbitMQ ensures that the Multicast Guaranteed Multicast is implemented in the gm. erl file.
Guaranteed multicast means that processes in a process group can be dynamically added or deleted. messages sent to the process group are sent to every process in the process group during the message lifecycle. The life cycle of a message starts when the message is sent until the message sender understands that the message has reached all processes in the process group.
This guarantee refers:

  1. If a process group contains a process, the message is sent to each process;
  2. If P sends m and M' successively, for all processes in the group that are added to the process group before m messages are sent, if P receives m ', then it must receive m;
  3. Message order guarantee. If P sends m and M' successively, all Members must receive m and M' successively. However, the causal order is not mandatory, for example, if P receives m and then sends m', other members do not guarantee that m is received first and then m' is received '.

The simplest way to ensure multicast is to send the message to each member in the group by the sender, which requires that all the members in the group be connected to each other. The problem is that if the sender fails to send the message, who is responsible for confirming the message sending success. In addition, when the sender sends a message to each member, the CPU and network pressure on the sender will also be high.
RabbitMQ is not implemented in this way. It organizes all members into a linked list and sends them along the linked list. In this way, no connection is required between all members. If the sender fails, the successor can take over from it, and the message sending overhead for each member is close to the same, so that the pressure on a Member is not high.
Asynchronous Message sending can improve the performance of the entire sending process. In linked list A-> B-> C-> D, if A sends A message, it does not need to establish A connection with C and D. After D receives the message, A can confirm that the message has been sent to each member.

Implementation of Backing Queue

Backing queue is the specific form and engine of message storage. The default backing queue of RabbitMQ is rabbit_variable_queue. To improve memory and disk utilization, rabbit_variable_queue stores messages in the memory or disk according to the specific situation. Four statuses of messages in rabbit_variable_queue:

  • The content and location of the alpha message are in the memory;
  • The beta message is stored on the disk and in the memory;
  • The gamma message content is stored on the disk, in the memory, and on the disk;
  • The delta message content and location are on the disk and are displayed as a group of messages.

For persistent messages (delivery_mode = 2, and exchange and queue are both persistent), messages and locations both exist on disks, and the status belongs to one of the above four states.
In most cases, the message is moved to q1-> q2-> delta-> q3-> q4, and most of the four statuses are skipped. Q1 and q4 only contain alpha status messages; q2 and q3 Contain beta and gamma statuses. When a new message arrives, it determines the status to which it belongs. q1 or other q may be skipped. When a consumer reads a message, it first reads q4. If q4 is null, it reads q3. If q3 is null, the next group of messages in delta is read into q3, and the size of delta is reduced. If a persistent message is sent to a persistent queue, the message is immediately written to msg_store and queue_index.

RabbitMQ message index rabbit_queue_index

Rabbit_queue_index records the location of the message in the disk file system. When the disk is started, RabbitMQ loads the index file and recovers after the crush operation.
Index is divided into many ordered index segment. index segment increases progressively from 0. By default, each index segment file contains 16834 publish, develiver, and ack.
Therefore, index segment 0 contains messages whose id is 0-16834-1, and index segment 1 contains messages whose id is 16834-16834*2-1. Message seq id % 16834 = the position of the message in the segment. When the consumption speed is fast, messages may not be written to the disk. When publish num = ack number in the segment file, the segment is deleted.

Journal File

Because messages may be consumed immediately during production, to avoid redundant IO operations, there is also a fixed length journal file that records each action in sequence. When the journal file is full, the operations are appended to the corresponding segment file and the journal File is cleared. The seq id in the journal File is absolute id, and the id in the segment is relative id. The journal file is also fully stored in the memory, and the seging between the segment id and the corresponding file status is also saved. All operations are appended to the file status. When the journal file is flushed to the segment file, it is found that the number of publish files is consistent with the number of ack files, and no write operation is required. When sync consistency is required, you can sync the journal File.
The message status in the Journal File is as follows: {('no _ pub' | {MsgId, MsgProps, IsPersistent}), ('del '| 'no _ del '), ('ack' | 'no _ ack ')}
Journal File Name: journal. jif
Qistate records dirty count (the number of accumulated logs) and segment Cache Information and file directories. Each action occurs in dirty count + 1, the segment cache information contains the number of message information JEntries and Unack in journal.
When the new action is appended to the log, JEntries is saved in the memory as an Array, RelSeq :{...}, Record the number of Unack, new message + 1, ack-1 at the same time.
New message publish:
If not, save {MsgId, MsgProps, IsPersistent}
RelSeq: {MsgId, MsgProps, IsPersistent}, no_del, no_ack}
Message deletion:
Originally {MsgId, MsgProps, IsPersistent}, no_del, no_ack} and the action was del
RelSeq: {MsgId, MsgProps, IsPersistent}, del, no_ack}
Message ack:
Originally {no_pub, del, no_ack} and the action is ack
RelSeq: {no_pub, no_del, ack}
Message ack:
Originally {MsgId, MsgProps, IsPersistent}, del, no_ack} and the action was ack
Then delete it.
When dirty count is greater than the log limit, the data is flushed into the segment. If unack is set to 0, it indicates that the message is completely consumed. Delete the corresponding segment file. Otherwise, append the message to the corresponding segment file. In the process, you must skip the message of del, ack, and no_pub.

Segment file and other directory files

The suffix of the Segment file. idx. The structure is <REL_ SQL _ONLY_PREFIX, IsPersistent, RelSeq, Body, [DEL], [ACK]> where DEL and ACK are <REL_ SQL _ONLY_PREFIX, RelSeq>.
RabbitMQ creates an MD5 ing folder for each queue in the queues directory. When the folder is down, it creates clean. dot file, and save the data in the memory. Data will be restored from journal during abnormal shutdown and restart. The journal file is flushed to the segment when the queue is idle. When loading a segment, the read ahead method is used to read the object.

File handle cache file_handle_cache

This is an encapsulation of the Erlang file API by RabbitMQ. These APIs are used for both index and message body storage.
Features:

  • Each file supports one write and multiple reads.
  • All writes are append.
  • There is write buffer, no read buffer
  • Manual sync is supported.
  • All call prim_file: * Function
Message storage rabbit_msg_store

Index stores the ing between MsgId and message location {MsgId, RefCount, File, Offset, TotalSize}
FileSummary, ets table File-to-Abstract ing {File, ValidTotalSize, Left, Right, FileSize, Locked, Readers}
Messages in all queues are stored in one file, and the file is also in append mode. After the message is increased, the new file is split. When some messages are consumed, the file will generate holes. ValidTotalSize records the actual space usage. This value is used to calculate whether to execute file GC. File GC combines files with other files to improve storage utilization and execution efficiency. In the case of abnormal shutdown, index and filesummary are reconstructed by scanning the files affected by the GC process. By default, GC is executed when the number of holes in a file exceeds 50%. The GC process is to merge the files on the right to the left: the files on the left will be re-written to the temporary files to form a file without holes, and then written back. Append the valid data in the file on the right to the file on the left. Then update index and filesummary. The message body is counted by reference. messages of the same msgid are stored only once and the number of writes is recorded. The message is deleted only when the same number of times is deleted. The number of references is not stored in the message body. When reading a message, only messages with more than 1 references will be read to the cache, reducing memory usage and improving performance. When a message is deleted, the message is not deleted even if the reference count is equal to 0. To prevent messages from being stored in multiple queues, one queue has been deleted, and the other queue has not started writing. When the file is GC, the file will be locked. Queue operations. The file has a write back cache. The content written by a client can be immediately read by other clients, which eliminates the read blocking during sync. When the write process is very busy, there is no latency in reading and writing. Because msg_store has a buffer, many write and delete events are queued. Flying_ets is used to deal with the situation where publish and remove come before the actual write, and offset by + 1 and-1 count, so that some write operations can be avoided.

Rabbit_amqqueue

Process the Declaration and status information of the queue, high availability policy, permission verification, statistics information, and provide the queue operation interface. This information is stored in mnesia # amqqueue.

Rabbit_amqqueue_process

Queue operation and processing process.

Remove per-connection Traffic Control

You only need to modify:

% Case {CS, (Throttle # throttle. conserve_resources orelse
% Credit_flow: blocked ()}

Is:

Case {CS, Throttle # throttle. conserve_resources}

Consumer Load Balancing

In rabbit_amqueue_process: deliver_msgs_to_consumers, queue: out and queue: in achieve RR load balancing.

Read the message body from the persistent File Based on the Message ID

Ref = rabbit_guid: gen (), MSCState = rabbit_msg_store: client_init (msg_store_persistent, Ref, undefined, undefined), MsgId = <73,201,192, 75,136,167, 149,197,104,141, 81,33 >>, MSCState1 = rabbit_msg_store: read (MsgId, MSCState ).

Install RabbitMQ in CentOS 5.6

Detailed installation record of RabbitMQ client C ++

Try RabbitMQ in Python

Deployment of production instances in the RabbitMQ Cluster Environment

Use PHP + RabbitMQ in Ubuntu

Process of installing RabbitMQ on CentOS

RabbitMQ concept and Environment Construction

RabbitMQ getting started

RabbitMQ details: click here
RabbitMQ: click here

This article permanently updates the link address:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.