10P by neo 24일전 | favorite | 댓글 1개
  • Redka는 Redis의 장점을 SQLite로 재구현하면서 Redis API와 호환되도록 만드는 것을 목표로 함
  • 주요 특징:
    • 데이터는 RAM 크기에 맞출 필요 없음
    • ACID 트랜잭션 지원
    • SQL 뷰를 통한 데이터 조회 및 리포팅 기능 강화
    • In-process(Go API)와 Standalone(RESP) 서버 모두 지원
    • Redis 호환 명령어와 프로토콜 지원
  • 현재 개발 진행 중이며, 지원 현황과 로드맵은 아래 문서 참고

지원 명령어

  • Redka는 Redis의 5가지 핵심 데이터 타입인 String, List, Set, Hash, Sorted Set을 지원하는 것이 목표
  • String, Hash, Key 관리, 트랜잭션 명령어는 이미 지원되며, List, Set, Sorted Set은 개발 중
  • 자세한 명령어 목록은 원문 참고

설치 방법

독립 실행 서버

  • Release 페이지에서 OS에 맞는 바이너리 파일 다운로드 후 실행
  • Docker를 사용할 경우 docker pull nalgeon/redka 로 이미지 다운로드

Go 모듈

  • go get github.com/nalgeon/redka 로 모듈 설치
  • SQLite 드라이버로 github.com/mattn/go-sqlite3modernc.org/sqlite 사용

사용 방법

독립 실행 서버

  • 다운로드 받은 바이너리 파일을 redka [-h host] [-p port] [db-path] 형태로 실행
    • 기본값은 host localhost, port 6379, DB 경로 없음(인메모리)
  • Docker 사용시 docker run 명령어로 실행. 자세한 옵션은 원문 참고
  • 서버 실행 후에는 redis-cliredis-py, go-redis 같은 Redis 호환 클라이언트로 접속 가능

In-process 서버

  • redka.Open() 함수로 DB 객체 생성. 드라이버 임포트 필수
  • redka.DB 객체의 메소드를 호출하여 각종 명령어 실행
  • View(읽기 전용)과 Update(쓰기 가능) 메소드로 트랜잭션 처리

영속성

  • Redka는 SQLite 데이터베이스에 rkey, rstring, rhash 테이블을 사용하여 데이터 저장
  • 각 데이터 타입별 뷰(vstring, vhash 등)를 통해 SQL로 데이터 조회 가능

성능

  • redis-benchmark 도구로 Redis와 Redka 성능 비교
    • Redka가 SET은 6배, GET은 2배 정도 느림
    • 그래도 초당 23K writes, 57K reads 수준의 성능을 보여줌
  • 컨테이너에서 실행할 경우 성능 저하가 있을 수 있음

로드맵

  • 1.0 릴리즈에는 Redis 2.x 시절의 주요 기능 중심으로 구현 예정
    • String, Hash, Key 관리, 트랜잭션 지원 완료
    • Sorted Set 개발 중
    • List, Set 개발 예정
  • 향후 버전에서 Stream, HyperLogLog, Geo 같은 데이터 타입과 Pub/Sub 기능 추가 예정
  • Lua 스크립팅, 인증/ACL, 멀티 DB, Watch/Unwatch 등은 구현 계획 없음
  • 클러스터와 센티널 기능도 구현하지 않을 예정

GN⁺의 의견

  • Redis와 대부분 호환되면서 영속성을 제공하는 Redka의 접근 방식이 흥미롭습니다. ACID 트랜잭션을 지원한다는 것도 장점이 될 것 같네요.
  • 성능 면에서는 Redis에 미치지 못하지만, 영속성이 필요한 경우라면 충분히 고려해볼만한 대안이 될 것 같습니다.
  • 다만 아직 개발 초기 단계여서 안정성 면에서는 좀 더 지켜봐야할 것 같고, 로드맵에 빠진 기능들이 꽤 있는 점은 실제 도입시 고려해야 할 사항입니다.
  • In-memory 용도로는 결국 Redis를 이길 순 없겠지만, SQLite에 기반한 영속성 계층으로써는 유용하게 쓰일 수 있을 것 같습니다.
  • 요즘 엣지 컴퓨팅 환경에서 경량화된 스택에 대한 수요가 높아지고 있는데, 그런 분야에서 Redis 대신 Redka를 사용해볼 수 있겠네요.
Hacker News 의견
  • Redis의 "모든 것이 하나의 스레드에서 직렬화된" 동시성 없는 모델을 어느 정도 따를지에 대한 고민이 있음
  • SQLite의 저수준 라이브러리를 사용하고, WAL을 활성화하며, 읽기용 goroutine마다 커넥션을 사용하고, 전용 writer 스레드로 버퍼링된 채널/큐를 통해 쓰기 배치를 보내면 SQLite에서 더 나은 성능을 얻을 수 있음
  • 이를 통해 SQLite의 내장 커넥션별 뮤텍스를 끄고도 각 커넥션이 한 번에 하나의 스레드에서만 사용되므로 스레드 안전성을 유지할 수 있음
  • 네트워크 요청/소켓에서 들어오는 파라미터 바이트를 버퍼에 복사하거나 SQLite에서 직접 소켓으로 복사하는 등 arena 스타일의 큰 버퍼를 사용하면 개별 문자열 할당 및 전달을 줄여 시간을 많이 절약할 수 있음
  • Go에서 SQLite로부터 최대 쓰기 처리량을 얻으려고 노력한 경험에서 나온 팁들임
  • Redis와 SQLite를 모두 좋아해서 두 가지를 결합하기로 결정함. SQLite는 많은 작은 쿼리에 특화되어 있어 관계형 엔진이 Redis에 가까워질 수 있는 만큼 가까워졌기에 잘 맞을 것 같음
  • TigerBeetle의 상태 머신을 교체하여 Redis API를 구현할 누군가를 기다리고 있음
  • 데이터 세트가 메모리에 맞는지 여부에 대해 생각할 필요가 없는 Redis 대안이 있으면 좋겠음
  • Redis의 전체 가치 제안은 메모리에서 작동하여 메모리와 같은 성능을 제공한다는 것임. 디스크로 이동하면 Redis를 사용할 이유가 거의 없음
  • 네트워크 I/O가 추가되면 Redis의 환상적인 성능 중 많은 부분이 사라짐. SaaS 호스팅 Redis 서비스를 사용하면 성능이 큰 타격을 받음. 자체 클러스터에서 Redis 호환 키/값 스토어를 더 쉽게 실행할 수 있다면 이는 이점임
  • 이것 또는 Garnet이 Redis 명령을 더 많이 지원하는지 궁금함. 로컬 디버깅 목적으로 프로그램에 Redis 호환 기능의 하위 집합을 내장하려고 하는데, 중간에 API가 있어 지원되지 않는 Redis 명령에 대해 보호할 수 있음
  • Foursquare가 MongoDB를 유명하게 만들었을 때 누군가 MySQL에 구현된 NoSQL DB의 PoC를 게시했지만 유행하지는 않았음. 하지만 DB가 필요할 때마다 SQL을 다시 발명하지 않도록 하기 위해 얼마나 많은 성능을 희생했는지 생각하게 만듦. 이와 같은 실험을 좋아하며 때로는 새로운 프로젝트로 이어짐
  • Redis를 DB 앞에 캐시 레이어로 사용함. 이 개념을 이해하지 못함
  • 그런데 SetMaxConnections(1)을 사용하고 있지만, WAL 모드(사용 중임)에서 SQLite는 읽기를 차단하지 않는 쓰기를 지원하므로 읽기 동시성을 허용하면 이점이 있을 수 있음