server_memory
Redis SERVER Main Memory 사용량 계산
Redis Server Course | Redis Technical Support | Redis Enterprise Server |
---|
Redis SERVER Memory 사용량 계산
레디스 서버(인스턴스)가 데이터를 저장할 때 사용하는 메모리(RAM)량을 계산하는 방법이다.
다른 모든 데이터베이스 관리 시스템과 마찬가지로 레디스도 관리 메모리(overhead)가 필요 하다.
실 데이터 크기를 기반으로 어느 정도 메모리가 더 필요한지 계산한다.
계산 방법은 각 데이터 타입별로 값 하나 입력할 때 오버헤드를 크기(바이트)를 제시했다.
계산 결과와 실 사용량을 비교해 보면 1.7%에서 8.4% 차이가 난다.
서버(머신) 사양(spec)을 정하는 용도로 충분히 사용할 수 있다고 본다.
키의 관리 메모리(overhead)는 50 바이트이다.
이는 키 하나에 할당되는 dictEntry, redisObject, sdshdr과 메모리 할당 단위 그리고
해시 테이블(buckets)이 사용하는 메모리를 고려해서 산출한 것이다.
아래 표(Case)에서는 키 길이를 10바이트로 했다.
다섯 가지 데이터 타입의 값의 관리 메모리는 아래 리스트에 있다.
여기서는 값의 개수가 적을 때 사용되는 Ziplist, Intset 같은 내부 데이터 타입은 고려하지 않았다.
왜냐하면 여기 계산한 사용량보다 적기 때문이다.
리스트는 레디스 3.2 기준으로 퀵 리스트로 테스트했고, 압축을 사용하지 않았다.
압축했을 때 비교는 맨 마지막에 있다.
해시 테이블을 사용하는 키, Sets, Hashes, ZSets은 키 또는 값의 개수에 따라 사용하는 메모리가 다르지만,
여기서는 계산을 간편하게 하기 위해 관리 메모리로 사용하는 바이트(overhead)를 일정한 값으로 정했다.
이 문서는 버전 3.2.2을 기준으로 만들었다.
각 데이터 타입별 관리 메모리(overhead)
- Key: 50 bytes
- Strings: 30 bytes
- Lists: 15 bytes
- Sets: 75 bytes
- ZSets: 120 bytes
- Hashes: 100 bytes
계산 방법 예시
- Strings 일 때 계산 방법
- 키 크기 10바이트, 키 개수 10만 개, 값 크기(평균) 100바이트일 때
- ((키 overhead 50 바이트 + 키 크기 10 바이트) * 키 개수 10만 개) +
((Strings 값 overhead 30 바이트 + 값 크기 100 바이트) * 값 개수 10만 개) - ((50 + 10) * 100000) + (30 + 100) * 100000) = 19,000,000 바이트
- Lists 일 때 계산 방법
- 키 크기 10바이트, 키 개수 100개, 키 당 값 개수(평균) 1,000개, 값 크기(평균) 100바이트일 때
- ((키 overhead 50 바이트 + 키 크기 10 바이트) * 키 개수 100개) +
((Lists 값 overhead 15 바이트 + 값 크기 100 바이트) * 값 개수 10만 개(키 당 값 1000개) - ((50 + 10) * 100) + (15 + 100) * 100000) = 11,506,000 바이트
- Sets 일 때 계산 방법
- 키 크기 10바이트, 키 개수 100개, 키 당 값 개수(평균) 1,000개, 값 크기(평균) 100바이트일 때
- ((키 overhead 50 바이트 + 키 크기 10 바이트) * 키 개수 100개) +
((Lists 값 overhead 75 바이트 + 값 크기 100 바이트) * 값 개수 10만 개(키 당 값 1000개) - ((50 + 10) * 100) + (75 + 100) * 100000) = 17,506,000 바이트
- ZSets, Hashes도 Lists 나 Sets과 같은 계산 방법으로 하면된다. 단, Hashes 일 때는 값의 크기에 필드 크기도 같이 계산해서 넣으면 된다. 필드 크기 10 바이트, 값 크기 100 바이트이면 값 크기를 110 바이트로 계산한다.
- 계산 결과는 표 Case 1과 비교해보면 사용 메모리(계산)과 일치함을 알 수 있다.
Case 1
키의 길이는 10바이트, 값의 길이는 100바이트이고, 컬렉션 타입 키 각 100개.
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 100,000 | 1 | 19,000,000 | 18,705,032 |
Lists | 100 | 1,000 | 11,506,000 | 10,290,400 |
Sets | 100 | 1,000 | 17,506,000 | 16,034,400 |
ZSets | 100 | 1,000 | 22,006,000 | 20,681,624 |
Hashes | 100 | 1,000 | 21,006,000 | 19,234,712 |
합계 | 91,024,000 | 84,946,168 |
실 사용 메모리 81mB, 계산한 것과 실 사용량이 7.2% 차이난다.
Case 2
키의 길이는 10바이트, 값의 길이는 100바이트이고, 컬렉션 타입 키 각 1,000개.
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 1,000,000 | 1 | 190,000,000 | 177,241,648 |
Lists | 1,000 | 1,000 | 115,060,000 | 102,904,000 |
Sets | 1,000 | 1,000 | 175,060,000 | 160,344,000 |
ZSets | 1,000 | 1,000 | 220,060,000 | 206,857,648 |
Hashes | 1,000 | 1,000 | 210,060,000 | 192,344,000 |
합계 | 910,240,000 | 839,691,296 |
실 사용 메모리 800mB, 계산한 것과 실 사용량이 8.4% 차이난다.
Case 3
키의 길이는 10바이트, 값의 길이는 100바이트이고, 컬렉션 타입 키 당 값 5,000개.
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 5,000,000 | 1 | 950,000,000 | 907,962,112 |
Lists | 1,000 | 5,000 | 575,060,000 | 514,104,000 |
Sets | 1,000 | 5,000 | 875,060,000 | 858,456,176 |
ZSets | 1,000 | 5,000 | 1,100,060,000 | 1,088,324,984 |
Hashes | 1,000 | 5,000 | 1,050,060,000 | 1,018,456,000 |
합계 | 4,550,240,000 | 4,387,303,272 |
실 사용 메모리 4.09gB, 계산한 것과 실 사용량이 3.7% 차이난다.
Case 4
키의 길이는 10바이트, 값의 길이는 100바이트이고, 컬렉션 타입 키 당 값 5,000개.
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 5,000,000 | 1 | 950,000,000 | 907,962,080 |
Lists | 2,000 | 5,000 | 1,150,120,000 | 1,028,208,312 |
Sets | 2,000 | 5,000 | 1,750,120,000 | 1,716,912,000 |
ZSets | 2,000 | 5,000 | 2,200,120,000 | 2,176,673,928 |
Hashes | 2,000 | 5,000 | 2,100,120,000 | 2,036,914,184 |
합계 | 8,150,480,000 | 7,866,670,504 |
실 사용 메모리 7.33gB, 계산한 것과 실 사용량이 4.6% 차이난다.
Case 5
키의 길이는 10바이트, 값의 길이는 500바이트이고, 컬렉션 타입 키 당 값 1,000개.
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 100,000 | 1 | 59,000,000 | 58,747,840 |
Lists | 100 | 1,000 | 51,506,000 | 51,410,400 |
Sets | 100 | 1,000 | 57,506,000 | 56,034,400 |
ZSets | 100 | 1,000 | 62,006,000 | 60,688,888 |
Hashes | 100 | 1,000 | 61,006,000 | 59,234,400 |
합계 | 291,024,000 | 286,115,928 |
실 사용 메모리 273mB, 계산한 것과 실 사용량이 1.7%차이난다.
Case 6
각 데이터 타입 당 1백만 개 값 입력
Data Type | 키 개수 | 키 당 값 개수 | 사용 메모리(계산) | 실 사용 메모리 |
---|---|---|---|---|
Strings | 1,000,000 | 1 | 590,000,000 | 577,286,704 |
Lists | 1,000 | 1,000 | 515,060,000 | 514,105,272 |
Sets | 1,000 | 1,000 | 575,060,000 | 560,342,728 |
ZSets | 1,000 | 1,000 | 620,060,000 | 606,886,272 |
Hashes | 1,000 | 1,000 | 610,060,000 | 592,345,272 |
합계 |
실 사용 메모리 2.66gB, 계산한 것과 실 사용량이 2.1%차이난다.
Lists: Quick List 압축을 사용할 때 메모리 사용량
레디스 서버 3.2.0 이상 버전에서는 퀵 리스트(Quick list)를 사용하며 압축을 할 수 있다. 압축 관련 파라미터 list-compress-depth는 2로 설정했다. 의미는 리스트에서 앞, 뒤 2개 노드씩 4개 노드는 압축을 하지 않고, 나머지 가운데 노드는 모두 압축하는 것이다.
값 길이 (바이트) | 값 개수 | 압축 전 사용 메모리 | 압축 후 사용 메모리 | 압축률 |
---|---|---|---|---|
100 | 100,000 | 10,290,400 | 4,049,776 | 61% |
100 | 1,000,000 | 102,904,000 | 32,388,944 | 69% |
100 | 5,000,000 | 514,104,000 | 46,789,048 | 91% |
100 | 10,000,000 | 1,028,208,312 | 92,635,600 | 91% |
500 | 100,000 | 51,410,400 | 7,714,904 | 85% |
500 | 1,000,000 | 514,105,272 | 69,404,576 | 86% |
500 | 5,000,000 | 2,570,104,000 | 237,404,680 | 91% |
정리 整理 Summary
이 글에서는 키와 각 데이터 타입의 오버헤드를 고려한 메모리(RAM) 사용량을 계산해 보았습니다.
다음 페이지에서는 Copy-on-Write의 개념과 이로 인한 추가 메모리에 대해서 알아보겠습니다.
이 글을 보시고 질문이나 의문사항 있으면 댓글을 올려주세요.
더불어 잘못된 내용이 있으면 알려주시면 고맙겠습니다.
<< Repl Functions | Copy-on-Write >> |
---|