# 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混合編程