PHP7新特性及優化
阿新 • • 發佈:2021-10-15
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-slave2.在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 ./6382
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節點
3.在主節點6380上,進行讀寫操作,操作成功 4.在從節點6381上 讀操作執行成功,並且成功從6380上同步了資料;寫操作執行失敗。(從節點,只能讀,不能寫)
redis-cli -p 6380 redis-cli -p 6381 redis-cli -p 6382
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網路結構。 為什麼要使用sentinel網路呢? 當只有一個sentinel的時候,如果這個sentinel掛掉了,那麼就無法實現自動故障切換了。在sentinel網路中,只要還有一個sentinel活著,就可以實現故障切換。5.2.2.2 故障切換的過程
1.投票(半數原則) 當任何一個Sentinel發現被監控的Master下線時,會通知其它的Sentinel開會,投票確定該Master是否下線(半數以上,所以sentinel通常配奇數個並且至少3個)。 2.選舉 當Sentinel確定Master下線後,會在所有的Slaves中,選舉一個新的節點,升級成Master節點。 其它Slaves節點,轉為該節點的從節點。 投票: 選舉: 3.原Master重新上線 當原Master節點重新上線後,自動轉為當前Master節點的從節點。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哨兵配置如下: S2哨兵配置如下: S3哨兵配置如下: 5.再開啟三個xshell視窗,在每一個視窗中,啟動一個哨兵例項,並觀察日誌輸出
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 redis 關閉服務:kill -9 1841 2.再次上線6380節點。發現,6380節點成為了新的主節點的從節點 5.3.4 結論 Sentinel哨兵模式,確實能實現自動故障切換。提供穩定的服務。 5.3.5 注意事項 如果哨兵和redis節點不在同一臺伺服器上,需要注意IP繫結的問題。 1.主從模型,所有的節點,使用ip繫結 2.所有的哨兵,也都使用ip去繫結主機 3.所有的哨兵,都是通過主節點的ip,去監控主從模型6.Redis-cluster叢集
6.1 哨兵模式的缺陷
在哨兵模式中,仍然只有一個Master節點。當併發寫請求較大時,哨兵模式並不能緩解寫壓力。 只有主節點才具有寫能力,那如果在一個叢集中,能夠配置多個主節點,就可以緩解寫壓力了,這就是redis-cluster叢集模式。6.2 Redis-cluster叢集概念
1.由多個Redis伺服器組成的分散式網路服務叢集; 2.叢集之中有多個Master主節點,每一個主節點都可讀可寫; 3.節點之間會互相通訊,兩兩相連; 4.Redis叢集無中心節點。6.3叢集節點複製
在Redis-Cluster叢集中,可以給每一個主節點新增從節點,主節點和從節點直接遵循主從模型的特性。當用戶需要處理更多讀請求的時候,新增從節點可以擴充套件系統的讀效能。6.4 故障轉移
Redis叢集的主節點內建了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當叢集中的某個主節點下線時,叢集中的其他線上主節點會注意到這一點,並對已下線的主節點進行故障轉移。 叢集進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在叢集裡面,故障轉移是由叢集中其他線上的主節點負責進行的,所以叢集不必另外使用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環境2.安裝ruby和redis的介面程式 拷貝redis-3.0.0.gem至/usr/local下,執行安裝:
yum -y install ruby yum -y install rubygems
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環境。其中--replicas 1 表示為每個主節點建立1個子節點 建立過程如下:
./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
6.7.5 查詢叢集資訊
叢集建立成功登陸任意redis結點查詢叢集中的節點情況。./redis-cli -c -h ip -p 埠說明: -c表示以叢集方式連線redis, -h指定ip地址, -p指定埠號 cluster nodes 查詢叢集結點資訊; cluster info 查詢叢集狀態信。
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(連線叢集中任意一個可用節點都行)第二步:輸入要分配的槽數量 第三步:輸入接收槽的節點id 第四步:輸入源節點id 這裡輸入all,表示從所有其它主節點中分配。 第五步:輸入yes開始移動槽到目標結點id
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槽的結點會失敗,報錯如下: 需要將該結點佔用的hash槽分配出去(參考6.8.1.2 hash槽重新分配)。7. java程式連線redis叢集
7.1 連線步驟
第一步:建立專案,匯入jar包 第二步:建立redis叢集的客戶端 根據叢集redirect轉向的原理(詳見6.6 叢集redirect轉向),我們在建立redis叢集的客戶端時需要配置所有redis叢集的節點,使客戶端可以找到負責處理對應槽位命令的主節點
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(); } }