Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Redis Stream Sharding

최근에 계속 관심있게 보고있는건 Redis 5.0 부터 추가된 stream 큐이다. (6.2) autoclaim 추가되면서 idletime 기반 claim 편의성이 증가했고 (8.2) 에서 xackdel 추가 및 ACKED 옵션으로 큐 용량관리가 빨리지고 용이해졌다. (8.4) 는 xreadgroup 에 claim 옵션 추가되면서 기존 별도 스케줄러로 PEL 내 메세지 재처리를 autoclaim 으로 직접 해줬지만 xreadgroup 으로 재처리 + 처리 로직을 병합시킬 수 있게 되었다. (8.6)에선 at-most-once 위해서 xadd로 produce 할 때 멱등키 옵션을 설정할 수 있게 되었다. 그리고 (8.8) 마일스톤보면 nack 도 지원한다고 한다.

요즘 기술 변화 빠른 거 재밌어서 계속 트래킹하고 있고, codex로 stream PR도 매일 요약 받아보고 있는데 확실히 편의성은 계속 좋아지는 중이다. 다만 대규모 실무로 가면 얘기가 달라진다. Redis는 주로 클러스터로 확장하는데 stream은 단일 key 기반이라 결국 한 노드에 write가 몰린다. 그래서 그대로 쓰면 수평 확장이 막혀버린다. 이걸 풀려면 stream을 여러 개로 쪼개서 샤딩하고, key 기준으로 고르게 분산시키는 구조가 필요하다. 그리고 consumer는 쉽게 늘릴 수 있긴 한데(xreadgroup 스레드를 늘리면 됨), 순서 보장이 필요한 순간부터는 샤딩이 필수가 된다.

정리하면 Redis Stream 인프라 레벨 확장 및 순서보장을 위해선 샤딩은 필수다.

사실 AI 로 이것저것 만들어봤는데 일반적인 것들은 너무 쉬워서 좀 어려운 주제를 택해봤다. 먼저 플래닝부터 시작해보자!

수정중인 문서

고려사항들을 시간순서로…

  1. 중앙 Coordinator 에서 Eager(Stop-The-World)/Cooperative Rebalancing 선택해서 셋업
  2. 생각해보니 Coordinator 또 만들어버리면 너무 운영복잡도가 증가하니까 이러면 안됨. 동기화 된 consumer_list 저장하고있는 메타데이터 셋이랑 revendoz 해싱으로 consumer 스스로 계속 리프레시해주는게 깔끔함.
  3. 하지만 또 보니 consumer-1 이 맡은 샤딩 release 후 consumer-2 재배정 시 중간 ack 안날라온것들을 reclaim 해서 먼저 읽어야 순서보장이 되는데, idle-time 이 안지나면 xreadgroup + claim 하기 어려움. 그래서 결국 순서보장이 정말 어려움…
  4. v1 토픽에서 v2 토픽으로 업데이트 시 기존 v1 토픽 draining 서비스 설계. 그리고 shard-count scale-in/out 첫 기동 pod 가 이를 감지 후(metadata CAS) 샤드 생성. 이거 네이밍을 다르게 만들것.
  5. 파티셔닝 키를 통한 순서보장을 신경쓰게 된다면 아예 다른이야기가 된다. 예로 파티셔닝 키가 있는 스트림을 scale-out 시 기존 producing 순서를 어떻게 보장할건지? 순서 보장을 유지하면서 Kafka에서 키가 있는 토픽 확장 parallel-consumer 그리고 이렇게 될 경우 메타데이터 관리는 어떻게 싱크를 맞출건지 힘들어진다.
  • PRD 가 너무 커져서 작게 만든 뒤 lazy loading 으로 링크를 걸어줄 것이다. codex 컨텍스트가 90 가까이 되면서 성능이 너무 안좋아져서 최대한 작게 유지할 수 있는 방법으로!
  • kafka 레퍼런스를 보면서 순서 보장을 유지하면서 Kafka에서 파티션 키가 있는 토픽의 파티션 확장을 볼려고했는데 아무리 봐도 레퍼런스가 없어서 포기함. 결국 일차적인 방법으로 v2 토픽 만들고 확장시킨 뒤 v1 -> v2 마이그레이션하도록. 당연히 v1, v2 토픽과 파티션이 다르니 기존 파티셔닝 키 기반 순서보장에 공백이 생길 수 있음.