정보창고 정보창고

LSM Tree Compaction이 SSD 쓰기 증폭과 데이터베이스 성능에 미치는 영향

읽는 시간 약 14분

LSM 트리와 SSD가 만났을 때 벌어지는 일들

데이터베이스를 다루는 개발자나 인프라 엔지니어라면 한 번쯤 들어봤을 용어가 있습니다. 바로 LSM 트리(Log Structured Merge Tree)입니다. 카산드라, RocksDB, LevelDB와 같은 현대적인 데이터베이스 엔진의 핵심 구조인 LSM 트리는 쓰기 성능을 극대화하기 위해 설계되었습니다.

하지만 이 구조가 SSD라는 저장 매체를 만났을 때 미처 예상하지 못한 부작용이 발생할 수 있습니다. 바로 쓰기 증폭(Write Amplification)입니다. 처음에는 데이터가 빠르게 저장돼 별다른 문제가 없어 보이지만, 운영 시간이 길어지면서 디스크 사용량이 빠르게 늘거나 특정 시간마다 응답 지연이 발생하기도 합니다.

이 글에서는 LSM 트리와 SSD의 관계, 그리고 안정적인 성능을 유지하기 위해 알아야 할 실용적인 내용을 다룹니다.

LSM 트리 작동 원리와 컴팩션의 필요성

LSM 트리는 데이터를 디스크에 직접 기록하는 대신 메모리 버퍼에 먼저 쌓아둡니다. 메모리가 가득 차면 데이터를 정렬된 파일 형태로 디스크에 한꺼번에 기록하는데, 이를 SSTable이라고 부릅니다.

작은 랜덤 쓰기를 큰 순차 쓰기로 바꿀 수 있기 때문에 데이터 입력 속도가 매우 빠릅니다. 쓰기 작업이 많은 서비스에서 LSM 트리 기반 데이터베이스를 사용하는 이유도 여기에 있습니다.

하지만 데이터가 계속 쌓이면 문제가 발생합니다. 디스크에는 수많은 SSTable이 생성되고, 같은 키를 가진 이전 값과 최신 값이 여러 파일에 동시에 남게 됩니다. 데이터를 조회할 때 확인해야 하는 파일이 늘어나면서 읽기 성능도 점차 떨어질 수 있습니다.

그래서 LSM 트리는 여러 SSTable을 병합하고, 오래된 데이터와 중복된 값을 제거한 뒤 다시 정렬하는 작업을 수행합니다. 이것이 바로 컴팩션(Compaction)입니다.

장시간 데이터 적재 테스트에서는 초반까지 빠르게 동작하다가 일정 시간이 지난 뒤부터 응답 시간이 불규칙하게 상승하는 경우가 있습니다. 처음에는 애플리케이션이나 네트워크 문제처럼 보이지만, 디스크 읽기와 쓰기 사용량이 동시에 증가했다면 컴팩션 대기열과 SSTable 개수도 함께 확인해야 합니다.

쓰기 증폭이란 무엇인가

쓰기 증폭은 데이터베이스가 실제로 저장하려는 데이터보다 더 많은 양이 물리적인 SSD에 기록되는 현상을 말합니다.

예를 들어 애플리케이션이 100MB의 데이터를 저장했더라도 컴팩션과 SSD 내부 처리 과정까지 포함하면 실제 기록량은 300MB나 500MB 이상이 될 수 있습니다. 정확한 배율은 데이터 구조와 설정에 따라 달라지지만, 논리적인 저장량보다 물리적인 기록량이 커진다는 점이 핵심입니다.

LSM 트리의 컴팩션 과정에서는 기존 SSTable을 읽고 데이터를 다시 정렬한 뒤 새로운 파일로 기록해야 합니다. 이 과정에서 변경되지 않은 데이터까지 새로운 파일에 포함되면서 같은 데이터가 여러 차례 SSD에 기록될 수 있습니다.

SSD는 쓰기 횟수에 제한이 있는 NAND 플래시 메모리를 사용합니다. 쓰기 증폭이 심해지면 SSD의 수명이 예상보다 빠르게 줄어들 수 있으며, 내부적으로 가비지 컬렉션(Garbage Collection)이 자주 발생해 시스템 전체의 지연 시간이 높아질 수 있습니다.

운영 기록을 살펴보다 보면 데이터베이스에 입력한 양과 SSD의 총 기록량 사이에 예상보다 큰 차이가 나타나기도 합니다. 처음에는 저장량 계산이 잘못된 것처럼 보이지만, 컴팩션과 SSD 내부 쓰기 증폭까지 함께 고려하면 원인을 이해하기 쉬워집니다.

컴팩션 전략에 따른 성능 차이

모든 컴팩션이 똑같은 방식으로 작동하는 것은 아닙니다. 데이터베이스 엔진마다 채택하는 전략이 다르며, 서비스의 읽기와 쓰기 패턴에 따라 적절한 방식을 선택해야 합니다.

레벨 기반 컴팩션

레벨 기반 컴팩션은 데이터를 여러 계층으로 나누어 관리합니다. 상위 레벨로 이동할수록 해당 계층이 관리하는 전체 데이터 규모가 커지며, 각 레벨에서는 파일의 키 범위가 최대한 겹치지 않도록 정리합니다.

읽을 때 확인해야 하는 파일 수가 비교적 일정하기 때문에 조회 성능을 안정적으로 유지하기 좋습니다. 반면 데이터를 여러 레벨로 이동시키는 과정에서 기존 데이터가 반복적으로 기록되므로 쓰기 증폭이 커질 수 있습니다.

읽기 요청이 많고 일정한 응답 시간이 중요한 서비스에는 유리하지만, 쓰기량이 매우 많은 환경에서는 컴팩션으로 발생하는 추가 기록량을 함께 살펴봐야 합니다.

사이즈 계층 컴팩션

사이즈 계층 컴팩션은 크기가 비슷한 SSTable이 일정 개수 이상 쌓였을 때 이를 병합합니다. 대량의 쓰기 요청을 처리하는 데 유리하지만, 같은 키가 여러 SSTable에 남아 있을 수 있어 읽기 성능이 떨어지고 디스크 공간을 더 많이 사용하는 경향이 있습니다.

쓰기 중심 서비스라는 이유만으로 사이즈 계층 방식을 선택했다가 저장공간이 예상보다 빠르게 줄어드는 경우도 있습니다. 데이터를 삭제했더라도 해당 데이터가 포함된 SSTable이 컴팩션되기 전까지는 파일이 그대로 남아 있기 때문입니다.

삭제한 용량만큼 디스크 공간이 즉시 반환될 것으로 예상했다면 실제 운영 과정에서 용량 계획이 어긋날 수 있습니다.

흔한 오해와 사실 관계

많은 사람이 SSD는 무조건 빠르기 때문에 컴팩션 설정을 신경 쓸 필요가 없다고 생각합니다. 하지만 SSD의 처리 속도가 빠른 것과 쓰기 작업을 무제한으로 수행할 수 있다는 것은 전혀 다른 문제입니다.

SSD는 무한히 쓸 수 있다

SSD에는 제품이 감당할 수 있는 총 쓰기 용량이 정해져 있습니다. 쓰기 증폭이 높아지면 애플리케이션에서 저장한 데이터보다 훨씬 많은 양이 실제 SSD에 기록되므로 예상보다 빠르게 저장장치가 마모될 수 있습니다.

데이터베이스 내부의 저장량만 확인해서는 실제 SSD에 얼마나 많은 데이터가 기록됐는지 정확하게 판단하기 어려운 이유입니다.

컴팩션을 끄면 성능이 좋아진다

컴팩션을 중지하면 초기에는 CPU와 디스크 사용량이 줄어든 것처럼 보일 수 있습니다. 하지만 시간이 지나면서 SSTable이 계속 쌓이고 조회할 파일 수가 늘어나면 읽기 지연과 저장공간 사용량이 함께 증가합니다.

처음에는 문제가 해결된 것처럼 보여도 나중에는 처리되지 않은 컴팩션 작업이 한꺼번에 쌓여 더 큰 부하가 발생할 수 있습니다. 결국 컴팩션을 끄는 것은 문제를 해결하는 것이 아니라 뒤로 미루는 것에 가깝습니다.

하드디스크와 SSD의 설정은 같아도 된다

SSD는 하드디스크보다 랜덤 입출력과 병렬 처리 성능이 뛰어납니다. 하지만 SSD 내부에서는 가비지 컬렉션과 마모 균등화 작업이 별도로 수행됩니다.

따라서 하드디스크에서 사용하던 컴팩션 설정을 SSD에 그대로 적용하기보다 저장장치의 대역폭과 지연 시간, 내부 병렬 처리 특성을 함께 고려해야 합니다.

비용 효율적인 활용을 위한 실무 팁

데이터베이스 인프라를 운영할 때는 단순히 최고 성능만 추구하기보다 비용과 안정성 사이의 균형을 맞춰야 합니다.

쓰기 부하를 고려한 오버프로비저닝

SSD의 전체 용량을 100% 사용하지 않고 일정한 여유 공간을 남겨두는 방법을 오버프로비저닝이라고 합니다. 일반적으로 전체 용량의 약 10~20%를 여유 공간으로 확보하는 방법이 사용되지만, 적정 비율은 SSD 종류와 쓰기 부하에 따라 달라질 수 있습니다.

운영 중 디스크 사용률이 90%를 넘긴 시점부터 쓰기 지연이 반복되는 경우가 있습니다. 데이터 일부를 다른 저장공간으로 옮긴 뒤 지연이 줄어들었다면 SSD 내부 정리 작업과 컴팩션에 필요한 공간이 부족했던 것일 수 있습니다.

LSM 트리 기반 데이터베이스에서 남은 공간은 단순한 예비 용량이 아닙니다. 기존 SSTable을 읽고 새로운 파일을 생성하는 컴팩션 작업을 위해서도 충분한 여유 공간이 필요합니다.

데이터 압축 활용

LSM 트리의 각 단계에서 데이터를 압축하면 SSD에 기록되는 물리적인 데이터양을 줄일 수 있습니다. 이는 쓰기 증폭을 완화하는 효과적인 방법 중 하나입니다.

압축과 해제 과정에서 CPU 자원이 추가로 사용되지만, 디스크 입출력량과 저장공간 사용량을 줄일 수 있다는 장점이 있습니다. SSD 수명과 입출력 비용을 고려하면 압축을 사용하는 편이 더 경제적인 경우도 많습니다.

반복되는 문자열이나 구조가 비슷한 로그 데이터는 압축 효과가 큰 편입니다. 반면 이미 압축된 이미지나 동영상 파일은 압축률이 높지 않을 수 있으므로 설정 적용 전 실제 데이터를 이용해 확인하는 것이 좋습니다.

컴팩션 우선순위 조절

데이터베이스 설정에서 컴팩션이 지나치게 공격적으로 실행되지 않도록 임계치와 처리 속도를 조절해야 합니다. 컴팩션이 한꺼번에 몰리면 사용자 요청과 백그라운드 작업이 동일한 디스크 자원을 두고 경쟁하게 됩니다.

이 경우 평균 처리 속도는 정상처럼 보여도 일부 요청의 지연 시간이 크게 튈 수 있습니다.

컴팩션 스레드 수와 처리 속도, SSTable 크기와 실행 임계치를 한 번에 크게 변경하기보다는 컴팩션 대기량과 디스크 사용량을 확인하면서 단계적으로 조정하는 것이 안전합니다.

서비스 트래픽이 낮은 시간대에 대규모 컴팩션이 진행되도록 구성하는 방법도 사용할 수 있습니다. 다만 컴팩션을 너무 오래 미루면 처리해야 할 데이터가 계속 쌓일 수 있으므로 대기열 상태도 함께 확인해야 합니다.

전문가의 조언

데이터베이스 성능 최적화는 하나의 설정을 변경한다고 끝나는 작업이 아닙니다. 가장 먼저 서비스가 읽기 중심인지, 쓰기 중심인지, 같은 데이터를 얼마나 자주 수정하는지를 파악해야 합니다.

읽기 요청이 많고 일정한 응답 시간이 중요하다면 레벨 기반 컴팩션을 고려할 수 있습니다. 반대로 대량의 데이터를 빠르게 적재하는 것이 우선이라면 사이즈 계층 컴팩션이나 쓰기 증폭을 줄일 수 있는 다른 전략을 검토해야 합니다.

SSD 상태도 정기적으로 확인해야 합니다. SMART 정보에서 총 기록량, 사용 수명 비율, 미디어 오류 등을 확인하면 SSD의 상태와 교체 시점을 판단하는 데 도움이 됩니다.

데이터베이스가 기록했다고 표시하는 논리적인 데이터양과 SSD에 실제로 기록된 양을 비교하면 현재 시스템에서 발생하는 쓰기 증폭 수준도 간접적으로 파악할 수 있습니다.

자주 묻는 질문과 답변

컴팩션이 너무 자주 일어나서 CPU 사용량이 높습니다. 어떻게 해야 할까요?

컴팩션 작업 스레드 수와 처리 속도를 제한하고, 컴팩션이 실행되는 파일 개수나 데이터 크기 임계치를 확인해야 합니다. 데이터 파티셔닝을 조정해 한 번에 처리되는 범위를 줄이는 것도 도움이 될 수 있습니다.

다만 CPU 사용량을 줄이기 위해 컴팩션을 무조건 늦추면 처리되지 않은 작업이 계속 쌓일 수 있습니다. CPU 사용량뿐만 아니라 컴팩션 대기열과 디스크 처리량도 함께 확인해야 합니다.

쓰기 증폭을 완전히 없앨 수는 없나요?

LSM 트리 구조에서는 쓰기 증폭을 완전히 제거하기 어렵습니다. 기존 데이터를 바로 덮어쓰지 않고 새로운 데이터를 추가한 뒤 나중에 병합하는 구조이기 때문입니다.

다만 데이터 압축, 적절한 컴팩션 전략, 불필요한 업데이트 감소, 데이터 보존 기간 조정을 통해 실제 쓰기량을 줄일 수 있습니다.

SSD 종류에 따라 컴팩션 전략이 달라야 하나요?

NVMe SSD는 높은 대역폭과 병렬 처리 성능을 제공하므로 여러 컴팩션 작업을 동시에 처리하기에 상대적으로 유리합니다.

하지만 컴팩션 스레드를 지나치게 늘리면 CPU 사용량이 높아지고 사용자 요청의 지연 시간도 증가할 수 있습니다. NVMe를 사용한다는 이유만으로 스레드 수를 무조건 늘리는 것은 적절하지 않습니다.

SATA SSD는 인터페이스 대역폭이 제한되므로 대규모 컴팩션 작업이 한꺼번에 몰리지 않도록 처리 속도를 세밀하게 조절해야 합니다.

저장장치 종류만 보고 설정을 결정하기보다 실제 디스크 처리량과 지연 시간, CPU 사용량, SSD 내구성을 함께 확인하는 것이 안전합니다.

시스템 설계를 위한 고려사항

LSM 트리 기반 데이터베이스를 도입할 때는 단순히 쓰기 성능이 빠르다는 이유만으로 제품을 선택해서는 안 됩니다. 데이터 크기와 업데이트 빈도, 데이터 보존 기간, SSD 내구성, 컴팩션에 필요한 추가 저장공간을 함께 계산해야 합니다.

특히 클라우드 환경에서는 디스크의 최대 IOPS와 처리량이 제한되는 경우가 많습니다. 평상시에는 제한에 도달하지 않더라도 컴팩션이 시작되면 읽기와 쓰기 작업이 동시에 증가하면서 스로틀링(Throttling)이 발생할 수 있습니다.

CPU와 메모리 사용량만 확인하다가 디스크 처리량 제한을 뒤늦게 발견하는 경우도 있습니다. 애플리케이션 요청량은 그대로인데 특정 시간마다 지연이 반복된다면 컴팩션 일정, 디스크 처리량, SSTable 개수와 남은 저장공간을 함께 확인해야 합니다.

결국 안정적인 성능은 고성능 SSD 하나만으로 만들어지지 않습니다. 데이터 특성에 맞는 컴팩션 전략과 충분한 여유 공간, 장시간 부하 테스트, 지속적인 SSD 상태 모니터링이 함께 구성되어야 합니다.

정보창고

함께 보면 좋은 글

댓글 0

첫 댓글을 남겨보세요.