Redis 文档阅读笔记 (一)
1. Pipelining
Redis是一個TCPServer,使用CS模型
1次請求將命令集合發(fā)送,Redis執(zhí)行命令后將結(jié)果隊(duì)列化后,再寫入返回
隊(duì)列化執(zhí)行結(jié)果需要使用內(nèi)存,如果多次大批量操作需要注意內(nèi)存的使用
使用Redis腳本能夠處理更快處理批量命令.管道無法在腳本中使用,因?yàn)槭褂霉艿罆r在寫入之前需要返回響應(yīng)給客戶端(需要注意:這里個人理解可能存在偏差).反之,管道可以使用腳本
2. Redis Pub/Sub
發(fā)布訂閱模式: 發(fā)布者發(fā)布消息到Channel,訂閱者訂閱Channel接收消息
Redis客戶端一旦為訂閱模式,不能接收其他命令
redis-cli命令行客戶端時進(jìn)入訂閱模式之后只能通過ctrl-c取消訂閱,因?yàn)榇藭r客戶端阻塞等待接收訂閱消息
發(fā)布訂閱無關(guān)于key所在空間,db10發(fā)布的,db1訂閱仍能接收
可用模式匹配發(fā)布多個channel 和訂閱多個channel
3. Redis Lua scripting
EVAL,EVALSHA命令執(zhí)行Lua腳本
Lua 腳本可以使用redis.call 或redis.pcall執(zhí)行redis命令
redis.call執(zhí)行遇到錯誤時直接拋出Lua異常結(jié)果,redis.pcall則會把異常處理成Lua table返回
Lua調(diào)用redis命令時把數(shù)據(jù)轉(zhuǎn)成redis對應(yīng)數(shù)據(jù)類型,腳本執(zhí)行結(jié)果返回給客戶端時Lua的數(shù)據(jù)類型轉(zhuǎn)成redis對應(yīng)數(shù)據(jù)類型
使用Lua腳本時對于浮點(diǎn)數(shù)最好使用字符串替代
如果Lua返回?cái)?shù)組中包含nil,則數(shù)據(jù)轉(zhuǎn)換終止,最終只能返回nil之前的結(jié)果
redis.error_reply,redis.status_reply 在Lua腳本中是比較有用的按redis數(shù)據(jù)類型返回結(jié)果的方法
執(zhí)行Lua腳本時,其他客戶端的命令和腳本將無法執(zhí)行
redis內(nèi)部緩存機(jī)制會緩存腳本,使用EVALSHA,如果redis通過匹配SHA1文摘匹配到腳本,則執(zhí)行腳本,否則返回錯誤信息通知使用EVAL代替
使用SCRIPT FLUSH或重啟redis實(shí)例會刷新腳本緩存
腳本自身會被從庫復(fù)制或?qū)懭階OF文件,而不是腳本的結(jié)果命令.不過從3.2版本開始,已經(jīng)可選設(shè)置復(fù)制結(jié)果命令
腳本不允許設(shè)置全局變量
4. Debugging Lua scripts
Redis Lua debugger默認(rèn),每一個新的Debug session是一個forked session,這意味著當(dāng)腳本在debug中時,不會阻塞redis server執(zhí)行其他命令,同時也意味著debug結(jié)束后會回滾腳本執(zhí)行的結(jié)果
官網(wǎng)有視頻詳解https://redis.io/topics/ldb
5. Memory optimization
通過修改redis.conf調(diào)整每一種數(shù)據(jù)類型的最大數(shù)量和最大空間
RDB和AOF文件兼容32位和64位,之間可以互轉(zhuǎn)
合理利用bit和byte操作
盡可能使用hash結(jié)構(gòu)存儲數(shù)據(jù)
每個hash最多存儲100個field是cpu和內(nèi)存之間的最佳妥協(xié)
redis根據(jù)配置文件maxmemory分配內(nèi)存
被刪除的key實(shí)際上并不會立刻釋放內(nèi)存,例如在同一頁中存在其他的key未被刪除,需要根據(jù)峰值內(nèi)存使用量限定內(nèi)存使用
redis底層內(nèi)存分配器會盡可能重復(fù)利用被刪除key的內(nèi)存,所以也不用太擔(dān)心被刪除key沒有及時釋放的問題
如果不設(shè)置maxmemory,所有的內(nèi)存將可能被吃光
當(dāng)超過最大內(nèi)存限制時,導(dǎo)致寫入時out of memory error,但不會因此導(dǎo)致整個機(jī)器掛掉
6. Expires
過期時間只針對key不針對值
過期時間可以通過persist命令清除
通過rename重命名key,原key的過期時間仍然有效,如果由別的key rename覆蓋,則該key具有別的key的特性
如果設(shè)置的過期時間為過去時間,則key相當(dāng)于del 而不是expired
消極檢查: 當(dāng)客戶端獲取該key時才檢查該key是否過期
積極檢查: redis 1秒內(nèi)執(zhí)行10個檢查過期,每次隨機(jī)選取20個key,發(fā)現(xiàn)過期的則清除,如果發(fā)現(xiàn)超過25%過期,則繼續(xù)下一個檢查
過期執(zhí)行刪除的命令會傳遞給從庫和AOF文件同步執(zhí)行.從庫不會檢查key過期,當(dāng)切換為主庫時才會去檢查
7. Redis as an LRU (Less Recently Used) cache
7.1 Redis達(dá)到最大內(nèi)存限制時策略
noeviction: 直接拋出異常
allkeys-lru: 將最近不常用的key清除騰出空間
volatile-lru: 將帶有過期時間的最近不常用的key清除騰出空間
allkeys-random: 隨機(jī)將key清除騰出空間
volatile-random: 隨機(jī)將帶有過期時間的key清除騰出空間
volatile-ttl: 將較小剩余存活時間的key清除騰出空間
如果不確定使用哪種策略,allkeys-lru是一個較好選擇
volatile-lru和volatile-random比較適用于只用單個實(shí)例,混用緩存和持久key
7.2 近似LRU算法
redis使用的并不是實(shí)際的LRU算法,而是大致評估一定樣本量中選取最符合的key
可以通過設(shè)置配置樣本量參數(shù)maxmemory-samples調(diào)節(jié)精度
7.3 LFU (Least Frequently Used)
4.0版本以后新增了新策略,根據(jù)命中的頻率決定清除哪些key
lfu-log-factor和lfu-decay-time是兩項(xiàng)主要調(diào)節(jié)參數(shù)
8. Redis transactions
事務(wù)中的所有命令會序列化并串行化執(zhí)行,在事務(wù)過程中,其他客戶端發(fā)起的請求不會被處理
所有命令要么全部被處理或不處理(這里的處理并不表示一定執(zhí)行成功),保證了原子性
如果使用append-only file,在發(fā)生崩潰或強(qiáng)制關(guān)閉redis時有可能導(dǎo)致執(zhí)行事務(wù)中部分命令.redis重啟后會檢測到直接退出.使用redis-check-aof tool修復(fù)
MULTI開啟事務(wù),命令存儲到隊(duì)列,命令EXEC執(zhí)行事務(wù)所有命令
執(zhí)行EXEC檢測到命令錯誤時,會在EXEC直接返回錯誤信息,并丟棄所有命令
執(zhí)行EXEC后,部分命令執(zhí)行失敗,對應(yīng)的命令返回錯誤信息,其他命令執(zhí)行成功
redis不支持回滾:因?yàn)楣俜秸J(rèn)為不需要,語法上的錯誤,在命令隊(duì)列化時就能檢測到,而編碼錯誤導(dǎo)致命令執(zhí)行失敗redis表示不背這個鍋,redis追求更簡單,更快
使用WATCH命令實(shí)現(xiàn)樂觀鎖,如果多個客戶端對同一個key進(jìn)行操作并存儲時,被觀察的key被改變后,其他客戶端對該key的修改的事務(wù)則會失敗,實(shí)現(xiàn)了對該key的原子操作
需要注意的一點(diǎn),當(dāng)WATCH某個key之后,key過期了,那EXEC就會正常執(zhí)行
使用WATCH可以實(shí)現(xiàn)對有序集合操作的原子性
對事務(wù)的操作在腳本中也能實(shí)現(xiàn),而且腳本可以更簡單更快
總結(jié)
以上是生活随笔為你收集整理的Redis 文档阅读笔记 (一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 记帐数据只记部分后如何处理
- 下一篇: 小试牛刀(1)简单实现用户添加和登录(文