앞 단계에서 채널마다 증가하는 번호로 순서를 정했습니다. 이제 그 메시지를 어디에 어떻게 담아 두고 어떻게 다시 꺼내는지 정합니다. 저장 설계는 읽기와 쓰기 중 어느 쪽이 많은지부터 봅니다.
| 항목 | 값 | 성격 |
|---|---|---|
| 쓰기 | 하루 2억 건 | 계속 들어온다. 수정은 거의 없다 |
| 읽기 | 대화방을 열 때 최근 50건 | 최근 것만 본다. 오래된 것은 거의 안 본다 |
쓰기가 많고 읽기는 최근 쪽에 몰립니다. 이 편중이 저장 방식을 정합니다.
무엇을 기준으로 나누고 무엇으로 정렬하나
조회는 늘 "이 채널의 최근 것부터" 입니다. 그래서 채널 번호로 나누고 그 안에서 순서 번호로 정렬해 둡니다.
나누는 기준: 채널 번호
정렬 기준: 채널 안 순서 번호 내림차순
이렇게 두면 대화방을 열 때 한 채널의 앞쪽 50건을 연속으로 읽어 오면 끝납니다. 흩어진 곳을 여러 번 찾아가지 않습니다. 순서 보장을 위해 고른 파티션 기준이 조회 성능까지 같이 해결해 준 것입니다.
위치로 자르면 같은 메시지를 두 번 본다
지난 대화를 더 불러올 때 "몇 번째부터 몇 개" 로 요청하면 문제가 생깁니다. 채팅은 보고 있는 동안에도 새 메시지가 들어오기 때문입니다.
그래서 위치가 아니라 값을 기준으로 자릅니다. "번호 49보다 작은 것 50개" 처럼 요청하면 새 메시지가 몇 개 들어와도 경계가 밀리지 않습니다. 마지막으로 받은 번호가 다음 요청의 기준이 됩니다.
오래된 메시지를 같은 곳에 두지 않는다
하루 {REQ['msgs_per_day']} 이면 한 달에 60억 건입니다. 그런데 조회는 최근 쪽에 몰립니다.
| 구간 | 어디에 | 왜 |
|---|---|---|
| 최근 며칠 | 빠른 저장소 | 대화방을 열 때마다 읽는다 |
| 그보다 오래된 것 | 값싼 저장소 | 거의 안 읽는다. 읽을 때 조금 느려도 된다 |
나누는 기준이 이미 채널과 번호이므로 오래된 구간만 떼어 옮기기 쉽습니다. 보관 주기를 요구사항에서 미리 정하지 않으면 저장 비용이 계속 늘어나는데 아무도 지우자고 말하지 않는 상태가 됩니다.
첨부 파일은 메시지에 담지 않는다
이미지와 파일은 따로 저장하고 메시지에는 그 위치와 크기, 이름만 담습니다. 큰 데이터가 메시지 안에 들어오면 최근 50건을 읽는 흔한 조회가 무거워집니다.
삭제는 지우는 것이 아니다
메시지를 실제로 지우면 번호에 구멍이 생기고, 상대 화면에는 이미 도착한 것을 되돌릴 수 없습니다. 삭제 표시만 남기고 내용을 비웁니다. 번호는 남겨야 앞뒤 순서와 페이징이 그대로 동작합니다.