Redis數據庫集羣node
Redis 集羣是一個分佈式(distributed)、容錯(fault-tolerant)的 Redis 實現, 集羣可使用的功能是普通單機 Redis 所能使用的功能的一個子集(subset),是一個能夠在多個 Redis 節點之間進行數據共享的設施(installation)。web
Redis 集羣中不存在中心(central)節點或者代理(proxy)節點, 集羣的其中一個主要設計目標是達到線性可擴展性(linear scalability)。redis
Redis 集羣不支持那些須要同時處理多個鍵的 Redis 命令, 由於執行這些命令須要在多個 Redis 節點之間移動數據, 而且在高負載的狀況下, 這些命令將下降 Redis 集羣的性能, 並致使不可預測的行爲。數據庫
Redis 集羣經過分區(partition)來提供必定程度的可用性(availability): 即便集羣中有一部分節點失效或者沒法進行通信, 集羣也能夠繼續處理命令請求。ruby
Redis 集羣提供瞭如下兩個好處:bash
q 將數據自動切分(split)到多個節點的能力。網絡
q 當集羣中的一部分節點失效或者沒法進行通信時, 仍然能夠繼續處理命令請求的能力。app
Redis 集羣使用數據分片(sharding)而非一致性哈希(consistency hashing)來實現: 一個 Redis 集羣包含 16384 個哈希槽(hash slot), 數據庫中的每一個鍵都屬於這 16384 個哈希槽的其中一個, 集羣使用公式 CRC16(key)
%
16384 來計算鍵 key 屬於哪一個槽, 其中 CRC16(key) 語句用於計算鍵 key 的 CRC16 校驗和 。less
集羣中的每一個節點負責處理一部分哈希槽。 舉個例子, 一個集羣能夠有三個哈希槽, 其中:異步
節點 A 負責處理 0 號至 5500 號哈希槽。
節點 B 負責處理 5501 號至 11000 號哈希槽。
節點 C 負責處理 11001 號至 16384 號哈希槽。
這種將哈希槽分佈到不一樣節點的作法使得用戶能夠很容易地向集羣中添加或者刪除節點。 好比說,若是用戶將新節點 D 添加到集羣中, 那麼集羣只須要將節點 A 、B 、 C 中的某些槽移動到節點 D 就能夠了。與此相似, 若是用戶要從集羣中移除節點 A , 那麼集羣只須要將節點 A 中的全部哈希槽移動到節點 B 和節點 C , 而後再移除空白(不包含任何哈希槽)的節點 A 就能夠了。
由於將一個哈希槽從一個節點移動到另外一個節點不會形成節點阻塞, 因此不管是添加新節點仍是移除已存在節點, 又或者改變某個節點包含的哈希槽數量, 都不會形成集羣下線。
爲了使得集羣在一部分節點下線或者沒法與集羣的大多數(majority)節點進行通信的狀況下, 仍然能夠正常運做, Redis 集羣對節點使用了主從複製功能: 集羣中的每一個節點都有 1 個至 N 個複製品(replica), 其中一個複製品爲主節點(master), 而其他的 N-1 個複製品爲從節點(slave)。
在以前列舉的節點 A 、B 、C 的例子中, 若是節點 B 下線了, 那麼集羣將沒法正常運行, 由於集羣找不到節點來處理 5501 號至 11000號的哈希槽。
另外一方面, 假如在建立集羣的時候(或者至少在節點 B 下線以前), 咱們爲主節點 B 添加了從節點 B1 , 那麼當主節點 B 下線的時候, 集羣就會將 B1 設置爲新的主節點, 並讓它代替下線的主節點 B , 繼續處理 5501 號至 11000 號的哈希槽, 這樣集羣就不會由於主節點 B 的下線而沒法正常運做了。不過若是節點 B 和 B1 都下線的話, Redis 集羣仍是會中止運做。
Redis 集羣不保證數據的強一致性(strong consistency): 在特定條件下, Redis 集羣可能會丟失已經被執行過的寫命令。
使用異步複製(asynchronous replication)是 Redis 集羣可能會丟失寫命令的其中一個緣由。 考慮如下這個寫命令的例子:
1、客戶端向主節點 B 發送一條寫命令。
2、主節點 B 執行寫命令,並向客戶端返回命令回覆。
3、主節點 B 將剛剛執行的寫命令複製給它的從節點 B1 、 B2 和 B3 。
可見, 主節點對命令的複製工做發生在返回命令回覆以後, 由於若是每次處理命令請求都須要等待複製操做完成的話,那麼主節點處理命令請求的速度將極大地下降 —— 咱們必須在性能和一致性之間作出權衡。
Redis 集羣另一種可能會丟失命令的狀況是, 集羣出現網絡分裂(network partition), 而且一個客戶端與至少包括一個主節點在內的少數(minority)實例被孤立。舉個例子:
1、假設集羣包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點,其中 A 、B 、C 爲主節點,而 A1 、B1 、C1 分別爲三個主節點的從節點, 另外還有一個客戶端 Z1 。
2、假設集羣中發生網絡分裂, 那麼集羣可能會分裂爲兩方, 大多數(majority)的一方包含節點 A 、C 、A1 、B1 和 C1 , 而少數(minority)的一方則包含節點 B 和客戶端 Z1 。
3、在網絡分裂期間, 主節點 B 仍然會接受 Z1 發送的寫命令:
4、若是網絡分裂出現的時間很短, 那麼集羣會繼續正常運行;
5、可是, 若是網絡分裂出現的時間足夠長, 使得大多數一方將從節點 B1 設置爲新的主節點, 並使用 B1 來代替原來的主節點 B , 那麼 Z1 發送給主節點 B 的寫命令將丟失。
注意, 在網絡分裂出現期間, 客戶端 Z1 能夠向主節點 B 發送寫命令的最大時間是有限制的, 這一時間限制稱爲節點超時時間(node timeout), 是 Redis 集羣的一個重要的配置選項。
q 對於大多數一方來講, 若是一個主節點未能在節點超時時間所設定的時限內從新聯繫上集羣, 那麼集羣會將這個主節點視爲下線, 並使用從節點來代替這個主節點繼續工做。
q 對於少數一方, 若是一個主節點未能在節點超時時間所設定的時限內從新聯繫上集羣, 那麼它將中止處理寫命令, 並向客戶端報告錯誤。
Redis 集羣由多個運行在集羣模式(cluster mode)下的 Redis 實例組成, 實例的集羣模式須要經過配置來開啓, 開啓集羣模式的實例將可使用集羣特有的功能和命令。
如下是一個包含了最少選項的集羣配置文件示例:
port 7000 cluster-enabled yes #<==打開實例的集羣模式 cluster-config-file nodes.conf #<==設定保存節點的配置文件,無需人爲修改 cluster-node-timeout 5000 #<==集羣節點超時時間 appendonly yes
普通安裝過程與單節點一致,可用yum或者編譯的方式安裝,這裏再也不敘述。可是Redis集羣模式會使用到redis-trib工具,這是一個ruby語言的工具,所以須要事先安裝好ruby語言的執行環境。
yum -y install ruby ruby-devel rubygems rpm-build
再用 gem 這個命令來安裝 redis接口,gem是ruby的一個工具包.
gem install redis -v 3.2.1 1 gem installed Installing ri documentation for redis-3.2.1... Installing RDoc documentation for redis-3.2.1...
若是下載失敗的話,能夠去這個網址手動下載,再經過命令gem install命令手動安裝
https://rubygems.org/gems/redis/versions/3.2.1
本此實驗環境爲在單臺主機上啓動六個不一樣端口的實例,若是是分佈在不一樣的機器上,則不須要。
mkdir /opt/redis/cluster/{7000..7005} -p
將如下配置文件放入7000-7005六個目錄中,注意修改每一個目錄下面對應的端口號。
#<==在原默認配置上進行修改 bind 10.0.0.16 port 7000 pidfile /var/run/redis_7000.pid logfile "/opt/redis/cluster/7000/redis.log" daemonize yes appendonly yes dir /opt/redis/cluster/7000 #新增集羣的配置 cluster-enabled yes cluster-config-file /opt/redis/cluster/7000/nodes-7000.conf cluster-node-timeout 15000 protected-mode yes tcp-backlog 511 timeout 0 tcp-keepalive 300 supervised no loglevel notice databases 16 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes
分別啓動六個不一樣的實例:
./../../src/redis-server ../7000/redis.conf ./../../src/redis-server ../7001/redis.conf ./../../src/redis-server ../7002/redis.conf ./../../src/redis-server ../7003/redis.conf ./../../src/redis-server ../7004/redis.conf ./../../src/redis-server ../7005/redis.conf
查看實例運行狀況:
[root@test3 7000]# ps -ef |grep redis root 108314 1 0 20:53 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7000 [cluster] root 108322 1 0 20:54 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7001 [cluster] root 108324 1 0 20:54 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7002 [cluster] root 108328 1 0 20:54 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7003 [cluster] root 108330 1 0 20:54 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7004 [cluster] root 108332 1 0 20:54 ? 00:00:00 ./../../src/redis-server 10.0.0.16:7005 [cluster]
如今咱們已經有了六個正在運行中的 Redis 實例, 接下來咱們須要使用這些實例來建立集羣, 併爲每一個節點編寫配置文件。
經過使用 Redis 集羣命令行工具 redis-trib , 編寫節點配置文件的工做能夠很是容易地完成: redis-trib 位於 Redis 源碼的 src 文件夾中, 它是一個 Ruby 程序, 這個程序經過向實例發送特殊命令來完成建立新集羣, 檢查集羣, 或者對集羣進行從新分片(reshared)等工做。
集羣建立命令:
./../../src/redis-trib.rb create --replicas 1 10.0.0.16:7000 10.0.0.16:7001 10.0.0.16:7002 10.0.0.16:7003 10.0.0.16:7004 10.0.0.16:7005
q 命令的意義以下:
create : 這表示咱們但願建立一個新的集羣。
--replicas 1 : 表示咱們但願爲集羣中的每一個主節點建立一個從節點。
以後跟着的其餘參數則是實例的地址列表, 咱們但願程序使用這些地址所指示的實例來建立新集羣。簡單來講, 以上命令的意思就是讓 redis-trib 程序建立一個包含三個主節點和三個從節點的集羣。接着, redis-trib 會打印出一份預想中的配置給你看, 若是你以爲沒問題的話, 就能夠輸入 yes , redis-trib 就會將這份配置應用到集羣當中:
>>> Creating cluster >>> Performing hash slots allocation on 6 nodes... Using 3 masters: 10.0.0.16:7000 10.0.0.16:7001 10.0.0.16:7002 Adding replica 10.0.0.16:7003 to 10.0.0.16:7000 Adding replica 10.0.0.16:7004 to 10.0.0.16:7001 Adding replica 10.0.0.16:7005 to 10.0.0.16:7002 M: 62d87bd83fd636e6ba1fe031777178cce8f9f776 10.0.0.16:7000 slots:0-5460 (5461 slots) master M: ccc65af4a214689b15d0cfd9dea584d214a0c2ad 10.0.0.16:7001 slots:5461-10922 (5462 slots) master M: 2366c6765ecf21ee86b064376693ce59047478a5 10.0.0.16:7002 slots:10923-16383 (5461 slots) master S: 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 replicates 62d87bd83fd636e6ba1fe031777178cce8f9f776 S: 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 replicates ccc65af4a214689b15d0cfd9dea584d214a0c2ad S: 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 replicates 2366c6765ecf21ee86b064376693ce59047478a5 Can I set the above configuration? (type 'yes' to accept):yes #<==手動輸入yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join.. >>> Performing Cluster Check (using node 10.0.0.16:7000) M: 62d87bd83fd636e6ba1fe031777178cce8f9f776 10.0.0.16:7000 slots:0-5460 (5461 slots) master 1 additional replica(s) S: 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 slots: (0 slots) slave replicates 2366c6765ecf21ee86b064376693ce59047478a5 M: ccc65af4a214689b15d0cfd9dea584d214a0c2ad 10.0.0.16:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s) M: 2366c6765ecf21ee86b064376693ce59047478a5 10.0.0.16:7002 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 slots: (0 slots) slave replicates ccc65af4a214689b15d0cfd9dea584d214a0c2ad S: 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 slots: (0 slots) slave replicates 62d87bd83fd636e6ba1fe031777178cce8f9f776 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. #<==這表示集羣中的 16384個槽都有至少一個主節點在處理, 集羣運做正常。
新集羣建立完畢!!!
q redis-rb-cluster
是antirez編寫的 Ruby 實現, 用於做爲其餘實現的參考。 該實現是對 redis-rb 的一個簡單包裝, 高效地實現了與集羣進行通信所需的最少語義(semantic)。
q redis-py-cluster
看上去是 redis-rb-cluster 的一個 Python 版本, 這個項目有一段時間沒有更新了, 不過能夠將這個項目用做學習集羣的起點。
q Predis
流行的 Predis 曾經對早期的 Redis 集羣有過必定的支持, 但不肯定它對如今集羣的支持是否完整, 也不清楚它是否和最新版本的 Redis 集羣兼容 (由於新版的 Redis 集羣將槽的數量從 4k 改成 16k 了)。
q redis-cli
Redis unstable 分支中的 redis-cli 程序實現了很是基本的集羣支持,因此它老是依靠 Redis 集羣節點來將它轉向(redirect)至正確的節點。
使用 redis-cli 爲例來進行演示:
10.0.0.16:7000> set foo bar -> Redirected to slot [12182] located at 10.0.0.16:7002 OK 10.0.0.16:7002> set hello world -> Redirected to slot [866] located at 10.0.0.16:7000 OK 10.0.0.16:7000> get foo -> Redirected to slot [12182] located at 10.0.0.16:7002 "bar" 10.0.0.16:7002> get hello -> Redirected to slot [866] located at 10.0.0.16:7000 "world" 10.0.0.16:7000>
從新分片操做基本上就是將某些節點上的哈希槽移動到另一些節點上面, 和建立集羣同樣, 從新分片也可使用 redis-trib 程序來執行。
原hash槽分配:
10.0.0.16:7000---- 0-5460
10.0.0.16:7001---- 5461-10922
10.0.0.16:7002---- 10923-16383
q 執行如下命令能夠開始一次從新分片操做:
./redis-trib.rb reshard 10.0.0.16:7000
你只須要指定集羣中其中一個節點的地址, redis-trib 就會自動找到集羣中的其餘節點。目前 redis-trib 只能在管理員的協助下完成從新分片的工做, 要讓 redis-trib 自動將哈希槽從一個節點移動到另外一個節點, 目前來講還作不到。
q 設定打算移動哈希槽的數量
執行 redis-trib 的第一步就是設定你打算移動的哈希槽的數量:
>>> Performing Cluster Check (using node 10.0.0.16:7000) M: 62d87bd83fd636e6ba1fe031777178cce8f9f776 10.0.0.16:7000 slots:0-5460 (5461 slots) master 1 additional replica(s) S: 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 slots: (0 slots) slave replicates 2366c6765ecf21ee86b064376693ce59047478a5 M: ccc65af4a214689b15d0cfd9dea584d214a0c2ad 10.0.0.16:7001 slots:5461-10922 (5462 slots) master 1 additional replica(s) M: 2366c6765ecf21ee86b064376693ce59047478a5 10.0.0.16:7002 slots:10923-16383 (5461 slots) master 1 additional replica(s) S: 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 slots: (0 slots) slave replicates ccc65af4a214689b15d0cfd9dea584d214a0c2ad S: 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 slots: (0 slots) slave replicates 62d87bd83fd636e6ba1fe031777178cce8f9f776 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)? 1000 #<==移動1000個hash槽
q 設置目標ID
除了移動的哈希槽數量以外, redis-trib 還須要知道從新分片的目標(target node), 也就是負責接收這 1000 個哈希槽的節點。
指定目標須要使用節點的 ID , 而不是 IP 地址和端口。 好比說, 咱們打算使用集羣的第一個主節點來做爲目標, 它的 IP 地址和端口是 10.0.0.16:7001 , 而節點 ID 則是62d87bd83fd636e6ba1fe031777178cce8f9f776 , 那麼咱們應該向 redis-trib 提供節點的 ID :
How many slots do you want to move (from 1 to 16384)? 1000 What is the receiving node ID? 62d87bd83fd636e6ba1fe031777178cce8f9f776
q 設置源節點
接下來, redis-trib 會向你詢問從新分片的源節點(source node),也就是要從哪一個節點中取出 1000 個哈希槽, 並將這些槽移動到目標節點上面。若是咱們不打算從特定的節點上取出指定數量的哈希槽,那麼能夠向 redis-trib 輸入 all ,這樣的話,集羣中的全部主節點都會成爲源節點, redis-trib 將從各個源節點中各取出一部分哈希槽, 湊夠 1000 個, 而後移動到目標節點上面:
What is the receiving node ID? 62d87bd83fd636e6ba1fe031777178cce8f9f776 Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:all #<==這裏能夠選擇all或者具體節點ID回車再輸入done來指定具體節點,能夠用來清除主節點的solt。
輸入 all 並按下回車以後, redis-trib 將打印出哈希槽的移動計劃, 若是你以爲沒問題的話, 就能夠輸入 yes 並再次按下回車:
...... Moving slot 11420 from 2366c6765ecf21ee86b064376693ce59047478a5 Moving slot 11421 from 2366c6765ecf21ee86b064376693ce59047478a5 Do you want to proceed with the proposed reshard plan (yes/no)? yes
輸入 yes 並使用按下回車以後, redis-trib 就會正式開始執行從新分片操做, 將指定的哈希槽從源節點一個個地移動到目標節點上面。
q 從新檢查集羣狀態
[root@test3 src]# ./redis-trib.rb check 10.0.0.16:7000 >>> Performing Cluster Check (using node 10.0.0.16:7000) M: 62d87bd83fd636e6ba1fe031777178cce8f9f776 10.0.0.16:7000 slots:0-5961,10923-11421 (6461 slots) master 1 additional replica(s) S: 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 slots: (0 slots) slave replicates 2366c6765ecf21ee86b064376693ce59047478a5 M: ccc65af4a214689b15d0cfd9dea584d214a0c2ad 10.0.0.16:7001 slots:5962-10922 (4961 slots) master 1 additional replica(s) M: 2366c6765ecf21ee86b064376693ce59047478a5 10.0.0.16:7002 slots:11422-16383 (4962 slots) master 1 additional replica(s) S: 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 slots: (0 slots) slave replicates ccc65af4a214689b15d0cfd9dea584d214a0c2ad S: 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 slots: (0 slots) slave replicates 62d87bd83fd636e6ba1fe031777178cce8f9f776 [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
須要注意的就是, 在三個主節點中, 節點 127.0.0.1:7000 包含了 6461 個哈希槽, 而節點 127.0.0.1:7001 和節點 127.0.0.1:7002 都只包含了 4961 個哈希槽, 由於後二者都將本身的 500 個哈希槽移動到了節點 127.0.0.1:7000 。
根據新添加節點的種類, 咱們須要用兩種方法來將新節點添加到集羣裏面:
q 若是要添加的新節點是一個主節點, 那麼咱們須要建立一個空節點(empty node), 而後將某些哈希槽移動到這個空節點裏面。
q 若是要添加的新節點是一個從節點, 那麼咱們須要將這個新節點設置爲集羣中某個節點的複製品(replica)。
同理,再啓動一個新的7006端口的Redis節點,過程見redis(一)、入門。
執行如下命令, 將這個新節點添加到集羣裏面:
./redis-trib.rb add-node 10.0.0.16:7006 10.0.0.16:7000
命令中的 add-node 表示咱們要讓 redis-trib 將一個節點添加到集羣裏面, add-node 以後跟着的是新節點的 IP 地址和端口號, 再以後跟着的是集羣中任意一個已存在節點的 IP 地址和端口號, 這裏咱們使用的是 10.0.0.16:7000 。
經過 cluster nodes 命令, 咱們能夠確認新節點 10.0.0.16:7006 已經被添加到集羣裏面了:
[root@test3 cluster]# redis-cli -c -h 10.0.0.16 -p 7000 cluster nodes 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 slave 2366c6765ecf21ee86b064376693ce59047478a5 0 1523112658032 6 connected ccc65af4a214689b15d0cfd9dea584d214a0c2ad 10.0.0.16:7001 master - 0 1523112656012 8 connected 0-565 5962-10922 11422-11855 2366c6765ecf21ee86b064376693ce59047478a5 10.0.0.16:7002 master - 0 1523112651972 3 connected 11856-16383 62d87bd83fd636e6ba1fe031777178cce8f9f776 10.0.0.16:7000 myself,master - 0 0 7 connected 566-5961 10923-11421 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 slave ccc65af4a214689b15d0cfd9dea584d214a0c2ad 0 1523112655003 8 connected 96fdc35b69c4f0929ba9ba5550a5fca8f3b0b514 10.0.0.16:7006 master - 0 1523112657022 0 connected 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 slave 62d87bd83fd636e6ba1fe031777178cce8f9f776 0 1523112652982 7 connected
新節點如今已經鏈接上了集羣, 成爲集羣的一份子, 而且能夠對客戶端的命令請求進行轉向了, 可是和其餘主節點相比, 新節點還有兩點區別:
1、新節點沒有包含任何數據, 由於它沒有包含任何哈希槽。
2、儘管新節點沒有包含任何哈希槽, 但它仍然是一個主節點, 因此在集羣須要將某個從節點升級爲新的主節點時, 這個新節點不會被選中。
當把節點添加進集羣的時候,已經默認設置爲主節點了,只是該節點沒有數據而已。這時只須要咱們將哈希槽移動到新的節點裏面,新節點就會成爲真正的主節點了。
詳細過程見第六章。
使用客戶端鏈接上新節點,並運行以下命令:
[root@test3 cluster]# redis-cli -c -h 10.0.0.16 -p 7006 10.0.0.16:7006> cluster replicate 62d87bd83fd636e6ba1fe031777178cce8f9f776 OK 10.0.0.16:7006>
注:以上這條命令也適合於隨時修改從節點的master。
q 一步到位法:
redis-trib.rb add-node --slave --master-id 62d87bd83fd636e6ba1fe031777178cce8f9f77 10.0.0.16:7006 10.0.0.16:7000 --slave:表示添加的是從節點 --master-id 62d87bd83fd636e6ba1fe031777178cce8f9f77:主節點的node id 10.0.0.16:7006:新的節點 10.0.0.16:7000:任何一個集羣中的舊節點
查看是否設置成功:
[root@test3 cluster]# redis-cli -c -h 10.0.0.16 -p 7000 cluster nodes | grep slave 287a24936fa3c0c29ce33d768921769cf1969115 10.0.0.16:7005 slave 2366c6765ecf21ee86b064376693ce59047478a5 0 1523113268561 6 connected 60c3b5d3c1a53328046b627bd015da99e30436c0 10.0.0.16:7004 slave ccc65af4a214689b15d0cfd9dea584d214a0c2ad 0 1523113270579 8 connected 96fdc35b69c4f0929ba9ba5550a5fca8f3b0b514 10.0.0.16:7006 slave 62d87bd83fd636e6ba1fe031777178cce8f9f776 0 1523113269569 9 connected 19920c1ccf4be5849a1fca5d5f41643a3598cfcc 10.0.0.16:7003 slave 62d87bd83fd636e6ba1fe031777178cce8f9f776 0 1523113267550 7 connected #<==能夠看出新節點已經成爲slave了
執行以下命令,將節點移出集羣:
/opt/redis/src/redis-trib.rb del-node 10.0.0.16:7006 '96fdc35b69c4f0929ba9ba5550a5fca8f3b0b514'
q 若是主節點有從節點,先將從節點移到其餘主節點
10.0.0.16:7006> cluster replicate 62d87bd83fd636e6ba1fe031777178cce8f9f776
q 若是主節點有solt,去掉分配的solt
詳細過程見第6章,只須要把all替換爲需刪除的主節點便可。
q 刪除主節點
/opt/redis/src/redis-trib.rb del-node 10.0.0.16:7006 '96fdc35b69c4f0929ba9ba5550a5fca8f3b0b514'
//集羣(cluster) CLUSTER INFO #<==打印集羣的信息 CLUSTER NODES #<==列出集羣當前已知的全部節點(node),以及這些節點的相關信息。 //節點(node) CLUSTER MEET <ip> <port> #<==將ip和port所指定的節點添加到集羣當中,讓它成爲集羣的一份子。 CLUSTER FORGET <node_id> #<==從集羣中移除node_id指定的節點。 CLUSTER REPLICATE <node_id> #<==將當前節點設置爲node_id指定的節點的從節點。 CLUSTER SAVECONFIG #<==將節點的配置文件保存到硬盤裏面。 //槽(slot) CLUSTER ADDSLOTS <slot> [slot ...] #<==將一個或多個槽(slot)指派(assign)給當前節點。 CLUSTER DELSLOTS <slot> [slot ...] #<==移除一個或多個槽對當前節點的指派。 CLUSTER FLUSHSLOTS #<==移除指派給當前節點的全部槽,讓當前節點變成一個沒有指派任何槽的節點。 CLUSTER SETSLOT <slot> NODE <node_id> #<==將槽slot指派給node_id指定的節點,若是槽已經指派給另外一個節點,那麼先讓另外一個節點刪除該槽,而後再進行指派。 CLUSTER SETSLOT <slot> MIGRATING <node_id> #<==將本節點的槽 slot 遷移到 node_id 指定的節點中。 CLUSTER SETSLOT <slot> IMPORTING <node_id> #<==從 node_id 指定的節點中導入槽 slot 到本節點。 CLUSTER SETSLOT <slot> STABLE #<==取消對槽 slot 的導入(import)或者遷移(migrate)。 //鍵 (key) CLUSTER KEYSLOT <key> #<==計算鍵 key 應該被放置在哪一個槽上。 CLUSTER COUNTKEYSINSLOT <slot> #<==回槽slot目前包含的鍵值對數量。 CLUSTER GETKEYSINSLOT <slot> <count> #<==返回count個slot槽中的鍵。