summaryrefslogtreecommitdiff
path: root/doc/book/src/producer-flow-control.xml
blob: fd44f51e810e6da2c8f33b04b0337def63fc577a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
<?xml version="1.0" encoding="utf-8"?>
<!--
 
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at
 
   http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 
-->

<section id="producer-flow-control">
  <title>
    Producer Flow Control
  </title>

  <section role="h2" id="producerflowcontrol-Overview">
    <title>
      Overview
    </title>
      <para>
	As of release 0.10, the C++ broker supports the use of flow control to
	throttle back message producers that are at risk of overflowing a
	destination queue.
      </para>

      <para>
        Each queue in the C++ broker has two threshold values associated with it:
      </para>

      <para>
        Flow Stop Threshold: this is the level of queue resource
        utilization above which flow control will be enabled.  Once this
        threshold is crossed, the queue is considered in danger of overflow.
      </para>

      <para>
        Flow Resume Threshold - this is the level of queue resource utilization
        below which flow control will be disabled.  Once this threshold is
        crossed, the queue is no longer considered in danger of overflow.
      </para>

      <para>
        In the above description, queue resource utilization may be
        defined as the total count of messages currently enqueued, or the total
        sum of all message content in bytes.
      </para>

      <para>
        The value for a queue's Flow Stop Threshold must be greater than or
        equal to the value of the queue's Flow Resume Threshold.
      </para>

    <section role="h3" id="producerflowcontrol-QueueThresholdsExample">
      <title>
	Example
      </title>

      <para>
        Let's consider a queue with a maximum limit set on the total number of
        messages that may be enqueued to that queue.  Assume this maximum
        message limit is 1000 messages.  Assume also that the user configures a
        Flow Stop Threshold of 900 messages, and a Flow Resume Threshold of 500
        messages.  Then the following holds:
      </para>

      <para>
        The queue's initial flow control state is "OFF".
      </para>

      <para>
        While the total number of enqueued messages is less than or equal to
        900, the queue's flow control state remains "OFF".
      </para>

      <para>
        When the total number of enqueued messages is greater than 900, the
        queue's flow control state transitions to "ON".
      </para>

      <para>
        When the queue's flow control state is "ON", it remains "ON" until the
        total number of enqueued messages is less than 500.  At that point, the queue's
        flow control state transitions to "OFF".
      </para>

      <para>
        A similar example using total enqueued content bytes as the threshold
        units are permitted.
      </para>
    </section>

    <para>
      Thresholds may be set using both total message counts and total byte
      counts.  In this case, the following rules apply:
    </para>

    <para>
      1) Flow control is "ON" when either stop threshold value is crossed.
    </para>
    <para>
      2) Flow control remains "ON" until both resume thresholds are satisfied.
    </para>

    <section role="h3" id="producerflowcontro-MultiThresholdExample">
      <title>
	Example
      </title>

    <para>
      Let's consider a queue with a maximum size limit of 10K bytes, and 5000
      messages.  A user may assign a Flow Stop Threshold based on a total
      message count of 4000 messages.  They may also assigne a Flow Stop
      Threshold of 8K bytes.  The queue's flow control state transitions to
      "ON" if either threshold is crossed: (total-msgs greater-than 4000 OR total-bytes
      greater-than 8K).
    </para>

    <para>
      Assume the user has assigned Flow Resume threshold's of 3000 messages and
      6K bytes.  Then the queue's flow control will remain active until both
      thresholds are satified: (total-msg less-than 3000 AND total-bytes less-than 6K).
    </para>
    </section>

    <para>
      The Broker enforces flow control by delaying the completion of the
      Message.Transfer command that causes a message to be delivered to a queue
      with active flow control.  The completion of the Message.Transfer command
      is held off until flow control state transitions to "OFF" for all queues
      that are a destination for that command.
    </para>

    <para>
      A message producing client is permitted to have a finite number of
      commands pending completion.  When the total number of these outstanding
      commands reaches the limit, the client must not issue further commands
      until one or more of the outstanding commands have completed.  This
      window of outstanding commands is considered the sender's "capacity".
      This allows any given producer to have a "capacity's" worth of messages
      blocked due to flow control before the sender must stop sending further
      messages.
      </para>

      <para>
        This capacity window must be considered when determining a suitable
        flow stop threshold for a given queue, as a producer may send its
        capacity worth of messages _after_ a queue has reached the flow stop
        threshold.  Therefore, a flow stop threshould should be set such that
        the queue can accomodate more messages without overflowing.
      </para>

      <para>
        For example, assume two clients, C1 and C2, are producing messages to
        one particular destination queue.  Assume client C1 has a configured
        capacity of 50 messages, and client C2's capacity is 15 messages.  In
        this example, assume C1 and C2 are the only clients queuing messages to
        a given queue.  If this queue has a Flow Stop Threshold of 100
        messages, then, worst-case, the queue may receive up to 165 messages
        before clients C1 and C2 are blocked from sending further messages.
        This is due to the fact that the queue will enable flow control on
        receipt of its 101'st message - preventing the completion of the
        Message.Transfer command that carried the 101'st message.  However, C1
        and C2 are allowed to have a total of 65 (50 for C1 and 15 for C2)
        messages pending completion of Message.Transfer before they will stop
        producing messages.  Thus, up to 65 messages may be enqueued beyond the
        flow stop threshold before the producers will be blocked.
      </para>
    </section>

    <section role="h2" id="producerflowcontrol-UserInterface">
      <title>
        User Interface
      </title>

      <para>
        By default, the C++ broker assigns a queue's flow stop and flow resume
        thresholds when the queue is created.  The C++ broker also allows the
        user to manually specify the flow control thresholds on a per queue
        basis.
      </para>

      <para>
        However, queues that have been configured with a Limit Policy of type
        RING or RING-STRICT do NOT have queue flow thresholds enabled by
        default.  The nature of a RING queue defines its behavior when its
        capacity is reach: replace the oldest message.
      </para>

      <para>
        The flow control state of a queue can be determined by the "flowState"
        boolean in the queue's QMF management object.  The queue's management
        object also contains a counter that increments each time flow control
        becomes active for the queue.
      </para>

      <para>
        The broker applies a threshold ratio to compute a queue's default flow
        control configuration.  These thresholds are expressed as a percentage
        of a queue's maximum capacity.  There is one value for determining the
        stop threshold, and another for determining the resume threshold.  The
        user may configure these percentages using the following broker
        configuration options:
      </para>

      <programlisting>
        --default-flow-stop-threshold ("Queue capacity level at which flow control is activated.")
        --default-flow-resume-threshold ("Queue capacity level at which flow control is de-activated.")
      </programlisting>

      <para>
        For example:
      </para>

      <programlisting>
        qpidd --default-flow-stop-threshold=90 --default-flow-resume-threshold=75
      </programlisting>

      <para>
        Sets the default flow stop threshold to 90% of a queue's maximum
        capacity and the flow resume threshold to 75% of the maximum capacity.
        If a queue is created with a default-queue-limit of 10000 bytes, then
        the default flow stop threshold would be 90% of 10000 = 9000 bytes and
        the flow resume threshold would be 75% of 10000 = 7500.  The same
        computation is performed should a queue be created with a maximum size
        expressed as a message count instead of a byte count.
      </para>

      <para>
        If not overridden by the user, the value of the
        default-flow-stop-threshold is 80% and the value of the
        default-flow-resume-threshold is 70%.
      </para>

      <para>
        The user may disable default queue flow control broker-wide by
        specifying the value 0 for both of these configuration options.  Note
        that flow control may still be applied manually on a per-queue basis in
        this case.
      </para>

      <para>
        The user may manually set the flow thresholds when creating a queue.
        The following options may be provided when adding a queue using the
        <command>qpid-config</command> command line tool:
      </para>

      <programlisting>
        --flow-stop-size=<replaceable>N</replaceable>  Sets the queue's flow stop threshold to <replaceable>N</replaceable> total bytes.
        --flow-resume-size=<replaceable>N</replaceable>  Sets the queue's flow resume threshold to <replaceable>N</replaceable> total bytes.
        --flow-stop-count=<replaceable>N</replaceable> Sets the queue's flow stop threshold to <replaceable>N</replaceable> total messages.
        --flow-resume-count=<replaceable>N</replaceable> Sets the queue's flow resume threshold to <replaceable>N</replaceable> total messages.
      </programlisting>

      <para>
        Flow thresholds may also be specified in the
        <command>queue.declare</command> method, via the
        <command>arguments</command> parameter map.  The following keys can be
        provided in the arguments map for setting flow thresholds:
      </para>

      <table>
        <title>Queue Declare Method Flow Control Arguments</title>
        <tgroup cols="2">
          <thead>
            <row>
              <entry>Key</entry>
              <entry>Value</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>qpid.flow_stop_size</entry>
              <entry>integer - queue's flow stop threshold value in bytes</entry>
            </row>
            <row>
              <entry>qpid.flow_resume_size</entry>
              <entry>integer - queue's flow resume threshold value in bytes</entry>
            </row>
            <row>
              <entry>qpid.flow_stop_count</entry>
              <entry>integer - queue's flow stop threshold value as a message count</entry>
            </row>
            <row>
              <entry>qpid.flow_resume_count</entry>
              <entry>integer - queue's flow resume threshold value as a message count</entry>
            </row>
          </tbody>
        </tgroup>
      </table>

      <para>
        The user may disable flow control on a per queue basis by setting
        the flow-stop-size and flow-stop-count to zero for the queue.
      </para>

      <para>
        The current state of flow control for a given queue can be
        determined by the "flowStopped" statistic.  This statistic is
        available in the queue's QMF management object. The value of
        flowStopped is True when the queue's capacity has exceeded the
        flow stop threshold.  The value of flowStopped is False when the
        queue is no longer blocking due to flow control.
      </para>

      <para>
        A queue will also track the number of times flow control has been
        activated.  The "flowStoppedCount" statistic is incremented each time
        the queue's capacity exceeds a flow stop threshold.  This statistic can
        be used to monitor the activity of flow control for any given queue
        over time.
      </para>

      <table>
        <title>Flow Control Statistics available in Queue's QMF Class</title>
        <tgroup cols="3">
          <thead>
            <row>
              <entry>Statistic Name</entry>
              <entry>Type</entry>
              <entry>Description</entry>
            </row>
          </thead>
          <tbody>
            <row>
              <entry>flowStopped</entry>
              <entry>Boolean</entry>
              <entry>If true, producers are blocked by flow control.</entry>
            </row>
            <row>
              <entry>flowStoppedCount</entry>
              <entry>count32</entry>
              <entry>Number of times flow control was activated for this queue</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section>
    <!--h2-->
  </section>