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

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