# 19 Lua 与 redis
## 1 redis-lua 库
### 安装
```lua
$ sudo luarocks install redis-lua
```
### redis-lua 库 redis客户端端编程示例:
```lua
local params = {
host = '127.0.0.1',
port = 6380,
}
local client = redis.connect(params)
--string类型的操作
client:set('foo', 'bar')
local value = client:get('foo')
print(value)
--list操作
client:lpush("lua_list_key", "123", "456")
client:rpush("lua_list_key", "ABC")
local list_array = client:lrange("lua_list_key", 0, -1)
for key, val in pairs(list_array)
do
print("key = ", key)
print("val = ", val)
end
--hash操作
client:hset("lua_hash_key", "name", "zhang3")
client:hset("lua_hash_key", "age", 18)
local name = client:hget("lua_hash_key", "name")
print("name = ".. name);
local age = client:hget("lua_hash_key", "age")
print("age = " .. age);
local hash_zhang3 = client:hgetall("lua_hash_key")
for key, val in pairs(hash_zhang3)
do
print("key = ", key)
print("val = ", val)
end
--set 操作
client:sadd("wbq_friends", "chenhe", "lichen", "marong", "dengchao")
client:sadd("sz_friends", "sz_wife", "marong")
local wbq_sz_friends = client:sinter("wbq_friends", "sz_friends")
for key, val in pairs(wbq_sz_friends)
do
print("key = ", key)
print("val = ", val)
end
--zset 操作
client:zadd("music_top_zset", 98, "music01")
client:zadd("music_top_zset", 91, "music02")
client:zadd("music_top_zset", 97, "music03")
local top_musics = client:zrange("music_top_zset", 0, -1)
for key, val in pairs(top_musics)
do
print("key = ", key)
print("val = ", val)
end
print("----- use withscores ----")
local top_musics = client:zrange("music_top_zset", 0, -1, {withscores=true})
for key, val in pairs(top_musics)
do
print("key = ", key)
for index, value in pairs(val)
do
if (index == 1) then
print("member = ", value)
end
if (index == 2) then
print("socre = ", value)
end
end
end
--key 操作
client:del("foo")
client:del("lua_list_key")
client:del("wbq_friends")
client:del("sz_friends")
client:del("music_top_zset")
```
## 2 redis 嵌入lua脚本
Lua 脚本功能是 Reids 2.6 版本的最大亮点, 通过内嵌对 Lua 环境的支持, Redis 解决了长久以来不能高效地处理 CAS (check-and-set)命令的缺点, 并且可以通过组合使用多个命令, 轻松实现以前很难实现或者不能高效实现的模式。
本章先介绍 Lua 环境的初始化步骤, 然后对 Lua 脚本的安全性问题、以及解决这些问题的方法进行说明, 最后对执行 Lua 脚本的两个命令 ——[EVAL](http://redis.readthedocs.org/en/latest/script/eval.html#eval)和[EVALSHA](http://redis.readthedocs.org/en/latest/script/evalsha.html#evalsha)的实现原理进行介绍。
### 2.1 redis直接执行lua脚本文件
```lua
local msg = "hello lua in redis"
return msg
```
这是非常简单的,第一行代码定义了一个本地变量msg存储我们的信息, 第二行代码表示 从redis 服务端返回msg的值给客户端。 保存这个文件到hello\_redis.lua,像这样去运行:local msg = "hello lua in redis"
```lua
redis-cli EVAL "$(cat hello.lua)" 0
```
运行这段代码会打印"hello lua in redis", EVAL在第一个参数是我们的lua脚本, 这我们用cat命令从文件中读取我们的脚本内容。第二个参数是这个脚本需要访问的Redis 的键的数字号。我们简单的 “Hello Script" 不会访问任何键,所以我们使用0.
### 2.2 **访问键和参数**
> 案例1
假设我们要建立一个URL简写服务器。我们就要去存储每条进入的URL并返回一个唯一数值,以便以后通过这个数值访问到该URL。
我们将利用Lua脚本立即从Redis中用INCRand获取一个唯一标识ID,以这个标识ID作为URL存储于一个哈希中的键值:
```lua
local ret = redis.call("SET", KEYS[1], ARGV[1])
redis.call("HSET", KEYS[2], "name", ARGV[2])
return ret
```
把以上代码保存为文件“redis\_script.lua"中。
执行:
```lua
redis-cli -p 6380 EVAL "$(cat redis_script.lua)" 2 my_string_key my_hash_key zhang3 li4
```
在EVAL语句中,2指出需要传入的KEY的个数,后面跟着需要传入的两个KEY,最后传入是ARGV的值。在Redis中执行Lua脚本时,Redis-cli会检查传入KEY的个数,除非传入的完全是命令。
以上指令相当于脚本
```lua
local ret = redis.call("SET", "my_string_key", "zhang3")
redis.call("HSET", "my_hash_key", "name", "li4")
return ret
```
上面的的脚本也可以通过如下执行:
```lua
redis-cli -p 6380 --eval redis_script.lua "my_string_key" "my_hash_key" , "zhang3" "li4"
```
> 案例2
```lua
if redis.call("EXISTS",KEYS[1]) == 1 then
return redis.call("INCR",KEYS[1])
else
return nil
end
```
### 2.3 执行SHA脚本
可以用SCRIPT LOAD指令 加载一个 lua脚本,得到SHA1编码。
```lua
redis-cli -p 6380 SCRIPT LOAD "$(cat redis_script.lua)"
$"b7e5a651ef461b2e0a98f7c83633816f1a0fb159"
```
然后通过得到的SHA执行脚本
```lua
redis-cli -p 6380 EVALSHA "b7e5a651ef461b2e0a98f7c83633816f1a0fb159" 2 my_string_key my_hash_key zhang3 li4
```
- 1 Lua介绍及环境
- 2 基本语法
- 3 数据类型
- 4 Lua 变量
- 5 循环
- 6 流程控制
- 7 函数
- 8 运算符
- 9 字符串
- 10 数组
- 11 迭代器
- 12 table
- 13 Lua 模块与包
- 14 Lua 元表(Metatable)
- 14.1 元表案例
- 15 Lua 协同程序(coroutine)
- 16 Lua 文件IO
- 17 Lua 面向对象
- 17.1 类
- 17.2 继承
- 17.3 封装
- 18 Lua 与 Mysql
- 19 Lua 与 redis
- 20 Lua 与 JSON
- 21 Lua 与 http
- 22 Lua 与 Nginx
- 22.1 Nginx_Lua的安装及环境
- 22.2 ngx_lua API(全表)
- 22.3 常用命令介绍
- 22 Lua 人工智能
- (1) Torch的安装
- (2)Tensor
- Lua与C混合编程