openresty開發系列30--openresty中使用全局緩存
Nginx全局內存---本地緩存
使用過如Java的朋友可能知道如Ehcache等這種進程內本地緩存。
Nginx是一個Master進程多個Worker進程的工做方式,所以咱們可能須要在多個Worker進程中共享數據。
使用ngx.shared.DICT來實現全局內存共享。
一)首先在nginx.conf的http部分分配內存大小
語法:lua_shared_dict <name> <size>
該命令主要是定義一塊名爲name的共享內存空間,內存大小爲size。
經過該命令定義的共享內存對象對於Nginx中全部worker進程都是可見的
注意:當Nginx經過reload命令重啓時,共享內存字典項會重新獲取它的內容 (即共享內存保留)
當Nginx退出時,字典項的值將會丟失。(即共享內存丟失)
http {
lua_shared_dict dogs 10m;
... ...
}
二)經過ngx.shared.DICT接口獲取共享內存字典項對象
語法:dict = ngx.shared.DICT
dict = ngx.shared[name_var]
其中,DICT和name_var表示的名稱是一致的,好比上面例子中,
dogs = ngx.shared.dogs 就是dict = ngx.shared.DICT的表達形式;
也能夠經過下面的方式達到一樣的目的:
dogs = ngx.shared["dogs"]
三)對象操做方法
1)獲取 ngx.shared.DICT.get
語法:value, flags = ngx.shared.DICT:get(key)
獲取共享內存上key對應的值。若是key不存在,或者key已通過期,將會返回nil;
若是出現錯誤,那麼將會返回nil以及錯誤信息。
local dogs = ngx.shared.dogs
local value, flags = dogs:get("Marry") ---(冒號點號)等價於 dogs.get(dogs, "Marry")
返回列表中的flags,是在ngx.shared.DICT.set方法中設置的值,默認值爲0.
若是設置的flags爲0,那麼在這裏flags的值將不會被返回。
2)獲取包含過時的key ngx.shared.DICT.get_stale
語法:value, flags, stale = ngx.shared.DICT:get_stale(key)
與get方法相似,區別在於該方法對於過時的key也會返回,
第三個返回參數代表返回的key的值是否已通過期,true表示過時,false表示沒有過時。
3)設置 ngx.shared.DICT.set
語法:success, err, forcible = ngx.shared.DICT:set(key, value, exptime?, flags?)
"無條件"地往共享內存上插入key-value對,這裏講的"無條件"指的是無論待插入的共享內存上是否已經存在相同的key。
三個返回值的含義:
success:成功插入爲true,插入失敗爲false
err:操做失敗時的錯誤信息,可能相似"no memory"
forcible:true代表經過強制刪除(LRU算法)共享內存上其餘字典項來實現插入,
false代表沒有刪除共享內存上的字典項來實現插入。
第三個參數exptime代表key的有效期時間,單位是秒(s),默認值爲0,代表永遠不會過時。
第四個參數flags是一個用戶標誌值,會在調用get方法時同時獲取獲得。
local dogs = ngx.shared.dogs
local succ, err, forcible = dogs:set("Marry", "it is a nice cat!")
4)安全設置 ngx.shared.DICT.safe_set
語法:ok, err = ngx.shared.DICT:safe_set(key, value, exptime?, flags?)
與set方法相似,區別在於不會在共享內存用完的狀況下,經過強制刪除(LRU算法)的方法實現插入。
若是內存不足,會直接返回nil和err信息"no memory"
注意:set和safe_set共同點是:若是待插入的key已經存在,那麼key對應的原來的值會被新的value覆蓋!
5)增長 ngx.shared.DICT.add
語法:success, err, forcible = ngx.shared.DICT:add(key, value, exptime?, flags?)
與set方法相似,與set方法區別在於不會插入重複的鍵(能夠簡單認爲add方法是set方法的一個子方法),
若是待插入的key已經存在,將會返回nil和和err="exists"
6)安全增長 ngx.shared.DICT.safe_add
語法:ok, err = ngx.shared.DICT:safe_add(key, value, exptime?, flags?)
與safe_set方法相似,區別在於不會插入重複的鍵(能夠簡單認爲safe_add方法是safe_set方法的一個子方法),
若是待插入的key已經存在,將會返回nil和err="exists"
7)替換 ngx.shared.DICT.replace
語法:success, err, forcible = ngx.shared.DICT:replace(key, value, exptime?, flags?)
與set方法相似,區別在於只對已經存在的key進行操做(能夠簡單認爲replace方法是set方法的一個子方法),
若是待插入的key在字典上不存在,將會返回nil和錯誤信息"not found"
8)刪除 ngx.shared.DICT.delete
語法:ngx.shared.DICT:delete(key)
無條件刪除指定的key-value對,其等價於
ngx.shared.DICT:set(key, nil)
9)自增 ngx.shared.DICT.incr
語法:newval, err = ngx.shared.DICT:incr(key, value)
對key對應的值進行增量操做,增量值是value,其中value的值能夠是一個正數,0,也能夠是一個負數。
value必須是一個Lua類型中的number類型,不然將會返回nil和"not a number";
key必須是一個已經存在於共享內存中的key,不然將會返回nil和"not found".
10)清除 ngx.shared.DICT.flush_all
語法:ngx.shared.DICT:flush_all()
清除字典上的全部字段,但不會真正釋放掉字段所佔用的內存,而僅僅是將每一個字段標誌爲過時。
11)清除過時內存 ngx.shared.DICT.flush_expired
語法:flushed = ngx.shared.DICT:flush_expired(max_count?)
清除字典上過時的字段,max_count代表上限值,若是爲0或者沒有給出,代表須要清除全部過時的字段,
返回值flushed是實際刪除掉的過時字段的數目。
注意:與flush_all方法的區別在於,該方法將會釋放掉過時字段所佔用的內存。
12)獲取keys ngx.shared.DICT.get_keys
語法:keys = ngx.shared.DICT:get_keys(max_count?)
從字典上獲取字段列表,個數爲max_count,若是爲0或沒有給出,代表不限定個數。默認值是1024個
注意:強烈建議在調用該方法時,指定一個max_count參數,由於在keys數量很大的狀況下,
若是不指定max_count的值,可能會致使字典被鎖定,從而阻塞試圖訪問字典的worker進程。
-----------------案例---------------------
http部分配置共享內存
lua_shared_dict shared_data 10m;
--一、獲取全局共享內存變量
local shared_data = ngx.shared.shared_data
--二、獲取字典值
local i = shared_data:get("i")
if not i then
i = 1
--三、賦值
shared_data:set("i", i)
ngx.say("set i ", i, "<br/>")
end
--遞增
i = shared_data:incr("i", 1)
ngx.say("i=", i, "<br/>")nginx