Hash(HSET)
1. 두 가지 얼굴
담긴 데이터의 양에 따라 내부 저장 방식을 바꾼다.
소량: Listpack (과거에는 ZipList)
- 장점: 포인터 오버헤드가 없고, 데이터가 밀집되어 있어 메모리를 극도로 아낀다.
- 단점: 특정 키를 찾으려면 처음부터 끝까지 스캔해야 한다.(O(N)) 하지만 데이터가 적으면(보통 512개 이하) CPU 캐시 덕분에 속도가 빠르다.
대량: Hash Table
2. 점진적 재해시
일반적인 해시 테이블은 크기를 늘릴 때 모든 데이터를 한꺼번에 새 테이블로 옮긴다. 하지만 데이터가 1,000만 개라면 이 작업 동안 레디스는 멈춰버릴 것이다. 이를 방지하기 위해 Redis는 다음곽 같은 방법을 쓴다.
- 두 개의 테이블 운영: 기존 테이블(ht[0])과 더 큰 새 테이블(ht[1])을 동시에 둔다.
- 조금씩 이동: 사용자가 HGET이나 HSET 명령을 보낼 때마다, 한 인덱스씩 데이터를 ht[1]로 옮긴다.
- 백그라운드 처리: 사용자의 요청이 없더라도 조금씩 데이터를 옮겨서 결국 ht[0]를 비운다.
3. 전환 기준
레디스 설정 파일(redis.conf)에서 조절한다.
hash-max-listpack-entries 512: 항목이 512개 이하일 때까지 Listpack 사용
hash-max-listpack-value 64: 개별 값의 크기가 64바이트 이하일 때까지 Listpack 사용