環境搭建
三台伺服器:
192.168.126.100(master)
192.168.126.110(slaver)
192.168.126.120(slaver)
拷貝192.168.126.100(主)伺服器中的Redis到從機,保證Redis版本、環境一緻:
scp -r redis-3.2.0/ [email protected]:/usr/local/ // 安裝目錄
scp -r redis/ [email protected]:/usr/local/ // 自定義配置、資料目錄
scp -r redis-3.2.0/ [email protected]:/usr/local/
scp -r redis/ [email protected]:/usr/local/
主從複制 - 讀寫分離
Redis的複制功能是支援多個資料庫之間的資料同步。一類是主資料庫(master)一類是從資料庫(slave),主資料庫可以進行讀寫操作,當發生寫操作的時候自動将資料同步到從資料庫,而從資料庫一般是隻讀的,并接收主資料庫同步過來的資料,一個主資料庫可以有多個從資料庫,而一個從資料庫隻能有一個主資料庫。
通過redis的複制功能可以很好的實作資料庫的讀寫分離,提高伺服器的負載能力。主資料庫主要進行寫操作,而從資料庫負責讀操作。
主從複制過程
過程:
1:當一個從資料庫啟動時,會向主資料庫發送sync指令,
2:主資料庫接收到sync指令後會開始在背景儲存快照(執行rdb操作),并将儲存期間接收到的指令緩存起來
3:當快照完成後,redis會将快照檔案和所有緩存的指令發送給從資料庫。
4:從資料庫收到後,會載入快照檔案并執行收到的緩存的指令。
注意:redis2.8之前的版本:當主從資料庫同步的時候從資料庫因為網絡原因斷開重連後會重新執行上述操作,不支援斷點續傳。redis2.8之後支援斷點續傳。
配置
隻需要修改兩台從節點中redis的配置檔案:
注意:如果主資料庫設定了密碼,需要在從資料的配置檔案中通過masterauth參數設定主資料庫的密碼
效果
節點 | |
---|---|
192.168.126.100(master) | |
192.168.126.110(slaver) | |
常見問題
啟動從節點的redis,可能出現以下錯誤:
解決辦法:
1、修改主節點redis的配置檔案:
bind 0.0.0.0
2、重新開機服務
哨兵( Sentinel)機制 - 主從高可用方案
簡介
Redis-Sentinel是Redis官方推薦的高可用性(HA)解決方案。實際上這意味着你可以使用Sentinel模式建立一個可以不用人為幹預而應對各種故障的Redis部署。
主要功能
- 監控(Monitoring): Sentinel 會不斷地檢查你的主伺服器和從伺服器是否運作正常。
- 提醒(Notification): 當被監控的某個 Redis 伺服器出現問題時, Sentinel 可以通過 API 向管理者或者其他應用程式發送通知。
- 自動故障遷移(Automatic failover): 當一個主伺服器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會将失效主伺服器的其中一個從伺服器更新為新的主伺服器, 并讓失效主伺服器的其他從伺服器改為複制新的主伺服器; 當用戶端試圖連接配接失效的主伺服器時, 叢集也會向用戶端傳回新主伺服器的位址, 使得叢集可以使用新主伺服器代替失效伺服器。
Redis Sentinel 是一個分布式系統, 你可以在一個架構中運作多個 Sentinel 程序(progress), 這些程序使用流言協定(gossip protocols)來接收關于主伺服器是否下線的資訊, 并使用投票協定(agreement protocols)來決定是否執行自動故障遷移, 以及選擇哪個從伺服器作為新的主伺服器。
Sentinel的主從原理
修改110、120伺服器下Sentinel的配置檔案sentinel.conf:
sentinel monitor mymaster 192.168.126.100 6379 1
-
該配置指定 Sentinel 去監視一個名為 mymaster 的主伺服器, 這個主伺服器的 IP 位址為 192.168.126.100 , 端口号為 6379 , 而将這個主伺服器判斷為失效至少需要 1 個 Sentinel 同意 (隻要同意 Sentinel 的數量不達标,自動故障遷移就不會執行)。
需要注意的是: 無論你設定要多少個 Sentinel 同意才能判斷一個伺服器失效, 一個 Sentinel 都需要獲得系統中多數 Sentinel 的支援, 才能發起一次自動故障遷移, 并預留一個給定的配置紀元 (configuration Epoch ,一個配置紀元就是一個新主伺服器配置的版本号)。換句話說, 在隻有少數 Sentinel 程序正常運作的情況下, Sentinel 是不能執行自動故障遷移的。
sentinel down-after-milliseconds mymaster 5000
-
該配置指定了 Sentinel 認為伺服器已經斷線所需的毫秒數。
如果伺服器在給定的毫秒數之内, 沒有傳回 Sentinel 發送的 PING 指令的回複, 或者傳回一個錯誤, 那麼 Sentinel 将這個伺服器标記為主觀下線(subjectively down,簡稱 SDOWN )。
不過隻有一個 Sentinel 将伺服器标記為主觀下線并不一定會引起伺服器的自動故障遷移: 隻有在足夠數量的 Sentinel 都将一個伺服器标記為主觀下線之後, 伺服器才會被标記為客觀下線(objectively down, 簡稱 ODOWN ), 這時自動故障遷移才會執行。
将伺服器标記為客觀下線所需的 Sentinel 數量由對主伺服器的配置決定。
sentinel parallel-syncs mymaster 1
-
該配置指定了在執行故障轉移時, 最多可以有多少個從伺服器同時對新的主伺服器進行同步, 這個數字越小, 完成故障轉移所需的時間就越長。
如果從伺服器被設定為允許使用過期資料集(參見對 redis.conf 檔案中對 slave-serve-stale-data 選項的說明), 那麼你可能不希望所有從伺服器都在同一時間向新的主伺服器發送同步請求, 因為盡管複制過程的絕大部分步驟都不會阻塞從伺服器, 但從伺服器在載入主伺服器發來的 RDB 檔案時, 仍然會造成從伺服器在一段時間内不能處理指令請求: 如果全部從伺服器一起對新的主伺服器進行同步, 那麼就可能會造成所有從伺服器在短時間内全部不可用的情況出現。
你可以通過将這個值設為 1 來保證每次隻有一個從伺服器處于不能處理指令請求的狀态。
sentinel failover-timeout mymaster 180000
- failover(故障轉移)過期時間,當failover開始後,在此時間内仍然沒有觸發任何failover操作, 目前sentinel将會認為此次failoer失敗。
啟動
方式一:使用redis-sentine指令啟動 Sentinel 系統:
redis-sentinel /path/to/sentinel.conf
方式二:redis-server指令啟動一個運作在 Sentinel 模式下的 Redis 伺服器:
redis-server /path/to/sentinel.conf --sentinel
啟動110、120伺服器下的Sentinel 服務:
192.168.126.110:
192.168.126.120:
檢視sentinel的狀态:
問題一:
[root@huangyk120 etc]# redis-cli -h 192.168.126.120 -p 26379 info Sentinel
Could not connect to Redis at 192.168.126.120:26379: Connection refused
配置檔案redis.conf配置了隻在127.0.0.1上綁定監聽,取消該配置。
################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 lookback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#bind 127.0.0.1
問題二:
DENIED Redis is running in protected mode because protected mode is enabled, no bind address was specified, no authentication password is requested to clients. In this mode connections are only accepted from the loopback interface. If you want to connect from external computers to Redis you may adopt one of the following solutions: 1) Just disable protected mode sending the command 'CONFIG SET protected-mode no' from the loopback interface by connecting to Redis from the same host the server is running, however MAKE SURE Redis is not publicly accessible from internet if you do so. Use CONFIG REWRITE to make this change permanent. 2) Alternatively you can just disable the protected mode by editing the Redis configuration file, and setting the protected mode option to 'no', and then restarting the server. 3) If you started the server manually just for testing, restart it with the '--protected-mode no' option. 4) Setup a bind address or an authentication password. NOTE: You only need to do one of the above things in order for the server to start accepting connections from the outside.
登入redis client
[root@huangyk120 etc]# redis-cli -h 192.168.126.120 -p 6379
或者檢視Sentinel資訊
[root@huangyk120 etc]# redis-cli -h 192.168.126.120 -p 26379 info Sentinel
都可能以上錯誤。
原因分析:
預設情況下redis運作在保護模式,這種模式下,如果沒有設定通路密碼,隻允許本地回路通路。如果需要遠端通路
1:修改protected-mode為no
2:添加認證,設定密碼
#requirepass foobared
requirepass 123456
修改配置檔案redis.conf中的protected-mode為no:
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
巨坑(這個問題坑了我好久):
隻修改redis.conf的protected-mode為no,發現檢視Sentinel資訊還是報錯。官方在redis.conf的注釋說明中有protected-mode這一配置項,但sentinel.conf的注釋中完全沒有提到過該配置項,嘗試在sentinel.conf中加入
protected-mode no
儲存并重新啟動sentinel。
檢視sentinel的狀态,終于成功了!!!
驗證redis sentinel的主從切換(故障轉移)
關閉100上的主redis服務(shutdown)。
檢視sentinel哨兵日志資訊,發現110上的redis服務被選舉為主服務,sentinel自動完成了故障切換。
啟動剛才被shutdown的110上的redis服務并檢視,發現它變成了從服務。
java操作sentinel
代碼示例:
package redistest;
import java.util.HashSet;
//需要在pom.xml檔案中引入jedis依賴
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
public class SentinelTest {
public static void main(String[] args) {
// 使用HashSet添加多個sentinel
HashSet<String> sentinels = new HashSet<String>();
// 添加sentinel主機和端口
sentinels.add("192.168.126.110:26379");
sentinels.add("192.168.126.120:26379");
// 建立config
JedisPoolConfig poolConfig = new JedisPoolConfig();
// 控制一個pool最多有多少個狀态為idle(空閑的)的jedis執行個體。
poolConfig.setMaxIdle(10);
// 控制一個pool最多有多少個jedis執行個體。
poolConfig.setMaxTotal(100);
// 表示當borrow(引入)一個jedis執行個體時,最大的等待時間,如果超過等待時間,則直接抛出JedisConnectionException;
poolConfig.setMaxWaitMillis(2000);
// 在borrow一個jedis執行個體時,是否提前進行validate操作;如果為true,則得到的jedis執行個體均是可用的;
poolConfig.setTestOnBorrow(true);
// 通過Jedis連接配接池建立一個Sentinel連接配接池
JedisSentinelPool pool = new JedisSentinelPool("mymaster", sentinels, poolConfig);
// 擷取master的主機和端口
HostAndPort currentHostMaster = pool.getCurrentHostMaster();
System.out.println(currentHostMaster.getHost() + "--" + currentHostMaster.getPort());
// 從Sentinel池中擷取資源
Jedis resource = pool.getResource();
// 列印資源中key為name的值
System.out.println(resource.get("a"));
// 關閉資源
resource.close();
}
}
執行結果:
版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/wuseyukui/article/details/75635606