【9k字+】第二篇:進階:掌握 Redis 的一些進階操做(Linux環境)

九 Redis 經常使用配置文件詳解

可以合理的查看,以及理解修改配置文件,能幫助咱們更好的使用 Redis,下面按照 Redis 配置文件的順序依次往下講redis

  • 1k 和 1kb,1m 和 1mb 、1g 和 1gb 的大小是有區別的,同時其對大小寫不敏感

  • include 至關於 import 的概念,能夠引入,而後組合多個配置文件

  • 網絡配置以下(爲了解決遠程鏈接問題,會註釋掉 bind 127.0.0.1,以及將保護模式 protected-mode 改成 no)
    • bind 127.0.0.1 —— 綁定的ip
    • protected-mode yes —— 保護模式
    • port 6379 —— 端口設置

  • 以守護進程的方式運行,默認爲 no,自行開啓爲 yes

  • 後臺運行,須要指定 pid 文件

  • 日誌相關
    • loglevel 指定日誌級別:debug ,verbose,notice,warning,其中 notice 是生產環境
    • logfile —— 具體的日誌名
    • database —— 數據庫的數量,默認爲 16
    • always-show-logo —— 是否老是顯示 logo

  • 持久化相關:因爲 Redis 是基於內存的數據庫,因此持久化就是將數據持久化到具體的文件中去
    • 有兩種方式,RDB、AOF 下面咱們會具體的講持久化的概念,這裏簡單說起
    • save 900 1 :若是 900 s 內,若是至少有 1 個 key 被修改,則進行持久化操做,下面兩個同理
    • stop-writes-on-bgsave-error:持久化出錯,是否還要繼續工做
    • rdbcompression:是否壓縮 rdb 文件(會消耗 CPU)
    • rdbchecksum:保存 rdb 文件的時候,進行錯誤的檢查校閱
    • dir: rdb 文件保存的目錄

  • 主從複製會在下面專門講解,這裏暫時略過算法

  • 接下來的 SECURITY 部分,註釋中有說起到關於密碼的設置,這裏多提一下在客戶端中設置密碼的方式shell

127.0.0.1:6379> ping PONG 
127.0.0.1:6379> config get requirepass # 獲取redis的密碼 
1) "requirepass" 
2) "" 

127.0.0.1:6379> config set requirepass "123456" # 設置redis的密碼 
OK
127.0.0.1:6379> config get requirepass # 發現全部的命令都沒有權限
(error) NOAUTH Authentication required. 
127.0.0.1:6379> ping
(error) NOAUTH Authentication required. 

127.0.0.1:6379> auth 123456 # 使用密碼進行登陸
OK
127.0.0.1:6379> config get requirepass 
1) "requirepass" 
2) "123456"
  • CLIENTS 客戶端鏈接部分,註釋太多,這裏很差截圖,就簡單說一說數據庫

    • maxclients —— 最大客戶端數量vim

    • maxmemory —— 最大內存限制centos

    • maxmemory-policy noeviction —— 內存達到限制值的處理策略緩存

    • redis 中的默認的過時策略是 volatile-lru ,設置方式以下:服務器

      • config set maxmemory-policy volatile-lru

maxmemory-policy 六種方式

  • volatile-lru:只對設置了過時時間的key進行LRU(默認值)網絡

  • allkeys-lru : 刪除lru算法的key架構

  • volatile-random:隨機刪除即將過時key

  • allkeys-random:隨機刪除volatile-ttl :刪除即將過時的

  • noeviction: 永不過時,返回錯誤

  • APPEND ONLY 部分爲持久化方式之一的 AOF 的配置方式,下面會細講這兩種持久化,因此這裏也是說起一下便可
    • appendonly no —— 默認是不開啓 AOF 模式的,默認是使用 RDB 方式持久化的,RDB 通常夠用
    • appendfilename "appendonly.aof" —— 持久化文件的名字
    • appendfsync always —— 每次修改都會 sync(消耗性能 )
    • appendfsync everysec —— 每秒執行一次 sync,可能會丟失這1s的數據
    • appendfsync no —— 不執行 sync,操做系統本身同步數據,速度最快

十 Redis 持久化

前面已經講過,Redis是一個內存數據庫,也就是說,咱們的數據所有存儲在內存中,而咱們常見的MySQL和Oracle等SQL數據庫會將數據存儲到硬盤中,凡事都是有利有弊,雖然內存數據庫讀寫速度要比在硬盤中讀寫的數據庫快的多,可是卻出現了一個很麻煩的問題,也就是說,當 Redis 服務器重啓或者宕機後,內存中的數據會所有丟失,爲了解決這個問題,Redis提供了一種持久化的技術,也就是將內存中的數據存儲到硬盤中去,往後方便咱們使用這些文件恢復數據庫中的數據

在配置文件的解釋中,提到了兩種持久化方式 RDB、AOF ,下面咱們具體來說解一下:

(一) RDB 方式

(1) 概念

在指定時間間隔後,將內存中的數據集快照寫入數據庫 ,在恢復時候,直接讀取快照文件,進行數據的恢復

簡單理解:必定的時間內,檢測key的變化狀況,而後持久化數據

默認狀況下, Redis 將數據庫快照保存在名字爲 dump.rdb 的二進制文件中。

文件名能夠在配置文件中進行自定義,例如:dbfilename dump.rdb

(2) 工做原理

在進行 RDB 的時候,redis 的主線程是不會作 io 操做的,主線程會 fork 一個子線程來完成該操做(這也是保證了其極大性能的特色)

  1. Redis 調用forks,同時擁有父進程和子進程。
  2. 子進程將數據集寫入到一個臨時 RDB 文件中。
  3. 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,並刪除舊的 RDB 文件。

這種工做方式使得 Redis 能夠從寫時複製(copy-on-write)機制中獲益(由於是使用子進程進行寫操做,而父進程依然能夠接收來自客戶端的請求。

咱們知道了一個進程如何採用請求調頁,僅調入包括第一條指令的頁面,從而可以很 快開始執行。然而,經過系統調用 fork() 的進程建立最初能夠經過使用相似於頁面共享的技術,繞過請求調頁的須要。這種技術提供了快速的進程建立,並最小化必須分配給新建立進程的新頁面的數量。

回想一下,系統調用 fork() 建立了父進程的一個複製,以做爲子進程。傳統上,fork() 爲子進程建立一個父進程地址空間的副本,複製屬於父進程的頁面。然而,考慮到許多子進程在建立以後當即調用系統調用 exec(),父進程地址空間的複製可能沒有必要。

所以,能夠採用一種稱爲寫時複製的技術,它經過容許父進程和子進程最初共享相同的頁面來工做。這些共享頁面標記爲寫時複製,這意味着若是任何一個進程寫入共享頁面,那麼就建立共享頁面的副本。

(3) 持久化觸發條件

  1. 知足 save 條件會自動觸發 rdb 原則

    • 如:save 900 1 :若是 900 s 內,若是至少有 1 個 key 被修改,則進行持久化操做
  2. 執行save / bgsave / flushall命令,也會觸發 rdb 原則

    • save:當即對內存中的數據進行持久化,可是會阻塞,即再也不接受其餘任何操做,這是由於 save 命令爲同步命令,會佔用 Redis 主進程,若 Redis 數據很是多,阻塞時間會很是長
    • bgsave:異步請求,持久化時,能夠持續響應客戶端請求,阻塞發生在 fock 階段,一般很快,可是消耗內存
    • flushall:此命令也會觸發持久化 ;
  3. 退出 Redis,也會自動產生 rdb 文件(默認生成位置就是 redis 的啓動目錄)

(4) 恢復 RDB 文件

只要將 rdb 文件,放在 Redis 的啓動目錄,Redis 會自動在這個目錄下檢查 dump.rdb 文件,而後恢復其中的數據

查詢配置文件中位置的命令

127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin"

(5) 優缺點

優勢:

  1. 適合大規模的數據恢復
  2. 對數據的完整性要求不高

缺點:

  1. 易丟失最後一次操做,由於其須要必定的時間間隔進行操做,若是 Redis 意外宕機了,這個最後一次修改的數據就沒有了
  2. fork進程的時候,會佔用必定的內存空間

(二) AOF 方式

(1) 概念

以日誌的形式來記錄每一個寫的操做,將Redis執行過的全部指令記錄下來(讀操做不記錄),只許追加文件但不能夠改寫文件,redis啓動之初會讀取該文件從新構建數據,換言之,redis重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工做。

若是你不深究其背後的操做,能夠簡單理解爲:每個操做執行後,進行持久化操做

想要使用 AOF 方式,須要主動打開,由於默認使用的是 RDB

在配置文件中,咱們找到這兩行,能夠設置 aof 的啓動,以及其持久化文件的名字

  • appendonly no :no 表明關閉 aof,改成 yes 表明開啓

  • appendfilename "appendonly.aof" —— 持久化文件的名字

這裏能夠修改其持久化的一個方式

  • appendfsync always —— 每次修改都會 sync(消耗性能 )

  • appendfsync everysec —— 每秒執行一次 sync,可能會丟失這1s的數據

  • appendfsync no —— 不執行 sync,操做系統本身同步數據,速度最快

其默認是無限追加模式的,若是 aof 文件大於 64m,就 fork一個新的進程來將咱們的文件進行重寫

no-appendfsync-on-rewrite no
aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

(2) aof 文件錯位的解決方案

若是這個 aof 文件有錯位,這時候redis是啓動不起來的

Redis 給咱們提供了一個工具 redis-check-aof --fix

# 命令示例
redis-check-aof --fix appendonly.aof

(3) 優缺點

優勢

  1. 文件的完整性會更加好,由於每一次修改都會同步
  2. 若使用 appendfsync no 速度最快,效率最高

缺點

  1. aof 文件大小遠大於 rdb,修復速度所以比 rdb慢
  2. aof 運行效率也要比 rdb 慢,因此咱們redis默認的配置就是rdb持久化
  3. 若使用每秒同步一次,可能會丟失一秒的數據

(三) 擴展要點(來源於網絡,侵刪)

  1. 若是你只但願你的數據在服務器運行的時候存在,你也能夠不使用任何持久化,即只當作緩存使用

  2. 同時開啓兩種持久化方式

    在這種狀況下,當redis重啓的時候會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF

    文件保存的數據集要比RDB文件保存的數據集要完整。

    RDB 的數據不實時,同時使用二者時服務器重啓也只會找AOF文件,那要不要只使用AOF呢?做者

    建議不要,由於RDB更適合用於備份數據庫(AOF在不斷變化很差備份),快速重啓,並且不會有

    AOF可能潛在的Bug,留着做爲一個萬一的手段。

  3. 性能建議

    由於RDB文件只用做後備用途,建議只在Slave上持久化RDB文件,並且只要15分鐘備份一次就夠

    了,只保留 save 900 1 這條規則。

    若是Enable AOF ,好處是在最惡劣狀況下也只會丟失不超過兩秒數據,啓動腳本較簡單隻load自

    己的AOF文件就能夠了,代價以下:

    • 一是帶來了持續的IO,

    • 二是AOF rewrite 的最後將 rewrite 過程當中產生的新數據寫到新文件形成的阻塞幾乎是不可避免的。

    所以只要硬盤許可,應該儘可能減小AOF rewrite的頻率,AOF重寫的基礎大小默認值64M過小了,能夠設到5G以上,默認超過原大小100%大小重寫能夠改到適當的數值。

    若是不Enable AOF ,僅靠 Master-Slave Repllcation 實現高可用性也能夠,能省掉一大筆IO,也

    減小了rewrite時帶來的系統波動。

    • 代價是若是Master/Slave 同時倒掉,會丟失十幾分鐘的數據,啓動腳本也要比較兩個 Master/Slave 中的 RDB文件,載入較新的那個,微博就是這種架構。

十一 Redis 發佈與訂閱

(一) 概念

這部分,用的不是特別多,做爲一個補充。 下面是我在 菜鳥教程(runoob)貼過來的定義,重製了一下圖

定義:Redis 發佈訂閱 (pub/sub) 是一種消息通訊模式:發送者 (pub) 發送消息,訂閱者 (sub) 接收消息。

Redis 客戶端能夠訂閱任意數量的頻道。

下圖展現了頻道 channel1 , 以及訂閱這個頻道的三個客戶端 —— client2 、 client5 和 client1 之間的關係:

當有新消息經過 PUBLISH 命令發送給頻道 channel1 時, 這個消息就會被髮送給訂閱它的三個客戶端:

(二) 命令

  • PSUBSCRIBE pattern [pattern..] —— 訂閱一個或多個符合給定模式的頻道。
  • PUNSUBSCRIBE pattern [pattern..] —— 退訂一個或多個符合給定模式的頻道。
  • PUBSUB subcommand [argument[argument]] —— 查看訂閱與發佈系統狀態。
  • PUBLISH channel message —— 向指定頻道發佈消息
  • SUBSCRIBE channel [channel..] —— 訂閱給定的一個或多個頻道。
  • SUBSCRIBE channel [channel..] —— 退訂一個或多個頻道

演示

------------訂閱端----------------------
127.0.0.1:6379> SUBSCRIBE ideal-20 # 訂閱ideal-20頻道
Reading messages... (press Ctrl-C to quit) # 等待接收消息
1) "subscribe" # 訂閱成功的消息
2) "ideal-20"
3) (integer) 1

1) "message" # 接收到來自 ideal-20 頻道的消息 "hello ideal"
2) "ideal-20"
3) "hello ideal"

1) "message" # 接收到來自 ideal-20 頻道的消息 "hello i am ideal-20"
2) "ideal-20"
3) "Hi,i am BWH_Steven"

--------------消息發佈端-------------------
127.0.0.1:6379> PUBLISH ideal-20 "hello ideal" # 發佈消息到ideal-20頻道
(integer) 1
127.0.0.1:6379> PUBLISH ideal-20 "Hi,i am BWH_Steven" # 發佈消息
(integer) 1

-----------------查看活躍的頻道------------
127.0.0.1:6379> PUBSUB channels
1) "ideal-20"

(三) 原理簡述

說明:每一個 Redis 服務器進程都維持着一個表示服務器狀態的 redis.h/redisServer 結構,而結構的 pubsub_channels 屬性是一個字典, 這個字典就用於保存訂閱頻道的信息

  • 其中,字典的鍵爲正在被訂閱的頻道, 而字典的值則是一個鏈表鏈表中保存了全部訂閱這個頻道的客戶端

例子示意圖:在下圖展現的這個 pubsub_channels 示例中, client2 、 client5 和 client1 就訂閱了 channel1(頻道1) ,其餘 channel (頻道)同理

有了這個結構上的概念,訂閱以及發佈的動做就很好理解了:

  • 訂閱:當客戶端調用 SUBSCRIBE 命令執行訂閱頻道操做時,程序就會把一個個客戶端(client)和要訂閱的頻道(channel)在 pubsub_channels 中關聯起來

  • 發佈: 程序首先根據 channel 定位到字典的鍵(例如找到 channel1), 而後將信息發送給字典值鏈表中的全部客戶端(例如 client二、client五、client1)。

(四) 缺點

  1. 依賴於數據傳輸的可靠性,訂閱方斷線,會致使其丟失在斷線期間發佈者發佈的消息
  2. 客戶端若是讀取所訂閱頻道發來消息的速度不夠快,積壓的消息會使得 Redis 輸出緩存區說起變得愈來愈大,輕則下降 Redis 速度,重則崩潰

(五) 應用

  1. 多人在線聊天室
  2. 消息訂閱,如公衆號那種形式,可是實際大部分都用 MQ 來作(後面會寫)

十二 Redis主從複製

(一) 使用緣由

首先,在一個項目中,使用一臺 Redis 服務器確定是有問題的:

  • 一臺服務器處理全部請求,壓力過大,且容易出現故障,會致使整個相關服務出現問題

  • 一臺服務器的內存是有限的,不可能將全部內存用做 Redis 存儲(推薦不該該超過 20g)

  • 大部分場景下,大部分都是讀的操做,寫的操做會相對少一點,因此對讀取的要求會大一些

而主從複製就能夠將讀寫分離,下面來一塊兒瞭解一下

(二) 概念

主從複製,是指將一臺Redis服務器的數據,複製到其餘的Redis服務器

  • 前者稱爲主節點(Master/Leader),後者稱爲從節點(Slave/Follower)

  • 數據的複製是單向的!只能由主節點複製到從節點(主節點以寫爲主、從節點以讀爲主)

簡單理解一下就是:一臺服務器做爲主機器,其餘服務器做爲從機器,他們經過命令或配置進行了鏈接,這樣從機就能獲取到主機的數據了,從機能夠幫主機分擔不少讀的請求等等

(三) 做用

  1. 數據冗餘:主從複製實現了數據的熱備份,是持久化以外的一種數據冗餘的方式。
  2. 故障恢復:當主節點故障時,從節點能夠暫時替代主節點提供服務,是一種服務冗餘的方式
  3. 負載均衡:在主從複製的基礎上,配合讀寫分離,由主節點進行寫操做,從節點進行讀操做,分擔服務器的負載;尤爲是在多讀少寫的場景下,經過多個從節點分擔負載,提升併發量。
  4. 高可用基石:主從複製仍是哨兵和集羣可以實施的基礎。

(四) 集羣環境搭建(模擬)

正常的狀況,應該是多臺不一樣的服務器,爲了演示方便,這裏使用幾個不一樣的端口來模擬不一樣的 Redis 服務器

首先,要使用不一樣的端口,天然須要多個不一樣的配置文件了,咱們先將原先的配置文件,複製三份(分別表明等會的一臺主機和兩臺從機)

# 一段都是爲了告訴你們個人配置文件的目錄,即redis 啓動目錄下面的 myconfig 目錄下
[root@centos7 ~]# cd /usr/local/bin 
[root@centos7 bin]# ls
appendonly.aof  dump.rdb  myconfig  redis-benchmark  redis-check-aof  redis-check-rdb  redis-cli  redis-sentinel  redis-server  temp-2415.rdb
[root@centos7 bin]# cd myconfig/
[root@centos7 myconfig]# ls
redis.conf

# 複製三份,分別按照等會的端口號起名
[root@centos7 myconfig]# cp redis.conf redis6379.conf
[root@centos7 myconfig]# cp redis.conf redis6380.conf
[root@centos7 myconfig]# cp redis.conf redis6381.conf

# 這樣三份就賦值好了
[root@centos7 myconfig]# ls
redis6379.conf  redis6380.conf  redis6381.conf  redis.conf

複製後,就須要分別經過 vim 修改每一個配置文件的 port 、daemonize、pid 、 logfile、dbfilename

例如:

port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile "6380.log"
dbfilename dump6380.rdb

在 XShell 中再打開兩個窗口,而後分別運行不一樣端口號的 Redis

在第一個窗口運行 Redis 服務,使用 6379 這個配置文件

[root@centos7 bin]# redis-server myconfig/redis6379.conf

其餘兩個也是同理,分別啓動 6380、6381

查看一下,三個端口的 Redis 都啓動了

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1b4bf5017e5d4e2781d83fe698f9a67c~tplv-k3u1fbpfcp-zoom-1.image)

(五) 一主二從

一主二從,就是表明一臺主機,還有兩臺是從機,而 Redis 默認都是主機,也就是說,咱們上面模擬搭建出來的幾臺 Redis 服務器,如今還都是主機,並且相互之間並不存在什麼關係

在客戶端中經過 info replication 命令能夠查看當前的一個信息

127.0.0.1:6379> info replication
# Replication
role:master # 當前是一個 master 主機
connected_slaves:0
master_replid:bfee90411a4ee99e80ace78ee587fdb7b564b4b4
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

說明:如下演示中主機端口號爲 6379,兩臺從機分別爲 6380、6381

(1) 命令的方式(暫時)

配置一主二從,只須要配置從機,使用 SLAVEOF 127.0.0.1 6379 便可

分別在 6380 和 6381 的窗口中執行

而後查詢從機自身的信息,例如查詢 6380 這臺

127.0.0.1:6380> info replication
# Replication
role:slave # 當前身份變成了一臺從機
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:364
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:364
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:85
repl_backlog_histlen:280

一樣在主機中查詢,也能看到有兩臺從機已經鏈接

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=84,lag=0 # 第一臺
slave1:ip=127.0.0.1,port=6380,state=online,offset=84,lag=0 # 第二臺
master_replid:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84

(2) 修改配置文件的方式(永久)

上面使用命令的方式,須要每一次重啓等都須要執行命令,而將其寫到配置文件中的時候,就能夠每次根據配置自動加載了,首先修改從機配置文件中的 replicaof 後面跟隨主機的 ip 和 端口

若是主機的 Redis 設置了密碼,別忘了在從機中的 masterauth 中加上主機的密碼

(3) 規則說明

  1. 從機只能讀,不能寫,主機可讀可寫可是多用於寫。

    • 從機執行寫操做會報錯 (error) READONLY You can't write against a read only replica.
  2. 主機斷電/宕機後,默認角色不變,從機還是從機,集羣只是失去了寫操做,等待主機恢復,會從新回到原來的狀態

    • 主機故障後,若須要一臺從機做爲主機,有兩種方式可選
      • ① 從機手動執行命令 slaveof no one 使其成爲主機
      • ② 使用哨兵模式自動選舉(下面接着講解哨兵模式)
  3. 從機斷電/宕機後,若以前使用的是命令的方式稱爲從機,則啓動後沒法獲取主機,從新配置或者是使用配置文件的方式成爲從機,重啓後,能夠從新獲取到主機全部數據

(4) 複製原理

Slave(從機) 啓動成功鏈接到 Master(註解) 後會發送一個 sync(同步命令)

Master 接到命令,啓動後臺的存盤進程,同時收集全部接收到的用於修改數據集命令,在後臺進程執行,完畢以後,master將傳送整個數據文件到slave,並完成一次徹底同步。

全量複製:而slave服務在接收到數據庫文件數據後,將其存盤並加載到內存中。

增量複製:Master 繼續將新的全部收集到的修改命令依次傳給slave,完成同步

可是隻要是從新鏈接master,一次徹底同步(全量複製)將被自動執行,從機中就能看到全部數據

十三 哨兵模式

(一) 概念

在前面的主從複製的概念中,咱們知道,一旦主服務器宕機,就須要使用手動的方式,將一臺從服務器切換爲主服務器,這種方式很麻煩,還有一種方式就是哨兵模式,也是一種比較推薦的方式

定義:哨兵模式是一種特殊的模式,首先Redis提供了哨兵的命令,哨兵是一個獨立的進程,做爲進程,它會獨立運行。其原理是哨兵經過發送命令,等待Redis服務器響應,從而監控運行的多個Redis實例。

其做用以下:

  • 經過發送命令,讓Redis服務器返回監控包括主服務器和從服務器的運行狀態,。
  • 當哨兵監測到master宕機,會自動將slave切換成master,而後經過發佈訂閱模式通知其餘的從服務器,修改配置文件,讓它們切換主機。

單哨兵與多哨兵模式:

單哨兵模式:以獨立的進程監控3臺 Redis 服務器是否正常運行

多哨兵模式:除了監控Redis 服務器,哨兵之間也會互相監控

(二) 配置以及啓動

Redis 啓動目錄下的 redis-sentinel 就是咱們要啓動的哨兵,可是咱們須要爲其指定配置文件,這樣哨兵太知道要監控誰

我在個人 Redis 啓動目錄 /usr/local/bin/ 下的 myconfig 目錄中,建立了一個名爲 sentinel.conf 的配置文件

[root@centos7 bin]# vim myconfig/sentinel.conf

裏面寫入了其核心配置內容,即指定監控咱們本地 6379 端口的主機,後面的數字1,表明主機宕機後,會使用投票算法機制選擇一臺從機做爲新的主機

# sentinel monitor 被監控的名稱 host port 1 
sentinel monitor myredis 127.0.0.1 6379 1

接着咱們回到 Redis 啓動目錄,以剛纔那個配置文件啓動哨兵

[root@centos7 bin]# redis-sentinel myconfig/sentinel.conf

啓動成功以下圖:

一旦將主機斷開鏈接,等待一下,哨兵監測到,就會發起投票(這裏只有一個哨兵,因此是 100%的),而後切換一臺從機成爲新的主機,而主機一旦從新上線後,也只能做爲新主機的一臺從機了

能夠根據哨兵這邊自動彈出來的日誌看到,首先 6379 這臺主機斷開後,1 個哨兵認爲其斷開,而後下面的 switch 即選擇了新的 6380 做爲新的主機,6379 從新上線後,只能做爲 6380 的從機了

查看一下 6380 的信息,其果真已經成爲了主機

127.0.0.1:6380> info replication
# Replication
role:master # 主機
connected_slaves:2
slave0:ip=127.0.0.1,port=6381,state=online,offset=147896,lag=0
slave1:ip=127.0.0.1,port=6379,state=online,offset=147764,lag=0
master_replid:d32e400babb8bfdabfd8ea1d3fc559f714ef0d5a
master_replid2:bd7b9c5f3bb1287211b23a3f62e41f24e009b77e
master_repl_offset:147896
second_repl_offset:7221
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:85
repl_backlog_histlen:147812

(三) 完整配置文件

實際上最核心的也就是咱們剛纔演示中的那一句即下面的:sentinel monitor mymaster 127.0.0.1 6379 1

還有端口修改會用到,其餘的能夠根據狀況設置

其配置文件仍是比較複雜的

# Example sentinel.conf
 
# 哨兵sentinel實例運行的端口 默認26379
port 26379
 
# 哨兵sentinel的工做目錄
dir /tmp
 
# 哨兵sentinel監控的redis主節點的 ip port 
# master-name  能夠本身命名的主節點名字 只能由字母A-z、數字0-9 、這三個字符".-_"組成。
# quorum 當這些quorum個數sentinel哨兵認爲master主節點失聯 那麼這時 客觀上認爲主節點失聯了
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel monitor mymaster 127.0.0.1 6379 1
 
# 當在Redis實例中開啓了requirepass foobared 受權密碼 這樣全部鏈接Redis實例的客戶端都要提供密碼
# 設置哨兵sentinel 鏈接主從的密碼 注意必須爲主從設置同樣的驗證密碼
# sentinel auth-pass <master-name> <password>
sentinel auth-pass mymaster MySUPER--secret-0123passw0rd
 
 
# 指定多少毫秒以後 主節點沒有應答哨兵sentinel 此時 哨兵主觀上認爲主節點下線 默認30秒
# sentinel down-after-milliseconds <master-name> <milliseconds>
sentinel down-after-milliseconds mymaster 30000
 
# 這個配置項指定了在發生failover主備切換時最多能夠有多少個slave同時對新的master進行 同步,
這個數字越小,完成failover所需的時間就越長,
可是若是這個數字越大,就意味着越 多的slave由於replication而不可用。
能夠經過將這個值設爲 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。
# sentinel parallel-syncs <master-name> <numslaves>
sentinel parallel-syncs mymaster 1
 
 
 
# 故障轉移的超時時間 failover-timeout 能夠用在如下這些方面: 
#1. 同一個sentinel對同一個master兩次failover之間的間隔時間。
#2. 當一個slave從一個錯誤的master那裏同步數據開始計算時間。直到slave被糾正爲向正確的master那裏同步數據時。
#3.當想要取消一個正在進行的failover所須要的時間。  
#4.當進行failover時,配置全部slaves指向新的master所需的最大時間。不過,即便過了這個超時,slaves依然會被正確配置爲指向master,可是就不按parallel-syncs所配置的規則來了
# 默認三分鐘
# sentinel failover-timeout <master-name> <milliseconds>
sentinel failover-timeout mymaster 180000
 
# SCRIPTS EXECUTION
 
#配置當某一事件發生時所須要執行的腳本,能夠經過腳原本通知管理員,例如當系統運行不正常時發郵件通知相關人員。
#對於腳本的運行結果有如下規則:
#若腳本執行後返回1,那麼該腳本稍後將會被再次執行,重複次數目前默認爲10
#若腳本執行後返回2,或者比2更高的一個返回值,腳本將不會重複執行。
#若是腳本在執行過程當中因爲收到系統中斷信號被終止了,則同返回值爲1時的行爲相同。
#一個腳本的最大執行時間爲60s,若是超過這個時間,腳本將會被一個SIGKILL信號終止,以後從新執行。
 
#通知型腳本:當sentinel有任何警告級別的事件發生時(好比說redis實例的主觀失效和客觀失效等等),將會去調用這個腳本,
#這時這個腳本應該經過郵件,SMS等方式去通知系統管理員關於系統不正常運行的信息。調用該腳本時,將傳給腳本兩個參數,
#一個是事件的類型,
#一個是事件的描述。
#若是sentinel.conf配置文件中配置了這個腳本路徑,那麼必須保證這個腳本存在於這個路徑,而且是可執行的,不然sentinel沒法正常啓動成功。
#通知腳本
# sentinel notification-script <master-name> <script-path>
  sentinel notification-script mymaster /var/redis/notify.sh
 
# 客戶端從新配置主節點參數腳本
# 當一個master因爲failover而發生改變時,這個腳本將會被調用,通知相關的客戶端關於master地址已經發生改變的信息。
# 如下參數將會在調用腳本時傳給腳本:
# <master-name> <role> <state> <from-ip> <from-port> <to-ip> <to-port>
# 目前<state>老是「failover」,
# <role>是「leader」或者「observer」中的一個。 
# 參數 from-ip, from-port, to-ip, to-port是用來和舊的master和新的master(即舊的slave)通訊的
# 這個腳本應該是通用的,能被屢次調用,不是針對性的。
# sentinel client-reconfig-script <master-name> <script-path>
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh

十四 Redis 緩存穿透、擊穿、和雪崩

此部分爲一個補充知識點,本文重點仍是 Redis 的一個基本入門,而下面的這些知識點,更多的是在具體場景中產生的一些問題,並且其每個內容展開講都是很是複雜的,因此這裏只作一個基本概念的介紹,不作詳細說明

(一) 緩存穿透

用戶查詢數據,首先在 Redis 緩存中去查,若是沒有,也就是緩存沒有命中,就會去持久層數據庫,例如 MySQL 中去查。

緩存穿透:大量緩存未命中的狀況下,大量請求持久層數據庫,持久層數據庫承載很大的壓力,出現問題。

常看法決方案有兩種:

  • 布隆過濾器
  • 緩存空對象

① 布隆過濾器:

對全部可能查詢的參數以Hash的形式存儲,以便快速肯定是否存在這個值,在控制層先進行攔截校驗,校驗不經過直接打回,減輕了存儲系統的壓力。

② 緩存空對象:

次請求若在緩存和數據庫中都沒找到,就在緩存中方一個空對象用於處理後續這個請求

不過此方法存在兩種問題:

  • 空值也能被緩存的話,就會須要更多的空間來存儲更多的空值
  • 即便對空值設置了過時時間,仍是會存在緩存層和存儲層的數據會有一段時間窗口的不一致,這對於須要保持一致性的業務會有影響

(二) 緩存擊穿

定義:緩存擊穿,是指一個key很是熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個key在失效的瞬間,持續的大併發就穿破緩存,直接請求數據庫,就像在一個屏障上鑿開了一個洞

解決方案:

  1. 設置熱點數據永不過時

    這樣就不會出現熱點數據過時的狀況,可是當 Redis 內存空間滿的時候也會清理部分數據,並且此種方案會佔用空間,一旦熱點數據多了起來,就會佔用部分空間。

  2. 加互斥鎖(分佈式鎖)

    在訪問 key 以前,採用SETNX(set if not exists)來設置另外一個短時間key來鎖住當前key的訪問,訪問結束再刪除該短時間 key 。保證同時刻只有一個線程訪問。這樣對鎖的要求就十分高。

(三) 緩存雪崩

大量的key設置了相同的過時時間,致使在緩存在同一時刻所有失效,形成瞬時DB請求量大、壓力驟增,引發雪崩。

解決方案:

① redis高可用

  • 這個思想的含義是,既然redis有可能掛掉,那我多增設幾臺redis,這樣一臺掛掉以後其餘的還能夠繼續工做,其實就是搭建的集羣

② 限流降級

  • 這個解決方案的思想是,在緩存失效後,經過加鎖或者隊列來控制讀數據庫寫緩存的線程數量。好比對某個key只容許一個線程查詢數據和寫緩存,其餘線程等待

③ 數據預熱

  • 數據加熱的含義就是在正式部署以前,我先把可能的數據先預先訪問一遍,這樣部分可能大量訪問的數據就會加載到緩存中。在即將發生大併發訪問前手動觸發加載緩存不一樣的key,設置不一樣的過時時間,讓緩存失效的時間點儘可能均勻
相關文章
相關標籤/搜索