內部編碼:根據當前值的類型和長度決定使用哪一種編碼node
set key field
內部編碼:redis
hash-max-ziplist-entries
和全部值小於hash-max-ziplist-value
內部編碼:算法
hash-max-ziplist-entries
和全部值小於hash-max-ziplist-value
內部編碼:數據庫
set-max-intset-entries
配置內部編碼:後端
set-max-ziplist-entries
配置slowlog show get [n]
;採用隊列存儲,先進先出形式max-len > 1000
& slower-than 1ms
Redis的批量命令與Pipeline區別:數組
Lua腳本:Redis腳本語言緩存
setbit key offset value
bitop [and(交集) | or(並集) | not(非) | xor(異或)] destkey [keys...]
發佈者客戶端向指定的頻道(channel)發佈消 息,訂閱該頻道的每一個客戶端均可以收到該消息安全
publish
發佈,subscrible
訂閱地理信息定位功能:支持存儲地理位置信息來實現諸如附近位置、搖一搖這類依賴於地理位置信息的功能;底層實現是:zset服務器
客戶端通訊協議:基於TCP協議定製RESP實現交互的
RESP協議優勢:a)實現容易;b)解析快;c)人類可讀網絡
1.沒法從鏈接池中獲取到鏈接
對象個數默認是8個:
blockWhenExhausted=false
表明鏈接池沒有資源可能的緣由:
- 鏈接池設置太小
- 沒有釋放鏈接
- 存在慢查詢操做
- 服務端命令執行過程被堵塞
2.客戶端讀寫超時
1.讀寫超時時間設置太短
2.命令自己比較慢
3.客戶端與服務端網絡不正常
4.Redis自身發生堵塞
3.客戶端鏈接超時
1.鏈接超時設置太短
2.Redis發生堵塞,形成tcp-backlog已滿
3.客戶端緩衝區異常
4.輸出緩衝區滿
5.長時間閒置鏈接被服務端主動斷開
6.不正常併發讀寫
4.Lua腳本正在執行,並超過lua-time-limit
5.Redis正在加載持久化文件
6.Redis使用的內存超過maxmemory配置
7.客戶端鏈接數過大
RDB持久化:把當前進程數據生成快照保存到硬盤的過程,觸發RDB持久化分爲手動觸發和自動觸發
bgsave
命令Redis進程執行fork操做建立子進程,由子進程負責完成自動觸發:
sava m n
(表示m秒內數據集存在n次修改即自動觸發bgsave)bgsave
生成RDB文件併發送給從節點debug reload
命令從新加載Redis時,也會自動觸發save操做shutdown
命令時,若是沒有開啓AOF持久化功能則自動執行bgsave
RDB優勢:
RDB缺點:
AOF持久化:以獨立日誌的方式記錄每次寫命令,重啓時再從新執行AOF文件中的命令達到恢復數據的目的,解決數據持久化的實時性
1.命令寫入以追加方式到AOF_buf
2.AOF緩衝區根據策略同步到AOF文件
3.隨着AOF文件變大,須要按期對AOF文件進行重寫,達到壓縮目的
4.當Redis重啓時,能夠加載AOF文件進行數據恢復
命令寫入追加到緩衝區的目的:
同步策略:Redis提供多種AOF緩衝區同步文件策略,由appendfsync控制
- write操做:會觸發延遲寫機制,由於Linux在內核提供頁緩衝區來提供磁盤IO性能;write操做在寫入系統緩衝區後直接返回,同步硬盤依賴於系統調度機制
- fsync操做:針對單個文件操做作強制硬盤同步,fsync將阻塞直到寫入硬盤完成後返回,保證了數據持久化
重寫機制:把Redis進程內的數據轉化爲命令同步到新AOF文件的過程,這個過程會讓AOF文件體積變小,從而提升恢復時的效率
1.進程已經超時的數據再也不寫入新文件
2.經過進程內數據直接生成,避免舊文件中的無效命令
3.多條命令能夠合併爲一個
AOF重寫觸發方式:
手動觸發:執行bgrewriteaof命令
自動觸發:同時知足如下2個條件
1.auto-aof-rewrite-min-size
:表示運行AOF重寫時文件最小體積,默認爲64MB
2.auto-aof-rewrite-percentage
:表示當前AOF文件空間和上一次重寫後AOF文件空間的比值
Redis持久化加載流程
關於AOF文件異常
redis-check-aof-fix
命令修復後,進行對比並進行手工修改補全)AOF追加阻塞:當開啓AOF持久化時,經常使用的同步磁盤策略是everysec,對於這種方式,Redis會使用同步條線程每秒執行fsync同步硬盤,當系統硬盤資源繁忙時,會形成Redis主線程阻塞
everysec刷盤策略過程:
1.同步線程負責每秒調用fsync操做進行同步磁盤
2.主進程會去對比上次fsync同步時間,若是在2s內則經過,不然會堵塞(磁盤資源緊張)
3.everysec策略最多可能丟失2s數據;若是系統fsync緩慢,會致使主進程堵塞
AOF優勢:
AOF缺點:
創建複製的3種方式:
slaveof [masterHost] [masterPort]
redis-server --slaveof [masterHost] [masterPort]
slaveof [masterHost] [masterPort]
斷開復制:命令1操做後從節點晉升爲主節點;命令2操做後能夠完成切主操做
slaveof no none
slaveof [newmasterHost] [newmasterPort]
安全性:主節點經過requirepass參數
進行密碼驗證來保證數據安全性
slave-read-only=yes
配置爲只讀模式;由於從節點的數據沒法同步給主節點傳輸延遲:主從節點通常部署在不一樣機器上,複製時的網絡延遲成爲須要考慮的問題
repl-disable-tcp-nodelay=yes
時:表明關閉,主節點產生的命令不管大小都會及時發送給從節點,這樣作延遲會變小,可是增長了網絡帶寬消耗repl-disable-tcp-nodelay=no
時:表明開啓,主節點會合並比較小的TCP數據包從而節省網絡帶寬消耗,可是這樣增長了主從之間的延遲複製過程:
1.保存主節點信息:IP+Port
2.創建socket鏈接
3.發送ping命令:a)檢測socket是否可用;b)判斷主節點是否能處理命令
4.權限驗證
5.同步數據集:首次創建複製,主節點會把數據集所有發往從節點
6.命令持續複製:主節點把持續寫命令複製給從節點,保持數據一致性
全量複製過程
部門複製過程
心跳判斷:主從節點創建鏈接後保持長鏈接
repl-ping-slave-period
控制發送頻率)repl-timeout
配置的值(默認60秒),則斷定從節點下線並斷開復制客戶端鏈接補充知識點:
Redis是單線程架構:全部讀寫操做都是串行的而會致使阻塞問題
內在緣由:不合理使用API或數據結構、CPU飽和、持久化阻塞
外在緣由:CPU競爭,內存交換,網絡問題等
info
,查看blocked_clientsredis-cli --latency -h -p
查看延時狀況不合理使用API或數據結構:好比執行hgetall
獲取的數據量會很是大
redis-cli <ip+port> bigkeys
(大於10K)重點指標:mem_fragmentation_ratio
mem_fragmentation_ratio = used_memory_rss / used_memory
used_memory_rss: 系統認爲Redis使用的物理內存
used_memory: 內部存儲的全部數據佔用量
當mem_fragmentation_ratio > 1
表示存在內存碎片
當mem_fragmentation_ratio < 1
表示存在交換內存
Redis內存消耗劃分
Redis使用maxmemroy
參數限制最大可用內存,限制內存的主要目的:
1.緩存場景:當超過內存上限時根據淘汰策略刪除鍵釋放內存
2.防止所用內存超過物理內存(限制的是used_memory;因此考慮內存溢出)
內存回收策略
刪除過時鍵帶有
內存溢出控制策略:當達到maxmemory
自動觸發
1.關於volatile-lru和volatile-ttl控制策略:若是沒有,會回退到noeviction控制策略
2.在Redis的LRU算法中:能夠經過設置樣本的數量來調優算法精度(參數:maxmemory-samples 5->10
)
內存優化總結
1.精簡鍵值對大小,鍵值字面量精簡,使用高效二進制序列化工具。
2.使用對象共享池優化小整數對象。
3.數據優先使用整數,比字符串類型更節省空間。
4.優化字符串使用,避免預分配形成的內存浪費。
5.使用ziplist壓縮編碼優化hash、list等結構,注重效率和空間的平衡。
6.使用intset編碼優化整數集合。
7.使用ziplist編碼的hash結構下降小對象鏈規
主從架構問題:
Sentinel架構問題:
Cluster架構問題
Sentinel節點集合會按期對全部節點進行監控,從而實現主從的故障自動轉移
監控任務
主觀下線和客觀下線
領導Sentinel節點選舉:故障轉移工做的執行者
故障轉移過程:
slave no one
命令讓其成爲主節點slot=CRC16(key)&16383
。每個節點負責維護一部分槽以及槽所映射的鍵值數據Gossip消息分類:ping/pong/meet/fail
請求路由:使用客戶端去操做集羣
故障轉移
故障發現:經過ping/pong消息實現節點通訊
恢復流程:
開發和運維常見問題::超大規模集羣帶寬消耗, pub/sub廣播問題,集羣節點傾斜問題,手動故障轉移,在線遷移數據等
緩存收益:a)加速速度;b)減小後端負載
緩存成本:a)數據不一致性;b)代碼維護;c)運維
緩存場景:a)開銷大的複雜計算;b)加速請求響應
LRU/LFU/FIFO算法剔除:緩存使用量超過設定的最大值(maxmemory-policy
配置剔除策略)
超時剔除:緩存數據設置過時時間
主動更新:數據一致性要求高,須要真實數據更新後立馬更新緩存數據
最佳實踐
緩存穿透:查詢一個根本不存在的數據,致使不存在的數據每次請求都要到存儲層去查詢,會使後端存儲負載加大
基本緣由:
1.自身業務代碼或者數據出現問題
2.惡意攻擊、爬蟲等形成大量空命中
解決辦法:
1.緩存空對象
2.布隆過濾器
緩存雪崩:緩存層宕掉後,流量會忽然所有打到後端存儲
預防和解決緩存雪崩問題:
1.保證緩存層服務高可用性
2.依賴隔離組件爲後端限流並降級
問題緣由:當前key是一個熱點key,併發量很是大而重建緩存又不能在短期內完成
解決辦法:互斥鎖、「永遠不過時」可以在必定程度上解決熱點key問題
內存分配控制優化:
1.Redis設置合理的maxmemory
,保證機器有20%~30%的限制內存
2.設置vm.overcommit_memory=1
,防止極端狀況下形成fork失敗
Swap交換內存優化:當物理內存不足時,系統會使用swap致使磁盤IO會成爲性能瓶頸
權值越大,使用swap機率越高:0-100 默認60:
echo "vm.swappiness={bestvalue}" >> /etc/sysctl.conf
OMM killer: 當內存不足時選擇性殺死進程
下降redis優先級:
echo {value} > /proc/{pid}/oom_adj
Transparent Huge Pages:雖然能夠加快fork操做,可是寫時內存copy消耗從4KB-2MB
關閉大頁:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
打開文件描述符:
由於openfile
優先級大於redis maxclients
/etc/rc.local配置文件中:ulimit -Sn {max-open-files}
Tcp backlog: Tcp鏈接隊列長度
調高全鏈接隊列值:默認是511
echo 10000 > /proc/sys/net/core/somaxconn
快速恢復數據:
1.防止AOF重寫
2.去掉AOF文件中的flush相關內容
3.重啓Redis服務器,恢復數據
危害:
1.網絡擁塞
2.超時堵塞
3.內存空間不均勻
定位:找到鍵的serializedlength信息,而後判斷指定鍵值的大小
1.debug object key
2.strlen key
3.主動檢測:scan+debug object
;而後檢測每一個鍵值的長度
補充:使用redis-cli -h[ip] -p[port] bigkeys
命令(內部進行scan操做,把歷史掃描過的最大對象統計出來)
優雅刪除:直接刪除全部bigkey可能會致使堵塞
能夠結合Python的RedisAPI編寫腳本去實現:
1. hash key:經過hscan
命令,每次獲取500個字段,再用hdel
命令
2. set key:使用sscan
命令,每次掃描集合中500個元素,再用srem
命令每次刪除一個元素;
3. list key:刪除大的List鍵,經過ltrim
命令每次刪除少許元素。
4. sorted set key:刪除大的有序集合鍵,和List相似,使用sortedset自帶的zremrangebyrank
命令,每次刪除top 100個元素。
後臺刪除: lazyfree機制