|
123 | 123 |
|
124 | 124 | -behaviour(rabbit_backing_queue). |
125 | 125 |
|
126 | | --record(vqstate, |
127 | | - { q_head, |
128 | | - q_tail, |
129 | | - next_seq_id, |
130 | | - %% seq_id() of first undelivered message |
131 | | - %% everything before this seq_id() was delivered at least once |
132 | | - next_deliver_seq_id, |
133 | | - ram_pending_ack, %% msgs still in RAM |
134 | | - disk_pending_ack, %% msgs in store, paged out |
135 | | - index_state, |
136 | | - store_state, |
137 | | - msg_store_clients, |
138 | | - durable, |
139 | | - transient_threshold, |
140 | | - qi_embed_msgs_below, |
141 | | - |
142 | | - bytes, %% w/o unacked |
143 | | - unacked_bytes, |
144 | | - persistent_count, %% w unacked |
145 | | - persistent_bytes, %% w unacked |
146 | | - |
147 | | - ram_msg_count, %% w/o unacked |
148 | | - ram_bytes, %% w unacked |
149 | | - out_counter, |
150 | | - in_counter, |
151 | | - rates, |
152 | | - %% There are two confirms paths: either store/index produce confirms |
153 | | - %% separately (v2 with per-vhost message store) or the confirms |
154 | | - %% are produced all at once while syncing/flushing (v2 with per-queue |
155 | | - %% message store). The latter is more efficient as it avoids many |
156 | | - %% sets operations. |
157 | | - msgs_on_disk, |
158 | | - msg_indices_on_disk, |
159 | | - unconfirmed, |
160 | | - confirmed, |
161 | | - ack_out_counter, |
162 | | - ack_in_counter, |
163 | | - %% Unlike the other counters these two do not feed into |
164 | | - %% #rates{} and get reset |
165 | | - disk_read_count, |
166 | | - disk_write_count, |
167 | | - |
168 | | - %% Fast path for confirms handling. Instead of having |
169 | | - %% index/store keep track of confirms separately and |
170 | | - %% doing intersect/subtract/union we just put the messages |
171 | | - %% here and on sync move them to 'confirmed'. |
172 | | - unconfirmed_simple, |
173 | | - %% Queue data is grouped by VHost. We need to store it |
174 | | - %% to work with queue index. |
175 | | - virtual_host |
176 | | - }). |
| 126 | +-record(vqstate, { |
| 127 | + %% Head of the queue. Index information has been loaded into |
| 128 | + %% memory, and message body may have been depending on size. |
| 129 | + q_head, |
| 130 | + %% Tail of the queue, fully on disk. |
| 131 | + q_tail, |
| 132 | + |
| 133 | + %% SeqId of the next message published. |
| 134 | + next_seq_id, |
| 135 | + %% Everything before this SeqId was delivered at least once. |
| 136 | + %% @todo Do we really need this if we add delivery_count? |
| 137 | + %% No we don't, we will just check delivery_count to know if was already delivered (delivery_count > 1). |
| 138 | + %% NO!! We can also remove the is_delivered in the msg_status since that value --doesn't-- DOES!! survive restarts. |
| 139 | + %% Actually we are using next_deliver_seq_id to know whether a message was already delivered and that survives restarts. |
| 140 | + %% But we could very well do the same with a delivery_count map. So making the delivery_count map survive restarts |
| 141 | + %% (and properly clean up on restart by removing transients) is the key to getting rid of these things. |
| 142 | + next_deliver_seq_id, |
| 143 | + |
| 144 | + %% Messages pending acks. These messages have been delivered to the channel |
| 145 | + %% and we are expecting an ack (or requeue) back. Messages are in ram or disk |
| 146 | + %% depending on whether the #msg_status{} record contains the message body. |
| 147 | + %% Typically only smaller message bodies are kept in memory, larger ones are |
| 148 | + %% read only when needed. |
| 149 | + ram_pending_ack, |
| 150 | + disk_pending_ack, |
| 151 | + |
| 152 | + %% Index, queue store and shared message store states. In the latter's case |
| 153 | + %% since the shared message store is separate processes, the state only |
| 154 | + %% contains information to access it. |
| 155 | + index_state, |
| 156 | + store_state, |
| 157 | + msg_store_clients, |
| 158 | + |
| 159 | + %% Whether the queue is durable. Used to determine whether messages are |
| 160 | + %% truly persistent (both messages and queue must be durable). |
| 161 | + durable, |
| 162 | + |
| 163 | + %% We must keep the virtual host information around in order to write |
| 164 | + %% terms when terminating as the terms file is per-vhost. |
| 165 | + virtual_host, |
| 166 | + |
| 167 | + %% SeqId of the first persistent message. Determined during recovery and |
| 168 | + %% used to identify which transient messages belong to a previous |
| 169 | + %% incarnation of the node. We don't remove transient messages during |
| 170 | + %% recovery to keep recovery fast (otherwise we'd have to go over the |
| 171 | + %% entire queue contents), instead we mark where we left off and drop |
| 172 | + %% the messages when they would have been consumed. |
| 173 | + transient_threshold, |
| 174 | + |
| 175 | + %% Maximum size of messages written to the queue store. The queue |
| 176 | + %% store is meant to contain smaller messages, while larger messages |
| 177 | + %% go to the shared message store. The shared message store benefits |
| 178 | + %% from mechanisms like compaction and deduplication. |
| 179 | + qi_embed_msgs_below, |
| 180 | + |
| 181 | + %% There are two confirms paths: either store/index produce confirms |
| 182 | + %% separately (per-vhost message store) or the confirms |
| 183 | + %% are produced all at once while syncing/flushing (per-queue |
| 184 | + %% message store). The latter is more efficient as it avoids many |
| 185 | + %% sets operations. |
| 186 | + msgs_on_disk, |
| 187 | + msg_indices_on_disk, |
| 188 | + unconfirmed, |
| 189 | + confirmed, |
| 190 | + %% Fast path for confirms handling. Instead of having |
| 191 | + %% index/store keep track of confirms separately and |
| 192 | + %% doing intersect/subtract/union we just put the messages |
| 193 | + %% here and on sync move them to 'confirmed'. |
| 194 | + unconfirmed_simple, |
| 195 | + |
| 196 | + %% Metrics that are also used for sanity checking. |
| 197 | + %% |
| 198 | + %% They measure (with "unacked" meaning "messages pending acks"): |
| 199 | + %% * the number of bytes in the queue (excluding unacked) |
| 200 | + %% * the number of bytes in messages pending acks |
| 201 | + %% * the number of persistent messages (including unacked) |
| 202 | + %% * the number of bytes for persistent messages (including unacked) |
| 203 | + %% * the number of messages currently in memory |
| 204 | + %% (excluding unacked because we can get those via `map_size(RPA)`) |
| 205 | + %% * the number of bytes of messages currently in memory (including unacked) |
| 206 | + %% |
| 207 | + %% The total number of bytes of messages in the queue (including unacked) |
| 208 | + %% is bytes + unacked_bytes. |
| 209 | + %% |
| 210 | + %% Messages can be both persistent and in memory at the same time, |
| 211 | + %% for example when they are close to being delivered. |
| 212 | + bytes, |
| 213 | + unacked_bytes, |
| 214 | + persistent_count, |
| 215 | + persistent_bytes, |
| 216 | + ram_msg_count, |
| 217 | + ram_bytes, |
| 218 | + |
| 219 | + %% Metrics for outgoing and ingoing messages rates. |
| 220 | + %% |
| 221 | + %% Counters get incremented per event and then an average is calculated |
| 222 | + %% periodically into the #rates{} record. |
| 223 | + out_counter, |
| 224 | + in_counter, |
| 225 | + ack_out_counter, |
| 226 | + ack_in_counter, |
| 227 | + rates, |
| 228 | + |
| 229 | + %% Metrics totalling message reads and writes from/to disk. |
| 230 | + disk_read_count, |
| 231 | + disk_write_count |
| 232 | +}). |
177 | 233 |
|
178 | 234 | -record(rates, { in, out, ack_in, ack_out, timestamp }). |
179 | 235 |
|
|
0 commit comments