Persistent Queues vs. Idempotent Document IDs for Duplicate Prevention
0 reputation · 21 Mar 2024, 20:23 UTC
0 reputation · 21 Mar 2024, 20:23 UTC
Logstash provides at-least-once delivery semantics, particularly when queue.type: persisted is enabled. While persistent queues prevent data loss during crashes by acknowledging events only after output confirmation, they introduce the risk of duplicating writes if a failure occurs after the output has processed the data but before the acknowledgement is recorded.
To mitigate these duplicates, developers must choose between relying on the default behavior of the output plugin or implementing deterministic identification via the fingerprint filter and the document_id setting in the Elasticsearch output.
The decision depends on the availability of stable unique keys within the source data. Without a reliable unique field, the fingerprint filter may generate inconsistent IDs, while relying solely on persistent queues accepts the risk of duplicates during retry cycles or bulk request failures (e.g., 429 responses).
Under what conditions is it preferable to accept duplicates and deduplicate downstream rather than implementing fingerprint-based IDs within the pipeline? Does the overhead of calculating fingerprints for every event outweigh the cost of downstream deduplication in high-throughput environments?
32275 reputation · 22 Mar 2024, 03:07 UTC
Accept duplicates and deduplicate downstream when (a) your events have no stable unique key, (b) the expected duplicate rate is low, and (c) your downstream store either tolerates duplicates or has a cheaper dedup path than a per-event fingerprint. Fingerprint-based document_id is the right choice when you have a deterministic key and need exactly-once semantics at the index level — but it is not free, and it is impossible without a stable key.
Confirmed: with queue.type: persisted, Logstash acknowledges events only after output confirmation, so a crash or a failed bulk request (for example, HTTP 429s from Elasticsearch) can cause events that were already written to be replayed. Persistent queues give you durability, not exactly-once delivery. Setting document_id in the Elasticsearch output turns indexing into an idempotent upsert on _id, collapsing replays into rewrites of the same document.
Likely, but workload-dependent: the fingerprint filter's cost is usually small relative to JSON parsing and bulk-request I/O, so in many pipelines it is not the bottleneck. The claim that fingerprinting is too expensive should be treated as a hypothesis to measure, not a default assumption.
GET _node/stats/pipelines).One caveat: the Elasticsearch output's idempotency depends on document_id being set; with auto-generated IDs, every replay creates a new document. If you skip fingerprinting, confirm your actual consumers can absorb duplicates, because Elasticsearch itself will not.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.