【轉載】Redis Sentinel 高可用服務架構搭建

作者:田園裏的蟋蟀 
出處:http://www.cnblogs.com/xishuai/ 
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

閱讀目錄:

  1. 關於 Redis 的概念
  2. 關於 Redis Sentinel 的概念
  3. 搭建 Redis Server(master)
  4. 搭建 Redis Server(slave)
  5. 搭建 Redis Sentinel
  6. Redis Sentinel 故障轉移測試

前幾天,看到了一篇文章:高可用 Redis 服務架構分析與搭建,思路講的非常好,但是沒有搭建的過程,這篇文章就記錄下 Redis Sentinel 高可用服務架構搭建的過程。

搭建方案,就按照作者的第四種方案:


1. 關於 Redis 的概念

Redis 是完全開源免費的,遵守 BSD 協議,是一個高性能的 key-value 數據庫。

Redis 與其他 key-value 緩存產品有以下三個特點:

  • Redis 支持數據的持久化,可以將內存中的數據保存在磁盤中,重啓的時候可以再次加載進行使用。
  • Redis 不僅僅支持簡單的 key-value 類型的數據,同時還提供 list,set,zset,hash 等數據結構的存儲。
  • Redis 支持數據的備份,即 master-slave 模式的數據備份。

Redis 的優勢:

  • 性能極高 – Redis 能讀的速度是 110000 次/s,寫的速度是 81000 次/s。
  • 豐富的數據類型 – Redis 支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
  • 原子 – Redis 的所有操作都是原子性的,意思就是要麼成功執行要麼失敗完全不執行。單個操作是原子性的。多個操作也支持事務,即原子性,通過 MULTI 和 EXEC 指令包起來。
  • 豐富的特性 – Redis 還支持 publish/subscribe, 通知, key 過期等等特性。

以上內容摘自:http://www.runoob.com/redis/redis-intro.html

2. 關於 Redis Sentinel 的概念

Redis Sentinel(譯爲“哨兵”)是 Redis 官方推薦的高可用性(HA)解決方案,當用 Redis 做 Master-slave 的高可用方案時,假如 master 宕機了,Redis 本身(包括它的很多客戶端)都沒有實現自動進行主備切換,而 Redis-sentinel 本身也是一個獨立運行的進程,它能監控多個 master-slave 集羣,發現 master 宕機後能進行自懂切換。

Redis Sentinel 系統用於管理多個 Redis 服務器(instance),該系統執行以下三個任務:

  • 監控(Monitoring):Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
  • 提醒(Notification):當被監控的某個 Redis 服務器出現問題時,Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
  • 自動故障遷移(Automatic failover):當一個主服務器不能正常工作時,Sentinel 會開始一次自動故障遷移操作,它會將失效主服務器的其中一個從服務器升級爲新的主服務器,並讓失效主服務器的其他從服務器改爲複製新的主服務器;當客戶端試圖連接失效的主服務器時,集羣也會向客戶端返回新主服務器的地址,使得集羣可以使用新主服務器代替失效服務器。

Redis Sentinel 是一個分佈式系統,你可以在一個架構中運行多個 Sentinel 進程(progress),這些進程使用流言協議(gossip protocols)來接收關於主服務器是否下線的信息,並使用投票協議(agreement protocols)來決定是否執行自動故障遷移,以及選擇哪個從服務器作爲新的主服務器。

一個 Sentinel 進程可以與其他多個 Sentinel 進程進行連接,每個 Sentinel 進程之間可以互相檢查對方的可用性,並進行信息交換。

以上內容摘自:http://redisdoc.com/topic/sentinel.html

3. 搭建 Redis Server(master)

我們就按照上面的架構圖進行搭建,大概三臺服務器(防火牆關閉):

10.9.10.154 master   redis-server redis-sentinel
10.9.10.152 slave    redis-server redis-sentinel
10.9.10.215 redis-sentinel

先從 redis.io/releases,下載最新版本的 Redis(需要進行編譯)。

$ wget http://download.redis.io/releases/redis-4.0.8.tar.gz
$ tar xzf redis-4.0.8.tar.gz
$ cd redis-4.0.8
$ ls
00-RELEASENOTES  COPYING    Makefile   redis.conf       runtest-sentinel  tests
BUGS             INSTALL    README.md  runtest          sentinel.conf     utils
CONTRIBUTING     MANIFESTO  deps       runtest-cluster  src
$ cd src
$ make install

    CC Makefile.dep
    INSTALL redis-sentinel
    CC redis-cli.o
    LINK redis-cli
    CC redis-benchmark.o
    LINK redis-benchmark
    INSTALL redis-check-rdb

Hint: It's a good idea to run 'make test' ;)

    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install
    INSTALL install

編譯成功後,會在redis-4.0.8/src目錄下,生成redis-serverredis-sentinel可執行文件。

然後,我們在 master 節點(10.9.10.154)上,創建redis-4.0.8/redis-master.conf配置文件,示例配置:

# 使用守護進程模式
daemonize yes
# 非保護模式,可以外網訪問
protected-mode no
# 端口號
port 6379
# 綁定ip,本機的ip
bind 10.9.10.154
# 學習開發,使用最大日誌級別,能夠看到最多的日誌信息
loglevel debug
# 指定日誌文件路徑,沒有文件的話,先創建
logfile /home/ubuntu/redis/redis-4.0.8/redis-server.log
# 客戶端訪問,需要密碼連接
requirepass 123456

然後啓動 master:

$ src/redis-server redis-master.config
$ cat redis-server.log
8517:C 28 Feb 06:10:38.345 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8517:C 28 Feb 06:10:38.345 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=8517, just started
8517:C 28 Feb 06:10:38.345 # Configuration loaded
8518:M 28 Feb 06:10:38.349 * Increased maximum number of open files to 10032 (it was originally set to 1024).
8518:M 28 Feb 06:10:38.352 * Running mode=standalone, port=6379.
8518:M 28 Feb 06:10:38.352 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
8518:M 28 Feb 06:10:38.352 # Server initialized
8518:M 28 Feb 06:10:38.352 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
8518:M 28 Feb 06:10:38.352 * Ready to accept connections
8518:M 28 Feb 06:10:38.352 - 0 clients connected (0 slaves), 765776 bytes in use

查看 Redis 的狀態:

$ redis-cli -h 10.9.10.154 -p 6379 -a 123456
10.9.10.154:6379> INFO replication
# Replication
role:master
connected_slaves:0
master_replid:7f90fb4ba0c2c450b184a348f23f31d9c40b010d
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
10.9.10.154:6379> ping
PONG

添加和獲取鍵值測試:

10.9.10.154:6379> set test hello
OK
10.9.10.154:6379> get test
"hello"

Redis 常用命令:

  • 啓動服務:service redis start
  • 停止服務:service redis stop
  • 重啓服務:service ngredisnx restart

如果沒有配置爲 Service 服務,可以用下面命令關閉 Redis:

$ src/redis-cli shutdown
或者
$ ps aux | grep redis
$ kill 111

4. 搭建 Redis Server(slave)

slave 節點和 master 節點搭建差不多,只不過redis-slave.conf配置文件,有些不同:

# 使用守護進程模式
daemonize yes
# 非保護模式,可以外網訪問
protected-mode no 
# 端口號
port 6379
# 綁定ip,本機的ip
bind 10.9.10.152
# 指定 master 的 ip 地址和端口
slaveof 10.9.10.154 6379
# 學習開發,使用最大日誌級別,能夠看到最多的日誌信息
loglevel debug
# 指定日誌文件路徑,沒有文件的話,先創建
logfile /home/ubuntu/redis/redis-4.0.8/redis-server.log
# 設置訪問 master 的密碼
masterauth 123456

然後啓動 slave:

$ src/redis-server redis-slave.conf
$ cat redis-server.log
7307:C 28 Feb 06:11:00.987 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
7307:C 28 Feb 06:11:00.987 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=7307, just started
7307:C 28 Feb 06:11:00.987 # Configuration loaded
7308:S 28 Feb 06:11:00.989 * Increased maximum number of open files to 10032 (it was originally set to 1024).
7308:S 28 Feb 06:11:00.989 * Running mode=standalone, port=6379.
7308:S 28 Feb 06:11:00.990 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
7308:S 28 Feb 06:11:00.990 # Server initialized
7308:S 28 Feb 06:11:00.990 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
7308:S 28 Feb 06:11:00.990 * Ready to accept connections
7308:S 28 Feb 06:11:00.990 - 0 clients connected (0 slaves), 765736 bytes in use
7308:S 28 Feb 06:11:00.990 * Connecting to MASTER 10.9.10.154:6379
7308:S 28 Feb 06:11:00.990 * MASTER <-> SLAVE sync started
7308:S 28 Feb 06:11:00.990 * Non blocking connect for SYNC fired the event.
7308:S 28 Feb 06:11:00.991 * Master replied to PING, replication can continue...
7308:S 28 Feb 06:11:00.993 * Partial resynchronization not possible (no cached master)
7308:S 28 Feb 06:11:00.995 * Full resync from master: 55b29a9f06ffb89f96106287ce95ddfbdeccb986:0

查看 Redis 的狀態:

$ redis-cli -h 10.9.10.152 -p 6379 -a 123456
10.9.10.154:6379> INFO replication
# Replication
role:slave
master_host:10.9.10.154
master_port:6379
master_link_status:up
master_last_io_seconds_ago:10
master_sync_in_progress:0
slave_repl_offset:280
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:55b29a9f06ffb89f96106287ce95ddfbdeccb986
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:280
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:280
10.9.10.152:6379> ping
PONG

然後我們再查看下 master 的狀態(更新了connected_slaves的信息):

$ redis-cli -h 10.9.10.154 -p 6379 -a 123456
10.9.10.154:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.9.10.152,port=6379,state=online,offset=28,lag=1
master_replid:55b29a9f06ffb89f96106287ce95ddfbdeccb986
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:28

另外,你可以測試下,在 master 上添加一個 key 和 value,然後就可以在 salve 上獲取這個對應的 key 的 value。

5. 搭建 Redis Sentinel

接着,我們分別在三臺服務器上,配置 Redis Sentinel,創建redis-4.0.8/sentinel-my.conf配置文件,示例配置(記得更改不同的bind ip):

port 26379
bind 10.9.10.154
daemonize yes
logfile /home/ubuntu/redis/redis-4.0.8/redis-sentinel.log

sentinel monitor manager1 10.9.10.154 6379 2
sentinel auth-pass manager1 123456
sentinel down-after-milliseconds manager1 60000
sentinel failover-timeout manager1 180000
sentinel parallel-syncs manager1 1

這四行配置爲一組,因爲我們只有一個 master 節點,所以只配置了一個 master,可以配置多個 master,不用配置 slave 的信息,因爲 slave 能夠被自動檢測到(master 節點會有關於 slave 的消息)

第一行配置指示 Sentinel 去監視一個名爲manager1的主服務器,這個主服務器的 IP 地址爲10.9.10.154,端口號爲 6379,而將這個主服務器判斷爲失效至少需要 2 個 Sentinel 同意(只要同意 Sentinel 的數量不達標,自動故障遷移就不會執行)。

其他選項的基本格式如下:

sentinel <選項的名字> <主服務器的名字> <選項的值>

選項說明:

  • auth-pass:選項指定了 master 的連接密碼。
  • down-after-milliseconds:選項指定了 Sentinel 認爲服務器已經斷線所需的毫秒數。
  • failover-timeout:如果在該時間(ms)內未能完成 failover 操作,則認爲該 failover 失敗。
  • parallel-syncs:選項指定了在執行故障轉移時,最多可以有多少個從服務器同時對新的主服務器進行同步,這個數字越小,完成故障轉移所需的時間就越長。

接着,我們啓動 Redis Sentinel(默認端口 26379):

$ src/redis-server sentinel-my.conf --sentinel
或者
$ src/redis-sentinel sentinel-my.conf

$ cat redis-sentinel.log
5716:X 28 Feb 03:04:17.407 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
5716:X 28 Feb 03:04:17.407 # Redis version=4.0.8, bits=64, commit=00000000, modified=0, pid=5716, just started
5716:X 28 Feb 03:04:17.407 # Configuration loaded
5716:X 28 Feb 03:04:17.408 * Increased maximum number of open files to 10032 (it was originally set to 1024).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 4.0.8 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in sentinel mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 26379
 |    `-._   `._    /     _.-'    |     PID: 5716
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

5716:X 28 Feb 03:04:17.410 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
5716:X 28 Feb 03:04:17.412 # Sentinel ID is 493852dd16017dccdf7b169a256ce7eea2719aff
5716:X 28 Feb 03:04:17.412 # +monitor master manager1 10.9.10.154 6379 quorum 2

當有其他服務器啓動 Redis Sentinel 的時候,會有這樣的日誌(Redis Sentinel 是會相互通信的):

5716:X 28 Feb 03:18:46.404 # -tilt #tilt mode exited
5716:X 28 Feb 03:19:43.959 * +sentinel sentinel 55ebce153ac69c908800bc14beff24725fc5a721 10.9.10.152 26379 @ manager1 10.9.10.154 6379

連接測試(測試三臺服務器):

$ redis-cli -h 10.9.10.154 -p 26379
10.9.10.154:6379> ping
PONG

$ redis-cli -h 10.9.10.152 -p 26379
10.9.10.152:6379> ping
PONG

$ redis-cli -h 10.9.10.155 -p 26379
10.9.10.155:6379> ping
PONG

其他常用命令:

  • PING - 這個命令簡單的返回 PONE。
  • SENTINEL masters - 展示監控的 master 清單和它們的狀態。
  • SENTINEL master [master name] - 展示指定 master 的狀態和信息。
  • SENTINEL slaves [master name] - 展示 master 的 slave 清單和它們的狀態。
  • SENTINEL sentinels [master name] - 展示 master 的 sentinel 實例的清單和它們的狀態。
  • SENTINEL get-master-addr-by-name [master name] - 返回 master 的 IP 和端口。如果故障轉移在處理中或成功終止,返回晉升的 slave 的 IP 和端口。
  • SENTINEL reset [pattern] - 這個命令將重置所有匹配名字的 masters。參數是 blog 風格的。重置的過程清空 master 的所有狀態,並移除已經發現和關聯 master 的所有 slave 和 sentinel。
  • SENTINEL failover [master name] - 如果 master 不可到達,強制執行一個故障轉移,而不徵求其他 Sentinel 的同意。
  • SENTINEL ckquorum [master name] - 檢查當前的 Sentinel 配置是否能夠到達故障轉移需要的法定人數,並且需要授權故障轉移的多數。這個命令應該用於監控系統檢查部署是否正確。
  • SENTINEL flushconfig - 強制 Sentinel 在磁盤上重寫它的配置,包括當前的 Sentinel 狀態。通常 Sentinel 每次重寫配置改變它的狀態。然而有時由於操作錯誤、硬盤故障、包升級腳本或配置管理器可能導致配置文件丟失。在這種情況下收到強制 Sentinel 重寫配置文件。這個命令即使上面的配置文件完全不見了。

6. Redis Sentinel 故障轉移測試

我們的計劃是,將 master 的 Redis 服務停掉,看看 Redis Sentinel 是如何操作的。

首先,我們先查看下目前 master 節點的信息(記住 IP):

$ redis-cli -h 10.9.10.154 -p 6379
10.9.10.154:26379> SENTINEL get-master-addr-by-name manager1
1) "10.9.10.154"
2) "6379"

然後執行下面命令(強制 Redis Server 休眠 120 秒):

$ redis-cli -h 10.9.10.154 -p 6379 -a 123456 DEBUG sleep 120

然後我們再查看下 master 節點的信息:

$ redis-cli -h 10.9.10.154 -p 6379
10.9.10.154:26379> SENTINEL get-master-addr-by-name manager1
1) "10.9.10.152"
2) "6379"

發現 IP 已經變成了此前 salve 節點的,也就是說10.9.10.152變成了 master,然後我們查看下當前 master 的信息:

$ redis-cli -h 10.9.10.152 -p 6379 -a 123456
10.9.10.152:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=10.9.10.154,port=6379,state=online,offset=1270535,lag=0
master_replid:8b033de60b4be410a1706ff6b27b52b97bcc2981
master_replid2:e56e893b96e7df8fda00ebcacf1d4b24c9499c4a
master_repl_offset:1270535
second_repl_offset:1208143
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:221960
repl_backlog_histlen:1048576

slave0:ip=10.9.10.154,port=6379表示此前的 master,已變爲現在的 salve。

整個過程,我們可以查看 Redis Sentinel 的日誌:

20153:X 28 Feb 09:13:51.023 # +sdown master manager1 10.9.10.154 6379
20153:X 28 Feb 09:13:51.243 # +new-epoch 1
20153:X 28 Feb 09:13:51.244 # +vote-for-leader c14ac16f2a43c311c663677b7e056e744e2e2852 1
20153:X 28 Feb 09:13:52.102 # +odown master manager1 10.9.10.154 6379 #quorum 2/2
20153:X 28 Feb 09:13:52.102 # Next failover delay: I will not start a failover before Wed Feb 28 09:19:51 2018
20153:X 28 Feb 09:13:52.365 # +config-update-from sentinel c14ac16f2a43c311c663677b7e056e744e2e2852 10.9.10.152 26379 @ manager1 10.9.10.154 6379
20153:X 28 Feb 09:13:52.365 # +switch-master manager1 10.9.10.154 6379 10.9.10.152 6379
20153:X 28 Feb 09:13:52.365 * +slave slave 10.9.10.154:6379 10.9.10.154 6379 @ manager1 10.9.10.152 6379
20153:X 28 Feb 09:15:00.797 * +convert-to-slave slave 10.9.10.154:6379 10.9.10.154 6379 @ manager1 10.9.10.152 6379

翻譯一下就是:

  1. 每個 Sentinel 發現了主節點掛掉了並有一個 +sdown 事件
  2. 這個事件稍候升級到 +odown,意味着大多數 Sentinel 已經同意了主節點是不可達的。
  3. Sentinels 開始投票一個 Sentinel 開始並嘗試故障轉移
  4. 故障轉移開始

另外,需要注意的是,Redis Sentinel 並不是提供對外服務的地址,它只是管理 Redis 主備切換的監測工具,所以,對外 Client 提供的地址,仍是 Redis Server 的地址(包含 salve),當然,也可以像提供負載均衡(SLB)或者虛擬IP(Virtual IP,VIP),進行統一地址的訪問。

參考資料:

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