계속 진행하기 전에 GitHub 스타를 제공해 주세요 ️. 감사합니다!
다른 언어: 简体中文 日本語 한국어
웹사이트 • 문서 • 빠른 시작 • 커뮤니티 디스코드 • Dragonfly 포럼 • Dragonfly 커뮤니티 가입
GitHub 토론 • GitHub 문제 • 기여 • Dragonfly Cloud
Dragonfly는 최신 애플리케이션 워크로드를 위해 구축된 인메모리 데이터 저장소입니다.
Redis 및 Memcached API와 완벽하게 호환되는 Dragonfly는 코드 변경이 필요하지 않습니다. 레거시 인메모리 데이터 저장소에 비해 Dragonfly는 25배 더 많은 처리량, 더 낮은 테일 대기 시간으로 더 높은 캐시 적중률을 제공하고 동일한 규모의 워크로드에 대해 최대 80% 더 적은 리소스로 실행할 수 있습니다.
먼저 단일 스레드 아키텍처로 인해 Redis를 실행하는 데 일반적으로 사용되는 m5.large
인스턴스의 Redis와 Dragonfly를 비교합니다. 벤치마크 프로그램은 memtier_benchmark -c 20 --test-time 100 -t 4 -d 256 --distinct-client-seed
사용하여 동일한 AZ의 다른 부하 테스트 인스턴스(c5n)에서 실행됩니다.
Dragonfly는 비슷한 성능을 보여줍니다.
--ratio 1:0
):레디스 | DF |
---|---|
QPS: 159K, P99.9: 1.16ms, P99: 0.82ms | QPS:173K, P99.9: 1.26ms, P99: 0.9ms |
--ratio 0:1
):레디스 | DF |
---|---|
QPS: 194K, P99.9: 0.8ms, P99: 0.65ms | QPS: 191K, P99.9: 0.95ms, P99: 0.8ms |
위의 벤치마크는 수직 확장을 허용하는 DF 내부의 알고리즘 계층이 단일 스레드를 실행할 때 큰 피해를 주지 않는다는 것을 보여줍니다.
그러나 좀 더 강력한 인스턴스(m5.xlarge)를 사용하면 DF와 Redis 간의 격차가 커지기 시작합니다. ( memtier_benchmark -c 20 --test-time 100 -t 6 -d 256 --distinct-client-seed
):
--ratio 1:0
):레디스 | DF |
---|---|
QPS: 190K, P99.9: 2.45ms, P99: 0.97ms | QPS: 279K, P99.9: 1.95ms, P99: 1.48ms |
--ratio 0:1
):레디스 | DF |
---|---|
QPS: 220K, P99.9: 0.98ms, P99: 0.8ms | QPS: 305K, P99.9: 1.03ms, P99: 0.87ms |
Dragonfly 처리량 용량은 인스턴스 크기에 따라 계속 증가하는 반면 단일 스레드 Redis는 CPU에 병목 현상이 발생하고 성능 측면에서 로컬 최대치에 도달합니다.
가장 네트워크 성능이 뛰어난 인스턴스 c6gn.16xlarge에서 Dragonfly와 Redis를 비교해 보면 Dragonfly는 Redis 단일 프로세스에 비해 처리량이 25배 증가하여 380만 QPS를 넘었습니다.
최고 처리량에서 Dragonfly의 99번째 백분위수 대기 시간 측정항목:
작전 | r6g | c6gn | c7g |
---|---|---|---|
세트 | 0.8ms | 1ms | 1ms |
얻다 | 0.9ms | 0.9ms | 0.8ms |
세텍스 | 0.9ms | 1.1ms | 1.3ms |
모든 벤치마크는 서버 및 인스턴스 유형별로 조정된 스레드 수와 함께 memtier_benchmark
(아래 참조)를 사용하여 수행되었습니다. memtier
별도의 c6gn.16xlarge 시스템에서 실행되었습니다. 우리는 테스트가 끝난 후에도 SETEX 벤치마크가 지속될 수 있도록 만료 시간을 500으로 설정했습니다.
memtier_benchmark --ratio ... -t < threads > -c 30 -n 200000 --distinct-client-seed -d 256
--expiry-range=...
파이프라인 모드 --pipeline=30
에서 Dragonfly는 SET 작업의 경우 1,000만 QPS , GET 작업의 경우 1,500만 QPS 에 도달합니다.
AWS의 c6gn.16xlarge 인스턴스에서 Dragonfly와 Memcached를 비교했습니다.
비슷한 지연 시간으로 Dragonfly 처리량은 쓰기 및 읽기 워크로드 모두에서 Memcached 처리량을 능가했습니다. Dragonfly는 Memcached의 쓰기 경로 경합으로 인해 쓰기 작업 부하에서 더 나은 대기 시간을 보여주었습니다.
섬기는 사람 | QPS(천 qps) | 대기 시간 99% | 99.9% |
---|---|---|---|
잠자리 | ? 3844 | ? 0.9ms | ? 2.4ms |
멤캐시드 | 806 | 1.6ms | 3.2ms |
섬기는 사람 | QPS(천 qps) | 대기 시간 99% | 99.9% |
---|---|---|---|
잠자리 | ? 3717 | 1ms | 2.4ms |
멤캐시드 | 2100 | ? 0.34ms | ? 0.6ms |
Memcached는 읽기 벤치마크에서 지연 시간이 낮았지만 처리량도 낮았습니다.
메모리 효율성을 테스트하기 위해 우리는 debug populate 5000000 key 1024
명령을 사용하여 Dragonfly와 Redis를 ~5GB의 데이터로 채웠고, memtier
로 업데이트 트래픽을 전송하고, bgsave
명령으로 스냅샷을 시작했습니다.
이 그림은 메모리 효율성 측면에서 각 서버가 어떻게 작동하는지 보여줍니다.
Dragonfly는 유휴 상태에서 Redis보다 메모리 효율성이 30% 더 높았으며 스냅샷 단계에서는 메모리 사용량이 눈에 띄게 증가하지 않았습니다. 최고조에 달했을 때 Redis 메모리 사용량은 Dragonfly의 거의 3배까지 증가했습니다.
Dragonfly는 몇 초 내에 더 빠르게 스냅샷을 완료했습니다.
Dragonfly의 메모리 효율성에 대한 자세한 내용은 Dashtable 문서를 참조하세요.
Dragonfly는 해당되는 경우 일반적인 Redis 인수를 지원합니다. 예를 들어, dragonfly --requirepass=foo --bind localhost
실행할 수 있습니다.
Dragonfly는 현재 다음과 같은 Redis 관련 인수를 지원합니다.
port
: Redis 연결 포트( default: 6379
).bind
: localhost
사용하여 localhost 연결만 허용하거나 공용 IP 주소를 사용하여 해당 IP 주소에 대한 연결(예: 외부에서도 연결)을 허용합니다. 모든 IPv4를 허용하려면 0.0.0.0
사용하세요.requirepass
: AUTH 인증을 위한 비밀번호( default: ""
).maxmemory
: 데이터베이스에서 사용하는 최대 메모리(사람이 읽을 수 있는 바이트 단위)에 대한 제한입니다( default: 0
). maxmemory
값이 0
이면 프로그램이 자동으로 최대 메모리 사용량을 결정한다는 의미입니다.dir
: Dragonfly Docker는 기본적으로 스냅샷 생성을 위해 /data
폴더를 사용하고, CLI는 ""
사용합니다. -v
Docker 옵션을 사용하여 이를 호스트 폴더에 매핑할 수 있습니다.dbfilename
: 데이터베이스를 저장하고 로드할 파일 이름( default: dump
).Dragonfly와 관련된 몇 가지 주장도 있습니다.
memcached_port
: Memcached 호환 API를 활성화할 포트입니다( default: disabled
).
keys_output_limit
: keys
명령에서 반환된 키의 최대 수( default: 8192
). keys
는 위험한 명령입니다. 너무 많은 키를 가져올 때 메모리 사용량이 급증하는 것을 방지하기 위해 결과를 자릅니다.
dbnum
: select
에 대해 지원되는 최대 데이터베이스 수입니다.
cache_mode
: 아래의 새로운 캐시 디자인 섹션을 참조하세요.
hz
: 키 만료 평가 빈도( default: 100
). 빈도가 낮을수록 제거 속도가 느려지므로 유휴 상태일 때 CPU를 덜 사용합니다.
snapshot_cron
: 분 단위로 세분화된 표준 cron 구문을 사용하는 자동 백업 스냅샷에 대한 Cron 일정 표현입니다( default: ""
). 아래에는 몇 가지 cron 일정 표현 예가 있으며, 문서에서 이 인수에 대한 자세한 내용을 자유롭게 읽어보세요.
Cron 일정 표현 | 설명 |
---|---|
* * * * * | 매분마다 |
*/5 * * * * | 5분마다 |
5 */2 * * * | 매 2시간마다 5분마다 |
0 0 * * * | 매일 00:00(자정) |
0 6 * * 1-5 | 월요일부터 금요일까지 06:00(새벽) |
primary_port_http_enabled
: true
인 경우 기본 TCP 포트에서 HTTP 콘솔에 액세스할 수 있습니다( default: true
).
admin_port
: 할당된 포트에서 콘솔에 대한 관리자 액세스를 활성화합니다( default: disabled
). HTTP 및 RESP 프로토콜을 모두 지원합니다.
admin_bind
: 관리 콘솔 TCP 연결을 지정된 주소에 바인딩합니다( default: any
). HTTP 및 RESP 프로토콜을 모두 지원합니다.
admin_nopass
: 인증 토큰 없이 할당된 포트에서 콘솔에 대한 개방형 관리자 액세스를 활성화합니다( default: false
). HTTP 및 RESP 프로토콜을 모두 지원합니다.
cluster_mode
: 클러스터 모드가 지원됩니다( default: ""
). 현재는 emulated
.
cluster_announce_ip
: 클러스터 명령이 클라이언트에 알리는 IP입니다.
announce_port
: 클러스터 명령이 클라이언트와 복제 마스터에 알리는 포트입니다.
./dragonfly-x86_64 --logtostderr --requirepass=youshallnotpass --cache_mode=true -dbnum 1 --bind localhost --port 6379 --maxmemory=12gb --keys_output_limit=12288 --dbfilename dump.rdb
인수는 다음을 통해 제공될 수도 있습니다.
--flagfile <filename>
: 파일은 키-값 플래그에 공백 대신 등호를 사용하여 한 줄에 하나의 플래그를 나열해야 합니다. 플래그 값에는 따옴표가 필요하지 않습니다.DFLY_x
설정합니다. 여기서 x
플래그의 정확한 이름이며 대소문자를 구분합니다. 로그 관리 또는 TLS 지원과 같은 추가 옵션을 보려면 dragonfly --help
실행하세요.
Dragonfly는 현재 ~185개의 Redis 명령과 cas
이외의 모든 Memcached 명령을 지원합니다. Redis 5 API와 거의 동등한 Dragonfly의 다음 이정표는 기본 기능을 안정화하고 복제 API를 구현하는 것입니다. 필요한 명령이 아직 구현되지 않은 경우 이슈를 열어주세요.
Dragonfly 기본 복제를 위해 우리는 훨씬 더 빠른 속도를 지원하는 분산 로그 형식을 설계하고 있습니다.
복제 기능에 이어 Redis 버전 3-6 API에 대해 누락된 명령을 계속 추가할 예정입니다.
현재 Dragonfly에서 지원하는 명령은 명령 참조를 참조하세요.
Dragonfly에는 간단하고 메모리 효율적인 단일 통합 적응형 캐싱 알고리즘이 있습니다.
--cache_mode=true
플래그를 전달하여 캐싱 모드를 활성화할 수 있습니다. 이 모드가 활성화되면 Dragonfly는 향후에 발견될 가능성이 가장 적은 항목을 제거하지만 해당 항목이 maxmemory
제한에 가까울 때만 제거합니다.
만료 범위는 최대 8년으로 제한됩니다.
밀리초 단위의 만료 기한(PEXPIRE, PSETEX 등)은 2^28ms보다 큰 기한에 대해 가장 가까운 초로 반올림됩니다. 이는 0.001% 미만의 오류를 가지며 넓은 범위에서 허용됩니다. 이것이 귀하의 사용 사례에 적합하지 않은 경우 연락하거나 귀하의 사례를 설명하는 문제를 열어주세요.
Dragonfly 만료 기한과 Redis 구현 간의 자세한 차이점은 여기를 참조하세요.
기본적으로 Dragonfly는 기본 TCP 포트(6379)를 통한 HTTP 액세스를 허용합니다. 맞습니다. Redis 프로토콜과 HTTP 프로토콜을 통해 Dragonfly에 연결할 수 있습니다. 서버는 연결 시작 중에 자동으로 프로토콜을 인식합니다. 브라우저로 시도해 보세요. 현재 HTTP 액세스에는 많은 정보가 없지만 앞으로는 유용한 디버깅 및 관리 정보가 포함될 것입니다.
Prometheus 호환 측정항목을 보려면 URL :6379/metrics
로 이동하세요.
Prometheus에서 내보낸 측정항목은 Grafana 대시보드와 호환됩니다. 여기를 참조하세요.
중요한! HTTP 콘솔은 안전한 네트워크 내에서 액세스하도록 되어 있습니다. Dragonfly의 TCP 포트를 외부에 노출하는 경우 --http_admin_console=false
또는 --nohttp_admin_console
사용하여 콘솔을 비활성화하는 것이 좋습니다.
Dragonfly는 인 메모리 데이터 저장소가 2022년에 설계되면 어떻게 보일지 알아보기 위한 실험으로 시작했습니다. 클라우드 회사에서 근무한 엔지니어와 메모리 저장소 사용자로서의 경험을 바탕으로 우리는 두 가지를 보존해야 한다는 것을 알았습니다. Dragonfly의 주요 속성: 모든 작업에 대한 원자성을 보장하고 매우 높은 처리량에 대해 밀리초 미만의 낮은 대기 시간을 보장합니다.
우리의 첫 번째 과제는 현재 퍼블릭 클라우드에서 사용 가능한 서버를 사용하여 CPU, 메모리 및 I/O 리소스를 최대한 활용하는 방법이었습니다. 이 문제를 해결하기 위해 우리는 스레드 간에 메모리 저장소의 키 공간을 분할하여 각 스레드가 자체 사전 데이터 조각을 관리할 수 있도록 하는 비공유 아키텍처를 사용합니다. 우리는 이러한 조각을 "샤드"라고 부릅니다. 비공유 아키텍처에 대한 스레드 및 I/O 관리를 지원하는 라이브러리는 여기에서 오픈 소스로 제공됩니다.
다중 키 작업에 대한 원자성 보장을 제공하기 위해 우리는 최근 학술 연구의 발전을 사용합니다. 우리는 Dragonfly의 트랜잭션 프레임워크를 개발하기 위해 "VLL: 주 메모리 데이터베이스 시스템을 위한 잠금 관리자 재설계"라는 논문을 선택했습니다. 비공유 아키텍처와 VLL의 선택을 통해 우리는 뮤텍스나 스핀록을 사용하지 않고 원자 다중 키 작업을 구성할 수 있었습니다. PoC의 주요 이정표였으며 그 성능은 다른 상용 및 오픈 소스 솔루션보다 돋보였습니다.
두 번째 과제는 새 매장을 위해 보다 효율적인 데이터 구조를 설계하는 것이었습니다. 이 목표를 달성하기 위해 우리는 "대시: 지속 메모리의 확장 가능한 해싱" 논문을 기반으로 핵심 해시 테이블 구조를 기반으로 했습니다. 논문 자체는 영구 메모리 영역을 중심으로 하며 주 메모리 저장소와 직접적인 관련이 없지만 여전히 우리 문제에 가장 적합합니다. 백서에 제안된 해시 테이블 설계를 통해 Redis 사전에 존재하는 두 가지 특수 속성을 유지할 수 있었습니다. 즉, 데이터 저장소 증가 중 증분 해싱 기능, 상태 비저장 스캔 작업을 사용하여 변경 사항이 있을 때 사전을 탐색하는 기능입니다. 이 두 가지 속성 외에도 Dash는 CPU 및 메모리 사용 측면에서 더 효율적입니다. Dash의 디자인을 활용하여 우리는 다음 기능을 통해 더욱 혁신할 수 있었습니다.
Dragonfly의 기반을 구축하고 성능에 만족한 후 계속해서 Redis 및 Memcached 기능을 구현했습니다. 우리는 현재까지 ~185개의 Redis 명령(Redis 5.0 API와 거의 동일)과 13개의 Memcached 명령을 구현해야 합니다.
그리고 마지막으로,
우리의 임무는 최신 하드웨어 발전을 활용하는 클라우드 워크로드를 위해 잘 설계되고 초고속이며 비용 효율적인 인 메모리 데이터 저장소를 구축하는 것입니다. 우리는 제품 API와 제안을 유지하면서 현재 솔루션의 문제점을 해결하려고 합니다.