redis lua腳本(優勢)


Redis支持LUA腳本的主要優勢

LUA腳本的融合將使Redis數據庫產生更多的使用場景,迸發更多新的優勢:
  • 高效性:減少網絡開銷及時延,多次redis服務器網絡請求的操作,使用LUA腳本可以用一個請求完成
  • 數據可靠性:Redis會將整個腳本作為一個整體執行,中間不會被其他命令插入。
  • 復用性:LUA腳本執行后會永久存儲在Redis服務器端,其他客戶端可以直接復用
  • 便捷性:實現程序熱更新
  • 可嵌入性:可嵌入JAVA,C#等多種編程語言,支持不同操作系統跨平台交互
  • 簡單強大:小巧輕便,資源占用率低,支持過程化和對象化的編程語言
  • 免費開源:遵循MIT Licence協議,可免費商用化
Redis LUA腳本應用場景
1.游戲開發:Lua大量用於游戲開發中,實現熱升級,提升應用擴展性
  • 1)活躍用戶判斷:判斷一個游戲用戶是否屬於活躍用戶,如果符合標准,則活躍用戶人數+1
Lua腳本(sha: 089ccf077629d371793d5e928a3f06e9e483eb08)
   if redis.call("EXISTS",KEYS[1]) == 1 then
     return redis.call("INCRBY",KEYS[1],ARGV[1])
   else
     return nil
   end  
游戲用戶示例信息如下:
    > evalsha f74dd5c086898b8a3d69655334b94fa7e006a9b1 1 activeusers 1 (nil)
> set activeusers 0 OK
> evalsha f74dd5c086898b8a3d69655334b94fa7e006a9b1 1 activeusers 1 (integer) 1
> evalsha f74dd5c086898b8a3d69655334b94fa7e006a9b1 1 activeusers 2 (integer) 3
 
  • 2)簡單DDOS防護:限制n秒內同ip的訪問次數
Lua腳本(sha: 089ccf077629d371793d5e928a3f06e9e483eb08)
示例信息如下:10秒內192.168.1.1訪問是否超過了5次
   local cnt = redis.call('INCR', KEYS[1])
   if cnt > tonumber(ARGV[1])
   then
     return 1
   end
   if cnt == 1
   then
     redis.call('PEXPIRE', KEYS[1], ARGV[2])
   end
   return 0  

> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 0
> evalsha 089ccf077629d371793d5e928a3f06e9e483eb08 1 ratelimit:192.168.1.1 5 10000 (integer) 1
  • 3)用戶游戲社區判斷:判斷當前用戶是否在多個游戲社區中 
Lua腳本(Sha:d7550c872f553141096d5134c027af5eeed283db)
   for i=1,#KEYS do 
     if redis.call('sismember', KEYS[i], ARGV[1]) == 1 then
       return 1
     end
   end
   return 0
示例信息如下:
    > sadd users alice bob (integer) 2
> sadd admin jenny (integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 2 users admin alice (integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 3 users admin guests jenny (integer) 1
> evalsha d7550c872f553141096d5134c027af5eeed283db 2 users admin abner (integer) 0
  • 4)獲取游戲商店中的貨品:取出hash表中符合條件的對象 
Lua腳本(SHA:700c06c5ce9835bf9eef2198c8bc4d268b3b5095)
 local fields = redis.call("SMEMBERS", KEYS[2])
   local values = redis.call("HMGET", KEYS[1], unpack(fields))
   local result = {}
   for i,k in ipairs(fields) do result[i] = {k, values[i]} end
   return result  

示例信息如下:取出所有在produce集合中的對象在hash表groceries中的值

    > hset groceries bread 2 (integer) 1
> hset groceries apples 5 (integer) 1
> hset groceries oranges 6 (integer) 1
> hset groceries broccoli 1 (integer) 1
> sadd produce apples oranges broccoli (integer) 3
> evalsha 700c06c5ce9835bf9eef2198c8bc4d268b3b5095 2 groceries produce
1) 1) "apples"
2) "5"
2) 1) "broccoli"
2) "1"
3) 1) "oranges"
2) "6"
2.數據分析:通過Lua腳本實現數據格式化,提供給軟件平台通用接口能力
  • 1)實時平均值統計
Lua腳本(sha:399fddde578fd9cb924edce746c783e8340d8251)
  local currentval = tonumber(redis.call('get', KEYS[1])) or 0
   local count = redis.call('incr', KEYS[2])
   currentval = tostring(currentval * (count - 1)/count + (ARGV[1]/count))
   redis.call('set', KEYS[1], currentval)
   return currentval  
示例如下:
    > evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 80 "80"
> evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 100 "90"
> evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 75 "85"
> evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 98 "88.25"
> evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 98 "90.2"
> evalsha 399fddde578fd9cb924edce746c783e8340d8251 2 score:avg score:count 98 "91.5"
> get score:avg "91.5"
> get score:count "6"

原文鏈接:https://www.cnblogs.com/Don/articles/5731856.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM