การรัน Redis SQL query ไม่จำเป็นต้องยาก ผมเคยยกประเด็นนี้เมื่อหลายปีก่อน ตอนคุยกับเพื่อนที่ดูแล data warehousing ที่บริษัทค้าปลีก เราเริ่มพูดถึง Redis queries หลังเขาอธิบายปัญหาที่เผชิญ
"เรามีจุดอ่อนกับ data warehousing solutions มี use cases ที่ต้องบันทึกข้อมูลและทำ analytical operations แบบเรียลไทม์ แต่บางครั้งใช้เวลานาทีในการได้ผลลัพธ์ Redis ช่วยได้ไหม? จดจ่อว่าเราไม่สามารถ rip and replace SQL-based solution ทีเดียวได้ เราสามารถก้าวไปทีละขั้นเล็กน้อยเท่านั้น"
ถ้าคุณอยู่ในสถานการณ์เดียวกันกับเพื่อนผม มีข่าวดีครับ มีหลายวิธีที่สามารถรัน Redis query และนำ Redis เข้าสู่ architecture โดยไม่ รบกวน SQL-based solution ที่มีอยู่
มาสำรวจวิธีการกัน แต่ก่อนจะไปต่อ เรามีผู้เข้าแข่งขัน Redis Hackathon ที่สร้างแอปของตัวเองเพื่อ query ข้อมูลใน Redis ด้วย SQL ดูวิดีโอด้านล่างได้เลย
ปรับโครงสร้างตารางเป็น Redis data structures
การ map ตาราง (table) ไปเป็น Redis data structures ทำได้ง่าย โครงสร้างข้อมูลที่มีประโยชน์ที่สุดคือ:
- Hash
- Sorted Set
- Set
วิธีหนึ่งคือเก็บแต่ละแถว (row) เป็น Hash ด้วย key ที่อิงจาก primary key ของตาราง และเก็บ key ไว้ใน Set หรือ Sorted Set
รูปที่ 1 แสดงตัวอย่างการ map ตารางไปเป็น Redis data structures ในตัวอย่างมีตารางชื่อ Products ทุกแถว map ไปเป็น Hash data structure
แถวที่มี primary id 10001 จะไปเป็น Hash ด้วย key: product:10001 มี Sorted Sets 2 ตัว: ตัวแรกสำหรับ iterate ข้อมูลด้วย primary key ตัวที่สองสำหรับ query ตามราคา
ด้วยวิธีนี้ คุณต้องแก้โค้ดเพื่อใช้ Redis queries แทน SQL commands นี่คือตัวอย่างคำสั่ง SQL และคำสั่ง Redis เทียบเท่า:
A. เพิ่มข้อมูล (Insert data)
SQL: insert into Products (id, name, description, price) values = (10200, "ZXYW","Description for ZXYW", 300);
Redis: MULTI HMSET product:10200 name ZXYW desc "Description for ZXYW" price 300 ZADD product_list 10200 product:10200 ZADD product_price 300 product:10200 EXEC
B. Query ตาม product id
SQL: select * from Products where id = 10200
Redis: HGETALL product:10200
C. Query ตามราคา
SQL: select * from Product where price < 300
Redis: ZRANGEBYSCORE product_price 0 300
จะคืนค่า keys: product:10001, product:10002, product:10003 ตอนนี้รัน HGETALL สำหรับแต่ละ key
HGETALL product:10001 HGETALL product:10002 HGETALL product:10003
ใช้ DataFrames เพื่อ map ตารางไป Redis data structures อัตโนมัติ
ถ้าคุณต้องการรักษา SQL interface ใน solution และเปลี่ยนแค่ underlying data store เป็น Redis เพื่อความเร็ว สามารถทำได้ด้วย Apache Spark และ Spark-Redis library
Spark-Redis library ให้ใช้ DataFrame APIs เพื่อจัดเก็บและเข้าถึงข้อมูล Redis กล่าวคือ สามารถ insert, update, query ด้วย SQL commands แต่ข้อมูลภายใน map ไป Redis data structures
ก่อนอื่น ต้อง download spark-redis และ build library เพื่อได้ไฟล์ jar เช่น spark-redis 2.3.1 จะได้ spark-redis-2.3.1-SNAPSHOT-jar-with-dependencies.jar
ต่อมา ต้องแน่ใจว่า Redis instance รันอยู่ ในตัวอย่างรัน Redis บน localhost พอร์ต 6379 เริ่มต้น
สามารถรัน queries บน Apache Spark engine ได้ ตัวอย่าง:
$ spark-shell --jars spark-redis-2.3.1-SNAPSHOT-jar-with-dependencies.jar
scala> import org.apache.spark.sql.SparkSession scala> val spark = SparkSession .builder() .appName("redis-sql") .master("local[*]") .config("spark.redis.host","localhost") .config("spark.redis.port","6379").getOrCreate() scala> import spark.sql scala> import spark.implicits._ scala> sql("create table if not exists products(id string, name string, description string, price int) using org.apache.spark.sql.redis options (table 'product')") scala> sql("insert into products values = ('10200','ZXYW','Description of ZXYW', 300)") scala> val results = sql("select * from products") scala> results.show() +-----+----+-------------------+-----+ | id|name| description|price| +-----+----+-------------------+-----+ |10200|ZXYW|Description of ZXYW| 300| +-----+----+-------------------+-----+
ตอนนี้สามารถใช้ Redis client เข้าถึงข้อมูลนี้เป็น Redis data structures ได้:
127.0.0.1:6379> keys product* 1) "product:2e3f8611dbe94a588706a2aaea547caa"
วิธีที่มีประสิทธิภาพกว่าคือใช้คำสั่ง scan เพราะ paginate ได้ขณะ.navigate ข้อมูล
127.0.0.1:6379> scan 0 match product* 1) "3" 2) 1) "product:2e3f8611dbe94a588706a2aaea547caa" 127.0.0.1:6379> hgetall product:2e3f8611dbe94a588706a2aaea547caa 1) "name" 2) "ZXYW" 3) "price" 4) "300" 5) "description" 6) "Description of ZXYW" 7) "id" 8) "10200"
แล้วก็ได้ – 2 วิธีง่ายๆ ที่รัน Redis SQL query ได้โดยไม่รบกวนระบบเดิม หากอยากไปต่อ ให้อ่าน whitepaper Why Your SQL Server Needs Redis
แต่เรื่อง real-time data กับ Redis นี้เป็นเพียงหนึ่งในหลายวิธีที่ใช้ Redis ให้ประสบการณ์เรียลไทม์ หากอยากค้นพบว่า Redis รับประกัน real-time data transmission ยังไง ติดต่อเราได้เลย