Skip to content

Commit 6fff2a5

Browse files
committed
add better documentation
1 parent b4bdc26 commit 6fff2a5

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

src/sentry/scripts/spans/add-buffer.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ ARGS:
2828
- set_timeout -- int
2929
- byte_count -- int -- The total number of bytes in the subsegment.
3030
- max_segment_bytes -- int -- Maximum allowed ingested bytes for a segment. 0 means no limit.
31-
- salt -- str -- Salt to add to the segment key to avoid collisions.
31+
- salt -- str -- Unique identifier for this subsegment. When the segment exceeds max_segment_bytes, this subsegment
32+
is detached into its own segment keyed by salt. Empty string disables this behavior.
3233
- *span_id -- str[] -- The span ids in the subsegment.
3334
3435
RETURNS:

src/sentry/spans/buffer.py

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,26 @@
3232
3333
Now how does that look like in Redis? For each incoming span, we:
3434
35-
1. Store the span payload in a payload key:
36-
"span-buf:s:{project_id:trace_id:span_id}:span_id". Each subsegment
37-
gets its own key, distributed across Redis cluster nodes.
35+
1. Store the span payload in a payload key. Each subsegment gets its own key,
36+
distributed across Redis cluster nodes.
37+
a. When segment size enforcement is disabled, the key uses the parent_span_id to
38+
determine where to write span payloads to.
39+
Key: `span-buf:s:{project_id:trace_id:parent_span_id}:parent_span_id`
40+
b. When segment size enforcement is enabled, the key uses a unique salt per
41+
subsegment. This allows us to skip merging the subsegment into the parent segment
42+
and not lose any data, since the subsegment will become its own separate segment
43+
and be flushed out independently.
44+
Key: `span-buf:s:{project_id:trace_id:salt}:salt`
3845
2. The Lua script (add-buffer.lua) receives the span IDs and:
3946
a. Follows redirects from parent_span_id (hashmap at
4047
"span-buf:ssr:{project_id:trace_id}") to find the segment root.
4148
b. Updates the redirect table so future spans can find the segment root.
4249
c. Merges member-keys indexes and counters (ingested count, byte count)
4350
from span IDs that were previously separate segment roots into the
4451
current segment root.
52+
d. If segment size enforcement is enabled and the segment exceeds
53+
max_segment_bytes, detaches the subsegment into its own segment
54+
keyed by the salt.
4555
3. To a "global queue", we write the segment key, sorted by timeout.
4656
4757
Eventually, flushing cronjob looks at that global queue, and removes all timed
@@ -58,6 +68,22 @@
5868
or using spillover topics, especially when their new partition count is lower
5969
than the original topic.
6070
71+
Segment size enforcement:
72+
73+
Segments can grow unboundedly as spans arrive. To prevent oversized segments from
74+
consuming excessive memory during flush, the buffer enforces a maximum byte limit
75+
per segment (controlled by `spans.buffer.max-segment-bytes` and gated behind
76+
`spans.buffer.enforce-segment-size`).
77+
78+
Each subsegment is assigned a unique salt (UUID). The Lua script tracks cumulative
79+
ingested bytes per segment via `span-buf:ibc` keys. If adding a subsegment would
80+
push the segment over the byte limit, the script detaches it into a new segment
81+
keyed by the salt instead of merging it into the parent. The detached segment is
82+
independently tracked and flushed.
83+
84+
During flush, segments that exceed `max-segment-bytes` are chunked into multiple
85+
Kafka messages to stay within downstream size limits.
86+
6187
Glossary for types of keys:
6288
6389
* span-buf:s:{project_id:trace_id:span_id}:span_id -- payload keys containing span payloads, distributed across cluster nodes.

0 commit comments

Comments
 (0)