Redis系列筆記第二篇----Redis高級

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的特殊啓動形式

  1. 全量複製
    • 主從複製中詳細講解。
  2. 服務器運行過程中重啓
    • debug reload
  3. 關閉服務器時指定保存數據
    • 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重寫

  • 降低磁盤佔用量
  • 降低恢復時的數據量,提高恢復成功率。

重寫規則:

  1. 進程內超時的數據不再寫入。
  2. 忽略無效指令,set name 1, set name 2,只保留最後一條。
  3. 合併數據,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 事務的注意事項

  1. 如果輸入的命令格式錯誤了怎麼辦?

如果有錯誤的指令,那麼所有的操作都會被清除。

  1. 如果事務執行過程中出錯了怎麼辦?

正確的命令會執行,錯誤的指令不會執行。

已經執行完畢的命令對應的數據不會自動回滾。

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

    • 逐出策略。
  1. 檢查易失數據。(在expires裏面刪除數據)

    • volatile-lru 最近使用時間離得最遠的數據。(Recently)(早期Redis默認操作)
    • volatile-lfu 最近使用次數最少。 (Frequently)
    • volatile-ttl 挑選即將過期的數據。
    • volatile-random 任意選擇。
  2. 檢測全庫數據(在dict中刪除數據)

    • allkeys-lru
    • allkeys-lfu
    • allkeys-random
  3. 放棄數據逐出(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...]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章