Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

Redis Lua Scripting: เพิ่มประสิทธิภาพด้วย Script ฝั่งเซิร์ฟเวอร์

ทำไมต้อง Lua Scripts?

  • Performance: รันหลายขั้นตอนใน Redis ได้ในครั้งเดียว (ลด network round-trips)
  • Atomicity: คำสั่งทั้งหมดใน script รันแบบ atomic — ไม่มีคำสั่งอื่นแทรกแซงระหว่างรัน

Lua พื้นฐาน

Lua ง่าย ใกล้เคียง C-family ใช้ table (1-based index), string concatenation ด้วย ..

รัน Script ด้วย EVAL

eval "redis.call('set', KEYS[1], ARGV[1])" 1 key:name value
  • EVAL บอก Redis รัน script
  • KEYS[1] = key:name (จำนวน keys = 1)
  • ARGV[1] = value

อ่านคืน: eval "return redis.call('get', KEYS[1])" 1 key:name → "value"

Script ซับซ้อน: เรียงข้อมูลจาก Hash ตาม Sorted Set

# Setup
hmset hkeys key:1 value:1 key:2 value:2 key:3 value:3 key:4 value:4 key:5 value:5 key:6 value:6
zadd order 1 key:3 2 key:1 3 key:2

# Script
eval "local order = redis.call('zrange', KEYS[1], 0, -1); return redis.call('hmget', KEYS[2], unpack(order));" 2 order hkeys
# ผล: "value:3" "value:1" "value:2"

SCRIPT LOAD และ EVALSHA

โหลด script ลงหน่วยความจำ คืน SHA1 hash → ใช้ EVALSHA แทน script เต็ม ลด bandwidth

script load "return redis.call('get', KEYS[1])"
# คืน SHA1 เช่น "4e6d8fc8bb01276962cce5371fa795a7763657ae"
evalsha 4e6d8fc8bb01276962cce5371fa795a7763657ae 1 key:name

แก้ไข JSON ใน Redis ด้วย Lua

ปัญหา: GET → parse → modify → SET → race condition + slow

แก้: Lua script ทำใน Redis atomic

set obj '{"a":"foo","b":"bar"}'

EVAL 'local obj = redis.call("get",KEYS[1]);
      local obj2 = string.gsub(obj,"(" .. ARGV[1] .. "\":)([^,}]+)", "%1" .. ARGV[2]);
      return redis.call("set",KEYS[1],obj2);' 1 obj b bar2

# ผล: {"a":"foo","b":"bar2"}

รายละเอียด: .. = concatenation, % = escape/backreference ใน Lua regex

เมื่อไหร่ควรใช้ Lua?

  • พิสูจน์ได้ว่าเร็วกว่า (benchmark ก่อน)
  • <ไม่น่าใช้แค่เพื่อ atomicity → ใช้ Redis Transactions (MULTI/EXEC) แทน
  • Script ไม่ควรยาวเกินไป (timeout 5 วินาที) ไม่งั้นกลายเป็น bottleneck

สรุป

Lua script ใน Redis ช่วย performance และ atomicity สำหรับออปเรชันซับซ้อน ใช้จำแค่เมื่อจำเป็น มี library ช่วยสร้าง script อัตโนมัติ (เช่น node.js library ของผู้เขียน)