Redis系列(五)發佈訂閱模式、主從複製和哨兵模式

来源:https://www.cnblogs.com/itzhouq/archive/2020/05/16/redis5.html
-Advertisement-
Play Games

NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...


NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。

Redis 系列:

  1. Redis系列(一)Redis入門
  2. Redis系列(二)Redis的8種數據類型
  3. Redis系列(三)Redis的事務和Spring Boot整合
  4. Redis系列(四)Redis配置文件和持久化
  5. Redis系列(五)發佈訂閱模式、主從複製和哨兵模式
  6. Redis系列(六)Redis 的緩存穿透、緩存擊穿和緩存雪崩
  7. Redis命令參考

1、Redis 訂閱發佈

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

Redis 客戶端可以訂閱任意數量的頻道。

訂閱 / 發佈消息圖:

下圖展示了頻道 channel1,已經訂閱這個頻道的三個客戶端。

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

命令

這些命令被廣泛應用於構建即時通訊應用、比如網路聊天室和實時廣播、實時提醒等。

序號 命令及描述
1 [PSUBSCRIBE pattern pattern ...] 訂閱一個或多個符合給定模式的頻道。
2 [PUBSUB subcommand argument [argument ...]] 查看訂閱與發佈系統狀態。
3 PUBLISH channel message 將信息發送到指定的頻道。
4 [PUNSUBSCRIBE pattern [pattern ...]] 退訂所有給定模式的頻道。
5 [SUBSCRIBE channel channel ...] 訂閱給定的一個或多個頻道的信息。
6 [UNSUBSCRIBE channel [channel ...]] 指退訂給定的頻道。

測試

以下實例演示了發佈訂閱是如何工作的。在我們實例中我們創建了訂閱頻道名為 redisChat:

redis 127.0.0.1:6379> SUBSCRIBE redisChat

Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "redisChat"
3) (integer) 1

現在,我們先重新開啟個 redis 客戶端,然後在同一個頻道 redisChat 發佈兩次消息,訂閱者就能接收到消息。

redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"

(integer) 1

redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by runoob.com"

(integer) 1

# 訂閱者的客戶端會顯示如下消息
1) "message"
2) "redisChat"
3) "Redis is a great caching technique"
1) "message"
2) "redisChat"
3) "Learn redis by runoob.com"

原理

Redis 是使用 C 實現的,通過分析 Redis 源碼里的 public.c 文件,瞭解發佈和訂閱機制的底層實現,藉此加深對 Redis 的理解。Redis 通過 public 、subscribe 和 psubscribe 等命令實現發佈和訂閱功能。

微信:

通過 subscribe 命令訂閱某頻道後,redis=server 裡面維護了一個字典,字典的鍵就是一個個頻道!而字典的值則是一個鏈表,鏈表保存了所有訂閱這個 channel 的客戶端。subscribe 命令的關鍵,就是講客戶端添加到給定 channel 的訂閱鏈中。

通過 publish 命令向訂閱者發送消息,redis-server 會使用給定的頻道作為鍵,在它所維護的channel 字典中查找記錄了訂閱這個頻道的所有客戶端的鏈表,遍歷這個鏈表,將消息發佈給所有的訂閱者。

使用場景:

1、實時消息系統

2、實時聊天

3、訂閱、關註系統都可以

稍微複雜的場景更多的使用消息中間件 MQ。


2、主從複製

1、概念

主從複製,是指將一臺 Redis 伺服器的數據,複製到其他的 Redis 伺服器。前者稱之為主節點(master/leader),後者稱之為從節點(slave/flower);數據的複製都是單向的,只能從主節點到從節點。Master 以寫為主,Slave 以讀為主。

預設情況下,每台 Redis 伺服器都是主節點。且一個主節點可以有多個從節點或者沒有從節點,但是一個從節點只能有一個主節點。

2、主從複製的作用

1、數據冗餘:主從複製實現了數據的熱備份,是持久化的之外的一種數據冗餘方式。

2、故障恢復:當主節點出現問題時,可以由從節點提供服務,實現快速的故障恢復。實際也是一種服務的冗餘。

3、負載均衡:在主從複製的基礎上,配合讀寫分離,可以由主節點提供寫服務,由從節點提供讀服務(即寫 Redis 數據時應用連接主節點,讀 Redis 的時候應用連接從節點),分擔伺服器負載;尤其是在寫少讀多的場景下,通過多個節點分擔讀負載,可以大大提高 Redis 伺服器的併發量。

4、高可用(集群)的基石:除了上述作用以外,主從複製還是哨兵模式和集群能夠實施的基礎,因此說主從複製是 Redis 高可用的基礎。

一般來說,要將Redis 運用於工程項目中,只使用一臺 Redis 是萬萬不能的(可能會宕機),原因如下:

1、從結構上,單個 Redis 伺服器會發生單點故障,並且一臺伺服器需要處理所有的請求負載,壓力很大;

2、從容量上,單個 Redis 伺服器記憶體容量有限,就算一臺 Redis 伺服器記憶體容量為 265G, 也不能將所有的記憶體用作 Redis 存儲記憶體,一般來說,單台 Redis最大使用記憶體不應該超過 20G

電商網站上的商品,一般都是一次上傳,無數次瀏覽的,說專業點就是“多讀少寫”。

對於這種場景,我們可以使用如下這種架構:

主從複製,讀寫分離!80% 的情況下,都是在進行讀操作。這種架構可以減少伺服器壓力,經常使用實際生產環境中,最少是“一主二從”的配置。真實環境中不可能使用單機 Redis。

3、環境配置

只配置從庫,不用配置主庫。

[root@itzhouc bin]# redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> info replication			# 查看當前庫的信息
# Replication
role:master									# 角色
connected_slaves:0							# 當前沒有從庫
master_replid:2467dd9bd1c252ce80df280c925187b3417055ad
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
127.0.0.1:6379> 

複製 3 個配置文件,然後修改對應的信息

1、埠

2、pid 名稱

3、log 文件名稱

4、dump.rdb 名稱

port 6381
pidfile /var/run/redis_6381.pid
logfile "6381.log"
dbfilename dump6381.rdb

修改完畢後,啟動我們的 3 個 redis 伺服器,可以通過進程信息查詢。

[root@itzhouc ~]# ps -ef|grep redis
root       426     1  0 16:53 ?        00:00:00 redis-server *:6379
root       446     1  0 16:54 ?        00:00:00 redis-server *:6380
root       457     1  0 16:54 ?        00:00:00 redis-server *:6381
root       464   304  0 16:54 pts/3    00:00:00 grep --color=auto redis

4、一主二從

預設情況下,每台 Redis 伺服器都是主節點,我們一般情況下,只用配置從機就好了。

主機:6379, 從機:6380 和 6381

配置的方式有兩種:一種是直接使用命令配置,這種方式當 Redis 重啟後配置會失效。另一種方式是使用配置文件。這裡使用命令演示一下。

下麵將80 和 81 兩個配置為在從機。

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379		# SLAVEOF host  port
OK
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:6
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:907bcdf00c69d361ede43f4f6181004e2148efb7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0
127.0.0.1:6380> 

配置好了之後,看主機:

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2		# 主節點下有兩個從節點
slave0:ip=127.0.0.1,port=6380,state=online,offset=420,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=420,lag=1
master_replid:907bcdf00c69d361ede43f4f6181004e2148efb7
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:420
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:420
127.0.0.1:6379> 

真實的主從配置應該是在配置文件中配置,這樣才是永久的。這裡使用命令是暫時的。

配置文件 redis.conf

################################# REPLICATION #################################

# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
#   +------------------+      +---------------+
#   |      Master      | ---> |    Replica    |
#   | (receive writes) |      |  (exact copy) |
#   +------------------+      +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
#    stop accepting writes if it appears to be not connected with at least
#    a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
#    master if the replication link is lost for a relatively small amount of
#    time. You may want to configure the replication backlog size (see the next
#    sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
#    network partition replicas automatically try to reconnect to masters
#    and resynchronize with them.
#
# replicaof <masterip> <masterport>			# 這裡配置

# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.
#
# masterauth <master-password>

配置方式也是一樣的。

5、幾個問題

1、主機可以寫,從機不能寫只能讀。主機中的所有信息和數據都會保存在從機中。如果從機嘗試進行寫操作就會報錯。

127.0.0.1:6381> get k1			# k1的值是在主機中寫入的,從機中可以讀取到。
"v1"
127.0.0.1:6381> set k2 v2			# 從機嘗試寫操作,報錯了
(error) READONLY You can't write against a read only replica.
127.0.0.1:6381> 

2、如果主機斷開了,從機依然鏈接到主機,可以進行讀操作,但是還是沒有寫操作。這個時候,主機如果恢復了,從機依然可以直接從主機同步信息。

3、使用命令行配置的主從機,如果從機重啟了,就會變回主機。如果再通過命令變回從機的話,立馬就可以從主機中獲取值。這是複製原理決定的。

6、複製原理

Slave 啟動成功連接到 Master 後會發送一個 sync 同步命令。

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

全量複製:Slave 服務在接收到資料庫文件後,將其存檔並載入到記憶體中。

增量複製: Master 繼續將新的所有收集到的修改命令一次傳給 slave,完成同步。

但是只要重新連接 master ,一次完全同步(全量複製)將被自動執行。我們的數據一定可以在從機中看到。

這種模式的原理圖:

第二種模式

這種模式的話,將 6381 的主節點配置為 6380 。主節點 6379 只有一個從機。

如果現在 6379 節點宕機了, 6380 和 6381 節點都是從節點,只能進行讀操作,都不會自動變為主節點。需要手動將其中一個變為主節點,使用如下命令:

SLAVEOF no one

3、哨兵模式

1、概述

主從切換技術的方式是:當主機伺服器宕機之後,需要手動將一臺伺服器切換為主伺服器,這需要人工干預,費時費力,還會造成一段時間內的服務不可用。這不是一種推薦的方式,更多的時候我們優先考慮的的是哨兵模式。Redis 從 2.8 開始正式提供了 Sentinel(哨兵)架構來解決這個問題。

哨兵模式能夠後臺監控主機是否故障,如果故障了根據投票數自動將從庫轉換為主庫。

哨兵模式是一種特殊的模式,首先 Redis 提供了哨兵的命令,哨兵是一個獨立的進程,作為進程,它獨立運行。其原理是哨兵通過發送命令,等待 Redis 伺服器響應,從而監控運行的多個 Redis 實例

這裡的哨兵有兩個作用

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

然而一個哨兵進程對 Redis 伺服器進行監控,可能會出現問題,為此,我們可以使用多個哨兵進行監控。各個哨兵之間還會進行監控,這樣就形成了多哨兵模式。

假設主伺服器宕機了,哨兵1先檢測到這個結果,系統並不會馬上進行 failover 過程,僅僅是哨兵 1 主觀認為主伺服器不可用,這個現象稱之為主觀下線。當後面的哨兵也檢測到主伺服器不可用,並且數量達到一定值時,那麼哨兵之間就會進行一次投票,投票的結果由一個哨兵發起,進行 failover 【故障轉移】。切換成功後,就會通過發佈訂閱模式,讓各個哨兵把自己監控的從伺服器實現切換主機,這個過程稱之為客觀下線

2、配置一個一主二從的哨兵模式

1、配置哨兵模式配置文件,新建文件 /usr/local/bin/kconfig/sentinel.conf

# sentinel monitor 被監控的名字(隨便寫) host 1
sentinel monitor myredis 127.0.0.1 1

後面的數字1代表主機宕機後,slave投票決定誰成為新的主機,票數最多成為主機。

2、啟動哨兵

[root@itzhouc bin]# ls
6379.log  6381.log      dump6380.rdb  dump.rdb  redis-benchmark  redis-check-rdb  redis-sentinel
6380.log  dump6379.rdb  dump6381.rdb  kconfig   redis-check-aof  redis-cli        redis-server
[root@itzhouc bin]# redis-sentinel kconfig/sentinel.conf 
2421:X 15 May 2020 20:24:06.847 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
2421:X 15 May 2020 20:24:06.847 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=2421, just started
2421:X 15 May 2020 20:24:06.847 # Configuration loaded
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 5.0.5 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 2421
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

2421:X 15 May 2020 20:24:06.848 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
2421:X 15 May 2020 20:24:06.851 # Sentinel ID is 100430af0018d23bd1ae2fe57e71e0d45f64d9a5
2421:X 15 May 2020 20:24:06.851 # +monitor master myredis 127.0.0.1 6379 quorum 1
2421:X 15 May 2020 20:24:06.852 * +slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379

啟動成功~!

如果現在 Master 節點宕機了,這個時候會從從機中根據投票演算法選擇一個作為主機。

如果原來的主機恢復運行了,只能歸到新的主機下,作為從機, 這就是哨兵模式的規則。

哨兵模式的優點

1、哨兵集群,基於主從複製模式,所有的主從配置優點,它全有

2、主從可以切換,故障可以轉移,系統的可用性就會更好

3、哨兵模式就是主從模式的升級,手動到自動,更加健壯。

哨兵模式的缺點

1、Redis 不方便線上擴容,集群達到一定的上限,線上擴容就會十分麻煩;

2、實現哨兵模式的配置其實也很麻煩,裡面有甚多的配置項。

下一篇筆記將介紹 Redis 的緩存穿透、緩存擊穿和緩存雪崩。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、伺服器硬體與基礎命令 1· 在32位操作系統最大可以使用_4 _G記憶體 2. 多核CPU和單核CPU的優點和缺點,是否所有程式在多核CPU上運行速度都快?為什麼? 3. 伺服器的主要組成部分有哪些 4. 在以前的工作中主要接觸哪些伺服器品牌和型號 5. 設超級用戶root當前所在目錄為:/usr ...
  • 你知道Unix、Linux、GNU、GNU/Linux 之間的關係嗎? ...
  • ThinkPad-BIOS 如有問題請指出 ~謝謝 ...
  • 當前標識 (IIS APPPOOL\.NET v4.5) 沒有對”C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files” 的寫訪問許可權。 ...
  • 如何在Vmware中創建Linux虛擬機並設置Vmware和虛擬機網路 創建Linux虛擬機 創建虛擬機 配置類型選擇自定義 虛擬機硬體相容性,選擇當前Vmware版本即可 選擇要使用的Linux ISO鏡像文件,鏡像從“阿裡雲鏡像站”下載。 虛擬機命名與虛擬機存放位置 虛擬機CPU核數配置 虛擬機 ...
  • 用戶和組的相關概念 賬號:是一種用來記錄單個用戶或是多個用戶的數據。在Linux 上的賬號可以分成兩類: 用戶賬號 用來儲存單一用戶的數據,你可以使用一個用戶賬號,來儲存某一個用戶的數據。 群組賬號 用來儲存多個用戶的信息,每一個群組賬號可以用來記錄一組用戶的數據。 依照賬號的位置 本機賬號: 儲存 ...
  • 目錄操作 基礎目錄操作 linux 沒有類似windows一樣的盤符之分,所有的目錄都是以“根‘ / ’”開始,linux 是多用戶登陸, 在 /home/ 的目錄下,存放著已添加用戶的用戶目錄。每個用戶一個文件夾,文件夾名為用戶名 // 下文中 $ 表示終端的提示符,不包含在命令當中 $ pwd ...
  • NoSQL 開發中或多或少都會用到,也是面試必問知識點。最近這幾天的面試每一場都問到了。但是感覺回答的並不好,還有很多需要梳理的知識點。這裡通過幾篇 Redis 筆記整個梳理一遍,後面再加上面試題。 Redis 系列: 1. Redis系列(一)Redis入門 2. Redis系列(二)Redi... ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...