1.什么是集群
所謂的集群,就是通過增加服務器的數量,提供相同的服務,從而讓服務器達到一個穩定、高效的狀態,2.使用redis集群的必要性
單個redis存在不穩定性,當redis服務宕機了,就沒有可用的服務了,而且單個redis的讀寫能力是有限的,使用redis集群可以強化redis的讀寫能力,并且當一臺服務器宕機了,其他服務器還能正常作業,不影響使用3.redis集群
1.redis集群中,每一個redis稱之為一個節點, 2.redis集群中,有兩種型別的節點:主節點(master)、從節點(slave), 3.redis集群,是基于redis主從復制實作,4.redis主從復制
4.1 概念
主從復制模型中,有多個redis節點, 其中,有且僅有一個為主節點Master,從節點Slave可以有多個,只要網路連接正常,Master會一直將自己的資料更新同步給Slaves,保持主從同步,4.2 特點
1.主節點Master可讀、可寫. 2.從節點Slave只讀,(read-only) 因此,主從模型可以提高讀的能力,在一定程度上緩解了寫的能力,因為能寫仍然只有Master節點一個,可以將讀的操作全部移交到從節點上,變相提高了寫能力,4.3 配置
建議克隆一個虛擬機,再進行配置4.3.1 需求
配置主節點:6380 配置從節點(兩個):6381、63824.3.2 配置步驟
1.在/usr/local目錄下,創建一個/redis/master-slave目錄mkdir -p redis/master-slave
2.在master-slave目錄下,創建三個子目錄6380、6381、6382
mkdir 6380 6381 63823.依次拷貝redis解壓目錄下的redis.conf組態檔,到這三個子目錄中
cp -v /opt/soft/redis-3.2.9/redis.conf ./6380 cp -v /opt/soft/redis-3.2.9/redis.conf ./6381 cp -v /opt/soft/redis-3.2.9/redis.conf ./63824.進入6380目錄,修改redis.conf,將port埠修改成6380即可,
4.3.3 測驗
1.打開三個xshell視窗,在每一個視窗中,啟動一個redis節點,查看日志輸出,(不要改成后臺模式啟動,看不到日志,不直觀)cd 6380 && redis-server ./redis.conf cd 6381 && redis-server ./redis.conf cd 6382 && redis-server ./redis.conf2.另外再打開三個xshell視窗,在每一個視窗中,登陸一個redis節點
redis-cli -p 6380 redis-cli -p 6381 redis-cli -p 6382
3.在主節點6380上,進行讀寫操作,操作成功
5.Sentinel哨兵模式
5.1 主從模式的缺陷
當主節點宕機了,整個集群就沒有可寫的節點了, 由于從節點上備份了主節點的所有資料,那在主節點宕機的情況下,如果能夠將從節點變成一個主節點,就可以解決這個問題了,這就是Sentinel哨兵的作用,5.2 哨兵的任務
Redis 的 Sentinel 系統用于管理多個 Redis 服務器(instance), 該系統執行以下三個任務: 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常, 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程式發送通知, 自動故障遷移(Automatic failover): 當一個主服務器不能正常作業時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 并讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端回傳新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器,5.2.1 監控(Monitoring)
1.Sentinel可以監控任意多個Master和該Master下的Slaves,(即多個主從模式) 2.同一個哨兵下的、不同主從模型,彼此之間相互獨立, 3.Sentinel會不斷檢查Master和Slaves是否正常,5.2.2 自動故障切換(Automatic failover)
5.2.2.1 Sentinel網路
監控同一個Master的Sentinel會自動連接,組成一個分布式的Sentinel網路,互相通信并交換彼此關于被監視服務器的資訊,下圖中,三個監控s1的Sentinel,自動組成Sentinel網路結構,5.2.2.2 故障切換的程序
1.投票(半數原則) 當任何一個Sentinel發現被監控的Master下線時,會通知其它的Sentinel開會,投票確定該Master是否下線(半數以上,所以sentinel通常配奇數個并且至少3個), 2.選舉 當Sentinel確定Master下線后,會在所有的Slaves中,選舉一個新的節點,升級成Master節點, 其它Slaves節點,轉為該節點的從節點, 投票:5.3 哨兵模式部署
5.3.1 需求
前提:已經存在一個正在運行的主從模式, 另外,配置三個Sentinel實體,監控同一個Master節點,5.3.2 配置Sentinel
1.在/usr/local目錄下,創建/redis/sentinels/目錄mkdir -p sentinels2.在/sentinels目錄下,以次創建s1、s2、s3三個子目錄中
mkdir s1 s2 s33.依次拷貝redis解壓目錄下的sentinel.conf檔案,到這三個子目錄中
4.依次修改s1、s2、s3子目錄中的sentinel.conf檔案,修改埠,并指定要監控的主節點,(從節點不需要指定,sentinel會自動識別) S1哨兵配置如下:
cp -v /opt/soft/redis-3.2.9/sentinel.conf ./s1 cp -v /opt/soft/redis-3.2.9/sentinel.conf ./s2 cp -v /opt/soft/redis-3.2.9/sentinel.conf ./s3
redis-sentinel ./s1/sentinel.conf redis-sentinel ./s2/sentinel.conf redis-sentinel ./s3/sentinel.conf
核心日志輸出(部署成功):
5.3.3 測驗
1.先關閉6380節點,發現,確實重新指定了一個主節點 查看服務:ps -aux|grep redis6.Redis-cluster集群
6.1 哨兵模式的缺陷
在哨兵模式中,仍然只有一個Master節點,當并發寫請求較大時,哨兵模式并不能緩解寫壓力, 只有主節點才具有寫能力,那如果在一個集群中,能夠配置多個主節點,就可以緩解寫壓力了,這就是redis-cluster集群模式,6.2 Redis-cluster集群概念
1.由多個Redis服務器組成的分布式網路服務集群; 2.集群之中有多個Master主節點,每一個主節點都可讀可寫; 3.節點之間會互相通信,兩兩相連; 4.Redis集群無中心節點,6.3集群節點復制
6.4 故障轉移
Redis集群的主節點內置了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當集群中的某個主節點下線時,集群中的其他在線主節點會注意到這一點,并對已下線的主節點進行故障轉移,6.5 集群分片策略
Redis-cluster分片策略,是用來解決key存盤位置的, 集群將整個資料庫分為16384個槽位slot,所有key-value資料都存盤在這些slot中的某一個上,一個slot槽位可以存放多個資料,key的槽位計算公式為:slot_number=crc16(key)%16384,其中crc16為16位的回圈冗余校驗和函式, 集群中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,集群進入上線狀態,并開始處理客戶端發送的資料命令請求,6.6 集群redirect轉向
由于Redis集群無中心節點,請求會隨機發給任意主節點,主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會回傳客戶端一個轉向錯誤,客戶端根據錯誤中包含的地址和埠重新向正確的負責的主節點發起命令請求,6.7 集群搭建
6.7.1準備作業
1.安裝ruby環境 redis集群管理工具redis-trib.rb依賴ruby環境,首先需要安裝ruby環境
yum -y install ruby yum -y install rubygems
2.安裝ruby和redis的介面程式 拷貝redis-3.0.0.gem至/usr/local下,執行安裝:
gem install /usr/local/redis-3.0.0.gem
6.7.2 集群規劃
1.Redis集群最少需要6個節點,可以分布在一臺或者多臺主機上, 本次搭建在一臺主機上創建偽分布式集群,不同的埠表示不同的redis節點,如下: 主節點:192.168.56.3:7001 192.168.56.3:7002 192.168.56.3:7003 從節點:192.168.56.3:7004 192.168.56.3:7005 192.168.56.3:7006 2.在/usr/local/redis下創建redis-cluster目錄,在其下創建7001、7002......7006目錄,如下:3.將redis解壓路徑下的組態檔redis.conf,依次拷貝到每個700X目錄內,并修改每個700X目錄下的redis.conf組態檔: 必選配置: port 700X bind ip(當前主機ip:192.168.xxx.xxx) cluster-enabled yes (啟動redis-cluster集群模式) 建議配置: daemonized yes logfile /usr/local/redis/redis-cluster/700X/node.log
mkdir -p redis/redis-cluster mkdir -v 7001 7002 7003 7004 7005 7006
6.7.3 啟動每個結點redis服務
依次以700X下的redis.conf,啟動redis節點,(必須指定redis.conf檔案)cd 700x && redis-server ./redis.conf
6.7.4 執行創建集群命令
進入到redis原始碼存放目錄redis/redis-4.10.3/src下,執行redis-trib.rb,此腳本是ruby腳本,它依賴ruby環境,
./redis-trib.rb create --replicas 1 192.168.192.128:7001 192.168.192.128:7002 192.168.192.128:7003 192.168.192.128:7004 192.168.192.128:7005 192.168.192.128:7006
其中--replicas 1 表示為每個主節點創建1個子節點 創建程序如下:
6.7.5 查詢集群資訊
集群創建成功登陸任意redis結點查詢集群中的節點情況,./redis-cli -c -h ip -p 埠說明: -c表示以集群方式連接redis, -h指定ip地址, -p指定埠號
6.8 集群管理
6.8.1添加主節點
6.8.1.1節點規劃
集群創建成功后可以向集群中添加節點,下面是添加一個master主節點, 添加7007節點,參考6.7.2 集群結點規劃添加一個“7007”目錄作為新節點, 集群添加節點命令:./redis-trib.rb add-node 新節點ip:埠 集群中任意節點ip:埠./redis-trib.rb add-node 192.168.23.3:7007 192.168.23.3:7001
查看集群結點發現7007已添加到集群中
6.8.1.2 hash槽重新分配
添加完新的主節點后,需要對主節點進行hash槽分配,這樣該主節才可以存盤資料, redis集群有16384個槽,被所有的主節點共同分配,通過查看集群結點可以看到槽占用情況, 給剛添加的7007結點分配槽: 第一步:連接上集群./redis-trib.rb reshard 192.168.192.128:7001(連接集群中任意一個可用節點都行)第二步:輸入要分配的槽數量
6.8.2 添加從節點
集群創建成功后可以向集群中添加節點,下面是添加一個slave從節點, 添加7008從結點,將7008作為7007的從結點, 新增從節點命令格式: ./redis-trib.rb add-node --slave --master-id masterID newNodIP:port MasterIP:port masterID 主節點id,從cluster nodes資訊中查看 newNodIP:port 新增節點的ip:埠 MasterIP:port 主節點的ip:埠 注意: 如果原來該結點在集群中的配置資訊已經生成cluster-config-file指定的組態檔中(如果cluster-config-file沒有指定則默認為nodes.conf),這時可能會報錯: [ERR] Node XXXXXX is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0 解決方法:洗掉生成的組態檔nodes.conf,洗掉后再執行./redis-trib.rb add-node指令,6.8.3 洗掉結點:
洗掉節點命令格式:./redis-trib.rb del-node nodeIP:port nodeID nodeIP:port 待洗掉節點的ip:埠 nodeID 待洗掉節點的id,從cluster node中查看 注意,洗掉已經占有hash槽的結點會失敗,報錯如下:7. java程式連接redis集群
7.1 連接步驟
第一步:創建專案,匯入jar包
package com.gjs.jedis.test; import java.util.HashSet; import java.util.Set; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; public class TestJedisCluster { public static void main(String[] args) { //創建jedidsCluster客戶端 //創建一個set集合,用來封裝所有redis節點的資訊 Set<HostAndPort> nodes = new HashSet<HostAndPort>(); nodes.add(new HostAndPort("192.168.192.128", 7001)); nodes.add(new HostAndPort("192.168.192.128", 7002)); nodes.add(new HostAndPort("192.168.192.128", 7003)); nodes.add(new HostAndPort("192.168.192.128", 7004)); nodes.add(new HostAndPort("192.168.192.128", 7005)); nodes.add(new HostAndPort("192.168.192.128", 7006)); JedisCluster jedis = new JedisCluster(nodes); jedis.set("name", "zhangsan"); System.out.println("姓名:"+jedis.get("name")); jedis.close(); } }
7.2 注意事項:
連接Redis集群時,需要修改防火墻,開放每一個redis節點的埠, 編輯防火墻組態檔 vi /etc/sysconfig/iptables轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/338903.html
標籤:Java
