Cassandra는 LSM Tree 기반 저장 엔진을 사용한다. LSM Tree의 핵심은 쓰기 요청을 먼저 메모리 구조에 반영하고, 이후 이를 정렬된 불변 디스크 파일로 내려쓴 뒤, 백그라운드에서 병합하는 데 있다. Cassandra는 이 구조를 Memtable, SSTable, Compaction 으로 구현하고, 여기에 장애 복구를 위한 CommitLog 를 더해 write path를 구성한다.
이 방식 덕분에 쓰기는 매우 빠르지만, 같은 파티션의 데이터가 여러 SSTable에 흩어질 수 있다. 그래서 읽기 시에는 “찾는 데이터가 한 파일에만 있다” 라는 가정이 성립하지 않고, 여러 후보 파일을 확인하고 병합해야한다.
공식 문서도 이러한 부분을 아래와 같이 설명한다.
<aside> 💡
While the write path is highly optimized, it comes with tradeoffs in terms of read performance and write amplification.
</aside>
즉, Cassandra의 읽기 성능 문제는 단순히 “디스크가 느리다”가 아니다.
핵심은 찾으려는 데이터가 여러 SSTable에 분산되어있을 수 있다는 점이다.
그래서 Cassandra의 읽기 최적화는
으로 설계되어있다.