  Log-structured merge (LSM) trees offer efficient ingestion by appending
incoming data, and thus, are widely used as the storage layer of production
NoSQL data stores. To enable competitive read performance, LSM-trees
periodically re-organize data to form a tree with levels of exponentially
increasing capacity, through iterative compactions. Compactions fundamentally
influence the performance of an LSM-engine in terms of write amplification,
write throughput, point and range lookup performance, space amplification, and
delete performance. Hence, choosing the appropriate compaction strategy is
crucial and, at the same time, hard as the LSM-compaction design space is vast,
largely unexplored, and has not been formally defined in the literature. As a
result, most LSM-based engines use a fixed compaction strategy, typically
hand-picked by an engineer, which decides how and when to compact data.
  In this paper, we present the design space of LSM-compactions, and evaluate
state-of-the-art compaction strategies with respect to key performance metrics.
Toward this goal, our first contribution is to introduce a set of four design
primitives that can formally define any compaction strategy: (i) the compaction
trigger, (ii) the data layout, (iii) the compaction granularity, and (iv) the
data movement policy. Together, these primitives can synthesize both existing
and completely new compaction strategies. Our second contribution is to
experimentally analyze 10 compaction strategies. We present 12 observations and
7 high-level takeaway messages, which show how LSM systems can navigate the
compaction design space.
