Design a Distributed Priority Queue
Today, we'll develop a Distributed Priority Queue, focusing on its implementation using a sharded SQL database. Our discussion will include:
API, Data Structure for Items, and Status of Messages
The message schema outlines the data format that will be entered into and retrieved from the queue.
Namespace: This represents the isolation boundary for different tenant environments.
Topic: Acts as a logical queue; a single namespace can have numerous topics.
Priority: 32-bit integer where a lesser value denotes higher message urgency.
Payload: An immutable binary data block, limited by size.
Metadata: Mutable key-value data intended for ancillary information
Deliver After: The scheduled time for a message to be made available for consumption
Lease Duration: The allocated time frame within which a consumer must acknowledge (ack) or reject (nack) a dequeued message.
Unique ID: A unique identifier.
TTL: Defines the duration a message remains in the queue before automatic deletion
Enqueue operation
Enqueue is an operation to push a message to a Priority Queue. If an enqueue succeeds, the item is persisted and can eventually be dequeued.
Submit to Enqueue Buffer
Recommended by LinkedIn
Process with Enqueue Workers
Distribute to SQL Shards
Acknowledge and Log
Dequeue operation
The dequeue API accepts a collection of (topic, count) pairs. For each topic requested, host will return, at most, count items for that topic. The items are ordered by deliver_after and priority, so items with current deliver_after and lower priority will be delivered first. If multiple items are tied for lowest priority, lower deliver_after items will be delivered first.
Dequeueing items typically involves the following steps:
Regional Deployment
During any event leading to the unavailability of a primary replica in Region X, SQL DB can elect secondary replicas from Region 2 as the new primary. After failover, the queue service in Region 1 must send queries to the new primary database in Region 2 where cross-region latencies increase up to hundreds of milliseconds.
In the event of complete network connectivity loss in region 1, the limitations of the regional architecture become more glaring:
Multi Regional Deployment
To enhance latency, we introduce a routing service acting as an intermediary between clients and the queue service. This service conceals the complexities of physical routing from clients and facilitates efficient distribution of messages
Routing service optimizes data allocation according to regional preferences. It uses in-memory mapping to associate logical regional preferences with the nearest SQL shards. The API allows clients to indicate their preferred storage regions.
When processing a request, Routing Service references its in-memory data to identify suitable queue nodes based on the client's regional choice. Consequently, items are stored in the designated physical location or an alternative region overseeing the relevant SQL shards in case of failover. If there's no region preference, items default to the nearest region from where the request originated.