當前位置:
首頁 > 知識 > Windows版本redis高可用方案探究

Windows版本redis高可用方案探究

目錄

  • 前言
  • 前提
  • 搭建redis主從
  • 配置主redis-28380
  • 配置從redis-23381
  • 配置從redis-23382
  • 將redis部署為服務
  • 啟動redis
  • 配置哨兵
  • 啟動哨兵
  • 主從自動切換
  • 動態新增從庫
  • 程序連接redis高可用
  • 總結
  • 參考文檔

前言

本篇文章專註於講解redis在windows環境下使用Redis Sentinel(哨兵)實現高可用方案。

前提

想要在windows環境下實現redis高可用,先要準備以下材料或知識點。

  1. redis 3.2.100
  2. 目前在windows版本最新的redis是3.2.100,可以到這裡下載
  3. Redis Sentinel
  4. redis本身不支持高可用方案,通過sentinel對redis進行監控進行主從監控及調節等。

搭建redis主從

下載的壓縮文件內容如下圖所示。

Windows版本redis高可用方案探究

具體結構如下圖所示

Windows版本redis高可用方案探究

應用層連接redis集群,集群包括3個redis服務(1主2從)和3個哨兵。


哨兵用於監控主redis可用性。若長時間不可用,則哨兵進行投票選舉出新的主redis。原來的主redis降級為從redis。哨兵會將所有redis的配置進行自動更新。

配置主redis-28380

將redis複製一份。一個文件夾用於部署redis服務,一個文件夾用於部署哨兵。

Windows版本redis高可用方案探究

規定redis服務埠為28380~28382。將redis.windiws-service.config改名為redis-28380.conf。打開進行修改。

  1. 修改綁定埠
  2. 注釋掉bind 127.0.0.1,默認為監聽所有ip。
  3. 將保護模式關閉
  4. 修改protected-mode yes為protected-mode no,默認redis開啟了保護模式,只允許本機通過127.0.0.1訪問,其他ip無法訪問。
  5. 修改監聽埠
  6. 修改port 6379為port 28380
  7. 修改日誌等級
  8. 修改loglevel debug為loglevel notice
  9. 修改日誌文件名
  10. 修改logfile "server_log.txt"為logfile "server_log_28380.txt"
  11. 修改windows日誌的事件名
  12. 修改syslog-ident redis為syslog-ident "redis-28380"
  13. 修改不保存rdb文件
  14. 注釋掉一下三行,由於rdb會每次全量寫文件,當數據量較大時會對redis穩定性造成一定影響,尤其是rbd保存失敗時會一定時間內拒絕寫入數據。

save 900 1
save 300 10
save 60 10000

  1. 創建密碼
  2. 修改# requirepass foobared為requirepass "test1"
  3. 新增masterauth "test1"

若要設置密碼,單台redis設置requirepass即可。集群redis必須同時設置requirepass和masterauth。若主redis沒有設置masterauth當它變為從時,就認為主無密碼。若從redis沒有設置requirepass,當它變為主時,會沒有密碼。以上兩種情況自動切換都無法自動連接到新的主。

  1. 啟用aof保存
  2. 修改appendonly no為appendonly yes
  3. 修改appendfilename "appendonly.aof"為appendfilename "appendonly_28380.aof"

aof寫入的是redis命令,每次向文件後面添加,因此對IO性能影響較小。最壞情況主redis丟失1s的數據。

配置改好後保存,這個當作主redis的配置。將改配置複製2份,分別改名為redis-28381.conf和redis-28382.conf

配置從redis-23381

  1. 修改監聽埠
  2. 修改port 28380為port 28381
  3. 修改日誌文件名
  4. 修改logfile "server_log-28380.txt"為logfile "server_log_28381.txt"
  5. 修改windows日誌的事件名
  6. 修改syslog-ident "redis-28380"為syslog-ident "redis-28381"
  7. 修改從庫對應的主庫ip
  8. 修改# slaveof <masterip> <masterport>為slaveof 127.0.0.1 28380

23880做為主庫,填寫的就是28380的埠

  1. 修改從庫競選主庫優先順序
  2. 修改slave-priority 100為slave-priority 99

將每個從庫設置為不通的優先順序,數字較低的優先被競選為主庫。

  1. 修改aof保存的文件名
  2. 修改appendfilename "appendonly_28380.aof"為appendfilename "appendonly_28381.aof"

配置從redis-23382

  1. 修改監聽埠
  2. 修改port 28380為port 28382
  3. 修改日誌文件名
  4. 修改logfile "server_log-28380.txt"為logfile "server_log_28382.txt"
  5. 修改windows日誌的事件名
  6. 修改syslog-ident "redis-28380"為syslog-ident "redis-28382"
  7. 修改從庫對應的主庫ip
  8. 修改# slaveof <masterip> <masterport>為slaveof 127.0.0.1 28380

23880做為主庫,填寫的就是28380的埠

  1. 修改從庫競選主庫優先順序
  2. 修改slave-priority 100為slave-priority 98

將每個從庫設置為不通的優先順序,數字較低的優先被競選為主庫。

  1. 修改aof保存的文件名
  2. 修改appendfilename "appendonly_28380.aof"為appendfilename "appendonly_28382.aof"

將redis部署為服務

通過命令redis-server --service-install 配置名 --service-name 服務名 將redis安裝為服務。

先cd到redis所在目錄,在cmd命令行中輸入一下三條語句將三個redis安裝成功為windows服務。

redis-server --service-install redis-28380.conf --service-name redis-28380
redis-server --service-install redis-28381.conf --service-name redis-28381
redis-server --service-install redis-28382.conf --service-name redis-28382

設置服務別名是為了在服務中能更好的看到哪個是哪個服務,否則默認都是redis服務。

Windows版本redis高可用方案探究

啟動redis

可以直接在服務中右鍵啟動或者通過命令redis-server --service-start --service-name 服務名 啟動指定服務。

通過redis-cli 連接到各個redis服務。

F:Study
edis> redis-cli -p 28380 -a test1
127.0.0.1:28380> info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=28382,state=online,offset=183,lag=1
slave1:ip=127.0.0.1,port=28381,state=online,offset=183,lag=1
master_repl_offset:183
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:182

可以看到我們的主從配置已經生效了。

連接到從庫28381

F:Study
edis> redis-cli -p 28381 -a test1
127.0.0.1:28381> info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:28380
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_repl_offset:323
slave_priority:99
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

連接到從庫28382

F:Study
edis> redis-cli -p 28382 -a test1
127.0.0.1:28382> info Replication
# Replication
role:slave
master_host:127.0.0.1
master_port:28380
master_link_status:up
master_last_io_seconds_ago:8
master_sync_in_progress:0
slave_repl_offset:379
slave_priority:99
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

現在我們往主庫寫入數據會自動並主動同步到從庫。


配置中默認配了以下配置了slave-read-only yes,從庫是只讀的,不允許寫入。

配置哨兵

設置三個哨兵埠為 24381~24383

配置哨兵24381

dir ./
logfile "sentinel.28481.txt"
port 28481
sentinel monitor master 127.0.0.1 28380 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 30000
sentinel auth-pass 127.0.0.1 28380 test1

  • sentinel monitor master 127.0.0.1 28380 2 設置主redis的別名為master,後面都通過master表示主redis。後面的2表示2個哨兵檢測到主redis掛了即為掛了,需要重新選舉出新的主redis,而原來的主redis降級為從redis。
  • sentinel down-after-milliseconds master 5000 哨兵多久連不上主redis即認為它掛了
  • sentinel failover-timeout master 30000 投票選舉超時時間,超過時間沒有選出則該輪投票失敗。
  • sentinel auth-pass master test1 主redis的密碼 。

由於哨兵只能設置主的密碼,因此主從的密碼應該設置為一樣的。

配置哨兵24382

dir ./
logfile "sentinel.28482.txt"
port 28482
sentinel monitor master 127.0.0.1 28380 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 30000
sentinel auth-pass 127.0.0.1 28380 test1

配置哨兵24383

dir ./
logfile "sentinel.28483.txt"
port 28483
sentinel monitor master 127.0.0.1 28380 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 30000
sentinel auth-pass 127.0.0.1 28380 test1

啟動哨兵

通過命令redis-server.exe 配置 --sentinel 啟動哨兵

redis-server redis-sentinel-28481.conf --sentinel
redis-server redis-sentinel-28482.conf --sentinel
redis-server redis-sentinel-28483.conf --sentinel

啟動哨兵28481後查看日誌

[8464] 21 Nov 02:02:05.258 # +tilt #tilt mode entered
[8464] 21 Nov 08:33:01.513 # +tilt #tilt mode entered
[8464] 21 Nov 08:33:31.561 # -tilt #tilt mode exited
_._
_.-``__ ""-._
_.-`` `. `_. ""-._ Redis 3.2.100 (00000000/0) 64 bit
.-`` .-```. ```/ _.,_ ""-._
( " , .-` | `, ) Running in sentinel mode
|`-._`-...-` __...-.``-._|"` _.-"| Port: 28481
| `-._ `._ / _.-" | PID: 22332
`-._ `-._ `-./ _.-" _.-"
|`-._`-._ `-.__.-" _.-"_.-"|
| `-._`-._ _.-"_.-" | http://redis.io
`-._ `-._`-.__.-"_.-" _.-"
|`-._`-._ `-.__.-" _.-"_.-"|
| `-._`-._ _.-"_.-" |
`-._ `-._`-.__.-"_.-" _.-"
`-._ `-.__.-" _.-"
`-._ _.-"
`-.__.-"
[22332] 05 Jan 12:01:48.399 # Sentinel ID is 48693b2911456ef3da6ebfd14d1adf46e76fbb8b
[22332] 05 Jan 12:01:48.399 # +monitor master master 127.0.0.1 28382 quorum 2
[22332] 05 Jan 12:01:53.399 # +sdown sentinel ce50397a76e2e3ca165ce407859cbc94d7caf504 127.0.0.1 28482 @ master 127.0.0.1 28382
[22332] 05 Jan 12:01:53.399 # +sdown sentinel 162c66f370550a9926b794abecfb431cf3f8bcc9 127.0.0.1 28483 @ master 127.0.0.1 28382
[22332] 05 Jan 12:02:13.404 # +sdown master master 127.0.0.1 28382

同時啟動完會自動在哨兵的配置文件中生成一些配置,完整的redis-sentinel-28481.conf配置如下

dir "F:\Study\redis\redis-sentinel"
logfile "sentinel.28481.txt"
port 28481
sentinel myid 48693b2911456ef3da6ebfd14d1adf46e76fbb8b
sentinel monitor master 127.0.0.1 28381 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 30000
# Generated by CONFIG REWRITE
sentinel auth-pass master test1
sentinel config-epoch master 11
sentinel leader-epoch master 11
sentinel known-slave master 127.0.0.1 28382
sentinel known-slave master 127.0.0.1 28380
sentinel known-sentinel master 127.0.0.1 28482 ce50397a76e2e3ca165ce407859cbc94d7caf504
sentinel known-sentinel master 127.0.0.1 28483 162c66f370550a9926b794abecfb431cf3f8bcc9
sentinel current-epoch 11

啟動後會為哨兵生成一個id,同時會記錄一些關鍵信息。

主從自動切換

將主redis關閉,讓哨兵自動切換主從。

哨兵24381日誌

[22332] 05 Jan 12:34:49.286 # +sdown master master 127.0.0.1 28380
[22332] 05 Jan 12:34:49.295 # +new-epoch 16
[22332] 05 Jan 12:34:49.296 # +vote-for-leader ce50397a76e2e3ca165ce407859cbc94d7caf504 16
[22332] 05 Jan 12:34:49.363 # +odown master master 127.0.0.1 28380 #quorum 3/2
[22332] 05 Jan 12:34:49.363 # Next failover delay: I will not start a failover before Sat Jan 05 12:35:49 2019
[22332] 05 Jan 12:34:50.397 # +config-update-from sentinel ce50397a76e2e3ca165ce407859cbc94d7caf504 127.0.0.1 28482 @ master 127.0.0.1 28380
[22332] 05 Jan 12:34:50.397 # +switch-master master 127.0.0.1 28380 127.0.0.1 28382
[22332] 05 Jan 12:34:50.397 * +slave slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28382
[22332] 05 Jan 12:34:50.397 * +slave slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382
[22332] 05 Jan 12:34:55.442 # +sdown slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382

哨兵24382日誌

[8760] 05 Jan 12:34:49.237 # +sdown master master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.292 # +odown master master 127.0.0.1 28380 #quorum 2/2
[8760] 05 Jan 12:34:49.292 # +new-epoch 16
[8760] 05 Jan 12:34:49.292 # +try-failover master master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.293 # +vote-for-leader ce50397a76e2e3ca165ce407859cbc94d7caf504 16
[8760] 05 Jan 12:34:49.296 # 162c66f370550a9926b794abecfb431cf3f8bcc9 voted for ce50397a76e2e3ca165ce407859cbc94d7caf504 16
[8760] 05 Jan 12:34:49.296 # 48693b2911456ef3da6ebfd14d1adf46e76fbb8b voted for ce50397a76e2e3ca165ce407859cbc94d7caf504 16
[8760] 05 Jan 12:34:49.394 # +elected-leader master master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.394 # +failover-state-select-slave master master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.470 # +selected-slave slave 127.0.0.1:28382 127.0.0.1 28382 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.470 * +failover-state-send-slaveof-noone slave 127.0.0.1:28382 127.0.0.1 28382 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:49.541 * +failover-state-wait-promotion slave 127.0.0.1:28382 127.0.0.1 28382 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:50.341 # +promoted-slave slave 127.0.0.1:28382 127.0.0.1 28382 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:50.341 # +failover-state-reconf-slaves master master 127.0.0.1 28380
[8760] 05 Jan 12:34:50.396 * +slave-reconf-sent slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:51.380 * +slave-reconf-inprog slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:51.446 # -odown master master 127.0.0.1 28380
[8760] 05 Jan 12:34:52.393 * +slave-reconf-done slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28380
[8760] 05 Jan 12:34:52.468 # +failover-end master master 127.0.0.1 28380
[8760] 05 Jan 12:34:52.468 # +switch-master master 127.0.0.1 28380 127.0.0.1 28382
[8760] 05 Jan 12:34:52.469 * +slave slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28382
[8760] 05 Jan 12:34:52.469 * +slave slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382
[8760] 05 Jan 12:34:57.562 # +sdown slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382

哨兵24383日誌

[26484] 05 Jan 12:34:49.161 # +sdown master master 127.0.0.1 28380
[26484] 05 Jan 12:34:49.294 # +new-epoch 16
[26484] 05 Jan 12:34:49.295 # +vote-for-leader ce50397a76e2e3ca165ce407859cbc94d7caf504 16
[26484] 05 Jan 12:34:50.284 # +odown master master 127.0.0.1 28380 #quorum 3/2
[26484] 05 Jan 12:34:50.284 # Next failover delay: I will not start a failover before Sat Jan 05 12:35:49 2019
[26484] 05 Jan 12:34:50.397 # +config-update-from sentinel ce50397a76e2e3ca165ce407859cbc94d7caf504 127.0.0.1 28482 @ master 127.0.0.1 28380
[26484] 05 Jan 12:34:50.397 # +switch-master master 127.0.0.1 28380 127.0.0.1 28382
[26484] 05 Jan 12:34:50.397 * +slave slave 127.0.0.1:28381 127.0.0.1 28381 @ master 127.0.0.1 28382
[26484] 05 Jan 12:34:50.397 * +slave slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382
[26484] 05 Jan 12:34:55.437 # +sdown slave 127.0.0.1:28380 127.0.0.1 28380 @ master 127.0.0.1 28382

具體投票過程這裡不做具體分析。

當選出新的主redis,哨兵會對redis配置進行更新,將主redis的slaveof XXX XXX配置刪除,將從的slaveof XXX XXX設置為主的地址。同時哨兵會監控redis28380。當28380恢復後會將slaveof XXX XXX添加到它的配置中。

連接到28382查看

127.0.0.1:28382> info Replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=28381,state=online,offset=193307,lag=1
slave1:ip=127.0.0.1,port=28380,state=online,offset=193441,lag=1
master_repl_offset:193575
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:193574

動態新增從庫

若我們此時動態新增一個從redis,埠為28383,則複製一個28380的配置進行修改,將優先順序改為97。並啟動服務即可。

redis-28383日誌如下

[14048] 05 Jan 12:55:20.421 * Redis 3.2.100 (00000000/0) 64 bit, standalone mode, port 28383, pid 14048 ready to start.
[14048] 05 Jan 12:55:20.422 # Server started, Redis version 3.2.100
[14048] 05 Jan 12:55:20.423 * The server is now ready to accept connections on port 28383
[14048] 05 Jan 12:55:20.424 * Connecting to MASTER 127.0.0.1:28382
[14048] 05 Jan 12:55:20.426 * MASTER <-> SLAVE sync started
[14048] 05 Jan 12:55:20.427 * Non blocking connect for SYNC fired the event.
[14048] 05 Jan 12:55:20.428 * Master replied to PING, replication can continue...
[14048] 05 Jan 12:55:20.428 * Partial resynchronization not possible (no cached master)
[14048] 05 Jan 12:55:20.432 * Full resync from master: 2c344529e4acdc44cd311818fe8179825877a9f4:241347
[14048] 05 Jan 12:55:20.653 * MASTER <-> SLAVE sync: receiving 107 bytes from master
[14048] 05 Jan 12:55:20.655 * MASTER <-> SLAVE sync: Flushing old data
[14048] 05 Jan 12:55:20.655 * MASTER <-> SLAVE sync: Loading DB in memory
[14048] 05 Jan 12:55:20.656 * MASTER <-> SLAVE sync: Finished with success
[14048] 05 Jan 12:55:20.660 * Background append only file rewriting started by pid 29392
[14048] 05 Jan 12:55:20.827 * AOF rewrite child asks to stop sending diffs.
[14048] 05 Jan 12:55:20.927 # fork operation complete
[14048] 05 Jan 12:55:20.928 * Background AOF rewrite terminated with success
[14048] 05 Jan 12:55:20.929 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
[14048] 05 Jan 12:55:20.931 * Background AOF rewrite finished successfully

再看下28382的主從連接信息

127.0.0.1:28382> info Replication
# Replication
role:master
connected_slaves:3
slave0:ip=127.0.0.1,port=28381,state=online,offset=268634,lag=0
slave1:ip=127.0.0.1,port=28380,state=online,offset=268768,lag=0
slave2:ip=127.0.0.1,port=28383,state=online,offset=268634,lag=0
master_repl_offset:268768
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:268767

哨兵也能檢測到新的從庫連接

[22332] 05 Jan 12:55:25.420 * +slave slave 127.0.0.1:28383 127.0.0.1 28383 @ master 127.0.0.1 28382

通過上述配置,就完成了redis高可用方案。

程序連接redis高可用

我使用的是StackExchange.Redis連接redis。

它本身就支持主從連接,在建立連接的時候輸入多個連接地址介面。由於從庫不允許寫入。因此它能辨別出哪個是主哪個是從。主從切換後寫入數據的時候重新判定哪個是主庫。

  1. 通過代碼設置redis地址

ConfigurationOptions options = ConfigurationOptions.Parse("password=test1");
options.EndPoints.Add("127.0.0.1", 28380);
options.EndPoints.Add("127.0.0.1", 28381);
options.EndPoints.Add("127.0.0.1", 28382);

  1. 通過配置字元串設置

ConfigurationOptions options = ConfigurationOptions.Parse("127.0.0.1:28380,127.0.0.1:28381,127.0.0.1:28382,keepAlive=5,password=test1");

總結

通過該篇文章詳細的探究了window下的redis高可用方案如何實現。本文對具體配置沒有做深入探究,僅僅為了抓住重點,具體配置其他的文檔都介紹的比較詳細,但是一些細節並沒有說明,通過該片文章將reids高可用的坑都填滿。若有錯誤,歡迎指正。

作者:傑哥很忙

https://www.cnblogs.com/Jack-Blog/p/10224193.html

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

J2Cache 和普通緩存框架有何不同,它解決了什麼問題?
美團即時物流的分散式系統架構設計

TAG:程序員小新人學習 |