Understanding Aeron Position¶
A position in Aeron is defined as the unique identification of a byte within each stream across time. The position is specific to a streamId on a given channel, and a sessionId on a given channel/streamId. In addition, the termId and termOffset come into play, as the position increases continuously as log buffer terms are rotated. The size of the data sent by your application is only one part of what could increment the position - header and padding data will also impact it.
To illustrate Position in action, we will look at a simple pair of applications, one holding an Aeron subscription (Subscriber Application) and another holding an Aeron publication (Publisher Application). The Publisher Application is sending a small packet of data to the Subscriber Application. In a flow like this, the primary moving parts are the Aeron publication and sender on the Publishing Application, and the receiver and subscription in the Subscriber Application.
Using the above example, the following positions will be found in the Aeron counters:
- Publication Application
pub-pos- this is the Publication's sampled position
pub-lmt- this is the Publication's limit
snd-pos- this is the position of the Sender in the Media Driver
snd-lmt- this is the limit of the Sender in the Media Driver
snd-bpe- this is the count of Back Pressure events in this channel/stream/session (see Back Pressure)
- Subscription Application
rcv-hwm- this is the high water mark position of the Receiver in the Media Driver
rcv-pos- this is the completed position of the Receiver in the Media Driver
sub-pos- this is the Subscription's position
The flow of positions can be simpler to understand when the movement of data is animated:
In a happy path scenario, the positions are moved as follows:
- As the Publisher Application writes to the Publication, the publisher position is increased. The data is appended to the term buffer, which updates the committed data position (i.e. the
- The Publisher Application Media Driver Sender checks for any new data appended in the term buffer. If it finds data to send, the data is sent and
- The Subscriber Application Media Driver Receiver receives data from the network buffer. It updates the
rcv-posafter appending the data to the local term buffer.
- The Subscriber polls the term buffer, and once it has consumed the message, the
Since the sample above is for a single message, the receiver position and receiver high water mark do not vary. They will vary when messages are received out of order by the Media Driver Receiver, for example:
Term Length & Positions¶
The maximum position supported is determined by the term length, and is term length * 2^31.
MTU & Positions¶
Aeron's position is not exclusively down to an application data position - the Aeron header and padding data are also included in the position. In turn, the amount of header and padding data is directly impacted by the MTU length, since the data offered to a Publication is processed for a given MTU length. If message length exceeds the MTU length (less header), messages will be fragmented into MTU sized messages and have additional headers and possibly padding added. Messages shorter than a MTU may be combined, with headers (and possibly padding) added.
This direct link to MTU is why the publication and subscription MTU must always be perfectly aligned. The same applies for Aeron Archive.
Viewing positions at runtime¶
Positions are published via Aeron counters. Aeron Counters can be viewed programmatically, or via the built in sample Aeron Tooling. The most commonly used tool is Aeron Stat. StreamStat is a similar tool, and is focused on displaying channel/stream/session positions.
Aeron Stat displays the positions for every active session on the Media Driver. In the snippets below, session
1985493803 represents the Publication process/Subscription process described above.
For more information on how to read Aeron Stat, see Aeron Tooling
10:02:06 - Aeron Stat (CnC v0.2.0), pid 49446, heartbeat age 635ms ====================================================================== ... 26: 1 - snd-channel: aeron:udp?endpoint=localhost:2000 127.0.0.1:55785 27: 1 - send-local-sockaddr: 26 127.0.0.1:55785 28: 64 - pub-pos (sampled): 1 1985493803 1 aeron:udp?endpoint=localhost:2000 29: 8,388,896 - pub-lmt: 1 1985493803 1 aeron:udp?endpoint=localhost:2000 30: 64 - snd-pos: 1 1985493803 1 aeron:udp?endpoint=localhost:2000 31: 131,360 - snd-lmt: 1 1985493803 1 aeron:udp?endpoint=localhost:2000 32: 0 - snd-bpe: 1 1985493803 1 aeron:udp?endpoint=localhost:2000 33: 1,597,672,926,244 - client-heartbeat: 0 34: 1 - rcv-channel: aeron:udp?endpoint=localhost:2001 127.0.0.1:2001 35: 1 - rcv-local-sockaddr: 34 127.0.0.1:2001
10:02:03 - Aeron Stat (CnC v0.2.0), pid 49492, heartbeat age 314ms ====================================================================== ... 26: 1 - rcv-channel: aeron:udp?endpoint=localhost:2000 127.0.0.1:2000 27: 1 - rcv-local-sockaddr: 26 127.0.0.1:2000 28: 1,597,672,923,134 - client-heartbeat: 0 29: 64 - sub-pos: 1 1985493803 1 aeron:udp?endpoint=localhost:2000 @0 30: 64 - rcv-hwm: 2 1985493803 1 aeron:udp?endpoint=localhost:2000 31: 64 - rcv-pos: 2 1985493803 1 aeron:udp?endpoint=localhost:2000 32: 1 - snd-channel: aeron:udp?endpoint=localhost:2001 127.0.0.1:61000 33: 1 - send-local-sockaddr: 32 127.0.0.1:61000