Redis主从、哨兵及集群搭建
1、主從復制
目的:讀寫分離,主寫,從讀,容災的快速恢復
主從復制原理:?- Slave 啟動成功連接到master后會發送—個sync命令。
- Master 接到命令啟動后臺的存盤進程,同時收集所有接收到的用于修改數據集命令,在后臺進程執行完畢之后,master將傳送整個數據文件到slave,以完成一次完全同步。
- 全量復制:而 slave 服務在接收到數據庫文件數據后,將其存盤并加載到內存中。
- 增量復制:Master 繼續將新的所有收集到的修改命令依次傳給 slave,完成同步。
- 但是只要是重新連接mater,一次完全同步(全量復制)將被自動執行。
?主節點配置:
port 6379 daemonize yes bind 主節點機器ip requirepass 123456 pidfile /var/run/redis-6379.pid logfile /var/log/redis/redis-6379.log dbfilename /var/db/dump-6379.rdb rdbcompression yes # 指定存儲到本地數據庫的時候是否進行壓縮從節點配置:默認從不可寫,只能讀
port??6379 daemonize??yes bind? 從節點機器ip requirepass 123456 masterauth 123456 pidfile???/var/run/redis-6380.pid logfile???/var/log/redis/redis-6380.log dbfilename /var/db/dump-6380.rdb rdbcompression yes??# 指定存儲到本地數據庫的時候是否進行壓縮 slaveof 主ip 主redis端口 #或 直接在從服務器客戶端執行命令 slaveof?主ip 主redis端口slave-priority 100 #?哨兵選舉優先級,值越小,優先級越高查看redis運行情況
#?./redis-cli -p 6379
# info replication
注意:
使用主從模式時應注意matser節點的持久化操作,matser節點在未使用持久化的情況詳情下如果宕機,并自動重新拉起服務,從服務器會出現丟失數據的情況。(關掉master持久化 # CONFIG SET save 的時候)
數據丟失的原因:
因為master服務掛了之后,重啟服務后,slave節點會與master節點進行一次完整的重同步操作,所以由于master節點沒有持久化,就導致slave節點上的數據也會丟失掉。所以在配置了Redis的主從模式的時候,應該打開主服務器的持久化功能。
?2、哨兵模式
sentinel,哨兵是 redis 集群中非常重要的一個組件,主要有以下功能:
-
集群監控:負責監控 redis master和 slave 進程是否正常工作。
-
消息通知:如果某個 redis 實例有故障,那么哨兵負責發送消息作為報警通知給管理員。
-
故障轉移:如果 master node 掛掉了,會自動轉移到 slave node 上。
-
配置中心:如果故障轉移發生了,通知 client 客戶端新的 master 地址。
哨兵用于實現 redis 集群的高可用,本身也是分布式的,作為一個哨兵集群去運行,互相協同工作。
-
故障轉移時,判斷一個 master node 是否宕機了,需要大部分的哨兵都同意才行,涉及到了分布式選舉
-
即使部分哨兵節點掛掉了,哨兵集群還是能正常工作的
-
哨兵通常需要3個實例,來保證自己的健壯性。
-
哨兵+redis 主從的部署架構,是不保證數據零丟失的,只能保證 redis 集群的高可用性。
-
對于哨兵 + redis 主從這種復雜的部署架構,盡量在測試環境和生產環境,都進行充足的測試和演練。
選擇條件:
-
優先級最高的(redis.conf中的slave-priority配置),不存在則找下一條
-
偏移量最大的(獲取主機數據最全的),不存在則找下一條
-
選擇runid最小的(每個redis實例啟動后都會隨機生成一個40位的runid)
配置:?
1、新建配置文件 sentinel.conf:
# 修改redis-sentinel配置文件:/etc/redis-sentinel.conf # 1. 綁定的地址 bind 172.19.131.247 # 2. 保護模式修改為否,允許遠程連接 protected-mode no # 3. 設定sentinel myid 每個都不一樣,使用yum安裝的時候,直接就生成了 sentinel myid 04d9d3fef5508f60498ac014388571e719188527 # 4. 設定監控地址,為對應的主redis庫的內網地址 sentinel monitor mymaster 主ip 6379 2[至少有2個哨兵同意后才進行主從切換] # 5. 設定5秒內沒有響應,說明服務器掛了,需要將配置放在sentinel monitor master 127.0.0.1 6379 1下面 sentinel down-after-milliseconds mymaster 5000 # 6. 設定15秒內master沒有活起來,就重新選舉主 sentinel failover-timeout mymaster 15000 # 7. 表示如果master重新選出來后,其它slave節點能同時并行從新master同步緩存的臺數有多少個,顯然該值越大,所有slave節點完成同步切換的整體速度越快,但如果此時正好有人在訪問這些slave,可能造成讀取失敗,影響面會更廣。最保定的設置為1,只同一時間,只能有一臺干這件事,這樣其它slave還能繼續服務,但是所有slave全部完成緩存更新同步的進程將變慢。 sentinel parallel-syncs mymaster 2 # 8. 主數據庫密碼,需要將配置放在sentinel monitor master 127.0.0.1 6379 1下面 sentinel auth-pass mymaster 1234567892、重新啟動:
# 啟動需要按照Master->Slave->Sentinel的順序進行啟動? 啟動redis? # 啟動redis哨兵 默認端口(26379) redis-sentinel?sentinel.conf java識別主從: private static JedisSentinelPool jedisSentinelPool = null;public static Jedis getJedisFromSentinel() {if (jedisSentinelPool == null) {Set<String> sentinelSet = new HashSet<>();sentinelSet.add("redisIp:26379");JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(10); //最大可用連接數:jedisPoolConfig.setMaxIdle(5); //最大閑置連接數jedisPoolConfig.setMinIdle(5); //最小閑置連接數。jedisPoolConfig.setBlockWhenExhausted(true);//連接耗盡是否等待jedisPoolConfig.setMaxWaitMillis(2000); //等待時間:jedisPoolConfig.setTestOnBorrow(true); //取連接的時候進行一下測試 pingjedisSentinelPool = new JedisSentinelPool("mymaster", sentinelSet, jedisPoolConfig);return jedisSentinelPool.getResource();} }集群(cluster):(無中心化集群,任何一個節點都可以作為集群入口?)
解決問題:
容量擴容(分布式存儲數據,啟動n個節點,每個節點存儲數據的1/n ,通過計算key所在的插槽-CRC16(key)%集群插槽總數,每個集群節點處理其中一部分的插槽)
并發寫操作,分攤壓力
?配置:
1、redis.conf
# 打開集群模式 cluster-enabled yes # 設置節點配置文件名 cluster-config-file nodes-6379.conf # 設定節點失聯時間,超過該時間(毫秒),集群自動進行主從切換 cluster-node-timeout 150002、啟動redis
啟動完成后會生成節點對應的nodes-6379.conf文件3、節點合并為集群(自動選擇主和從)
$ cd redis安裝包(不是安裝目錄)/src #?執行命令 redis-cli --cluster create --cluster-replicas 1 [以最簡單的方式配置集群,一主一從,三個節點] 節點1ip:端口?節點2ip:端口?節點3ip:端口 ... #?分配原則,盡量保證每個主節點分配在不同ip上,每個主庫和從庫分配在不同的ip上?4、連接
# 普通連接
$ redis-cli -p 6379
#?集群連接
$ redis-cli -c -p 6379[任何一個節點都可]
> cluster nodes? # 查看集群節點信息
5、集群操作
#?查詢key的插槽值
> cluster keyslot keyName
#?計算插槽值中有幾個key
> cluster countkeysinslot 12709[數值]
#?返回插槽中符合key的10個值
> cluster getkeysinslot 12709 10?
6、故障恢復?
- 節點主機掛掉后,從機代替主機,重啟主機,主機變為從機
- 如果所有某一段插槽的主從節點都宕掉,redis 服務是否還能繼續?
?7、集群jedis開發
public static void main(String[] args) {
????Set<HostAndPort>set =new HashSet<HostAndPort>();
????set.add(new HostAndPort("192.168.0.101",6379));
????JedisCluster jedisCluster = new JedisCluster(set);
????jedisCluster.set("k1", "v1");
????System.out,println(jedisCluster.get("k1"));
}
8、集群操作的不足?
-
多鍵操作是不被支持的。
-
多鍵的 Redis 事務是不被支持的。lua腳本不被支持。
-
由于集群方案出現較晚,很多公司已經采用了其他的集群方案,而代理或者客戶端分片的方案想要遷移至 redis cluster,需要整體遷移而不是逐步過渡,復雜度較大。
總結
以上是生活随笔為你收集整理的Redis主从、哨兵及集群搭建的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux ssh图形化
- 下一篇: 面试:KOOM内存泄漏的监控