Redis筆記第二篇—Redis高級
本文目錄
Redis學習系列第二篇筆記,將學習Redis持久化、Redis事務、Redis刪除策略、Redis配置文件以及高級數據類型。
1. Linux環境的Redis安裝
1.1 從Redis源碼編譯安裝
$tar -xvf redis-VERSION.tar.gz
$cd redis-VERSION
$make install
1.2 從指定端口號啓動
#服務端從6380端口啓動
$redis-server --port 6380
#客戶端從6380端口連接
$redis-cli -p 6380
1.3 從配置文件啓動
配置文件如下:
bind 127.0.0.1
port 6379
daemonize yes
按照守護進程方式啓動logfile "6379.log"
日誌文件的存儲路徑dir ./
上面的文件存儲在哪兒
從配置文件啓動:
$redis-server redis.conf
如果想啓動多個Redis服務,只需稍微修改下配置文件即可。
2. Redis持久化
2.1 什麼是持久化
- 比如意外斷電。
利用永久性介質將數據進行保存,在特定的時間將保存的數據進行恢復的工作機制叫做持久化。
爲了防止數據丟失。
數據持久化的兩種形式:
- 保存數據(快照)----RDB
- 保存操作過程(日誌)----AOF
2.2 RDB
2.2.1 save
手動執行save
指令,會立即生成dump.rdb文件。
rdb相關配置
dbfilename dump.rdb
一般設置爲dump-端口號.rdb,方便查看。dir
存儲rdb文件的路徑。rdbcompression yes
默認會壓縮數據。rdbchecksum yes
默認會開啓,數據校驗,防止數據出錯。
save指令工作原理
save指令會阻塞服務器,有可能造成長時間阻塞。不建議線上環境使用。
2.2.2 bgsave
後臺會在某個時間執行保存操作。
執行過程:
客戶端發送bgsave
指令,服務端返回給客戶端Background saving started
消息,同時調用fork函數生成一個子進程來創建rdb文件。
注意:
bgsave命令對save的阻塞進行了優化,Redis內部所有涉及到RDB的操作都採用了bgsave的方式。
stop-writes-on-bgsave-error yes
後臺存儲時如果出現了錯誤,是否停止保存。默認是yes。
2.2.3 自動執行的保存
在conf文件內進行配置。
save seconds changes
- 滿足特定時間內key的變化數量時即執行save操作。
2.2.4 兩種保存方式對比
方式 | save | bgsave |
---|---|---|
讀寫 | 同步 | 異步 |
是否阻塞服務端 | 是 | 否 |
額外內存 | 否 | 是 |
啓動新進程 | 否 | 是 |
2.2.5 RDB的特殊啓動形式
- 全量複製
- 主從複製中詳細講解。
- 服務器運行過程中重啓
debug reload
- 關閉服務器時指定保存數據
shutdown save
2.2.6 RDB的優缺點
優點:
- 內部是壓縮的二進制文件,存儲效率高。
- 存儲的是某個時間點的快照,適合進行數據備份。
- 恢復數據比AOF快得多。
- 應用於每隔x小時進行一次備份,用於災備。
缺點:
- 無法實時持久化,有丟失數據的可能。
- bgsave會犧牲性能。
- 可能多個版本的Redis之間不兼容。
2.3 AOF
AOF
, append only file, 目前是Redis實時持久化的主流方式。
- 記錄操作過程。
2.3.1 AOF寫數據的過程
AOF寫數據的三種策略:
always
每次,數據零誤差,性能較低。不建議使用。everysec
每秒,每秒將緩衝區的命令同步到AOF文件內,可能會丟失一秒的數據。Redis默認。no
系統控制,過程不可控。
在conf文件中啓用AOF:
# 開啓AOF, 默認是no
appendonly yes|no
# 配置AOF寫數據策略
appendfsync always|everysec|no
# 配置AOF文件名
appendfilename filename
2.3.2 AOF重寫
- 降低磁盤佔用量
- 降低恢復時的數據量,提高恢復成功率。
重寫規則:
- 進程內超時的數據不再寫入。
- 忽略無效指令,set name 1, set name 2,只保留最後一條。
- 合併數據,lpush a 1, lpush a 2, 合併爲lpush a 1 2。每條指令最多64個元素。
重寫命令
手動重寫:
bgrewriteaof
自動重寫:
3. Redis事務
3.1 事務簡介
Redis事務就是一個命令執行的隊列,將一系列預定義的命令包裝成一個整體。當執行時,一次性按照順序執行,中間不會被打斷。
3.2 事務基本操作
3.2.1 基本命令
事務的邊界:
開頭:multi
, 結尾:exec
。
取消事務:discard
3.2.2 事務的工作流程
3.2.3 事務的注意事項
- 如果輸入的命令格式錯誤了怎麼辦?
如果有錯誤的指令,那麼所有的操作都會被清除。
- 如果事務執行過程中出錯了怎麼辦?
正確的命令會執行,錯誤的指令不會執行。
已經執行完畢的命令對應的數據不會自動回滾。
3.3 鎖
基於特定條件的事務執行----鎖。
對key添加監視鎖,在exec之前如果key發生了變化,則不執行。
watch key1 [key2...]
unwatch
取消對所有key的監視。
注意:事務中不能watch。
3.4 分佈式鎖
如何避免最後一件商品被多個人買到?
分佈式鎖,類似於Java的同步代碼塊。
-
使用setnx設置一個公共鎖
setnx lock-key value
有值則返回失敗,沒有值則返回設置成功。
可以理解爲廁所鑰匙。
操作完畢後通過
del
刪除鎖。
3.5 分佈式鎖的客戶端問題
如果客戶端拿到分佈式鎖後客戶端宕機了怎麼辦?
給鎖設置時效性。
expire lock-key second
pexpire lock-key 毫秒
4. Redis刪除策略
已經過期的數據真的被刪除了嗎?
Redis數據有三種狀態:
- XX:具有時效性的數據。
- -1:永久有效的數據。
- -2:過期的數據。
set和get的優先級比較高,del優先級低。過期的數據不一定被立刻刪除,可能還會留一段時間。
4.1 數據刪除策略
Redis內部會有一個expires空間,裏面是[數據的內存地址-過期時間]
的形式。
刪除策略:在CPU和內存之間找一個平衡。
4.1.1 定時刪除
key的過期時間到了後定時器立刻去刪除數據。
- 優點:省內存。
- 缺點:CPU壓力大。
4.1.2 惰性刪除
數據到期後不做處理,如果過期後有人訪問這個數據,發現過期了,刪除,返回不存在。
- 優點:省CPU。
- 缺點:費內存。
4.1.3 定期刪除
啓動時,將server.hz設置爲10,每秒鐘執行hz次serverCron()->databaseCron()->activeExpireCycle()。
activeExpireCycle()對每個expire空間逐一進行檢測,每次執行(250/hz) ms
隨機挑w個key進行檢測,如果key超時,就刪除。如果刪除的量超過了w的25%,那麼就會接着執行這個過程。
參數current_db用以記錄activeExpireCycle()執行到了哪個db。
w取值由配置文件決定。ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP
4.3 數據逐出算法
如果數據進入Redis時內存不夠了怎麼辦?
臨時刪除一些數據,稱爲數據逐出/淘汰,這個策略稱爲逐出算法。
逐出算法可能會失敗,如果失敗了,會報錯。
影響逐出算法的配置:
-
maxmemory
- 最大可用內存,默認是0,表示不受限制,一般設爲50%以上。
-
maxmemory-samples
每次選取待刪除數據的個數。 -
maxmemory-policy
- 逐出策略。
-
檢查易失數據。(在expires裏面刪除數據)
- volatile-lru 最近使用時間離得最遠的數據。(Recently)(早期Redis默認操作)
- volatile-lfu 最近使用次數最少。 (Frequently)
- volatile-ttl 挑選即將過期的數據。
- volatile-random 任意選擇。
-
檢測全庫數據(在dict中刪除數據)
- allkeys-lru
- allkeys-lfu
- allkeys-random
-
放棄數據逐出(Redis4.0開始的默認操作)
- no-enviction 禁止取出數據,可能會Out Of Memory。
配置文件:maxmemory-policy 逐出策略
注意:
查看INFO信息中的命中緩存次數及未命中次數,根據這個信息來調優。
5. redis.conf
服務器基礎配置
-
設置服務器以守護進程的方式運行
daemonize yes|no
-
綁定主機地址(使之只能讓這個地址來訪問)
bind 127.0.0.1
-
設置端口
port 6379
-
設置數據庫數量
databases 16
日誌配置
-
指定日誌級別
loglevel debug|verbose|notice|warning
-
日誌記錄文件名
logfile 端口號.log
服務端對客戶端的配置
-
設定同一時間內最大客戶端連接數,0代表無限制。
maxclients 0
-
客戶端閒置最大時長,0代表不關閉。
timeout 300
多服務器快捷配置
-
導入並加載指定位置的配置文件,用於快捷創建Redis公共配置較多的Redis實例配置文件。
include /path/某個端口號.conf
6. Redis高級數據類型
高級數據類型更傾向於解決一種問題,應用面比較狹窄。
6.1 Bitmaps
6.1.1 基本操作
-
獲取指定key上對應偏移量上的bit值
getbit key offset
-
設定指定key上對應偏移量的值
setbit key offset value
6.1.2 擴展操作
-
統計指定key中1的個數
bitcount key [start end]
-
對指定的key進行位運算
bitop op destKey key1 [key2 key3...]
-
destKey 是目標key,結果存進這個key裏。
-
op有四種,交併非異或。
-
and 交(&&)
-
or 並 (||)
-
not 非 (!)
-
xor 異或 (^)
-
-
6.2 HyperLogLog
比如統計UV獨立用戶,HyperLogLog應用面更窄,用來做基數統計。
內部用了LogLog算法。
-
添加數據
pfadd key value1 [value2 value3...]
-
統計數據
pfcount key1 [key2 key3...]
-
合併數據
pfmerge destKey key1 [key2 key3...]
注意:
- 不存儲數據,只記錄數量。
- 數量是估算的,不保證精確。誤差接近0.81%。
- 佔用空間極小。使用最多12KB的內存。
- 合併後佔用的就是12K,不管合併前這幾個key佔用多大。
6.3 GEO
求兩個點的距離(關聯關係)。
-
添加座標點
geoadd key 橫座標1 縱座標1 value1 [橫座標2 縱座標2 value2 ...]
-
取出來座標
geopos key value
-
計算距離
geodist key value1 value2 [m/km/ft/mi]
- 後面四個是單位。ft和mi分別是英尺和英里。
- 這是計算地球上兩個座標的。
- 橫縱座標就是經緯度。
-
根據座標求範圍內的數據
georadius key 經度 維度 半徑 m/km/ft/mi [WITHCOORD WITHDIST WITHHASH] [COUNT count]
- WITHCOORD 結果帶座標
- WITHDIST 結果帶距離
- WITHHASH 結果帶哈希
- COUNT count 只展示最近的count個
-
根據點求範圍內數據
geiradiusbymember key value 半徑 單位 [後面的同上]
-
求座標哈希值
geohash key value1 [value2...]