본문 바로가기

개발

redis 1.0 분석 - 공유 메모리 풀

업데이트 내역

2023.12.16 현재도 공유 메모리 기술을 쓰는지에 대한 글 추가

들어가기 전에

Redis beta 1 버전을 기준으로 작성한 글입니다.

해당 버전의 코드는 다음 링크에서 확인하실 수 있습니다.

http://redisgate.kr/redis/introduction/redis_release1.php

 

Redis Release Notes 1

 

redisgate.kr

해당 기술고 관련된 포스트입니다.

https://groups.google.com/g/redis-db/c/cHTu12jRr78/m/h-L0-EOn9WgJ

 

Object sharing is fun!

Hello, some hour ago I implemented a new feature in Redis, object sharing, in order to save memory when there are duplicated objects in the database. The following is a short report of how it works since I think it's pretty fun, involves minimal coding, bu

groups.google.com

최근 버전에선 쓰고 있나?

결론부터 말하면 예약어만 쓴다.

2버전 분석 과정에서 tryObjectSharing 함수가 보이지 않았고, 비슷한 역할을 하는 함수가 없다는 것을 확인해다.

 

취지는 좋았지만, 교체 방식이 랜덤한 것에 대해서 해당 기술에 대해 의구심이 들어서 이걸 어떻게 개선할까 싶었다.

또한, 이전 값이 공유 메모리 풀에 등록됐다, 다음 값에 의해 교체되면 데이터가 소실되는 부분이 있었는데

결국 이런 문제를 해결하진 못한거 같다.

베타버전 레디스의 문제

만약 사람 이름과 주소에 대한 키, 값 쌍이 있다고 하면 다음과 같이 나올 것이다.

("이름A", "서울")

("이름B", "서울")

("이름C", "서울")

 

여기서 "서울" 이란 값은 중복임에도 불구하고 별개의 데이터로 저장된다.

이로 인해 메모리 공간의 낭비와 캐시 성능의 저하로 이어진다.
그래서 redis에선 중복 데이터끼리는 같은 주소 공간을 공유한다.

 

공유 메모리를 관리하는 방법

redis 서버 실행 시 공유 메모리 풀(sharingpool)이란 딕셔너리를 만든다.

명령어를 입력받으면 명령어를 파싱해 redis object로 만들고, 공유 메모리 풀에 같은 값이 있는지 본다.

 

사전에 정의된 명령어들은 공유 메모리 풀이 아닌, sharedObjectsStruct 란 객체에 따로 관리된다. 

 

redis에 KK란 키에 VV 란 값을 등록하는 과정을 예시로 보면 다음과 같다.

값이 공유 메모리 풀에 존재할때

현재 KK 란 값이 공유 메모리 풀에 있으므로, 파싱된 redis object는 공유 메모리 풀의 주소를 참조한다.

공유 메모리 풀에 hit 됐으므로, val 값을 1 증가시킨다.

기존에 생성된 redis object는 메모리에 반환한다.

공유 메모리 풀에 존재하지 않을 때

공간이 충분하다면 redis object를 공유 메모리 풀에 등록한다.

KK 란 값은 메모리 풀에 등록되있지 않지만, 공간이 있기 때문에 메모리 풀에 등록할 수 있다.

 

만약 공간이 부족하다면?

공유 메모리 풀에서 랜덤한 entry를 가져와 참조 값을 1 감소시킨다.

만약, 참조 값이 0이 되면 딕셔너리에서 지운 뒤, 새로운 데이터를 등록한다.

 

VV 란 값이 공유 메모리 풀에 없고, 랜덤 entry 선정에 XX가 선택됐다면 해당 val를 1 감소한다.

여기서 val 값이 0이 됐으므로, 공유 메모리 풀에서 제거하고 값 VV를 메모리 풀에 등록한다.

 

 

참조 값이 0이 되지 못해 지워지지 않는다면, 공유 메모리 풀에 등록하지 않고 사용한다.

 

예를 들자면, 이전에 KK 란 값이 공유 메모리 풀에 참조돼 val 값이 2인 상태고

랜덤 entry 선정에 KK가 선택돼 val 이 1 감소했지만, 0이 아니기 때문에 메모리 풀에 남아있다.

그 결과 VV 값은 공유 메모리 풀에 등록되지 않고, 메모리에 독립적으로 남는다.

 

 

개인적인 궁금증

아직 버전 1이기 때문에, 이후 패치됐을 것이라 생각한다.

 

공유 메모리 풀에 등록되진 않았지만 이후에 동일한 값이 공유 메모리 풀에 등록될 때

 

"서울" 데이터가 공유 메모리 풀에 등록되지 않았지만, 이후 "서울" 데이터를 입력받아 공유 메모리 풀에 등록됐다면 이전에 사용된 "서울" 데이터에 대한 처리가 없다.

 

공유 메모리 풀에 등록하는 코드를 보면 단순히 등록만 하고, 기존에 관리중인 데이터는 해제하지 않는다.

 

왜 캐시 교체를 랜덤한 방식으로 하는지

캐시 교체엔 가장 오랫동안 참조되지 않은 캐시를 지우는 LRU나, 가장 적게 호출된 캐시를 지우는 LFU 등이 있다.

왜 이러한 방식을 사용하지 않고 랜덤한 키의 카운팅을 1 줄이는지 의문이다.

 

 

'개발' 카테고리의 다른 글

redis 2.0 분석  (0) 2023.12.20
[java] Spring 애플 로그인 구현 과정  (0) 2023.12.11
초기 Redis 분석 - 이벤트 루프  (0) 2023.11.24
초기 Redis 분석 - 자료구조  (0) 2023.11.22
Uber H3 - 육각형 계층의 공간 인덱스  (2) 2022.12.23