Guide to Queuing

Ultra Load Balancing (ULB)

Use Ultra Load Balancing (ULB) to evenly distribute a message load to receiving applications without a broker between sending and receiving applications.

A ULB source sends messages on a UM topic. The source also sends receiver assignment control information. This control information identifies which receiver is to process each message. Receivers unicast message consumption reports back to the source.

ULB sources and receivers use standard Ultra Messaging contexts and do not connect to brokers.

For information on ULB configuration options, see Ultra Messaging Queuing Options, paying special attention to options with "ulb" in the name.

Attention
  The ULB feature is not compatible with setting ordered_delivery (receiver) to `"0"` (arrival order without reassembly).

# Application Sets and Receiver Type IDs <-

You must group ULB receivers into one or more groups called application sets. Within an application set, a ULB source assigns each sent message to only one receiver. If multiple applications sets are defined, then each message is assigned to one receiver in each set. I.e. multiple copies of each message are sent, one for each application set.

The following diagram shows how an ULB source disseminates messages to receivers in application sets:

Subscribing applications create ULB receivers that register with a ULB source. The source adds each receiver to an application set according to a receiver type ID which is supplied by the subscribing application. The source's configuration defines which receivers are added to which application sets using the configuration option umq_ulb_application_set (source).

Application Sets are identified with an integer between 0 and 65535. The sets must be numbered consecutively, starting from 0. In the diagram above, application set "A" would be 0, and "B" would be 1.

Receiver Type IDs are arbitrary 32-bit integers selected and managed by the application designer. There is no requirement for these IDs to be consecutively numbered. When a receiver registers with the source, the ID is used by the source to determine various configuration options to be associated with that receiver, such as which application set the receiver belongs in. Here are the configuration options that the source associates with receivers by their type IDs:

- umq_ulb_application_set (source)
- umq_ulb_receiver_portion (source)
- umq_ulb_receiver_priority (source)
- umq_ulb_receiver_events (source)

For example, in the diagram above the source might be an order entry system, load balancing orders across a set of three execution engines (application set A), and also load balancing those same orders across a set of two logger processes (application set B). We could define execution engines to be type 10 and the loggers to be type 20. The source would be configured as:

    source umq_ulb_application_set 0:10;1:20

Three execution engines would start up, each setting umq_receiver_type_id (receiver) to 10. Two logger processes would start up, each setting umq_receiver_type_id (receiver) to 20. Thus, each order will be sent to two receivers: one of the execution engines and one of the loggers.

A ULB source sends both the message data and the assignment control information on the same transport session to all receivers. The source also sends assignment data so that the assigned receiver in each application set processes the message. The receivers not assigned ignore the message. When the assigned receivers process their messages, they unicast Consumed reports back to the source.

# Load Balancing <-

ULB differs from brokered queues regarding assignment uniformity (fairness). Multiple ULB sources to the same topic do not coordinate their assignments with each other. It is possible for multiple ULB sources to all send their next message to the same receiver.

Ultra Load Balancing governs fairness between sources by using the following information:

- receiver feedback information
- receiver portion size
- configuration option umq_ulb_application_set_load_factor_behavior (source)

## ULB Performance <-

ULB is built on top of standard UM sources and receivers. As such, all receivers receive all messages sent to the topic, even ULB receivers. The normal load-balancing queuing semantics are implemented above the transport, so that only the assigned receiver delivers a particular message to the application; the other un-assigned receivers discard the message.

For multicast-based data transport (LBT-RM), there is no performance penalty to sending each message to all receivers. However, for unicast-based data transports (e.g. LBT-RU, LBT-TCP), the normal source semantic of delivering each message to all receivers represents an inefficiency and limits the maximum sustainable throughput. As receivers are added to a ULB topic, the efficiency continues to drop due to unnecessary sends of messages to unassigned receivers, thus lowering the maximum sustainable throughput further with each added receiver.

ULB Source-Side Filtering

Starting with UM version 6.12, the Source-Side Filtering feature has been enhanced to support load-balancing queue semantics. Configure the ULB source with the option transport_source_side_filtering_behavior (source) set to `"ulb"`. This causes the unicast source to send a particular message to only the assigned receiver. This reduces work for both the unicast source and for the un-assigned receivers. As receivers are added, the maximum sustainable throughput does not significantly drop.

To benefit from this feature, receivers must be configured for arrival order delivery by setting ordered_delivery (receiver) to `-1`. Receivers without that setting will work correctly with the source, but will not benefit from the ULB Source-Side Filtering feature. I.e. receivers configured for ordered delivery value `1` (the default) will continue to receive all messages sent, and discard the non-assigned messages.

A ULB source must be at UM version 6.12 or beyond to enable ULB Source Side Filtering. That source is fully interoperable with receivers at UM versions before 6.12, but the older receivers will not benefit from the ULB Source-Side Filtering feature. I.e. pre-6.12 receivers will continue to receive all messages sent, and discard the non-assigned messages.

# Ultra Load Balancing Flight Size <-

Ultra Load Balancing uses a flight size mechanism to limit the number of messages sent but not consumed, and blocks a source or warns when a send exceeds the configured flight size. Set Ultra Load Balancing with configuration option umq_ulb_flight_size (source).

You can set configuration option umq_ulb_flight_size_behavior (source) to either of the following behaviors:

- Block any sends that would exceed the flight size.
- Continue to allow sends while notifying the sending application.

Ultra Load Balancing considers a message in-flight until the source receives the MSG_COMPLETE event, based on a message consumption or a message timeout from all assigned receivers.

# Indexed Ultra Load Balancing <-

Indexed Ultra Load Balancing is a way to group messages and ensure that one receiver processes all messages in the group in the order they are sent. The source uses an index to assign the messages in a group. An index is an application-defined 64-bit unsigned number or free-form string.

If you must process a set of messages in order, it can be more efficient for one receiver to process the messages. You can set the same index in all related messages to ensure that they all go to one receiver.

Send messages with an index using send call lbm_src_sendv_ex() that includes a pointer to lbm_umq_index_info_t in lbm_src_send_ex_info_t.

By default, all receivers are eligible for index assignment. When the source assigns the first message with a particular index to a receiver in each application set, the source assigns subsequent messages with that same index to those same receivers.

Note that because Ultra Load Balancing sources make assignment decisions independently, multiple sources that send on the same index might assign the index to different receivers.

# Total Message Lifetimes for Ultra Load Balancing <-

You can set a total message lifetime for Ultra Load Balancing applications in different ways.

An Ultra Load Balancing message total lifetime starts when the source sends the message, and ends when the source receives a consumption report or times out. In each case, you set the timeout to a value in milliseconds. If the message times out, the source reclaims the memory.

By default, there is no message lifetime limit. Messages must be consumed.

A timeout can be set with the configuration option umq_ulb_application_set_message_lifetime (source).

Also, it is possible to set a timeout on a per-message basis using the lbm_src_send_ex() API. Set lbm_src_send_ex_info_t_stct::umq_total_lifetime to point at a lbm_umq_msg_total_lifetime_info_t structure, and fill in the lbm_umq_msg_total_lifetime_info_t_stct::umq_msg_total_lifetime field.

If you set a timeout using both the configuration option and the API, the API overrides the configured setting.