DynamoDB 파티션 키, 나중에 바꿀 수 없는 결정
키 종류가 많아도 요청이 한 값으로 몰리면 막힐 수 있어요. 파티션 키가 데이터를 나누는 방식과 실제 요청 분포를 살펴봐요.
이 글의 목차무엇이 키로 좋은가4
우체국에서 소포를 지역 번호 앞자리로 나눠 창구에 보낸다고 해 볼게요. 앞자리가 고르게 흩어지면 창구마다 비슷하게 붐벼요. 그런데 앞자리 대신 “오늘 접수”라는 기준으로 나누면 오늘 들어온 소포가 전부 한 창구로 가요. 창구를 열 개로 늘려도 소용없어요. 나누는 기준이 이미 한 곳을 가리키고 있기 때문이에요.
Amazon DynamoDB에서 파티션 키가 이 분배 기준이에요. 파티션은 데이터를 나눠 보관하고 처리하는 구획이에요. 한 구획의 처리 한도를 넘으면 요청을 제한하는 스로틀링(throttling)이 생길 수 있어요. 그래서 키를 고를 때는 이름의 가짓수뿐 아니라 실제 요청이 어느 값에 몰리는지도 봐야 해요.
무엇이 키로 좋은가
같은 문서는 좋은 키와 나쁜 키를 짝지어 비교해 두었는데, 그 목록이 판단 기준을 그대로 보여 줘요.
| 나누는 기준 | 도움이 되는 조건 | 몰리는 경우 |
|---|---|---|
| 사용자 식별자 | 여러 사용자의 요청이 분산됨 | 한 사용자가 요청 대부분을 만듦 |
| 몇 가지 상태 코드 | 각 상태의 부하가 작음 | 인기 상태 하나로 요청 집중 |
| 날짜 | 날짜별 요청이 고르게 분산됨 | 새 쓰기가 오늘 날짜에 집중 |
| 장치 식별자 | 장치별 요청량이 비슷함 | 한 장치만 매우 자주 전송 |
공평하게 덧붙일 것이 있어요. 같은 문서는 뜨거운 파티션이 저절로 풀리는 경우도 설명해요. 서비스가 열이 몰린 파티션을 자동으로 쪼개기 때문에 잠깐 나타났다 사라지는 스로틀링도 있어요. 다만 같은 문서가 표 전체의 용량이 충분해도 파티션 단위에서는 막힐 수 있다고 적어요. 용량을 늘려 푸는 문제가 아니라는 뜻이에요.
마지막 줄이 특히 헷갈리는 자리예요. 값의 종류가 많으면 괜찮을 것 같지만, 실제로 오가는 요청이 한 값에 쏠리면 결과는 같아요. 가짓수가 아니라 요청의 분포가 기준이에요.
세 번째 줄은 앞 시리즈의 로그 이야기와 겹쳐요. 시간 순으로 쌓이는 데이터를 시간으로 나누면, 지금 쓰는 곳은 언제나 마지막 한 칸이에요. 과거 칸들은 조용하고 현재 칸만 뜨거워요.
예시 요청 18개를 세 키에 나누거나 한 키에 몰아 보세요.
키 A6
키 B6
키 C6
키 A16
키 B1
키 C1
서로 다른 키가 많아도 실제 요청이 한 키로 몰리면 부담은 고르게 나뉘지 않아요.
18개 요청이 세 키에 6개씩 나뉘어요.
키별 요청 수의 가상 예시예요. DynamoDB의 실제 물리 파티션 배치·적응형 용량·정확한 처리 한계는 표시하지 않아요.
되돌릴 수 없다는 성질
여기서 실무의 무게가 달라져요. AWS 문서는 관계형 쪽에서는 정의를 나중에 바꿀 수 있다고 적으면서, DynamoDB는 표를 만들 때 키 스키마를 함께 지정해야 한다고 비교해 둬요. 용량 방식이나 자동 확장은 나중에 조정할 수 있지만 키는 그런 종류의 설정이 아니에요.
그래서 잘못 골랐을 때의 대책도 성격이 달라요. 특정 파티션이 한도를 넘어 막힐 때 AWS가 제시하는 장기 대책은 파티션 키 설계를 바꾸는 것이에요. 설정 하나를 조정하는 일이 아니라 새 표를 만들어 데이터를 옮기고 읽고 쓰는 코드를 함께 고치는 일이 돼요.
앞 시리즈에서 되돌릴 수 없는 배포를 다루며 적은 것과 같은 구조예요. 되돌릴 수 있는 결정과 없는 결정은 들이는 검토의 양이 달라야 해요. 그런데 이 둘이 같은 화면에서 몇 칸 떨어져 있을 뿐이라 무게 차이가 잘 느껴지지 않아요.
질문의 모양을 먼저 정한다
관계형 쪽에서는 데이터를 먼저 정규화해 두고 필요한 질의를 나중에 만들어요. 이쪽은 순서가 반대예요. 어떤 질문을 자주 던질지를 먼저 정하고, 그 질문이 한 번의 조회로 끝나도록 키를 설계해요.
AWS도 파티션 키 설계를 별도의 모범 사례 문서로 따로 두고 있어요. 조정 항목이 아니라 설계 항목으로 다룬다는 뜻이에요. 그래서 이 선택은 데이터베이스 설계라기보다 앞으로 만들 기능의 목록을 미리 적는 일에 가까워요. 나중에 새로운 질문이 생기면 보조 인덱스로 얼마간 감당할 수 있지만, 그것도 결국 같은 성질을 가져요. 무엇으로 나눌지 다시 정하는 일이에요.
저는 무엇을 잘못 골랐나
제가 만드는 앱에서 기록성 데이터를 다루면서 날짜를 키로 삼은 적이 있어요. 당시에는 날짜별로 조회할 일이 많아 자연스러운 선택처럼 보였어요.
문제는 쓰기 쪽에서 나타났어요. 읽기는 과거로 흩어지는데 쓰기는 언제나 오늘 한 칸으로 몰렸어요. 규모가 작아 큰 사고로 번지지는 않았지만, 사람이 늘면 그 한 칸이 먼저 막힐 구조라는 것이 보였어요. 지금은 사용자 쪽 식별자를 앞에 두고 날짜를 뒤에 붙이는 형태로 바꿨어요.
이 일을 겪고 남은 관점은 이것이에요. 이 데이터베이스에서 성능 문제는 대개 부하가 커져서 생기지 않았어요. 처음에 나누는 기준을 잘못 골라서 생겼고, 그 기준은 부하가 커진 뒤에는 고치기 가장 어려운 것이었어요.