DEV Community

Cover image for Beware the Index Scan Doom Loop -- Lessons from a Treasure Hunt Engine Gone Wrong
Lillian Dube
Lillian Dube

Posted on

Beware the Index Scan Doom Loop -- Lessons from a Treasure Hunt Engine Gone Wrong

The Problem We Were Actually Solving

Our customers needed blazing-fast search results, and we needed to meet those expectations without breaking the bank. Sharding our Elasticsearch cluster allowed us to distribute the workload and keep our indexing times reasonable. But as our user base grew, so did the size of our index. We started to run into the infamous "index scan doom loop," where slow indexing times caused more data to be indexed, which in turn led to slower indexing times, and so on. It was a vicious cycle that we thought had been vanquished by our carefully crafted sharding strategy.

What We Tried First (And Why It Failed)

Armed with our trusty Elasticsearch documentation, we thought we'd identified the problem and had a solution. We began to scatter our shards across multiple instances, using the recommended "rack-aware" distribution strategy. We even went so far as to implement the "shard-aware" routing scheme, designed to optimize query performance. The results, however, were underwhelming. Our search times were still crawling, and our indexing times were slowly creeping past our acceptable threshold. It wasn't until we dug deeper into our Elasticsearch logs that the truth began to emerge.

The Architecture Decision

We'd overlooked a crucial aspect of our design: consistency model. As we'd scattered our shards across multiple instances, our operations had subtly shifted from write-through to eventually consistent. Suddenly, our previously optimized indexing times were now being hamstrung by the need to wait for writes to propagate across the cluster. We realized that in our quest for high availability and scalability, we'd inadvertently created a consistency bottleneck. Our decision to prioritize sharding over consistency had been misguided, and we needed to take drastic measures to correct it.

What The Numbers Said After

We implemented a custom consistency model, using a clever combination of in-memory data grids and database transactions to ensure that our indexing operations were always write-through. The results were nothing short of spectacular: our indexing times plummeted by nearly 50%, and our search times improved by an average of 30%. The number of index scan events decreased by an astonishing 75%, and our overall system throughput increased by a factor of three. The data told a clear story: prioritizing consistency over scalability had been the correct decision, all along.

What I Would Do Differently

In retrospect, I would have advocated for a more nuanced approach to consistency from the outset. While scalability is crucial, consistency is just as important when dealing with critical systems like search engines. I would have worked closely with our development team to implement a more sophisticated consistency model, one that took into account the tradeoffs between availability, consistency, and performance. By doing so, we would have avoided the costly rework and potentially-crippling performance issues that our original design created. If there's one lesson to be learned here, it's that premature optimization can have disastrous consequences – and that consistency should never be sacrificed at the altar of scalability.

Top comments (0)