做者:田園裏的蟋蟀
出處:http://www.cnblogs.com/xishuai/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。css
閱讀目錄:html
- 關於 Redis 的概念
- 關於 Redis Sentinel 的概念
- 搭建 Redis Server(master)
- 搭建 Redis Server(slave)
- 搭建 Redis Sentinel
- Redis Sentinel 故障轉移測試
前幾天,看到了一篇文章:高可用 Redis 服務架構分析與搭建,思路講的很是好,可是沒有搭建的過程,這篇文章就記錄下 Redis Sentinel 高可用服務架構搭建的過程。redis
搭建方案,就按照做者的第四種方案:數據庫
1. 關於 Redis 的概念
Redis 是徹底開源免費的,遵照 BSD 協議,是一個高性能的 key-value 數據庫。ubuntu
Redis 與其餘 key-value 緩存產品有如下三個特色:segmentfault
- 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.htmlbash
2. 關於 Redis Sentinel 的概念
Redis Sentinel(譯爲「哨兵」)是 Redis 官方推薦的高可用性(HA)解決方案,當用 Redis 作 Master-slave 的高可用方案時,假如 master 宕機了,Redis 自己(包括它的不少客戶端)都沒有實現自動進行主備切換,而 Redis-sentinel 自己也是一個獨立運行的進程,它能監控多個 master-slave 集羣,發現 master 宕機後能進行自懂切換。服務器
Redis Sentinel 系統用於管理多個 Redis 服務器(instance),該系統執行如下三個任務:markdown
- 監控(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-server
和redis-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
翻譯一下就是:
- 每一個 Sentinel 發現了主節點掛掉了並有一個 +sdown 事件
- 這個事件稍候升級到 +odown,意味着大多數 Sentinel 已經贊成了主節點是不可達的。
- Sentinels 開始投票一個 Sentinel 開始並嘗試故障轉移
- 故障轉移開始
另外,須要注意的是,Redis Sentinel 並非提供對外服務的地址,它只是管理 Redis 主備切換的監測工具,因此,對外 Client 提供的地址,還是 Redis Server 的地址(包含 salve),固然,也能夠像提供負載均衡(SLB)或者虛擬IP(Virtual IP,VIP),進行統一地址的訪問。
參考資料: