10 คะแนน โดย GN⁺ 2024-04-15 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • Redka มีเป้าหมายในการสร้างข้อดีของ Redis ขึ้นใหม่บน SQLite พร้อมทำให้เข้ากันได้กับ Redis API
  • คุณสมบัติหลัก:
    • ข้อมูลไม่จำเป็นต้องพอดีกับขนาด RAM
    • รองรับทรานแซกชันแบบ ACID
    • เพิ่มความสามารถในการสืบค้นข้อมูลและการทำรายงานผ่าน SQL view
    • รองรับทั้งเซิร์ฟเวอร์แบบ in-process (Go API) และแบบ standalone (RESP)
    • รองรับคำสั่งและโปรโตคอลที่เข้ากันได้กับ Redis
  • ขณะนี้ยังอยู่ระหว่างการพัฒนา และสามารถดูสถานะการรองรับกับโรดแมปได้ในเอกสารด้านล่าง

คำสั่งที่รองรับ

  • Redka ตั้งเป้ารองรับชนิดข้อมูลหลัก 5 แบบของ Redis ได้แก่ String, List, Set, Hash และ Sorted Set
  • ขณะนี้รองรับ String, Hash, การจัดการ Key และคำสั่งทรานแซกชันแล้ว ส่วน List, Set และ Sorted Set ยังอยู่ระหว่างพัฒนา
  • รายการคำสั่งโดยละเอียดดูได้จากต้นฉบับ

วิธีติดตั้ง

เซิร์ฟเวอร์แบบสแตนด์อโลน

  • ดาวน์โหลดไฟล์ไบนารีตามระบบปฏิบัติการจากหน้า Release แล้วรัน
  • หากใช้ Docker ให้ดาวน์โหลดอิมเมจด้วย docker pull nalgeon/redka

Go module

  • ติดตั้งโมดูลด้วย go get github.com/nalgeon/redka
  • ใช้ github.com/mattn/go-sqlite3 หรือ modernc.org/sqlite เป็น SQLite driver

วิธีใช้งาน

เซิร์ฟเวอร์แบบสแตนด์อโลน

  • รันไฟล์ไบนารีที่ดาวน์โหลดมาในรูปแบบ redka [-h host] [-p port] [db-path]
    • ค่าเริ่มต้นคือ host localhost, port 6379 และไม่มีเส้นทาง DB (เก็บในหน่วยความจำ)
  • หากใช้ Docker ให้รันด้วยคำสั่ง docker run รายละเอียดออปชันเพิ่มเติมดูจากต้นฉบับ
  • หลังจากรันเซิร์ฟเวอร์แล้ว สามารถเชื่อมต่อด้วยไคลเอนต์ที่เข้ากันได้กับ Redis เช่น redis-cli, redis-py, go-redis

เซิร์ฟเวอร์แบบ in-process

  • สร้างอ็อบเจ็กต์ DB ด้วยฟังก์ชัน redka.Open() โดยต้อง import driver ด้วย
  • เรียกใช้คำสั่งต่าง ๆ ผ่านเมธอดของอ็อบเจ็กต์ redka.DB
  • จัดการทรานแซกชันด้วยเมธอด View (อ่านอย่างเดียว) และ Update (เขียนได้)

การทำงานแบบคงอยู่ถาวร

  • Redka จัดเก็บข้อมูลโดยใช้ตาราง rkey, rstring, rhash ในฐานข้อมูล SQLite
  • สามารถสืบค้นข้อมูลด้วย SQL ผ่าน view ของแต่ละชนิดข้อมูล เช่น vstring, vhash

ประสิทธิภาพ

  • เปรียบเทียบประสิทธิภาพของ Redis และ Redka ด้วยเครื่องมือ redis-benchmark
    • Redka ช้ากว่า Redis ราว 6 เท่าใน SET และราว 2 เท่าใน GET
    • ถึงอย่างนั้นก็ยังทำได้ประมาณ 23K writes/วินาที และ 57K reads/วินาที
  • หากรันในคอนเทนเนอร์ อาจมีประสิทธิภาพลดลง

โรดแมป

  • ในรีลีส 1.0 มีแผนจะเน้นฟังก์ชันหลักของ Redis ยุค 2.x
    • รองรับ String, Hash, การจัดการ Key และทรานแซกชันแล้ว
    • Sorted Set อยู่ระหว่างพัฒนา
    • List และ Set มีแผนจะพัฒนา
  • ในเวอร์ชันถัดไปมีแผนเพิ่มชนิดข้อมูลอย่าง Stream, HyperLogLog, Geo และฟังก์ชัน Pub/Sub
  • ไม่มีแผนรองรับ Lua scripting, การยืนยันตัวตน/ACL, multi DB, Watch/Unwatch
  • และไม่มีแผนทำฟังก์ชัน cluster กับ sentinel เช่นกัน

ความเห็นของ GN⁺

  • แนวทางของ Redka ที่เข้ากันได้กับ Redis เป็นส่วนใหญ่พร้อมให้ persistence นั้นน่าสนใจมาก การรองรับทรานแซกชันแบบ ACID ก็ดูจะเป็นข้อดีเช่นกัน
  • แม้ด้านประสิทธิภาพจะยังสู้ Redis ไม่ได้ แต่ถ้าต้องการ persistence ก็ถือเป็นทางเลือกที่น่าพิจารณาเพียงพอ
  • อย่างไรก็ตาม โครงการยังอยู่ในช่วงเริ่มต้น จึงคงต้องติดตามเรื่องเสถียรภาพต่อไป อีกทั้งยังมีฟังก์ชันหลายอย่างที่ไม่ได้อยู่ในโรดแมป ซึ่งควรพิจารณาเมื่อจะนำไปใช้งานจริง
  • สำหรับงาน in-memory คงยากที่จะเอาชนะ Redis ได้อยู่แล้ว แต่ในฐานะ persistence layer ที่อิงกับ SQLite ก็ดูน่าจะใช้งานได้ดี
  • ช่วงนี้ในสภาพแวดล้อม edge computing ความต้องการสแตกที่มีน้ำหนักเบากำลังสูงขึ้น และในงานลักษณะนั้นก็อาจลองใช้ Redka แทน Redis ได้

2 ความคิดเห็น

 
yangeok 2024-05-10

น่าจะมีประโยชน์เวลาอยากให้ scheduler ต่อกับ Redis นะครับ 555

 
GN⁺ 2024-04-15
ความคิดเห็นจาก Hacker News
  • มีการครุ่นคิดว่าจะเดินตามโมเดลแบบไม่มี concurrency ของ Redis ที่ "ทุกอย่างถูก serialize อยู่บนเธรดเดียว" มากน้อยแค่ไหน
  • สามารถรีดประสิทธิภาพจาก SQLite ได้ดีกว่าเดิมโดยใช้ไลบรารีระดับล่างของ SQLite, เปิดใช้ WAL, ใช้คอนเนกชันแยกต่อ goroutine สำหรับการอ่าน และส่งชุดงานเขียนผ่าน channel/queue แบบมีบัฟเฟอร์ไปยัง writer thread เฉพาะทาง
  • วิธีนี้ทำให้สามารถปิด mutex แบบต่อคอนเนกชันที่มีในตัวของ SQLite ได้ ขณะเดียวกันก็ยังคงความปลอดภัยด้านเธรดไว้ได้ เพราะแต่ละคอนเนกชันจะถูกใช้งานจากเพียงเธรดเดียวในแต่ละครั้ง
  • การใช้บัฟเฟอร์ก้อนใหญ่สไตล์ arena เช่น การคัดลอกพารามิเตอร์ไบต์ที่เข้ามาจาก network request/socket ลงบัฟเฟอร์ หรือคัดลอกจาก SQLite ออก socket โดยตรง สามารถลดการจองหน่วยความจำและการส่งต่อสตริงทีละตัวได้ จึงช่วยประหยัดเวลาได้มาก
  • นี่คือทิปส์ที่มาจากประสบการณ์พยายามดึง throughput ฝั่งเขียนสูงสุดจาก SQLite ใน Go
  • ชอบทั้ง Redis และ SQLite จึงตัดสินใจรวมทั้งสองอย่างเข้าด้วยกัน SQLite เหมาะกับคิวรีขนาดเล็กจำนวนมากอยู่แล้ว และ relational engine ก็เข้าใกล้ความเป็น Redis ได้มากเท่าที่จะเป็นไปได้ จึงน่าจะเข้ากันได้ดี
  • กำลังรอใครสักคนมาแทนที่ state machine ของ TigerBeetle แล้วทำ Redis API ขึ้นมา
  • คงจะดีถ้ามีทางเลือกแทน Redis ที่ไม่ต้องคอยคิดว่าชุดข้อมูลจะพอดีกับหน่วยความจำหรือไม่
  • คุณค่าหลักทั้งหมดของ Redis คือการทำงานอยู่ในหน่วยความจำและให้ประสิทธิภาพแบบหน่วยความจำ ถ้าย้ายไปอยู่บนดิสก์ ก็แทบไม่เหลือเหตุผลให้ใช้ Redis
  • เมื่อมี network I/O เพิ่มเข้ามา ประสิทธิภาพอันยอดเยี่ยมของ Redis ก็หายไปมาก การใช้บริการ Redis แบบ SaaS hosting ทำให้ประสิทธิภาพตกลงอย่างหนัก ถ้าสามารถรัน key/value store ที่เข้ากันได้กับ Redis บนคลัสเตอร์ของตัวเองได้ง่ายขึ้น นี่ก็ถือเป็นข้อดี
  • สงสัยว่านี่หรือ Garnet รองรับคำสั่ง Redis ได้มากกว่ากัน กำลังพยายามฝังฟังก์ชันที่เข้ากันได้กับ Redis บางส่วนไว้ในโปรแกรมเพื่อใช้สำหรับดีบักบนเครื่อง โดยมี API คั่นกลางเพื่อป้องกันคำสั่ง Redis ที่ยังไม่รองรับ
  • ตอนที่ Foursquare ทำให้ MongoDB โด่งดัง มีคนโพสต์ PoC ของ NoSQL DB ที่สร้างบน MySQL แต่สุดท้ายก็ไม่ติดกระแส ถึงอย่างนั้นมันก็ทำให้คิดว่าเราแลกประสิทธิภาพไปมากแค่ไหนเพื่อไม่ต้องประดิษฐ์ SQL ขึ้นมาใหม่ทุกครั้งที่ต้องใช้ DB ชอบการทดลองแบบนี้ และบางครั้งมันก็นำไปสู่โปรเจกต์ใหม่
  • ใช้ Redis เป็นชั้น cache อยู่หน้าฐานข้อมูล ไม่เข้าใจแนวคิดนี้
  • แต่เมื่อใช้ SetMaxConnections(1) อยู่ แม้ SQLite ในโหมด WAL (ซึ่งกำลังใช้อยู่) จะรองรับการเขียนที่ไม่บล็อกการอ่าน ดังนั้นการเปิดให้มี read concurrency ก็อาจมีประโยชน์