MEP | Redis 使用說明
Redis 使用說明
使用規(guī)范key 命名分隔符可讀性簡潔性不包含轉(zhuǎn)義字符過期時(shí)間和淘汰策略安全命令使用做好監(jiān)控跟蹤格式示例緩存 key分布式鎖 key其他問題
使用規(guī)范
key 命名
分隔符
分隔符使用 : 而不是下劃線,: 是一些可視化工具默認(rèn)的分隔符,在可視化工具中可以清晰的查看。
可讀性
以業(yè)務(wù)名為前綴,用冒號(hào)分隔,可使用業(yè)務(wù)名:子業(yè)務(wù)名:id的結(jié)構(gòu)命名,子業(yè)務(wù)下多單詞可再用下劃線分隔
舉例:消費(fèi)金融訂單審核鎖,可命名為 ecm:product:lock:verify:{productSerialNid}
簡潔性
保證語義的前提下,控制 key 的長度,當(dāng) key 較長時(shí),內(nèi)存占用也不容忽視
A few other rules about keys(關(guān)于 key 的一些其他規(guī)則):
Very long keys are not a good idea. For instance a key of 1024 bytes is a bad idea not only memory-wise, but also because the lookup of the key in the dataset may require several costly key-comparisons. Even when the task at hand is to match the existence of a large value, hashing it (for example with SHA1) is a better idea, especially from the perspective of memory and bandwidth.
Very short keys are often not a good idea. There is little point in writing "u1000flw" as a key if you can instead write "user:1000:followers". The latter is more readable and the added space is minor compared to the space used by the key object itself and the value object. While short keys will obviously consume a bit less memory, your job is to find the right balance.
Try to stick with a schema. For instance "object-type:id" is a good idea, as in "user:1000". Dots or dashes are often used for multi-word fields, as in
comment:1234:reply.toorcomment:1234:reply-to.The maximum allowed key size is 512 MB.
關(guān)于key有一些其他的規(guī)則:
非常長的key是不推薦的。一個(gè)
1024 bytes是一個(gè)非常壞的注意,不僅僅是因?yàn)閮?nèi)存浪費(fèi),更是因?yàn)樵跀?shù)據(jù)集中搜索對(duì)比的時(shí)候需要耗費(fèi)更多的成本。當(dāng)要處理的是匹配一個(gè)非常大的值,從內(nèi)存和帶寬的角度來看,使用這個(gè)值的hash值是更好的辦法(比如使用SHA1)。特別短的key通常也是不推薦的。在寫像u100flw這樣的鍵的時(shí)候,有一個(gè)小小的要點(diǎn),我們可以用
user:1000:followers代替??勺x性更好,對(duì)于key對(duì)象和value對(duì)象增加的空間占用與此相比來說倒是次要的。當(dāng)短的key可以很明顯減少空間占用的時(shí)候,你的工作就是找到正確的平衡嘗試去固定一個(gè)密室。比如
object-type:id是一個(gè)好主意,-和.通常用于多個(gè)字符的域,就像comment:1234:reply.to,或者comment:1234:reply-to。最大的
key允許512MB
不包含轉(zhuǎn)義字符
不包含空格、換行、單雙引號(hào)以及其他轉(zhuǎn)義字符
過期時(shí)間和淘汰策略
注意設(shè)置合理的過期時(shí)間
默認(rèn)策略是 volatile-lru,即超過最大內(nèi)存后,在過期鍵中使用lru算法進(jìn)行key的剔除,保證不過期數(shù)據(jù)不被刪除,但是可能會(huì)出現(xiàn)OOM問題。
其他策略如下:
allkeys-lru:根據(jù)LRU算法刪除鍵,不管數(shù)據(jù)有沒有設(shè)置超時(shí)屬性,直到騰出足夠空間為止;
allkeys-random:隨機(jī)刪除所有鍵,直到騰出足夠空間為止;
volatile-random:隨機(jī)刪除過期鍵,直到騰出足夠空間為止;
volatile-ttl:根據(jù)鍵值對(duì)象的ttl屬性,刪除最近將要過期數(shù)據(jù)。如果沒有,回退到noeviction策略;
noeviction:不會(huì)剔除任何數(shù)據(jù),拒絕所有寫入操作并返回客戶端錯(cuò)誤信息”(error) OOM command not allowed when used memory”,此時(shí)Redis只響應(yīng)讀操作;
安全
給 Redis 設(shè)置一個(gè)不簡單的密碼
修改默認(rèn)端口號(hào)
命令使用
禁止使用 keys 命令,性能堪憂;
禁止使用 flushall、flushdb 命令,防止誤刪數(shù)據(jù);
O(N) 命令關(guān)注N的數(shù)量 hgetall、lrange、smembers、zrange、sinter 等并非不能使用,但是需要明確N的值。有遍歷的需求可以使用hscan、sscan、zscan代替;
使用批量操作提高效率;
做好監(jiān)控
Redis 在大多數(shù)情況下作為緩存和分布式鎖使用,在項(xiàng)目初期每個(gè) key 的作用還能憑借記憶來記住,等 key 多的時(shí)候,就不能可光靠某幾個(gè)人記憶來記住了。當(dāng) key 無法被明確知道起什么作用的情況下,就會(huì)變成遺留代碼(無人知道、無人敢改的代碼)。良好的團(tuán)隊(duì)氛圍應(yīng)該去追蹤每個(gè) key 的使用。
跟蹤格式示例
緩存 key
| key | 占位符 | 場景 | ttl | 用途 |
|---|---|---|---|---|
ecm:handholdIdCardInfo:retry:{requestNo} | 活體請求流水號(hào) | 活體認(rèn)證 | 30 分鐘 | 保存同一個(gè)流水號(hào)手持身份認(rèn)證已經(jīng)重試了多少次 |
ecm:product:create:{userId} | 用戶userId | 進(jìn)件 | 5s | 保證一個(gè)用戶5s內(nèi)只能同時(shí)進(jìn)一個(gè)訂單,老版本,應(yīng)該廢棄 |
分布式鎖 key
| key | 占位符 | try 時(shí)間 | 最大ttl | 用途 |
|---|---|---|---|---|
lock:product:verify:{productSerialNid} | 消金標(biāo)號(hào) | 0 | 10 分鐘 | 鎖定標(biāo)的審核,同一個(gè)標(biāo)的同時(shí)只能有一個(gè)審核 |
lock:redis:create_pre_loan_stage_handler:{productSerialNid} | 消金標(biāo)號(hào) | 30s | 防止用戶 30s 內(nèi)重復(fù)進(jìn)行驗(yàn)密受托支付 |
其他問題
在使用緩存時(shí)還有其他問題,比如 緩存穿透、緩存擊穿、緩存雪崩、熱點(diǎn) key,這些都是在編寫程序時(shí)也應(yīng)該注意的。
