redis-cluster的安裝管理

redis-cluster的安裝管理

 

聲明:

本文只允許用於個人學習交流使用,如有錯誤之處請多多指正。

文檔版本:Version 1.0

修改記錄:2015-10-30


環境介紹

系統環境:RedHat Enterprise Linux Server release 6.2 (Santiago)

內核版本:Linuxzxt-02.com 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64x86_64 x86_64 GNU/Linux

軟件版本:redis-3.0.5

主機名:redis-01.comredis-02.com

主機IP192.168.1.193 192.168.1.176

安裝所需軟件環境:

Zlibruby(必須1.9.2以上)、rubygemgem-redis

注:在閱讀文本文檔之前需要讀者知道的是本文檔以及目前網絡上的大部分相近的文檔都來源於http://redis.io。如果您的英文閱讀能較好的話建議您閱讀Reis官方文檔。http://redis.io/topics/cluster-spec

http://redis.io/topics/cluster-tutorial

redis-cluster簡介:

Redis 集羣是一個可以在多個Redis節點之間進行數據共享的設施(installation)。Redis 集羣不支持那些需要同時處理多個鍵的Redis 命令,因爲執行這些命令需要在多個Redis 節點之間移動數據,並且在高負載的情況下,這些命令將降低Redis 集羣的性能,並導致不可預測的行爲。

Redis 集羣通過分區(partition)來提供一定程度的可用性(availability):即使集羣中有一部分節點失效或者無法進行通訊,集羣也可以繼續處理命令請求。

Redis集羣提供了以下兩個好處:

將數據自動切分(split)到多個節點的能力。

當集羣中的一部分節點失效或者無法進行通訊時,仍然可以繼續處理命令請求的能力

Redis 集羣的數據分片

Redis 集羣沒有使用一致性hash,而是引入了哈希槽的概念.

Redis 集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽.集羣的每個節點負責一部分hash,舉個例子,比如當前集羣有3個節點,那麼:

  • 節點 A 包含 0 5500號哈希槽

  • 節點 B 包含5501 11000 號哈希槽.

  • 節點 C 包含11001 16384號哈希槽.

這種結構很容易添加或者刪除節點. 比如如果我想新添加個節點D,我需要從節點 A, B, C中得部分槽到D. 如果我像移除節點A,需要將A中得槽移到BC節點上,然後將沒有任何槽的A節點從集羣中移除即可.

由於從一個節點將哈希槽移動到另一個節點並不會停止服務,所以無論添加刪除或者改變某個節點的哈希槽的數量都不會造成集羣不可用的狀態.

Redis 集羣的主從複製模型

爲了使在部分節點失敗或者大部分節點無法通信的情況下集羣仍然可用,所以集羣使用了主從複製模型,每個節點都會有N-1個複製品.

在我們例子中具有ABC三個節點的集羣,在沒有複製模型的情況下,如果節點B失敗了,那麼整個集羣就會以爲缺少5501-11000這個範圍的槽而不可用.

然而如果在集羣創建的時候(或者過一段時間)我們爲每個節點添加一個從節點A1B1C1,那麼整個集羣便有三個master節點和三個slave節點組成,這樣在節點B失敗後,集羣便會選舉B1爲新的主節點繼續服務,整個集羣便不會因爲槽找不到而不可用了

不過當BB1 都失敗後,集羣是不可用的.

Redis 一致性保證

Redis 並不能保證數據的強一致性.這意味這在實際中集羣在特定的條件下可能會丟失寫操作.

第一個原因是因爲集羣是用了異步複製. 寫操作過程:

    客戶端向主節點B寫入一條命令.

    主節點B向客戶端回覆命令狀態.

    主節點將寫操作複製給他得從節點 B1,B2 B3.

 

主節點對命令的複製工作發生在返回命令回覆之後, 因爲如果每次處理命令請求都需要等待複製操作完成的話, 那麼主節點處理命令請求的速度將極大地降低 —— 我們必須在性能和一致性之間做出權衡。

 

注意:Redis 集羣可能會在將來提供同步寫的方法。

Redis 集羣另外一種可能會丟失命令的情況是集羣出現了網絡分區, 並且一個客戶端與至少包括一個主節點在內的少數實例被孤立。.

 

舉個例子 假設集羣包含 A B C A1 B1 C1 六個節點, 其中 A B C 爲主節點, A1 B1 C1 ABC的從節點, 還有一個客戶端 Z1

 

假設集羣中發生網絡分區,那麼集羣可能會分爲兩方,大部分的一方包含節點 A C A1 B1 C1 ,小部分的一方則包含節點 B 和客戶端 Z1 .

 

Z1仍然能夠向主節點B中寫入, 如果網絡分區發生時間較短,那麼集羣將會繼續正常運作,如果分區的時間足夠讓大部分的一方將B1選舉爲新的master,那麼Z1寫入B中得數據便丟失了.

 

注意, 在網絡分裂出現期間, 客戶端 Z1 可以向主節點 B 發送寫命令的最大時間是有限制的, 這一時間限制稱爲節點超時時間(node timeout), Redis 集羣的一個重要的配置選項:

部署環境

redis-cluster要求最少需要3個節點,由於測試環境我這裏使用兩臺虛擬機安裝多個節點來模擬redis集羣。

主機節點分配:

node1    192.168.1.193:6379

node2    192.168.1.193:6479

node3    192.168.1.193:6579

備機節點:

node1    192.168.1.176:6379

node2    192.168.1.176:6479

node3    192.168.1.176:6579     

安裝redis cluste及依賴軟件:

1)   安裝zlib軟件;

Zlib軟件可以根據心情選擇yum安裝或者編譯安裝

Yum安裝

[zxt@redis-01 ~]$ yum install -y zlib*
[zxt@redis-01 ~]$ rpm -qa |grep zlib 
zlib-1.2.3-27.el6.x86_64
zlib-devel-1.2.3-27.el6.x86_64


 編譯安裝:

#download:  http://www.zlib.net/
tar zxf  zlib-1.2.7.tar.gz
cd zlib 
./configure  
make  
make install


2)   安裝ruby: version(1.9.2)

想要運行Redis cluter必須安裝ruby並需安裝1.9.2及以上版本。此處不要使用yum安裝,因爲RedHat6.2系統yum安裝默認版本爲1.8.7

#ruby-2.1.7.tar.gz  
tar   zxvf  ruby-2.1.7.tar.gz
cd  ruby-2.1.7
./configure -prefix=/usr/local/ruby  
make  
make install  
cp ruby /usr/local/bin


3)   安裝rubygem:version(1.8.5)

# rubygems-1.8.5.tgz  
tar zxvf  rubygems-1.8.5.tgz
cd rubygems-1.8.5
ruby setup.rb  
cp bin/gem /usr/local/bin

4)   安裝gem-redis:version(3.0.5)

安裝運行redis集羣所必需的redisruby的接口。

gem install redis --version 3.0.5

 

#由於某些原因,gem源不能訪問或者可能下載失敗可能下載失敗,以下提供兩種解決方案:

法一:手動下載下來安裝 

#download地址:
http://rubygems.org/gems/redis/versions/3.0.0  
gem install -l /soft/redis-3.0.5.gem


法二:更換gem 源

gem sources --removehttps://rubygems.org/
gem sources -ahttp://ruby.sdutlinux.org/
gem sources -l
*** CURRENT SOURCES***
https://ruby.taobao.org

常用的源

http://rubygems.org/
http://gems.github.com
http://gems.rubyforge.org
http://ruby.sdutlinux.org/
  #國內應該找個比較靠譜了,適合安裝大多數常見的gem

5)   安裝redis

tar xzfredis-3.0.5.tar.gz
cp  -r redis-3.0.5  /opt/app/
ln -s /opt/app/redis-3.0.5/   /opt/redis
cd  /opt/redis
make test
make
make install

說明:

make install命令執行完成後,會在/usr/local/bin目錄下生成本個可執行文件,分別是redis-serverredis-cliredis-benchmarkredis-check-aof redis-check-dump,它們的作用如下:

redis-serverRedis服務器的daemon啓動程序

redis-cliRedis命令行操作工具。也可以用telnet根據其純文本協議來操作

redis-benchmarkRedis性能測試工具,測試Redis在當前系統下的讀寫性能

redis-check-aof:數據修復

redis-check-dump:檢查導出工具

配置redis cluster

1)配置集羣初始化腳本:

cd /opt/redis 
cp/opt/redis/src/redis-trib.rb /usr/local/bin

2)配置redis cluster配置文件

daemonize yes
#以後臺進程redis運行.
pidfile/opt/redis/run/redis_6379.pid
#若以後臺進程運行Reids,則需指定pid文件及路徑.
port 6379
#指定redis監聽端口.
tcp-backlog 511
#在高併發的環境中,爲避免客戶端的連接緩慢問題.
bind 0.0.0.0
#綁定主機IP.(這裏設置爲4個0可以方便程序調用).
timeout 0
#客戶端連接時的超時時間,單位爲秒.
tcp-keepalive 60
#在 Linux 上,指定值(秒)用於發送 ACKs 的時間,注意關閉連接需要雙倍的時間.默認爲 0
loglevel notice
#日誌記錄等級,有4個可選值,debug,verbose(默認值),notice,warning
logfile"/var/log/redis/redis_6379.log"
#log 文件地址
databases 16
#可用數據庫數
save 900 1
save 300 10
save 60 10000
#根據給定的時間間隔和寫入次數將數據保存到磁盤,單位爲秒
stop-writes-on-bgsave-erroryes
#後臺存儲錯誤停止寫。
rdbcompression yes
#存儲至本地數據庫時(持久化到dump.rdb文件)是否壓縮數據,默認爲 yes
rdbchecksum yes
#是否校驗rdb文件.
dbfilenamedump_6379.rdb
#本地持久化數據庫文件名,默認值爲 dump.rdb
dir /opt/redis/data
#數據庫鏡像備份的文件放置的路徑。
#slaveof<masterip> <masterport>
#設置該數據庫爲其他數據庫的從數據庫時啓用該參數。
#masterauth<master-password>
#slave服務連接master的密碼
slave-serve-stale-datayes
slave-read-only yes
#slave只讀
repl-diskless-syncno
repl-diskless-sync-delay5
repl-disable-tcp-nodelayno
slave-priority 100
#requirepassfoobared
#設置客戶端連接密碼
appendonly yes
#打開aof持久化 
appendfilename"appendonly_6379.aof"
#aof文件名,默認爲appendonly.aof
appendfsync everysec
#每秒一次aof寫
no-appendfsync-on-rewriteyes
#關閉在aof rewrite的時候對新的寫操作進行fsync 
auto-aof-rewrite-percentage100
#部署在同一機器的redis實例,把auto-aof-rewrite搓開,因爲cluster環境下內存佔用基本一致. 
#防止同一機器下瞬間fork所有redis進程做aof rewrite,佔用大量內存(ps:cluster必須開啓aof)
auto-aof-rewrite-min-size64mb
aof-load-truncatedyes
lua-time-limit 5000
cluster-enabled yes
#打開redis集羣
cluster-config-filenodes-6379.conf
#集羣節點配置文件(啓動自動生成)
cluster-node-timeout15000
#節點互連超時的閥值 
cluster-migration-barrier1
slowlog-log-slower-than10000
slowlog-max-len 128
latency-monitor-threshold0
notify-keyspace-events""
hash-max-ziplist-entries512
hash-max-ziplist-value64
list-max-ziplist-entries512
list-max-ziplist-value64
set-max-intset-entries512
zset-max-ziplist-entries128
zset-max-ziplist-value64
hll-sparse-max-bytes3000
activerehashing yes
client-output-buffer-limitnormal 0 0 0
client-output-buffer-limitslave 256mb 64mb 60
client-output-buffer-limitpubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsyncyes

注意:其他節點只需要複製配置文件將所有端口號更改即可。

rediscluster運維操作

1、分別啓動這6redis實例節點

192.1.168.1.193
cd  /opt/redis
redis-serverredis_6379.conf
redis-serverredis_6479.conf
redis-serverredis_6579.conf
192.1.168.1.193
cd  /opt/redis
redis-serverredis_6379.conf
redis-serverredis_6479.conf
redis-serverredis_6579.conf

啓動之後使用netstat –lntp 命令查看端口是否監聽,如圖所示則啓動正常。

wKioL1kPJQ6hhUP3AABgm2c6RnI017.png-wh_50


2、使用自帶的redis-trib.rb構建集羣

redis-trib.rb create--replicas 1 192.168.1.193:6379 192.168.1.193:6479
192.168.1.193:6579 192.168.1.176:6379192.168.1.193:6479 192.168.1.193:6579

注:

#redis-trib.rbcreate子命令構建

#--replicas則指定了爲Redis Cluster中的每個Master節點配備幾個Slave節點 

#節點角色由順序決定,master之後是slave(爲方便辨認,slave的端口比master1000)

3、檢查集羣狀態

#redis-trib.rbcheck子命令

#ip:port可以是集羣的任意節點 

redis-trib.rb check 192.168.1.193:6379

最後輸出如下信息,沒有任何警告或錯誤(如圖),表示集羣啓動成功並處於ok狀態

wKiom1kPJYjQ5H-vAACqhKknIWo774.png-wh_50

4、添加新master節點

創建一個空節點(empty node),然後將某些哈希插槽移動到這個空節點上。

a)、創建新節點配置文件:

爲了方便區分我這裏再開啓一臺虛擬機增加一對節點:

192.168.1.187:6379

192.168.1.187:6479

cd /opt/redis
scp redis_6379.conf 192.168.1.187:/opt/redis/
cp redis_6379.conf   redis_6479.conf
sed –ie  s/6379/6479/g  redis_6479.conf


b)、啓動新節點:

      

 redis-server redis_6379.conf

c)、將新節點加入集羣:

redis-trib.rbadd-node 192.168.1.187:6379 192.168.1.193:6379

 

add-node  將一個節點添加到集羣裏面,第一個是新節點ip:port, 第二個是任意一個已存在節點ip:port

注意:在添加新節點時,新節點中不能包含任何數據,否則會添加失敗。

wKioL1kPJc7D3BXtAADGtqNg38A953.png-wh_50

wKioL1kPJc7SXOJ9AABJQd5KhA4174.png-wh_50

因爲它沒有包含任何哈希插槽。新加入的加點是一個主節點,當集羣需要將某個從節點升級爲新的主節點時,這個新節點不會被選中,同時新的主節點因爲沒有包含任何哈希插槽,不參加選舉和failover

d)、手動爲新節點添加哈希插槽:

  

redis-trib.rb reshard 192.168.1.187:6379

#根據提示選擇要遷移的哈希插槽數量 

How many slots do you want to move (from 1 to 16384)? 1000 

wKiom1kPJe7Q4YNNAADI8n-LDRI858.png-wh_50

#選擇要接受這些哈希插槽的node-id 

What is the receiving node ID? 36c46361327dbb15d098a0c3794ac3d72869e508

wKiom1kPJgOj0kG6AADWiB2N618684.png-wh_50

#選擇哈希插槽來源

#all表示從所有的master重新分配, 

#或者數據要提取哈希插槽的master節點id,最後用done結束 

 Please enter all the source node IDs. 

  Type 'all' to use all the nodes as sourcenodes for the hash slots. 

  Type 'done' once you entered all thesource nodes IDs. 

Source node #1:all 

wKioL1kPJvyR7zMQAACwUuokDPs779.png-wh_50

    #打印被移動的哈希插槽後,輸入yes開始移動哈希插槽以及對應的數據

#Do you want to proceed with the proposed reshard plan (yes/no)?yes 

wKioL1kPJjeA2CxmAAB4-L-MqJM805.png-wh_50

#結束 

可以使用命令查看對比哈希槽的分配情況(如圖)

redis-trib.rbcheck 192.168.1.176:6379

wKioL1kPJxrz1XSxAADRAQBri48772.png-wh_50

至此,一個新的主節點就添加完成了,執行命令查看現在的集羣中節點的狀態

redis-trib.rbcheck 192.168.1.176:6379
redis-cli-c -p 6379 cluster nodes

5、添加新slave節點

a):前三步操作同添加master一樣

注意:新添加的節點羣集默認分配爲master但是節點沒有分配任何插槽(如圖)

wKiom1kPJ1Tz7ZeRAAC_3N1dFGI245.png-wh_50

b)第四步:redis-cli連接上新節點shell,輸入命令:clusterreplicate 對應masternode-id(這裏我們輸入節點192.168.1.187:6379id)。

redis-cli  -h 192.168.1.187 -p 6479
clusterreplicate 36c46361327dbb15d098a0c3794ac3d72869e508 
exit

wKiom1kPJ46jydhkAACIHoP_i8k848.png-wh_50

也可通過查看集羣狀態確定是否添加成功

wKioL1kPJ-7AZN34AADJ7DyOCO8090.png-wh_50

注意:在線添加slave 時,需要bgsave整個master數據,並傳遞到slave,再由 slave加載rdb文件到內存,rdb生成和傳輸的過程中消耗Master大量內存和網絡IO,以此不建議單實例內存過大,線上小心操作。

5、刪除一個slave節點

法一:  

#redis-tribdel-node ip:port '<node-id>' 
redis-trib.rbdel-node  192.168.1.187:6479  4655fccff00ef4a7b99c10ffd590c8328ec6db8d

wKiom1kPKBXz8gVOAAAosoKMQE8623.png-wh_50

法二:直接停止或kill 節點即可

Redis-cli–p 6479 shutdown
or
kill-9  `cat /opt/redis/run/redis_6479.pid`

6、刪除一個master節點

a):刪除master節點之前首先要使用reshard移除master的全部slot,然後再刪除當前節點

#192.168.1.187:6379當前master遷移到192.168.1.176:6579

redis-trib.rbreshard 192.168.1.176:6579

#根據提示選擇要遷移的哈希插槽數量 

How manyslots do you want to move (from 1 to 16384)? 1000

(被刪除master的所有哈希插槽數量

#選擇要接受這些哈希插槽的192.168.1.176:6579

What isthe receiving node ID? e1c06dd4682a37eb6773d6cb1d5709034a3f2769(ps: 192.168.1.176:6579node-id) 

Pleaseenter 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. 

Sourcenode #36c46361327dbb15d098a0c3794ac3d72869e508 (被刪除masternode-id) 

Sourcenode #2:done 

wKioL1kPKCjBdVA_AACsWBwS3_o786.png-wh_50

#打印被移動的哈希插槽後,輸入yes開始移動哈希插槽以及對應的數據

#Do youwant to proceed with the proposed reshard plan (yes/no)? yes 

wKioL1kPKE_TfMNXAAAo6Yxn1z4708.png-wh_50

 

b):刪除空master節點

redis-trib.rbdel-node  192.168.1.187:6379 '36c46361327dbb15d098a0c3794ac3d72869e508'

三、redis cluste常用命令

1、查看集羣狀態

redis-trib.rbcheck 127.0.0.1:6379


2、查看集羣信息

redis-cli-c –p 6379 cluster nodes

3、查看集羣主從情況

redis-cli-c -p 6379 info Replication

4、查看集羣信息

redis-cli-c –p 6379 cluster info

附錄一:redis集羣常用命令系統管理相關指令簡介

集羣 

CLUSTER INFO 打印集羣的信息 

CLUSTER NODES 列出集羣當前已知的所有節點(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)。 

 

CLUSTER KEYSLOT <key> 計算鍵 key 應該被放置在哪個槽上。 

CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的鍵值對數量。 

CLUSTER GETKEYSINSLOT <slot><count> 返回 count slot 槽中的鍵。

參考資料與擴展知識:

http://hot66hot.iteye.com/blog/2050676/

Redis指令大全:

http://redis.io/commands

一個redis愛好者創建的相關問題討論網站:

http://www.rediscookbook.org/

 

爲什麼使用 Redis及其產品定位:

http://www.infoq.com/cn/articles/tq-why-choose-redis

 

Redis內存使用優化與存儲:

http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章