GrabWeilun WuProblem & solution
Search indexing optimisation
Summary
Grab Deliveries uses MySQL as canonical storage and Elasticsearch as derived search storage, with Food-Puxian synchronising updates through Kafka. The original incremental-sync design treated Kafka events mainly as notifications, reloaded records from MySQL, and used separate consumers and in-memory event buffering, creating heavy database traffic, data-loss gaps, coupling to table schemas, redundant Elasticsearch updates, and duplicate cascade updates. A CDC system based on MySQL row-based Binlog provides common events containing Operation, PayloadBefore, and PayloadAfter, enabling filtering of irrelevant changes, partial Elasticsearch updates, event merging in the buffer, and deduplication of cascade updates through a dedicated Kafka stream. The reported results were an 80% reduction in database load from the first optimisation and an 80% reduction in cascade-update events. Overall, DSP saved about 91% of database reads and 90% of Elasticsearch reads, while stream-consumer throughput rose from 200 to 800 QPS, with peaks above 1000 and lower synchronisation latency.
Context
Food-Puxian synchronises MySQL changes to Elasticsearch for search. MySQL stores canonical data, while Elasticsearch indexes may combine data from multiple MySQL tables and entities. The original Kafka-based incremental-sync design caused database bottlenecks, missed changes made outside application code, schema coupling, unnecessary Elasticsearch updates, and repeated cascade updates.
Approach / What changed
The optimised design uses MySQL row-based Binlog events delivered through Kafka, with Operation, PayloadBefore, and PayloadAfter fields. DSP filters changes irrelevant to Elasticsearch, compares relevant payloads, performs partial updates, merges successive events in the Event Buffer, and routes cascade updates through a dedicated Kafka stream so events with the same ID can be deduplicated.
Takeaways
MySQL row-based Binlog captures data modifications made to MySQL tables, including changes made through command-line or database-management tools, avoiding the application-code capture gap.
Comparing the Elasticsearch-relevant fields in PayloadBefore and PayloadAfter filters irrelevant events; the reported database-load reduction from this optimisation was 80%.
Cascade Update events sharing an ID are routed to the same Kafka partition and consumed by one DSP instance, allowing in-memory deduplication that reduced such events by 80%.
FAQ
Why replace notification-style Kafka events with Binlog payloads?
The original consumers used event IDs to reload records from MySQL, which created heavy database traffic. Binlog events include before and after row payloads, allowing DSP to identify relevant changes and use event data for partial Elasticsearch updates.
How does Event Buffer merging change incremental sync?
Instead of replacing an older event when a newer event with the same ID arrives, the buffer merges them into a new Binlog event. Its PayloadBefore comes from the older event and its PayloadAfter comes from the newer event, supporting partial updates while coalescing changes.
How are duplicate cascade updates reduced?
Object B handling sends a Cascade Update event to a dedicated Kafka stream rather than updating related object A directly. Events with the same ID are placed in the same partition and handled by one consumer, allowing the in-memory Event Buffer to deduplicate most of them.
Source and freshness
- Source
- engineering.grab.com
- Published
- Added to Yomu
Summaries are generated from the original by a language model. Check the original before relying on it.
Keep reading
Related reading
The Good Stuff
Paid picks we use ourselves. Links carry a referral code — a subscription through one earns us a commission at no extra cost to you.
The best engineering reads, once a week
One useful email. Unsubscribe anytime.