Redis使用lua脚本

本文介绍了Redis从2.6.0版本开始支持的Lua脚本功能,包括其时间复杂度、好处和使用方法。Lua脚本可以减少网络开销,执行原子操作,并能复用。使用EVAL命令执行脚本,例如设置并过期一个键值对。在PHP中,可以通过phpredis库来调用Lua脚本。示例展示了如何通过Lua脚本实现原子性的数值乘法操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  版本:自2.6.0起可用。

  时间复杂度:取决于执行的脚本。

  使用Lua脚本的好处:

  减少网络开销。可以将多个请求通过脚本的形式一次发送,减少网络时延。原子操作。redis会将整个脚本作为一个整体执行,中间不会被其他命令插入。因此在编写脚本的过程中无需担心会出现竞态条件,无需使用事务。复用。客户端发送的脚步会永久存在redis中,这样,其他客户端可以复用这一脚本而不需要使用代码完成相同的逻辑。

  如何使用

  基本使用

  命令格式:

  EVAL script numkeys key

  [

  key

  ...]

  arg

  [

  arg

  ...]

  说明:

  script是第一个参数,为Lua 5.1脚本。该脚本不需要定义Lua函数(也不应该)。第二个参数 numkeys指定后续参数有几个key。key[key...],是要操作的键,可以指定多个,在lua脚本中通过 KEYS[1], KEYS[2]获取arg[arg...],参数,在lua脚本中通过 ARGV[1], ARGV[2]获取。

  简单实例:

  127.0

  .

  0.1

  :

  6379

  >

  eval

  "return ARGV[1]"

  0

  100

  "100"

  127.0

  .

  0.1

  :

  6379

  >

  eval

  "return {ARGV[1],ARGV[2]}"

  0

  100

  101

  1

  )

  "100"

  2

  )

  "101"

  127.0

  .

  0.1

  :

  6379

  >

  eval

  "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}"

  2

  key1 key2 first second

  1

  )

  "key1"

  2

  )

  "key2"

  3

  )

  "first"

  4

  )

  "second"

  127.0

  .

  0.1

  :

  6379

  >

  eval

  "redis.call('SET', KEYS[1], ARGV[1]);redis.call('EXPIRE', KEYS[1], ARGV[2]); return 1;"

  1

  test

  10

  60

  (

  integer

  )

  1

  127.0

  .

  0.1

  :

  6379

  >

  ttl test

  (

  integer

  )

  59

  127.0

  .

  0.1

  :

  6379

  >

  get

  test

  "10"

  注:

  {}在lua里是指数据类型 table,类似数组。redis.call()可以调用redis命令。

  命令行里使用

  如果直接使用 redis-cli命令,格式会有点不一样:

  redis

  -

  cli

  --

  eval

  lua_file key1 key2

  ,

  arg1 arg2 arg3

  注意的地方:

  eval 后面参数是lua脚本文件, .lua后缀不用写 numkeys,而是使用 ,隔开。注意 ,前后有空格。

  示例:

  incrbymul.lua

  local

  num=redis

  .

  call

  (

  'GET'

  ,

  KEYS

  [

  1

  ]);

  if

  not

  num

  then

  return

  0

  ;

  else

  local

  res=num

  *

  ARGV

  [

  1

  ];

  redis

  .

  call

  (

  'SET'

  ,

  KEYS

  [

  1

  ],

  res

  );

  return

  res

  ;

  end

  命令行运行:

  $ redis

  -

  cli

  --

  eval

  incrbymul

  .

  lua lua

  :

  incrbymul

  ,

  8

  (

  integer

  )

  0

  $ redis

  -

  cli incr lua

  :

  incrbymul

  (

  integer

  )

  1

  $ redis

  -

  cli

  --

  eval

  incrbymul

  .

  lua lua

  :

  incrbymul

  ,

  8

  (

  integer

  )

  8

  $ redis

  -

  cli

  --

  eval

  incrbymul

  .

  lua lua

  :

  incrbymul

  ,

  8

  (

  integer

  )

  64

  $ redis

  -

  cli

  --

  eval

  incrbymul

  .

  lua lua

  :

  incrbymul

  ,

  2

  (

  integer

  )

  128

  由于redis没有提供命令可以实现将一个数原子性的乘以N倍,这里我们就用Lua脚本实现了,运行过程中确保不会被其它客户端打断。

  phpredis里使用

  接着上面的例子:

  incrbymul.php

  

  php

  $lua=<<<

  EOF

  local

  num=redis

  .

  call

  (

  'GET'

  ,

  KEYS

  [

  1

  ]);

  if

  not

  num

  then

  return

  0

  ;

  else

  local

  res=num

  *

  ARGV

  [

  1

  ];

  redis

  .

  call

  (

  'SET'

  ,

  KEYS

  [

  1

  ],

  res

  );

  return

  res

  ;

  end

  EOF

  ;

  $redis=new

  Redis

  ();

  $redis

  ->

  connect

  (

  '127.0.0.1'

  ,

  6379

  );

  $ret=$redis

  ->

  eval

  (

  $lua

  ,

  array

  (

  "lua:incrbymul"

  ,

  2

  ),

  1

  );

  echo $ret

  ;

  运行:

  $ redis

  -

  cli

  set

  lua

  :

  incrbymul

  0

  OK

  $ redis

  -

  cli incr lua

  :

  incrbymul

  (

  integer

  )

  1

  $ php incrbymul

  .

  php

  2

  $ php incrbymul

  .

  php

  4

  eval原型:

  Redis

  ::

  eval

  (

  string

  script

  ,

  [

  array keys

  ,

  long

  num_keys

  ])

  eval函数的第3个参数为KEYS个数,phpredis依据此值将KEYS和ARGV做区分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值