0. 前言
這篇文章簡要介紹Redis的主從部署,實現了一主二從,使用兩個哨兵監控,以實現簡單的HA,其中從庫作為備機。
1. 部署
這里有三台服務器,其中239主機上的Redis作為主庫,其余兩個作為從庫。這里涉及到了認證,所以當這里在主庫和從庫都使用了requirepass和masterauth,因為當主庫宕機后,哨兵將其中一個從庫提升為主庫的時候會要求認證,這里簡單起見,配置文件使用了同一配置和密碼。
239主庫涉及的配置:
requirepass messagequeue
masterauth messagequeue
從庫涉及相關配置:
slaveof 172.16.17.239 6379 masterauth messagequeue requirepass messagequeue
兩個哨兵的配置:
sentinel monitor gateway 172.16.17.239 6379 2 sentinel auth-pass gateway messagequeue
下圖為最終的部署圖。
最后部署完后可以通過redis-cli連接哨兵查看。
如下圖所示:可以看到主庫的ip和端口,從機數量以及哨兵的數量
2. 哨兵的詳細配置說明:
#端口號 port 26379 # dir <working-directory> dir /tmp # 監控主數據庫 sentinel monitor gateway 172.16.17.239 6379 2 #認證密碼 sentinel auth-pass gateway messagequeue #發送PING間隔,大於1秒則按1秒間隔,小於1秒則按配置的時間間隔 sentinel down-after-milliseconds gateway 30000 # 當進行災備時同時進行重新配置從機的個數 # 當從機用於查詢時,用來保證災備時一定量的從機可以繼續服務。 sentinel parallel-syncs gateway 1 # 1.自上次嘗試災備后,再次進行災備的時間 # 2.從機根據哨兵,從一個錯誤的主機強制去復制一個正確主機的所需時間,即災備超時時間。 # 3.取消災備的時間,即SLAVEOF NO ONE發送到從機,而從機沒有應答,超時。 # 4.所有從機配置指向主機的最大時間(災備總時間) # 3分鍾 sentinel failover-timeout gateway 180000 # 腳本最大運行時間為60秒,當腳本終止碼為1時則表示失敗重新再次執行(默認最多10次),為2時表成功 # 通知腳本,用以通知管理員(通過SMS,Email等) # 該腳本傳入兩個參數,第一個是事件類型,第二個是事件描述 # sentinel notification-script mymaster /var/redis/notify.sh # 客戶端重新配置腳本(腳本應該為可重入) # 用於主庫變更時執行一些特定任務,如通知客戶端主庫變更。 # sentinel client-reconfig-script <master-name> <script-path> # 下面參數會傳遞給腳本 # <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 為變更后主庫地址 # sentinel client-reconfig-script mymaster /var/redis/reconfig.sh
3. 哨兵應用
哨兵提供了一些方法,以供在災備切換主庫后查詢主庫的信息。
1. 如上配置文件,可以使用腳本方式來通知。
2. 可以通過連接哨兵使用 SENTINEL master <master_name>來查詢(其中master_name為上述哨兵配置文件sentinel monitor后面的gateway)。
如下局部代碼(采用hiredis庫,連接后要使用AUTH命令認證方可操作):
1 const char *pCommand = "SENTINEL master %s"; 2 redisReply *pReply = (redisReply*)redisCommand(pRedisContext->pContext, pCommand, pMasterName); 3 4 if (NULL != pReply) 5 { 6 if (REDIS_REPLY_ARRAY == pReply->type && pReply->elements >= 5) 7 { 8 nMasterIpLen = REDIS_MIN(20, pReply->element[3]->len); 9 memcpy(pMasterIP, pReply->element[3]->str, nMasterIpLen); 10 pMasterIP[nMasterIpLen] = '\0'; 11 *pMasterPort = atoi(pReply->element[5]->str); 12 nRet = REDIS_SUCCESS; 13 } 14 freeReplyObject(pReply); 15 }
4. 總結
如上圖所示的部署主要用於公司一個項目,實現在簡單的消息隊列,這里不采用其他開源消息隊列(如activemq,zeromq,rabbitmq等)有一些其他的因素在。