Redis 4.0 첫 번째 릴리스 후보가 나왔다
원문은 Salvatore Sanfilippo님이 에 게재했습니다. 이 블로그 구독하기
아직 안정 버전은 아니지만 곧 그렇게 될 예정이며, 우리 사용자들에게 Redis를 더 유용하게 만들어 줄 긴 개선 목록과 함께 왔다. 마침내 Redis 4.0 릴리스 후보 1이 나왔고, 3.4 대신 과감하게 스스로를 4.0이라 칭한다. 나에게 시맨틱 버저닝은 별 의미가 없다. 내가 선호하는 건 버전 숫자와 도약을 이용해 새 버전이 무엇을 의미하는지 전달하려는 시도이고, 이번 경우 4.0은 “이건 진짜 끝내준다”는 뜻이다.
사실 Redis 4.0에는 진작 있었어야 할 것들이 아주 많다. 한 명의 개발자가 북두의 권의 켄시로처럼 열 명으로 분신해 코딩을 시작할 수 있는 다른 세상이라면 모를까. 내가 vim 단축키를 아무리 열심히 배워도 분신술은 내 단축키 조합에 없다.
어쨌든 마침내 4.0에서 이런 것들을 많이 해냈다… 여기에 주요 기능 목록과 간단한 설명, 더 알아볼 수 있는 링크를 정리한다.
1. 모듈
아마 이미 알고 있겠지만 Redis 4.0에는 모듈 시스템이 생겼다. RDB/AOF로 영속화되는 새로운 자료형을 구현하거나 논블로킹 명령어를 만드는 등 꽤 멋진 일을 할 수 있는 시스템이다. 핵심은 이 모든 것이 코어와 완전히 분리된 고수준의 추상 API로 이루어진다는 점으로, 그래서 여러분이 작성한 모듈은 이후 Redis 릴리스에서도 그대로 동작할 것이다. 나는 모듈을 이용해 Redis 내부에서 학습시킬 수 있는 신경망 자료형인 Neural Redis를 만들었고, 많은 사람들이 아주 흥미로운 작업들을 하고 있다. 새로운 레이트 리미팅 명령어(Rust로 구현됐다!), Redis 위의 그래프 DB, 세컨더리 인덱스, 시계열 모듈, 전문 검색 인덱싱 등 여러 가지가 있고, 내 느낌으로는 이제 시작에 불과하다.
이는 Redis가 코어를 최소는 아니더라도 적어도 대다수 사용자에게 유용하고 많은 사람이 필요로 하는 꽤 범용적인 것들만 담은 채로, 새로운 영역을 커버하며 성장할 수 있게 할 뿐만 아니라, 많은 작업에서 네트워크 서버를 처음부터 다시 작성해야 하는 문제를 피할 잠재력도 가지고 있다. Redis나 데이터베이스, 캐싱, 혹은 Redis가 무엇이든 간에 그것과 관련 없는 무언가를 만드는 것이 목표라 해도 말이다. 즉, Redis “인프라”, 즉 프로토콜이나 사람들이 이미 만들어 둔 클라이언트 등을 활용하기 위해 모듈을 작성하기만 하면 된다. 그래서 나는 이 기능에 대해 긍정적으로 본다. 코어에 대한 부담은 없고, 더 미친 짓을 하고 싶은 사용자에게는 자유가 주어진다.
2. 리플리케이션 버전 2
이건 운영 관점에서 프로덕션에 아주 유용할 것이다. 과거 어느 시점에 우리는 “PSYNC”라고 알려진 것을 도입했다. 마스터와 슬레이브 사이의 연결이 끊겨도 양쪽이 있던 자리에서 그대로 이어서 복제할 수 있게 해주는 새로운 마스터-슬레이브 프로토콜이었다. 그 전에는 마스터와 슬레이브 사이의 복제 연결이 단 한 번이라도 끊기면 전체 동기화가 일어났다. 마스터에서 RDB 파일을 생성해 전송하고 슬레이브에서 로드하는, 다들 어떻게 동작하는지 아는 그 과정 말이다. 그래서 PSYNC는 진짜 개선이었다. 하지만 충분하지 않았다…
PSYNC는 페일오버 상황에서는 충분하지 않았다. 슬레이브가 마스터로 승격되면, 기존 마스터를 복제하던 슬레이브들이 새로 승격된 슬레이브에 연결해 PSYNC를 할 수 없었다. 전체 재동기화가 필요했던 것이다. 이는 좋지 않고 Redis Cluster에도 좋지 않다. 하지만 이를 고치려면 복제 프로토콜을 변경해야 했다. 인스턴스들 사이에 공통의 복제 히스토리가 있는 한 어떤 토폴로지 변경 후에도 부분 재동기화가 동작하도록 확실히 하고 싶었기 때문이다.
그래서 필요했던 첫 번째 변경은 “체인 리플리케이션”이 동작하는 방식에 관한 것이었다. 즉, 슬레이브의 슬레이브의 슬레이브… 이런 식은 어떻게 동작할까? 예를 들어 A가 마스터이고 다음과 같은 구조가 있다고 하자.
A —> B —> C —> D
즉 A는 B의 마스터이지만 B는 C의 마스터인 식이다. Redis 4.0 이전에는 B가 A로부터 복제 프로토콜을 받는 방식이었다. 복제 프로토콜은 보통 쓰기 명령어들의 스트림이다. B는 C에 대한 마스터로서 내부적으로 A가 하던 일을 그대로 했다. 매 쓰기마다 C에 전달할 적합한 복제 프로토콜을 다시 생성해 전달하는 식이었다.
하지만 이제 B는 A로부터 받은 내용을 그대로 verbatim으로 C에 프록시하고, C도 D에 대해 똑같이 한다. 모든 하위 슬레이브가 이제 동일한 바이트 스트림을 받으므로, 특정 히스토리에 “태그”를 붙이고, 그 태그와 오프셋을 이용해 공통점이 있을 때마다 계속 이어서 복제를 시도할 수 있다.
마스터 자체도 슬레이브로 전환될 때 이제 새로운 마스터와 PSYNC를 할 수 있다. 그리고 슬레이브들은 이제 복제 태그와 오프셋을 저장하는 RDB 파일 안의 정보를 이용해 “깔끔한” 재시작 이후에도 보통 마스터와 PSYNC를 할 수 있다.
제대로 동작하게 만들기 위한 세부 사항은 이보다 더 복잡하지만, 어쨌든 핵심은 가능하면 전체 재동기화로 귀찮아지지 말자는 것이다. 그리고 PSYNC v2는 겉보기에 이를 잘 해낸다. 이 기능에 관심 있다면 꼭 시험해 보고 알려 달라.
3. 캐시 제거 정책 개선
이건 몇 달 전에 전체 글을 쓴 적이 있다: http://antirez.com/news/109. 그래서 TLDR만 전하겠다. 이제 LFU(Least Frequently Used)가 생겼고, 다른 모든 정책들도 더 견고하고 빠르고 정확한 구현으로 바뀌었다. 그러니 캐싱 유스케이스에는 큰 소식이다. 이 부분에 관심 있다면 전체 글을 읽어 보라. 정보가 아주 많다.
4. 논블로킹 DEL과 FLUSHALL/FLUSHDB
코드명은 “객체의 지연 해제(lazy freeing of objects)”지만, 멋진 기능에 비하면 좀 심심한 이름이다. UNLINK라는 새로운 명령어가 생겼는데, 데이터베이스에서 키 참조만 삭제하고 실제 메모리 할당 해제는 별도 스레드에서 수행한다. 그래서 거대한 키에 대해 DEL 대신 UNLINK를 사용하면 서버가 블로킹되지 않는다. 더 좋은 건 FLUSHALL과 FLUSHDB의 ASYNC 옵션을 사용하면 DB 전체나 인스턴스 안의 모든 데이터에 대해서도 같은 일을 할 수 있다는 점이다. 두 Redis 데이터베이스의 내용을 교환하는 새로운 SWAPDB 명령어와 결합하면 FLUSHDB ASYNC가 꽤 흥미로워진다. 예를 들어 DB 1에 새로운 버전의 데이터를 채운 뒤 SWAPDB 0 1을 하고 오래된 데이터가 있는 데이터베이스를 FLUSHDB ASYNC로 비운 다음, 또 새로운 버전을 만들어 반복할 수 있다. 전체 DB를 비우는 것이 더 이상 블로킹되지 않게 됐기 때문에 이제야 가능해진 것이다.
UNLINK가 DEL의 기본 동작이 아닌 데에는 이유가 있다. 나만 아는 게 있다… 말할 수 없다(**).
5. 혼합 RDB-AOF 영속성 포맷
선택 사항으로, 활성화하면 이제 AOF 재작성이 AOF 파일 앞에 RDB 파일을 붙이는 방식으로 수행된다. 생성과 로드 모두 더 빠르다. 특정 환경에서는 아주 유용할 것이지만, AOF 파일을 덜 투명하게 만들기 때문에 일단은 선택 사항이다. 이 기능은 오랫동안 이야기가 나왔고 마침내 들어왔다.
6. 새로운 MEMORY 명령어
나는 이 기능이 정말 마음에 든다. 예전에 LATENCY DOCTOR를 도입했을 때 메일링 리스트의 “내 Redis가 느려요” 불평이 극히 일부로 줄어들었던 만큼이나 마음에 든다. 이제 메모리 문제에 대해서도 같은 것이 생겼다.
127.0.0.1:6379> MEMORY DOCTOR Hi Sam, this instance is empty or is using very little memory, my issues detector can't be used in these conditions. Please, leave for your mission on Earth and fill it with some data. The new Sam and I will be back to our programming as soon as I finished rebooting.
영화 판권 소유자들이 SF 대사 영감을 가져왔다고 고소할지도 모르겠지만 괜찮다. 내가 감옥에 가게 되면 오렌지나 가져다 달라.
MEMORY는 그보다 훨씬 더 많은 일을 한다.
127.0.0.1:6379> MEMORY HELP 1) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key" 2) "MEMORY STATS - Show memory usage details" 3) "MEMORY PURGE - Ask the allocator to release memory" 4) "MEMORY MALLOC-STATS - Show allocator internal stats"
USAGE 하위 명령어의 메모리 사용량 보고는 아주 유용할 것이고, “STATS”가 제공하는 심도 있는 정보도 마찬가지다.
지금으로서는 이 모든 것이 전혀 문서화되어 있지 않으니, 도대체 무슨 일을 하는지 직접 알아보는 재미를 느껴 보라.
7. Redis Cluster는 이제 NAT / Docker 호환
하지만 이건 사실 나쁜 소식이기도 하다. 노드들이 통신하는 데 사용하는 “Cluster bus”의 바이너리 프로토콜이 바뀌었기 때문에, 4.0으로 업그레이드하려면 Redis Cluster를 전부 재시작해야 한다. NAT / Docker 수정을 위해 이런 일을 벌이게 되어 미안하다. 용서해 달라. 하위 호환성을 유지하려 했지만, 완전히 어색한 짓을 하지 않고서는 쉽게는 물론 어렵게도 이를 얻을 방법이 없었다.
이 기능은 예제 redis.conf 파일에 설명되어 있다. 다른 기능들에 비해 내가 이 기능에 조금 덜 신나 있다는 걸 눈치채지 못했는가?
뭐… 아마 이게 전부인 것 같다. 이게 주요 내용들이다. 원한다면 여기에서 릴리스 노트도 읽어 보라: https://raw.githubusercontent.com/antirez/redis/4.0/00-RELEASENOTES
안정 버전까지 걸리는 ETA는 예전처럼 알 수 없다. 대략 2~4주마다 새로운 RC를 낼 계획이다. 버그의 심각도와 제보 빈도 모두에서 버그가 유의미하게 줄어들면 그때가 Redis 4.0 최종 버전이 될 때다. 하지만 업데이트해야 할 문서도 많이 남아 있으니 할 일은 충분히 남아 있다.
이 릴리스에 기여해 준 모든 분들께 감사드린다. 많은 분들이 중요한 방식으로 기여해 주셨다. 위 릴리스 노트에는 모든 커밋 목록이 있으니, 커미터들의 이름을 확인하기 위해 훑어볼 수 있다.
이 모든 것을 가능하게 해 준 Redis 커뮤니티와 Redis Labs에 감사드리며, 특히 Redis를 사용해 매일의 문제를 잘 해결하고 일을 처리해 내는 모든 개발자분들께 감사드린다. 코딩하는 재미와 더불어 그것이 바로 핵심이기 때문이다.
P.S. 새 코드를 가장 빨리 받는 방법은 GitHub에서 '4.0' 브랜치를 가져오는 것이다. 저장소는 예전처럼 antirez/redis다.
** UNLINK가 DEL의 기본 동작이 아닌 이유에 대한 더 자세한 정보는 https://news.ycombinator.com/item?id=13091370를 확인하라.
글을 무작위로 읽기
댓글
로그인하고 댓글 남기기