Lua ใน Redis (redis script) by

31
Jul
0

วันหนึ่งผมได้ค้นพบความเทพของ redis นั่นคือมันสามารถเขียน script เข้าไปในตัว redis เองได้ครับ โดยจะใช้ได้ตั้งแต่ Redis 2.6 ขึ้นไป ซึ่งตัวภาษาจะเป็น lua ถามว่าเขียนได้แล้วดียังไง? ก็คือเราสามารถสร้างคำสั่ง Redis อันสุดแสนประหลาดได้ด้วยตัวเองโดยไม่ต้องง้อให้ Redis ออก function ใหม่มาอีกต่อไป อยากได้อะไรก็เอา function ใน redis เดิมมาต้มยำทำแกงออกมาเป็นคำสั่งใหม่ได้ตามใจเล้ย!!

สำหรับการใช้งาน จะเรียกใช้ผ่าน eval ตัวอย่างเช่น


eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

ตรงนี้จะมี parameter ที่ส่งเข้าไปสองแบบคือแบบ key และแบบ argument ซึ่งแบบ key (ในที่นี้คือ key1, key2) จะใช้สำหรับส่งชื่อ key ที่ต้องการจะทำงานด้วยเข้าไปโดยเฉพาะ ส่วน argument (first, second) คือค่าอื่นๆ ที่ต้องการส่งเข้า script ซึ่งส่วนมากมักจะเป็น value ที่ต้องการ set เข้าไป บางคนอาจจะสงสัยว่าทำไมต้องแยกเป็นสองประเภท? คนสร้าง redis บอกว่าเพื่อให้ตัว redis รู้ว่าอะไรเป็น key แล้วจะส่งไปให้ redis อีกตัวเวลาใช้งาน redis cluster (ที่ยังไม่ออกตัวเสถียร) ได้ ดังนั้นหากคุณไม่ได้วางแผนจะใช้งาน redis มากกว่า 1 process ก็อาจจะไม่ต้องสนใจในส่วนนี้ก็ได้

สำหรับ parameter จริงๆ มี 3 ตัวเป็นอย่างน้อยได้แก่

  1. ตัว lua script คำสั่งต่างๆ
  2. ตัวเลขบอกว่าจะมี key กี่ตัว (ใส่ 0 ได้หากไม่ต้องการส่ง key เลย)
  3. ตั้งแต่ตัวที่ 3 เป็นต้นไปจะเป็น keys ต่อด้วย argument (ARGV) เช่น ใส่เลขในข้อสองไปว่า 1 จะทำให้ parameter ตัวนี้คือ KEYS[1] ส่วน parameter ตัวที่ 4 คือ ARGV[1]

ตัวอย่างการใช้งานจริงเช่น


eval "return redis.call('set','mykey',ARGV[1])" 0 value

ตัวอย่างนี้แสดงการสั่งคำสั่ง set แบบบังคับว่า key ชื่อ mykey เท่านั้น ส่วน value ส่งจากนอก script เข้าไปทำงาน อาจเกิดข้อสงสัยอีกข้อว่าในเมื่อเราส่งคำสั่ง eval เป็นตัว script lua ตรงๆ ซึ่งเราสร้าง string ส่งเข้าไปเอง ทำไมยังต้องมี argument ส่งเข้าไปอีก? คำตอบคือ redis มีคำสั่ง evalSha ซึ่งเราสามารถเรียก script ที่ “cache” เอาไว้ได้ เพื่อประสิทธิภาพสูงสุดครับ (ใช้ SCRIPT LOAD ในการสั่ง cache ครั้งแรก)

สำหรับอีกตัวอย่างที่ใช้งานจริงได้ เช่นผมอยากสร้างคำสั่ง myhset ซึ่งคำสั่งนี้จะเช็คค่า key ที่ชื่อว่า serverStatus ว่าเป้น open อยู่หรือเปล่า ถ้า open ถึงจะอนุญาตให้เซ็ตได้ ไม่งั้น return redis error มาจะเขียนดังนี้


local serverStatus = redis.get('serverStatus')
if serverStatus == 'open' then
return redis.call('hset', ARGV[1], ARGV[2])
else
return redis.error_reply("serverIsClosed")
end

จบบทความวันนี้ครับ :)

Enjoy this article?

Consider subscribing to our RSS feed!

ไม่มีความเห็น

ยังไม่มีความเห็น

ใส่ความเห็น

RSS feed for comments on this post

 เราชนะรอบ 4 | ยืมเงิน 3000 ด่วน | แอพกู้เงิน | แอพเงินด่วน | สินเชื่อออนไลน์อนุมัติทันที | Site Map | กู้เงินก้อน | กระเป๋าตัง | thisshop และ ยืมเงินฉุกเฉิน 5000 ด่วน