เนื้อหา

DragonflyDB vs Redis

ปกติแล้วเวลาเราใช้งาน In-memory database ก็มักจะนึกถึง Redis กับ Memcache วันนี้เลยจะมาแนะนำอีกตัวนึงที่น่าสนใจนั่นคือ Dragonfly ซึ่งเคลมตัวเองว่าเป็น multi-threaded Redis replacement เลยมาลองทดสอบดูว่าระหว่าง Dragonfly กับ Redis 7 ผลจะเป็นอย่างไร

Redis test compose

เริ่มจากสร้าง compose สำหรับทดสอบ Redis

services:
  redis:
    image: redis
    ulimits:
      memlock: -1
    volumes:
      - redis-data:/data
    hostname: redis
    command:
      ["redis-server", "--loglevel warning", "--unixsocket", "/data/redis.sock"]

  redis_tcp:
    depends_on:
      - redis
    image: redislabs/memtier_benchmark
    volumes:
      - redis-data:/redis-data
      - ./tmp:/data
    command: ["-h", "redis", "--out-file=/data/redis-tcp.log"]

  redis_sock:
    depends_on:
      - redis
    image: redislabs/memtier_benchmark
    volumes:
      - redis-data:/redis-data
      - ./tmp:/data
    command: ["-S", "/redis-data/redis.sock", "--out-file=/data/redis-sock.log"]

volumes:
  redis-data:

Dragonfly test compose

ต่อด้วย compose สำหรับ Dragonfly

Note
ปกติ Dragonfly จะใช้ Ram Limit ขั้นต่ำต่อ Logical CPU อยู่ที่ 256MB นะครับ
services:
  dragonfly:
    image: docker.dragonflydb.io/dragonflydb/dragonfly
    ulimits:
      memlock: -1
    volumes:
      - dragonfly-data:/data
    hostname: dragonfly
    command:
      ["dragonfly", "--logtostderr", "--unixsocket", "/data/dragonfly.sock"]

  dragonfly_tcp:
    depends_on:
      - dragonfly
    image: redislabs/memtier_benchmark
    volumes:
      - dragonfly-data:/dragonfly-data
      - ./tmp:/data
    command: ["-h", "dragonfly", "--out-file=/data/dragonfly-tcp.log"]

  dragonfly_sock:
    depends_on:
      - dragonfly
    image: redislabs/memtier_benchmark
    volumes:
      - dragonfly-data:/dragonfly-data
      - ./tmp:/data
    command: ["-S", "/dragonfly-data/dragonfly.sock", "--out-file=/data/dragonfly-sock.log"]

volumes:
  dragonfly-data:

TCP

เริ่มจากท่าที่ทุกคนน่าจะใช้งานกันปกติทดสอบผ่านทาง TCP/IP ระหว่าง container

Redis

docker compose -f docker-compose.redis.yml up redis_tcp 
TypeOps/secHits/secMisses/secAvg. Latencyp50 Latencyp99 Latencyp99.9 LatencyKB/sec
Sets6446.592.820532.687005.4070010.36700496.50
Gets64395.050.0064395.052.820982.687005.4070010.687002508.47
Waits0.00
Totals70841.640.0064395.052.820932.687005.4070010.623003004.97

Dragonfly

docker compose -f docker-compose.dragonfly.yml up dragonfly_tcp 
TypeOps/secHits/secMisses/secAvg. Latencyp50 Latencyp99 Latencyp99.9 LatencyKB/sec
Sets12683.031.534500.6630010.8790016.12700976.82
Gets126690.880.00126690.881.517680.6550010.9430016.319004935.16
Waits0.00
Totals139373.910.00126690.881.519210.6550010.9430016.319005911.97

UNIX socket

แล้วก็มาลองทดสอบด้วยการใช้ UNIX socket ระหว่าง container ดู

Redis

docker compose -f docker-compose.redis.yml up redis_sock 
TypeOps/secHits/secMisses/secAvg. Latencyp50 Latencyp99 Latencyp99.9 LatencyKB/sec
Sets17540.931.047330.999001.823004.991001350.96
Gets175216.520.00175216.521.045970.999001.823003.871006825.44
Waits0.00
Totals192757.450.00175216.521.046100.999001.823004.031008176.40

Dragonfly

docker compose -f docker-compose.dragonfly.yml up dragonfly_sock 
TypeOps/secHits/secMisses/secAvg. Latencyp50 Latencyp99 Latencyp99.9 LatencyKB/sec
Sets23136.830.804380.279007.7430014.399001781.94
Gets231114.050.00231114.050.786180.279007.3910012.671009002.89
Waits0.00
Totals254250.880.00231114.050.787830.279007.4230012.7990010784.83

สรุป

ด้วยพลังแห่ง Multi-thread ทำให้ผลที่ออกมา Dragonfly ดูดีเลยทีเดียว (ยิ่งผ่าน UNIX socket ยิ่งเห็นความต่างจาก TCP/IP) แต่ก็มีข้อสังเกตุคือ ตอนนี้ Dragonfly ไม่ได้รองรับ Redis API แบบ 100% นะครับ ถ้ามีการใช้ท่ายากท่าพิเศษ จะต้องเช็คกันก่อนว่าสามารถเอามาใช้งานแทนได้เลยหรือไม่ ที่ command-reference ซึ่งจากการทดลองใช้งานดูแล้ว ถ้าโดยปกติใช้งาน Redis แค่ Instance เดียว ไม่ได้ใช้งาน ด้าน Graph, Geo location โดยใช้แค่ หลัก ๆ เป็น Set Get และใช้ PubSub Stream นิดหน่อย ก็สามารถแทนด้วย Dragonfly ได้เลย โดยโค้ดและการเชื่อมต่อยังใช้ตามเดิม