簡介:
java
redis-cluster是redis自帶的分佈式集羣模式,其原理是將幾套redis實例的存儲空間劃分紅總共16384個hash數據槽,而後經過crc16算法計算key的名字得出一個hash值,把數據存儲到相應的數據槽上.若是數據分佈足夠平均,就能夠充分利用每一套redis實例來分散負載,從而達到高性能的目的,相反則會出現熱點區間,出現木桶短板原則限制.node
優勢:搭建簡單,自帶高可用,性能提升明顯,相比其餘集羣模式延時影響較低,支持redis原始命令.redis
缺點:擴容/縮容不方便,客戶端鏈接模式須要修改,容易出現熱點區間問題,至少須要3組redis實例搭建.算法
搭建:vim
首先,要搭建3組redis主從實例,由於這是redis-cluster要求的最少配置,搭建redis主備的方法就不說了,這個能夠看我以前的文章,這裏只強調須要額外配置的特殊配置.安全
#bind的IP必須是0.0.0.0,不能是*,否則會連不上 bind 0.0.0.0 #端口要儘可能注意區分,避免衝突 port 7001 #cluster啓動開關,這裏要啓用,固然是yes cluster-enabled yes #節點配置文件,有別於redis-server啓動文件redis.conf,須要額外存在別的地方 cluster-config-file /data/redis/data/config/rc4_7001/nodes_7001.conf #集羣節點超時檢測時間,若是超過這個時間沒有迴應,就認爲對方掛了,視網絡狀態設定 cluster-node-timeout 15000 #不能設定密碼,requirepass和masterauth都必須爲空
注意:不能設置密碼的緣由是由於搭建集羣的redis-trib.rb腳本中鏈接Redis的代碼裏面,並未設定密碼的參數,若是設定了密碼,在搭建的時候會報錯:[ERR] Sorry, can’t connect to node *.*.*.*:7001
ruby
因此須要密碼的話就要後期搭建完畢後才能修改密碼.固然,也能夠修改redis-trib.rb代碼來解決,不過這個不是這裏重點,先忽略一下,暫時只按默認方式來搭建,修改redis-trib.rb的代碼則在下面再講解.bash
注意2:安裝redis-cluster是不須要額外安裝sentinel哨兵的,高可用管理方式由集羣內部管理.
服務器
而後,搭建完3組redis以後,就要安裝一個ruby組件,這個組件是負責把集羣內部的機器互相聯通,並劃分16384數據槽位到對應的節點,網絡
#先安裝依賴環境 yum install -y ruby zlib-devel zlib #下載redis-cluster安裝組件,redis-3.3.5.gem版本能夠支持到redis5.0 wget http://rubygems.org/downloads/redis-3.3.5.gem #安裝組件 gem install redis-3.3.5.gem
再而後,這個時候咱們就能夠安裝redis-cluster了,
#在3.0/3.2/4.0安裝包的src目錄都自帶一個redis-trib.rb腳本,就是用來安裝redis-cluster的,上面說了這個腳本不能帶密碼 /opt/redis-4.0.14/src/redis-trib.rb create --replicas 1 172.25.100.11:7001 172.25.100.11:7002 172.25.100.15:7003 172.25.100.15:7004 172.25.100.17:7005 172.25.100.17:7006 #在5.0以後,安裝redis-cluster不須要那個腳本了,系統自帶redis-cli就有搭建集羣的功能,並且還能帶密碼了 redis-cli --cluster create 172.25.100.11:7001 172.25.100.11:7002 172.25.100.15:7003 172.25.100.15:7004 172.25.100.17:7005 172.25.100.17:7006 --cluster-replicas 1 -a password01!
注意:配置replicas 1的意思是有多少個從庫的意思,如今我搭建的redis實例只有一個從庫,因此就是1,若是是有2個從庫,那就是replicas 2,如此類推.
這個時候,若是是3.0/3.2/4.0的話,由於搭建的時候不能帶密碼,剛安裝完就確定是沒有密碼的狀態.因此就最好設個密碼(純內網能夠不用),由於不少例子證實,沒密碼的redis很容易被***,讓服務器變肉雞.例如我搭建的這個環境,由於一開始6臺所有都沒密碼,因此如今所有都要手動加密碼.
#先無密碼登陸 redis-cli -c -h 172.25.100.11 -p 7002 #設定主密碼,這個時候還能操做 config set masterauth rc_test_20210112 #設定客戶端密碼,這個時候就不能操做了 config set requirepass rc_test_20210112 #既然已經沒法操做了,須要用新密碼重新登陸 redis-cli -c -h 172.25.100.11 -p 7002 -a rc_test_20210112 #把修改的配置寫到配置文件 config rewrite
注意:鏈接redis-cluster必須加上-c參數,java客戶端則須要使用特定的集羣模式.
添加/刪除,新/舊節點:
在3.0/3.2/4.0版本,操做還須要圍繞redis-trib.rb腳本,在5.0以後,就能夠直接用redis-cli操做,
首先,假定咱們如今新建了兩個節點172.25.100.18:7007和172.25.100.18:7008,
#3.0/3.2/4.0版本添加爲主節點,不能帶密碼啊 redis-trib.rb add-node 172.25.100.18:7007 172.25.100.11:7001 #5.0版本以後添加爲主節點,能夠帶密碼了 redis-cli --cluster add-node 172.25.100.18:7007 172.25.100.11:7001 -a password01!
注意:add-node命令以後的172.25.100.18:7007爲須要新加的主節點,然後面的172.25.100.11:7001爲現存集羣的任意一個節點,
這個時候經過redis-cli命令登陸以後指令cluster nodes會發現能夠看到新節點了.可是尚未分配數據槽給新節點,致使新節點並不會有數據操做進去,在這一刻仍是沒有意義的,只是單純加了進去而已.
172.25.100.17:7006> CLUSTER NODES 653f26b0d647d6954c3151b60a0db5201b3e9afc 172.25.100.15:7003@17003 master - 0 1611215106400 3 connected 5461-10922 e28a4244cc0e3ca74d973e57b1e5c4d93cd230b1 172.25.100.17:7005@17005 master - 0 1611215105397 5 connected 10923-16383 acb57a858ddf4979da12e125cdf94fb13e19674c 172.25.100.17:7006@17006 myself,slave 653f26b0d647d6954c3151b60a0db5201b3e9afc 0 1611215104000 6 connected 132184b75bafe681869619bfb6df2b335f9e96b5 172.25.100.15:7004@17004 slave 7e4a0f849c1c383b9123d6f24bd1950cdc8b3ba3 0 1611215103393 4 connected 7e4a0f849c1c383b9123d6f24bd1950cdc8b3ba3 172.25.100.11:7001@17001 master - 0 1611215104000 1 connected 0-5460 2114ddc7d1355160a1703fb6992e1722983d3e4f 172.25.100.11:7002@17002 slave e28a4244cc0e3ca74d973e57b1e5c4d93cd230b1 0 1611215105000 5 connected 349a51df26f4723f14faba2a7fe3cad587659e86 172.25.100.18:7007@17007 master - 0 1611215104000 1 connected
因此,咱們第二部就是須要把數據槽分配給新節點,
#3.0/3.2/4.0版本須要手動添加,先用腳本指定集羣內部任意一個已分配數據槽的節點IP redis-trib.rb reshard 172.25.100.11:7001 #提示:你想遷移多少個數據槽,我這裏演示是4000個槽,因此填4000,而後按回車 How many slots do you want to move (from 1 to 16384)?4000 #提示:你想把這4000個槽分配給誰呢?那固然是新加的172.25.100.18:7007,可是這裏要填cluster nodes查出來的ID,而後按回車 What is the receiving node ID? 349a51df26f4723f14faba2a7fe3cad587659e86 #提示:你想從那個節點抽取這4000個槽,若是你填對應節點的ID則只從那個節點抽,若是你填all,就表明從全部的節點隨機抽過來 Source node #1: all #在5.0以後的版本,除了上面的手動分配方式,還支持自動分配,畢竟手動可能會有分配不合理的問題,其實自動更好. redis-cli --cluster rebalance --cluster-threshold 1 --cluster-use-empty-masters 172.25.100.11:7001 -a password01! #還能用check命令看看分配狀況 redis-cli --cluster check 172.25.100.11:7001 -a password01!
一頓操做以後,再cluster nodes看一下,你就會發現新節點分配了數據槽了,
349a51df26f4723f14faba2a7fe3cad587659e86 172.25.100.18:7007@17007 master - 0 1611215104000 1 connected 0-1000 6000-8000 10000-11000
這個時候,這個節點就會有數據操做,也就是真正添加完畢.
這個時候不由要問,這臺機只是主庫啊,尚未從庫,因此還須要把172.25.100.18:7008加進去
#3.0/3.2/4.0版本,把一個redis實例添加到集羣內部作其中一臺主庫的從庫 redis-trib.rb add-node --slave --master-id 349a51df26f4723f14faba2a7fe3cad587659e86 172.25.100.18:7008 172.25.100.11:7001 #5.0版本以後 redis-cli --cluster add-node --cluster-slave --cluster-master-id 349a51df26f4723f14faba2a7fe3cad587659e86 172.25.100.18:7008 172.25.100.11:7001 -a password01!
注意:
--slave 表示添加的是從節點
--master-id 349a51df26f4723f14faba2a7fe3cad587659e86 須要添加到的主節點的node id,咱們如今要添加的是7007的從庫,因此ID就是7007的ID了
172.25.100.18:7008 須要添加進去的,新的節點IP
172.25.100.11:7001 現存集羣的任意一個節點
由於添加slave不須要分配哈希槽,因此這樣就完事了
最後,咱們來談刪除節點,必需要理解的是,咱們刪除節點的前提是這個節點沒有數據,這樣才能安全刪除,因此咱們刪除節點以前,必需要遷移數據槽.還記得上面手動遷移數據槽嘛,如今再次操做一下.
#先刪除從庫 redis-trib.rb del-node 172.25.100.18:7008 c89856b99f08b02ecad68ce6e4ab92c9d989a177 #3.0/3.2/4.0版本,這個時候填的IP,就是要移除的主節點ip和端口號 redis-trib.rb reshard 172.25.100.18:7007 #要移除多少個數據槽,填的就是所有,也就是4000 How many slots do you want to move (from 1 to 16384)? 4000 #找誰接收這部分數據槽?隨便一個啦 What is the receiving node ID?e28a4244cc0e3ca74d973e57b1e5c4d93cd230b1 #被刪除master的node-id Source node #1:349a51df26f4723f14faba2a7fe3cad587659e86 #再次確認 Source node #2:done #就是執行這個reshard計劃的意思 Do you want to proceed with the proposed reshard plan (yes/no)? yes #這個時候,就能直接刪除了 redis-trib.rb del-node 172.25.100.18:7007 349a51df26f4723f14faba2a7fe3cad587659e86 #5.0以後 redis-cli --cluster del-node 172.25.100.18:7007 349a51df26f4723f14faba2a7fe3cad587659e86
這個時候,這個節點就不存在了,可是數據槽的分配勢必有些混亂,因此想要合理一些,還須要微調,這裏不展開說了.
redis cluster命令行
1.集羣(cluster)
CLUSTER INFO 打印集羣的信息
CLUSTER NODES 列出集羣當前已知的全部節點(node),以及這些節點的相關信息。
2.節點(node)
CLUSTER MEET 將 ip 和 port 所指定的節點添加到集羣當中,讓它成爲集羣的一份子。
CLUSTER FORGET 從集羣中移除 node_id 指定的節點。
CLUSTER REPLICATE 將當前節點設置爲 node_id 指定的節點的從節點。
CLUSTER SAVECONFIG 將節點的配置文件保存到硬盤裏面。
3.槽(slot)
CLUSTER ADDSLOTS [slot ...] 將一個或多個槽(slot)指派(assign)給當前節點。
CLUSTER DELSLOTS [slot ...] 移除一個或多個槽對當前節點的指派。
CLUSTER FLUSHSLOTS 移除指派給當前節點的全部槽,讓當前節點變成一個沒有指派任何槽的節點。
CLUSTER SETSLOT NODE 將槽 slot 指派給 node_id 指定的節點,若是槽已經指派給另外一個節點,那麼先讓另外一個節點刪除該槽>,而後再進行指派。
CLUSTER SETSLOT MIGRATING 將本節點的槽 slot 遷移到 node_id 指定的節點中。
CLUSTER SETSLOT IMPORTING 從 node_id 指定的節點中導入槽 slot 到本節點。
CLUSTER SETSLOT STABLE 取消對槽 slot 的導入(import)或者遷移(migrate)。
4.鍵 (key)
CLUSTER KEYSLOT 計算鍵 key 應該被放置在哪一個槽上。
CLUSTER COUNTKEYSINSLOT 返回槽 slot 目前包含的鍵值對數量。
CLUSTER GETKEYSINSLOT 返回 count 個 slot 槽中的鍵。
給redis-trib.rb添加密碼
上面提到了,redis-trib.rb腳本中鏈接Redis的代碼裏面,並未設定密碼的參數,形成使用不便,咱們能夠經過修改代碼實現帶密碼使用這個腳本,方法以下
#先打開這個腳本 vim /opt/redis-4.0.14/src/redis-trib.rb #找到對應函數connect的對應配置Redis.new,我這裏顯示是第99行代碼 def connect(o={}) return if @r print "Connecting to node #{self}: " if $verbose STDOUT.flush begin @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60) @r.ping rescue xputs "[ERR] Sorry, can't connect to node #{self}" exit 1 if o[:abort] @r = nil end xputs "OK" if $verbose end #而後修改爲 @r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60, :password => "你的密碼")
注意,這樣改代碼的密碼是固定的,也就是說在搭建集羣時,全部redis主從實例都要統一密碼.
而後,就能夠和上面同樣啓動
#雖然在這裏仍是看不到密碼,可是密碼已經寫入到redis-trib.rb腳本,也就是帶密碼了 /opt/redis-4.0.14/src/redis-trib.rb create --replicas 1 172.25.100.11:7001 172.25.100.11:7002 172.25.100.15:7003 172.25.100.15:7004 172.25.100.17:7005 172.25.100.17:7006
這樣就可使用了