您好,登錄后才能下訂單哦!
redis-cluster的安裝管理
環境介紹
系統環境:Red Hat Enterprise Linux Server release 6.2 (Santiago)
內核版本:Linux zxt-02.com 2.6.32-220.el6.x86_64 #1 SMP Wed Nov 9 08:03:13 EST 2011 x86_64 x86_64 x86_64 GNU/Linux
軟件版本:redis-3.0.5
主機名:redis-01.com、redis-02.com
主機IP:192.168.1.193 192.168.1.176
安裝所需軟件環境:
Zlib、ruby(必須1.9.2以上)、rubygem、gem-redis
注:在閱讀文本文檔之前需要讀者知道的是本文檔以及目前網絡上的大部分相近的文檔都來源于http://redis.io。如果您的英文閱讀能較好的話建議您閱讀Reis官方文檔。http://redis.io/topics/cluster-spec
http://redis.io/topics/cluster-tutorial
Redis 集群是一個可以在多個Redis 節點之間進行數據共享的設施(installation)。Redis 集群不支持那些需要同時處理多個鍵的Redis 命令,因為執行這些命令需要在多個Redis 節點之間移動數據,并且在高負載的情況下,這些命令將降低Redis 集群的性能,并導致不可預測的行為。
Redis 集群通過分區(partition)來提供一定程度的可用性(availability):即使集群中有一部分節點失效或者無法進行通訊,集群也可以繼續處理命令請求。
Redis 集群提供了以下兩個好處:
? 將數據自動切分(split)到多個節點的能力。
? 當集群中的一部分節點失效或者無法進行通訊時,仍然可以繼續處理命令請求的能力
Redis 集群沒有使用一致性hash, 而是引入了哈希槽的概念.
Redis 集群有16384個哈希槽,每個key通過CRC16校驗后對16384取模來決定放置哪個槽.集群的每個節點負責一部分hash槽,舉個例子,比如當前集群有3個節點,那么:
l 節點 A 包含 0 到 5500號哈希槽
l 節點 B 包含5501 到 11000 號哈希槽.
l 節點 C 包含11001 到 16384號哈希槽.
這種結構很容易添加或者刪除節點. 比如如果我想新添加個節點D, 我需要從節點 A, B, C中得部分槽到D上. 如果我像移除節點A,需要將A中得槽移到B和C節點上,然后將沒有任何槽的A節點從集群中移除即可.
由于從一個節點將哈希槽移動到另一個節點并不會停止服務,所以無論添加刪除或者改變某個節點的哈希槽的數量都不會造成集群不可用的狀態.
為了使在部分節點失敗或者大部分節點無法通信的情況下集群仍然可用,所以集群使用了主從復制模型,每個節點都會有N-1個復制品.
在我們例子中具有A,B,C三個節點的集群,在沒有復制模型的情況下,如果節點B失敗了,那么整個集群就會以為缺少5501-11000這個范圍的槽而不可用.
然而如果在集群創建的時候(或者過一段時間)我們為每個節點添加一個從節點A1,B1,C1,那么整個集群便有三個master節點和三個slave節點組成,這樣在節點B失敗后,集群便會選舉B1為新的主節點繼續服務,整個集群便不會因為槽找不到而不可用了
不過當B和B1 都失敗后,集群是不可用的.
Redis 并不能保證數據的強一致性. 這意味這在實際中集群在特定的條件下可能會丟失寫操作.
第一個原因是因為集群是用了異步復制. 寫操作過程:
客戶端向主節點B寫入一條命令.
主節點B向客戶端回復命令狀態.
主節點將寫操作復制給他得從節點 B1, B2 和 B3.
主節點對命令的復制工作發生在返回命令回復之后, 因為如果每次處理命令請求都需要等待復制操作完成的話, 那么主節點處理命令請求的速度將極大地降低 —— 我們必須在性能和一致性之間做出權衡。
注意:Redis 集群可能會在將來提供同步寫的方法。
Redis 集群另外一種可能會丟失命令的情況是集群出現了網絡分區, 并且一個客戶端與至少包括一個主節點在內的少數實例被孤立。.
舉個例子 假設集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六個節點, 其中 A 、B 、C 為主節點, A1 、B1 、C1 為A,B,C的從節點, 還有一個客戶端 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
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
想要運行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
# 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
安裝運行redis集群所必需的redis和ruby的接口。
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 --remove https://rubygems.org/ gem sources -a http://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/
https://ruby.taobao.org 國內應該找個比較靠譜了,適合安裝大多數常見的gem
tar xzf redis-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-server、redis-cli、redis-benchmark、redis-check-aof 、redis-check-dump,它們的作用如下:
redis-server:Redis服務器的daemon啟動程序
redis-cli:Redis命令行操作工具。也可以用telnet根據其純文本協議來操作
redis-benchmark:Redis性能測試工具,測試Redis在當前系統下的讀寫性能
redis-check-aof:數據修復
redis-check-dump:檢查導出工具
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-error yes #后臺存儲錯誤停止寫。 rdbcompression yes #存儲至本地數據庫時(持久化到dump.rdb文件)是否壓縮數據,默認為 yes rdbchecksum yes #是否校驗rdb文件. dbfilename dump_6379.rdb #本地持久化數據庫文件名,默認值為 dump.rdb dir /opt/redis/data #數據庫鏡像備份的文件放置的路徑。 #slaveof <masterip> <masterport> #設置該數據庫為其他數據庫的從數據庫時啟用該參數。 #masterauth <master-password> #slave服務連接master的密碼 slave-serve-stale-data yes slave-read-only yes #slave只讀 repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 #requirepass foobared #設置客戶端連接密碼 appendonly yes #打開aof持久化 appendfilename "appendonly_6379.aof" #aof文件名,默認為appendonly.aof appendfsync everysec #每秒一次aof寫 no-appendfsync-on-rewrite yes #關閉在aof rewrite的時候對新的寫操作進行fsync auto-aof-rewrite-percentage 100 #部署在同一機器的redis實例,把auto-aof-rewrite搓開,因為cluster環境下內存占用基本一致. #防止同一機器下瞬間fork所有redis進程做aof rewrite,占用大量內存(ps:cluster必須開啟aof) auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 cluster-enabled yes #打開redis集群 cluster-config-file nodes-6379.conf #集群節點配置文件(啟動自動生成) cluster-node-timeout 15000 #節點互連超時的閥值 cluster-migration-barrier 1 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-entries 512 list-max-ziplist-value 64 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
注意:其他節點只需要復制配置文件將所有端口號更改即可。
192.1.168.1.193 cd /opt/redis redis-server redis_6379.conf redis-server redis_6479.conf redis-server redis_6579.conf 192.1.168.1.193 cd /opt/redis redis-server redis_6379.conf redis-server redis_6479.conf redis-server redis_6579.conf
啟動之后使用netstat –lntp 命令查看端口是否別監聽,如圖所示則啟動正常。
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:6379 192.168.1.193:6479 192.168.1.193:6579
注:
#redis-trib.rb的create子命令構建
#--replicas 則指定了為Redis Cluster中的每個Master節點配備幾個Slave節點
#節點角色由順序決定,先master之后是slave(為方便辨認,slave的端口比master大1000)
#redis-trib.rb 的check子命令 #ip:port可以是集群的任意節點 redis-trib.rb check 192.168.1.193:6379
最后輸出如下信息,沒有任何警告或錯誤(如圖),表示集群啟動成功并處于ok狀態
創建一個空節點(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.rb add-node 192.168.1.187:6379 192.168.1.193:6379 add-node 將一個節點添加到集群里面, 第一個是新節點ip:port, 第二個是任意一個已存在節點ip:port
注意:在添加新節點時,新節點中不能包含任何數據,否則會添加失敗。
因為它沒有包含任何哈希插槽。新加入的加點是一個主節點,當集群需要將某個從節點升級為新的主節點時, 這個新節點不會被選中,同時新的主節點因為沒有包含任何哈希插槽,不參加選舉和failover。
d)、手動為新節點添加哈希插槽:
redis-trib.rb reshard 192.168.1.187:6379 #根據提示選擇要遷移的哈希插槽數量 How many slots do you want to move (from 1 to 16384)? 1000
#選擇要接受這些哈希插槽的node-id What is the receiving node ID? 36c46361327dbb15d098a0c3794ac3d72869e508
#選擇哈希插槽來源: #all表示從所有的master重新分配, #或者數據要提取哈希插槽的master節點id,最后用done結束 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
#打印被移動的哈希插槽后,輸入yes開始移動哈希插槽以及對應的數據. #Do you want to proceed with the proposed reshard plan (yes/no)? yes
#結束
可以使用命令查看對比哈希槽的分配情況(如圖)
redis-trib.rb check 192.168.1.176:6379
至此,一個新的主節點就添加完成了,執行命令查看現在的集群中節點的狀態
redis-trib.rb check 192.168.1.176:6379 redis-cli -c -p 6379 cluster nodes
a):前三步操作同添加master一樣
注意:新添加的節點群集默認分配為master但是節點沒有分配任何插槽(如圖)
b)第四步:redis-cli連接上新節點shell,輸入命令:cluster replicate 對應master的node-id(這里我們輸入節點192.168.1.187:6379的id)。
redis-cli -h 192.168.1.187 -p 6479 cluster replicate 36c46361327dbb15d098a0c3794ac3d72869e508 exit
也可通過查看集群狀態確定是否添加成功
注意:在線添加slave 時,需要bgsave整個master數據,并傳遞到slave,再由 slave加載rdb文件到內存,rdb生成和傳輸的過程中消耗Master大量內存和網絡IO,以此不建議單實例內存過大,線上小心操作。
法一: #redis-trib del-node ip:port '<node-id>' redis-trib.rb del-node 192.168.1.187:6479 4655fccff00ef4a7b99c10ffd590c8328ec6db8d
法二:
直接停止或kill掉 節點即可 Redis-cli –p 6479 shutdown or kill -9 `cat /opt/redis/run/redis_6479.pid`
a):刪除master節點之前首先要使用reshard移除master的全部slot,然后再刪除當前節點
#把192.168.1.187:6379當前master遷移到192.168.1.176:6579上 redis-trib.rb reshard 192.168.1.176:6579 #根據提示選擇要遷移的哈希插槽數量 How many slots do you want to move (from 1 to 16384)? 1000 (被刪除master的所有哈希插槽數量) #選擇要接受這些哈希插槽的192.168.1.176:6579 What is the receiving node ID? e1c06dd4682a37eb6773d6cb1d5709034a3f2769(ps: 192.168.1.176:6579的node-id) 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 #36c46361327dbb15d098a0c3794ac3d72869e508 (被刪除master的node-id) Source node #2:done
#打印被移動的哈希插槽后,輸入yes開始移動哈希插槽以及對應的數據. #Do you want to proceed with the proposed reshard plan (yes/no)? yes
b):刪除空master節點
redis-trib.rb del-node 192.168.1.187:6379 '36c46361327dbb15d098a0c3794ac3d72869e508'
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。