조사 배경
TTL이 만기된 캐시키들이 삭제(evicted)되지 않는 현상을 발견하면서, 레디스에서 메모리를 관리하는 방법이 궁금해졌다
알게된 것
* 레디스는 아래의 세가지 상황 때, 메모리를 정리한다.
A. 만료된 키를 가져올 때
B. 샘플링한 데이터 중에 만료된 키가 있는 경우
C. 메모리 관리 정책을 설정했을 때, 논리적인 데이터 사용량이 maxmemory를 초과한 경우
=> 실제 사용량으로 잡히는 rss를 기준으로 메모리를 정리하지 않는다.
* 레디스는 jemalloc을 쓴다.
* 용량이 큰 데이터를 자주 썼다가, 지우면 파편화가 발생하기 쉽다. 그리고 데이터의 크기 편차가 크면, 파편화가 생기기 쉽다. 실제 사용량보다 rss가 높게 나온다는 거다. 이 경우를 해결하려면, 장비를 이전하는게 낫다. 데뷰에서 카카오에서 레디스를 사용한 후기가 언급되었었는데, 좋은 방법은 없다고 한다. 주기적으로 데이터를 지워줬다고 한다. ( DEVIEW2014 -ARCUS차별기능,사용이슈,그리고카카오적용사례 )
* OOM 에러는 데이터를 저장할 수 없을 때 발생하는 에러다.
레디스 메모리 정리 방식별 고려사항
B. 샘플링한 데이터 중에 만료된 키가 있는 경우
* 레디스 서버는 디폴트로 1초에 10번(100ms마다) databasesCron()을 실행해서 만료된(expire) 키를 삭제한다. 참고 * redis나 sentinel이나 일정 주기로 처리되야 하는 로직을 정의 한 곳이 serverCron(..)이다. ( 참고 ) * 그리고 이 안에서 databaseCron() 함수가 100 millisecond마다 수행된다. ( 참고 ) * databaseCron(..)을 보면 active_expire_enabled 설정이 true이고 slave모드가 아니라면 activeExpireCycle(..)실행하게 되어 있다. activeExpireCycle(..)에서는 랜덤 샘플링을 이용하여 키들을 expire시킨다. ( 참고 ) * 만료된 키를 삭제하는 주기를 짧거하거나, 메모리 사용량이 높은 객체는 나눠서 저장하는게 캐시를 빠르게 삭제하는 데에 도움이 된다. ( 참고 ) * 샘플링 수를 무조건 늘리는게, 좋은건 아니다. redis는 싱글 쓰레드 구조로 되어 있다. 때문에 샘플링 개수가 많아지면, 처리속도가 지연되게 된다. 그래서 다른 요청에 대한 응답 또한 지연된다. |
C. 메모리 관리 정책을 설정했을 때, 논리적인 데이터 사용량이 maxmemory를 초과한 경우
* Redis의 LRU 알고리즘은 정확하지 않다. ( 참고 ) |
읽는 중인 것들
레디스 메모리 문제로 카오스를 겪는 사람을 전세계인이 도와주고 있는 이슈 해결 글 : https://github.com/antirez/redis/issues/2136
Redis 메모리 삭제 코드 (freeMemoryIfNeeded) 분석 - server.c, evit.c
읽은 것들
레디스 Expire 처리방법 - http://pigbrain.github.io/opensource/2015/02/18/RedisMemoyPolicyAboutExpireData_on_Redis
레디스 파편화 팁 - https://charsyam.wordpress.com/2017/05/27/혀로그래머-charsyam은-구라쟁이-2-캐시-멤캐시나-레디스-쓰/
유용한 사이트
redisgate - http://redisgate.jp/redis/configuration/redis_conf.php
'소프트웨어-이야기 > 데이터 저장소 + 시각화 ' 카테고리의 다른 글
[Redis]Redis에서 LRU Cache를 사용하는 방법 (0) | 2018.02.03 |
---|---|
[Redis]라이브 환경에서 설정 변경하기 (0) | 2018.01.27 |
(읽을거리)엘라스틱 서치 쿼리 성능 최적화 (0) | 2018.01.15 |
[MariaDB]RDB 속에서 NOSQL 사용하기 (4) | 2018.01.05 |
[Cache]Redis vs Memcached (0) | 2017.11.18 |