openresty開發系列30--openresty中使用全局緩存


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;


--1、獲取全局共享內存變量
local shared_data = ngx.shared.shared_data

--2、獲取字典值
local i = shared_data:get("i")
if not i then
    i = 1
    --3、賦值
    shared_data:set("i", i)
    ngx.say("set i ", i, "<br/>")
end
--遞增
i = shared_data:incr("i", 1)
ngx.say("i=", i, "<br/>")


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM