python redis lua script combat a flow restrictor or grab a red envelope business

Knowledge Point

What 1.lua
2.redis, relationship lua, python (java) three
3. bearer service logic lua

Why join a lua script

  • Reduce network overhead. The multiple requests can be sent in the form of a script, to reduce network latency
  • Atomic operation. redis entire script as a whole will perform, will not be inserted into the middle of other commands. Therefore, in the process of writing the script without worrying about race conditions occur, without the use of a transaction.
  • Multiplexing. Footsteps sent by the client will be permanently present in redis, so that other clients can be multiplexed without using the script code that perform the same logic.

lua environment installation

The machine test address on the virtual machine centos-30
mounted refer Redis installation
ps: Installation Guide for the cluster mode, this single instance can Redis Demo, reference to the preceding steps, without using ruby script portion.

  • Installation depends and Lua:
> yum install -y readline
> yum install -y readline-devel
> wget http://www.lua.org/ftp/lua-5.1.1.tar.gz
> tar -zxvf lua-5.1.1.tar.gz -C /usr/local/
> cd /usr/local/lua-5.1.1
> make linux
> make install

  • verification
> lua
> print("hello world")
> hello world

Redis Lua script calls in three ways * eval

  • evalsha
  • Load Script
    the eval lua script for direct execution, the following use
EVAL script numkeys key [key ...] arg [arg ...] > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second" 

rediskey to be operated on behalf of key
arg can pass custom parameters
numkeys used to identify a few key
script is that you write a script lua
lua script used inside KEYS [1] and ARGV [1] to get the pass key and arg

lua syntax see lua tutorial

local result=0
    local id= redis.call('get',KEYS[1])
if id then
    result= redis.call('sismember',id,KEYS[2])
end
 
if result==1 then
    redis.call('expire',KEYS[1],ARGV[1])
end
  
return result

Mode 1

redis-cli  --eval 1.lua 2 user1 user:list 1800

Mode 2

  redis-cli  eval "$(1.lua)" 2 user1 user:list 1800

Mode 3

  redis-cli  script load "$(cat 1.lua)"
  redis-cli  evalsha 2cfe726fe60678e8ed4d689a3e98727d1e1e2339 1 test 1
  • Demo script file name: redis.lua
redis.call('set','age','18')
local age = redis.call('get','age')
return age;

  • Start Redis
> /usr/local/redis-3.2.9/src/redis-server /usr/local/redis-3.2.9/redis.conf 
  • Run Script
    Since conf arranged in the bind ip, -h specified below so that the host. Performed using eval command
> /usr/local/redis-3.2.9/src/redis-cli -h 192.168.1.30 -p 6379 --eval /usr/local/luadir/redis.lua
>"18"     #set了age,并返回了value = 18

At this time, if the connection redis redis-cli. keys * may see the age of this key.

Redis Lua script calls with parameters

  • Syntax:
    / Redis-cli -h 192.168.1.30 -p 6379 --eval / .lua key1 key2 ..., value1 value2 *
  • Script Content:
--获取key1 的值,并赋值给local age
local age = redis.call('get', KEYS[1]);
if age == 18 then
redis.call('set',KEYS[2],ARGV[1])
end

When key1 = "age" the value is 18, set key2 = "name" to the value "mawenxia"

  • Run the script
> /usr/local/redis-3.2.9/src/redis-cli -h 192.168.1.30 -p 6379 --eval /usr/local/luadir/redis-arg.lua age name , mawenxia

  • We can see one more key for the name, and the content is "mawenxia"

    [Picture upload failed ... (image-90eef1-1540882227440)]

python operation redis lua script

import redis
pool = redis.ConnectionPool(host="localhost", port=6379, db=0) r = redis.Redis(connection_pool=pool) lua_2 = """ local ret = redis.call("get", KEYS[1]) return ret """ script_2 = r.register_script(lua_2) print(script_2(keys=["hugo"])) 

result:


 
image.png

JAVA operating Redis Lua script

public class TestSingleRedis {

    private static Jedis jedis; //单实例[] private static ShardedJedis shard; //分片[] private static ShardedJedisPool pool; //池化[apache common - pool2] 
  • NOTE: Since this is a key script takes the value "myhash", it is necessary to insert the data redis, otherwise the value is taken to empty.

Lua table type

  • Lua table type similar to an array. The difference is that with other languages, Lua can use any type as a subscript.
 //定义空表
T1={} 
//赋值 T1["name"] = "mawenxia" T1["age"] = 18 //其他赋值方式 T1.name = "mawenxia" T1.age = 18 //其他赋值方式 T1.person = {name="mawenxia",age=18} 
  • Installation of Lua Cjson tools
> wget http://www.kyne.com.au/~mark/software/download/lua-cjson-2.1.0.tar.gz
> tar -zvxf lua-cjson-2.1.0.tar.gz -C /usr/local/
> cd /usr/local/lua-cjson-2.1.0/
> vim Makefile
> 修改PREFIX 变量为/usr/local  保存
> make install
> cp cjson.so /usr/local/lib/lua/5.1/

  • Lua table type and Cjson binding. The hash operation may be conveniently of the type of data redis

Redis Lua script combine to achieve grab a red envelope scene

  • Mainly the use of the atomic Redis + lua script. To avoid the same situation twice to grab the user.
  • Premise: When a user initiates a red envelope, according to the number of good distribution amount, rather than rush when redistribution. After the assignment into the redis list.
  • The basic idea: two List1 (unassigned red), list2 (red after dispensing) and a set. Use set in the key can not be repeated to determine whether the user has been robbed.
  • Achieve operation in a three Lua script to ensure atomicity. 1: user id taken from the set, it is determined whether the grab, id does not exist, proceeds to step 2.2: pop a red removed from the list1. 3: To push in a red and list2 grab user id.
  • Finally, business systems list2 information can be read after allocation

Reference:
http://xiaorui.cc/2016/03/27/%E8%AF%A6%E8%A7%A3python%E8%B0%83%E7%94%A8redis-lua%E5%86%85%E5 % B5% 8C% E8% 84 % 9A% E6% 9C% AC% E7% 9A% 84% E9% AB% 98% E7% BA% A7% E7% 94% A8% E6% B3% 95 /

https://www.jianshu.com/p/bec0d7cf0b43

https://www.jianshu.com/p/d88e7359b025

 
 
0 people thumbs up
 
 


Author: hugoren
link: https: //www.jianshu.com/p/e7a3243b61e6
Source: Jane books
are copyrighted by the author. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

Guess you like

Origin www.cnblogs.com/ExMan/p/12622626.html