RESP
Redis Serialization Protocol
Redis協議將傳輸的結構分爲5種最小單元類型,單元結束時同一加上回車換行符號\r\n
- 單行字符串以"+"符號開頭
- 多行字符串以"$"符號開頭,後跟字符串長度
- 整數值以":"符號開頭,後跟整數的字符串形式
- 錯誤消息以"-"符號開頭
- 數組以"*"號開頭,後跟數組的長度
+hello world\r\n
$11\r\nhello world\r\n
:1024\r\n
-WRONGTYPE Oper.....\r\n
*3\r\n:1\r\n:2\r\n:3\r\n
注意多行和數組的\r\n
下面是NULL
$-1\r\n
下面是空字符串,視爲多行字符
$0\r\n\r\n
一般來說,多行字符串在client顯示的時候會被用引號括起來
持久化
rdb
Redis在持久化時會調用glibc的函數fork產生一個子進程,快照持久化完全交給子進程處理,父進程繼續處理客戶端請求.
這個時候會使用操作系統的CopyOnWrite機制來進行數據段頁面的分離…當父進程對其中一個頁面的數據進行修改時,會被共享的頁面複製一份分離出來,然後對這個複製的頁面進行修改.這時子進程相應的頁面是沒有變化的,還是進程產生時那一瞬間的數據.
可以看出,在執行了快照後,後續指令是不會影響快照的.
aof
Redis和hbase等對日誌的處理不同的一點是,Redis是先處理邏輯,再寫日誌.
重寫
bg rewrite aof
Redis提供了bgrewriteaof指令對於aof日誌進行瘦身,其原理就是開闢一個子進程對內存進行遍歷,轉換成一些列Redis的操作指令,序列化到一個新的AOF日誌文件中…
可以看出來重寫其實是捨棄了原先的日誌
fsync
默認情況下Redis每秒調用fsync來將內存數據寫入磁盤,另外還提供了兩種策略,讓OS決定和每條指令執行.
備份
一般讓從節點做備份工作,壓力小(缺點是網絡分區時存在丟失數據的可能)
內存優化
32bit vs 64bit
如同其他32bit程序一樣,32bit的redis的指針佔用更少空間,但是最大內存不能超過4G
ziplist intset
這是兩種存儲少量數據時候的數據類型,可以使用object encoding key來查看當前的key是使用了什麼數據結構,如果不滿足優化條件,那麼就會升級爲標準結構hashtable
內存回收
由於OS是按頁回收內存,所以一個頁上只要有key存在,就不會回收,相當於java垃圾回收中的引用計數(雖然計數都是1),如果使用flushdb則可以回收,相當於移動壓縮
redis使用第三方的jemalloc和tcmalloc來處理內存分配,client可以使用info memory指令來查看
info
info指令大致可以獲取以下內容
- server
- client
- memory
- persistence
- stats
- replication
- cpu
- cluster
- keyspace
安全
指令黑名單
Redis在配置文件中提供了rename-command指令用於將某些危險的指令修改成特別的名字…比如在配置文件的security塊中增加以下內容
rename-command keys asdf
修改後原指令會失效,如果想禁用該指定可以使用下面設置爲空字符串的語法
rename-command flushall ""
密碼
如果master設置了密碼,從節點也需要設置從而能連上主節點
- 主節點
requirepass mima
- 從節點
masterauth mima
Lua
爲了防止lua腳本,不要用root啓動redis
SSL
使用spiped