您好,登錄后才能下訂單哦!
一、Redis群集相關(guān)概念
Redis是從3.0版本開始支持cluter的,采用的是hash槽方式,可以將多個Redis實例整合在一起,形成一個群集,也就是將數(shù)據(jù)分散存儲到群集中的多個節(jié)點上。
Redis的cluster是一個無中心的結(jié)構(gòu),在群集中,每個master的身份是平等的,每個節(jié)點都保存數(shù)據(jù)和整個群集的狀態(tài),并且知道其他節(jié)點所負責的槽,也會定時發(fā)送心跳信息,能夠及時感知群集中異常的節(jié)點,并且采取投票的方式來決定該節(jié)點是否為不可用,若票數(shù)為群集中節(jié)點的半數(shù)以上,則認為該節(jié)點不可用,也正是因為此特點,所以要部署Redis群集,節(jié)點數(shù)量最少要三個及以上。
群集角色有master和slave,master之間分配slots(槽),槽點編號是0-16383(共16384個)。
默認情況下,每個群集節(jié)點有兩個TCP端口在監(jiān)聽,一個是6379(用于監(jiān)聽客戶端的訪問連接),另一個是16379(用于群集之間的節(jié)點通信)。注意,防火墻需要放行這兩個端口的流量。
Redis的所有數(shù)據(jù)都是保存在內(nèi)存中,然后不定期的通過異步方式保存到磁盤上(這稱為“半持久化模式”);也可以把每一次數(shù)據(jù)變化都寫入到一個append only file(aof)里面(這稱為“全持久化模式”)。
Redis提供的這兩種方式進行持久化,一種是RDB持久化(原理是將Redis在內(nèi)存中的數(shù)據(jù)庫定時記錄dump到磁盤上的RDB持久化),另一種是AOF(append only file)持久化(原理是將Redis的操作日志以追加的方式寫入文件)
RDB的優(yōu)點與缺點
RDB半持久化的優(yōu)點:
- 只包含一個文件,有利于文件備份;
- 災難恢復比aof持久化要快;
- 性能最大化。對于Redis的服務進程而言,在開始持久化時,它唯一需要做的只是fork出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執(zhí)行IO操作了。
- 相比較AOF機制,如果數(shù)據(jù)集過大,RDB的啟動效率會更高。
- RDB半持久化的缺點:
- 由于RDB是通過fork子進程來協(xié)助完成數(shù)據(jù)持久化工作的,因此,如果當數(shù)據(jù)集比較大時,可能會導致整個服務停止幾百毫秒,甚至是1秒鐘
AOF的優(yōu)點與缺點
AOF全持久化的優(yōu)點:
- 可以保證數(shù)據(jù)的高可用性;
- 寫入過程中及時出現(xiàn)宕機現(xiàn)象,也不會破壞日志文件中已經(jīng)存在的內(nèi)容,如果在寫入過程中宕機,重啟Redis后可以通過redis-check-aof工具來解決;
- 如果日志過大,Redis可以自動啟用rewrite機制,生成新的文件存儲aof日志;
- 該機制可以帶來更高的數(shù)據(jù)安全性,及數(shù)據(jù)持久性。Redis中提供了三種同步策略,即每秒同步、每修改同步和不同步。
- AOF全持久化的缺點:
- 對于相同數(shù)量的數(shù)據(jù)集而言,AOF文件通常要大于RDB文件。RDB在恢復大數(shù)據(jù)集時的速度比AOF的恢復速度要快;
- 根據(jù)同步策略的不同,AOF在運行效率上往往會慢于RDM,總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。
如果RDB和AOF同時存在,則優(yōu)先選擇AOF方式
二、部署Redis群集
1、環(huán)境如下:
總共六臺centos服務器,實現(xiàn)三臺master分別對應一臺slave
為了避免因為物理服務器的宕機而造成整個群集崩潰,也可以在一臺服務器上配置多個Redis實例,實現(xiàn)交叉主從復制,所謂交叉就是master在node01,但對應的slave在node02,node02上master對應的slave在node03,而node03對應的slave在node01
上述只是多個服務器部署Redis群集。
但我這里主要是在一臺服務器上部署多個節(jié)點,所以在node6上會有多個實例
配置前可先下載所需軟件包,也可自行下載準備,鏈接:https://pan.baidu.com/s/1mJGBD7b0QyR_II4mSpdD8Q
提取碼:72hi
2、配置Redis實例
這里以node01的配置進行示例,其他節(jié)點的配置和node1基本一樣
[root@node1 /]# mkdir redis # 個人習慣而已
[root@node1 /]# cd redis/
[root@node1 redis]# rz # 上傳所需軟件包
[root@node1 redis]# ls # node 節(jié)點只需要redis4.0這個包,其余兩個包是安裝ruby環(huán)境所需的
redis-3.3.0.gem redis-4.0.14.tar.gz ruby-2.3.1.tar.gz
[root@node1 redis]# tar zxf redis-4.0.14.tar.gz # 解包
[root@node1 redis]# mv redis-4.0.14 /usr/local/redis # 移動并改名
[root@node1 redis]# cd /usr/local/redis/ # 進入目錄
[root@node1 redis]# make && make install # 編譯并安裝
[root@node1 redis]# ./utils/install_server.sh # 對redis進行初始化
# 初始化的所有選項保持默認,一路回車確認即可,是在確認監(jiān)聽端口、配置文件、日志文件、pid存放Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
路徑等信息 # 當出現(xiàn)這些信息說明初始化成功
[root@node1 redis]# echo "512" > /proc/sys/net/core/somaxconn # 接下做一些優(yōu)化
[root@node1 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@node1 redis]# sysctl -p
vm.overcommit_memory = 1
[root@node1 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
[root@node1 redis]# vim /etc/redis/6379.conf # 編輯配置文件
bind 0.0.0.0 #找到?jīng)]有被注釋的這一行,修改為0.0.0.0
daemonize yes #若有注釋符號,需要刪除注釋符號,以便生效
cluster-enabled yes # 如有注釋,需要去掉注釋符號
cluster-node-timeout 5000 # 修改
appendonly yes # 改為 yes
[root@node1 redis]# /etc/init.d/redis_6379 restart # 重啟服務使配置生效
[root@node1 redis]# netstat -anput | grep 6379 # 確定已經(jīng)監(jiān)聽6379和16379兩個端口
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 44263/redis-server
tcp 0 0 0.0.0.0:16379 0.0.0.0:* LISTEN 44263/redis-server
在其他節(jié)點服務器上將上述配置依次進行即可,node6除外
3、配置node06主機的多Redis實例
node06這個節(jié)點上,我將配置其運行多個Redis數(shù)據(jù)庫實例,所以與前面五個節(jié)點的配置并不是完全一樣,小心配置
[root@node6 /]# mkdir redis
[root@node6 /]# cd redis/
[root@node6 redis]# rz
[root@node6 redis]# tar zxf redis-4.0.14.tar.gz
[root@node6 redis]# mv redis-4.0.14 /usr/local/redis
[root@node6 redis]# cd /usr/local/redis/
[root@node6 redis]# make && make install # 編譯并安裝,安裝完畢后無需初始化
[root@node6 redis]# redis-server # 執(zhí)行此命令啟動會出現(xiàn)3個警告,這三個警告就是我們需要優(yōu)化的三個選項
[root@node6 redis]# echo "512" > /proc/sys/net/core/somaxconn
[root@node6 redis]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@node6 redis]# sysctl -p
vm.overcommit_memory = 1
[root@node6 redis]# echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
[root@node6 redis]# vim redis.conf # 編輯配置文件
bind 0.0.0.0
port 7000 # redis的默認端口是6379,這里我修改為7000,為了方便識別
daemonize yes #開啟后臺守護進程,以便后臺運行
cluster-enabled yes #開啟群集
cluster-node-timeout 5000 #群集節(jié)點間的超時時間,單位是毫秒
appendonly yes #是否開啟同步到磁盤
appendfilename "appendonly-7000.aof" #aof日志的名字,因為本臺主機上擁有多個實例,所以各個端口是不一樣的,所以使用端口來命名日志名稱
[root@node6 redis]# mkdir -p /usr/local/redis-cluster/{7000..7004}
#以上是打算運行幾個Redis實例,就創(chuàng)建幾個目錄即可,這里我以實例的端口號給目錄命名(暫時打算運行4個Redis實例)
#以下是將修改后的配置文件復制到指定的目錄下一份
[root@node6 redis]# cp redis.conf /usr/local/redis-cluster/7000/
[root@node6 redis]# cp redis.conf /usr/local/redis-cluster/7001/
[root@node6 redis]# cp redis.conf /usr/local/redis-cluster/7002/
[root@node6 redis]# cp redis.conf /usr/local/redis-cluster/7003/
[root@node6 redis]# cp redis.conf /usr/local/redis-cluster/7004/
#然后下面將復制過去的各個配置文件中改為與Redis實例對應的端口號
[root@node6 redis]# cd /usr/local/redis-cluster/
[root@node6 redis-cluster]# ls
7000 7001 7002 7003 7004
[root@node6 redis-cluster]# sed -i s/7000/7001/g 7001/redis.conf
[root@node6 redis-cluster]# sed -i s/7000/7002/g 7002/redis.conf
[root@node6 redis-cluster]# sed -i s/7000/7003/g 7003/redis.conf
[root@node6 redis-cluster]# sed -i s/7000/7004/g 7004/redis.conf
[root@node6 redis-cluster]# cd 7000/ # 進入到7000實例目錄中
[root@node6 7000]# redis-server redis.conf # 啟動該實例
8142:C 13 Feb 10:44:17.501 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
8142:C 13 Feb 10:44:17.501 # Redis version=4.0.14, bits=64, commit=00000000, modified=0, pid=8142, just started
8142:C 13 Feb 10:44:17.501 # Configuration loaded
# 來就是依次進入到各個實例目錄中,啟動實例,這里我就不演示了
4、主機node01安裝配置ruby的運行環(huán)境,便于管理Redis群集
[root@node1 /]# yum -y install rpm-build openssl openssl-devel # 安裝所需依賴包
[root@node1 /]# cd /redis/
[root@node1 redis]# ls
redis-3.3.0.gem redis-4.0.14.tar.gz ruby-2.3.1.tar.gz
[root@node1 redis]# tar zxf ruby-2.3.1.tar.gz # 解包
[root@node1 redis]# cd ruby-2.3.1/
[root@node1 ruby-2.3.1]# ./configure --prefix=/usr/local/ruby && make && make install # 此環(huán)境編譯時間較長
[root@node1 ruby-2.3.1]# ln -s /usr/local/ruby/bin/* /usr/local/bin/ # 為命令做軟連接
[root@node1 ruby-2.3.1]# ln -s /usr/local/redis/src/redis-trib.rb /usr/local/bin/
[root@node1 ruby-2.3.1]# ln -s /usr/local/ruby/bin/* /usr/bin/
[root@node1 ruby-2.3.1]# cd ..
[root@node1 redis]# gem install redis-3.3.0.gem # 回到有g(shù)em文件的目錄,進行安裝
Successfully installed redis-3.3.0
Parsing documentation for redis-3.3.0
Installing ri documentation for redis-3.3.0
Done installing documentation for redis after 0 seconds
1 gem installed
# 范圍如上信息則表示安裝成功
5、配置群集中的各個節(jié)點
[root@node1 /]# redis-cli -p 6379 # 登錄到ben'di本地實例
127.0.0.1:6379> CLUSTER MEET 192.168.171.134 6379 # 將各個節(jié)點添加到群集中
OK
127.0.0.1:6379> CLUSTER MEET 192.168.171.135 6379
OK
127.0.0.1:6379> CLUSTER MEET 192.168.171.136 6379
OK
127.0.0.1:6379> CLUSTER MEET 192.168.171.137 6379
OK
127.0.0.1:6379> CLUSTER MEET 192.168.171.138 7000 # 這塊是因為node6修改過端口號
OK
127.0.0.1:6379> set test aaa # 由于并沒有分配hash槽,所以并不能添加數(shù)據(jù)
(error) CLUSTERDOWN Hash slot not served
127.0.0.1:6379> CLUSTER INFO # 查看群集的狀態(tài)
cluster_state:fail # 會發(fā)現(xiàn)這里是fail失敗的
cluster_slots_assigned:0
127.0.0.1:6379> exit
# 下來我們分配槽點,要小心配置
#雖然可以將命令中的“add”換為“del”,但是我沒有成功
#一定要將0至16383完全分配出去,最好是等份分配
#只需給作為master的節(jié)點分配即可,我這里node01至node03為master
[root@node1 /]# redis-cli -h 192.168.171.133 -p 6379 cluster addslots {0..5461}
OK
[root@node1 /]# redis-cli -h 192.168.171.134 -p 6379 cluster addslots {5462..10922}
OK
[root@node1 /]# redis-cli -h 192.168.171.135 -p 6379 cluster addslots {10923..16383}
OK
[root@node1 /]# redis-cli -p 6379 -c # 進入群集,需要添加-c選項
127.0.0.1:6379> CLUSTER NODES # 查看群集節(jié)點信息
#接下來是將各個slave從節(jié)點與master進行綁定
#node04作為node01的從節(jié)點,node05作為node02的從節(jié)點,node06的6379實例作為node03的從節(jié)點
#需要配置哪個從節(jié)點,就需要登錄到哪個實例
127.0.0.1:6379> CLUSTER NODES #可以先執(zhí)行此命令,查看相應節(jié)點的ID,以便接下來指定
[root@node1 /]# redis-cli -h 192.168.171.136 -p 6379 # 登錄到node4
192.168.171.136:6379> CLUSTER REPLICATE 4397bb3e5e43fdf1700551d0a2587f502e6c02a8
OK
#以上添加的是node1的節(jié)點id
192.168.171.136:6379> exit # 退出該節(jié)點
[root@node1 /]# redis-cli -h 192.168.171.137 -p 6379
192.168.171.137:6379> CLUSTER REPLICATE 1eca51f415ba5194a95d5400176daa5713d64990
OK
#以上添加的是node2的節(jié)點id
192.168.171.137:6379> exit
[root@node1 /]# redis-cli -h 192.168.171.138 -p 7000
192.168.171.138:7000> CLUSTER REPLICATE ee71a2fd995f35992ce69328096ccd50fc68f89e
OK
#以上添加的是node3的節(jié)點id
至此,群集即可正常讀寫數(shù)據(jù)了,如下:
[root@node1 /]# redis-cli -h 192.168.171.133 -p 6379 -c
192.168.171.133:6379> set test aaa
-> Redirected to slot [6918] located at 192.168.171.134:6379
OK
192.168.171.134:6379> get test
"aaa"
192.168.171.134:6379>
6、使用ruby安裝的命令管理Redis群集
[root@node1 /]# redis-trib.rb check 127.0.0.1:6379
7、將node06的7001實例添加節(jié)點到Redis群集中
添加節(jié)點
[root@node1 /]# redis-trib.rb add-node 192.168.171.138:7001 192.168.171.133:6379
#在添加節(jié)點時,不添加其他配置,默認加入群集后,角色是master
添加節(jié)點后需要分配相應的槽點
由于一個群集若要正常運行,必須將所有的槽點分配出去,所以當有新的節(jié)點加入后,需要重新給新加入的節(jié)點分配槽點,如下:
[root@node01 /]# redis-trib.rb check 127.0.0.1:6379 #執(zhí)行此命令進行確認新加入的節(jié)點時master
[root@node01 /]# redis-trib.rb reshard 192.168.171.133:6379 #指定群集地址及端口
How many slots do you want to move (from 1 to 16384)? 4096
#若是四個master,那么平均值為4096,所以這里輸入4096
What is the receiving node ID?
eca1db0392f69207c4fc3ad4ff290d5a94ea5f99
#指定接收的節(jié)點,也就是新加入的node06主機上7001的那個實例的ID
Source node #1:all #指定從哪個節(jié)點的槽點分配,這里輸入“all”選擇所有節(jié)點
Do you want to proceed with the proposed reshard plan (yes/no)? yes #輸入“yes”進行確認
至此,新的節(jié)點就添加完成了,并且分配了相應的槽點,但是還沒有從節(jié)點,所以接下來為新加入的master分配一個從節(jié)點
8、為新加入的master分配從節(jié)點
分配從節(jié)點的方式有兩種,一種是不指定為哪個master的從節(jié)點,自動綁定到?jīng)]有從節(jié)點的master上,一種是直接指定綁定到哪個master上,這里將這兩種方式都寫下來
方法一:
[root@node1 /]# redis-trib.rb add-node --slave 192.168.171.138:7002 192.168.171.138:7001
#將node06上的7002實例以slave的身份加入到群集
#注意,返回的信息不可有紅色字樣,那就說明有錯誤
[root@node1 /]# redis-trib.rb check 192.168.171.133:6379
方法二:
[root@node1 /]# redis-trib.rb add-node --slave --master-id eca1db0392f69207c4fc3ad4ff290d5a94ea5f99 192.168.171.138:7003 192.168.171.138:7001
#上述id為7001master的id
[root@node1 /]# redis-trib.rb check 192.168.171.133: 6379 # 查看群集狀態(tài),會發(fā)現(xiàn)7001有兩個從節(jié)點
9、刪除主節(jié)點操作
刪除主節(jié)點的操作其實就是把添加主節(jié)點的操作反了過了,需要先將要刪除的主節(jié)點上的槽點分配給其他master,然后才可以執(zhí)行刪除操作,并且刪除主節(jié)點后,該master對應的slave也將會隨著slots槽進行轉(zhuǎn)移到新的master上。
這里以移除node06上的7001實例為例
[root@node1 /]# redis-trib.rb reshard 192.168.171.133:6379
How many slots do you want to move (from 1 to 16384)? 4096 # 指定刪除多少槽點
What is the receiving node ID? 1eca51f415ba5194a95d5400176daa5713d64990
#上述添加的id為刪除主節(jié)點后,剩余的槽點分配給誰,這里我添加的是node2的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 #1:eca1db0392f69207c4fc3ad4ff290d5a94ea5f99
#上述指定的是要刪除的那個節(jié)點,這里是node6上的7001
Source node #2:done # 表示結(jié)束
Do you want to proceed with the proposed reshard plan (yes/no)? yes
#移除槽點后,接下來將7001實例從群集中移除,如下:
[root@node1 /]# redis-trib.rb del-node 192.168.171.133:6379 eca1db0392f69207c4fc3ad4ff290d5a94ea5f99
>>> Removing node eca1db0392f69207c4fc3ad4ff290d5a94ea5f99 from cluster 192.168.171.133:6379 # 指定的id為7001
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
至此,7001實例就被徹底移除群集了,并且原本與之對應的slave也隨著槽點轉(zhuǎn)移到node02也一起成為了node02的slave?,F(xiàn)在查看群集信息,node02的master應該是對應了三個slave
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。