redis-4.0.14 cluster 配置實戰


1.操作系統配置

切換到root用戶修改配置sysctl.conf

vim /etc/sysctl.conf

# 添加配置:
vm.max_map_count=655360
vm.overcommit_memory=1
net.core.somaxconn= 32767
fs.file-max=65535


# ulimit -n 最大文件描述符 65536

vim /etc/security/limits.conf
# 添加
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536

vi /etc/security/limits.d/20-nproc.conf  #加大普通用戶限制,也可以改為 unlimited
* soft nproc 40960
root soft nproc unlimited

reboot或者重新登錄

主節點平均分配到不同的機器上,否則容易造成單點故障以及復制風暴。

操作系統關閉THP:

vim /etc/rc.d/rc.local

if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi

if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi

然后給rc.local添加可執行權限:

chmod +x /etc/rc.d/rc.local
重啟生效

2.redis安裝准備

yum -y install gcc gcc-* automake autoconf libtool make zlib zlib-devel glibc-* tcl tree

2.1 redis下載及安裝

# 創建安裝目錄:
mkdir /usr/local/redis-4.0.14
# 創建軟連接:
ln -s /usr/local/redis-4.0.14 /usr/local/redis

# 官網
wget http://download.redis.io/releases/redis-4.0.14.tar.gz -P /opt

 

2.2 安裝redis(在三個服務器分別依次執行如下命令)

cd /opt
tar xzf redis-4.0.14.tar.gz
cd redis-4.0.14
cd src

make && echo $?

make test && echo $?

# 這里如果報錯,可以重新執行一遍就好了,有點莫名其妙的
make MALLOC=libc

echo $?

make PREFIX=/usr/local/redis install && echo $?

3. redis 基本配置

3.1 配置文件修改

創建目錄:
mkdir -p /usr/local/redis/{conf,data,logs}

bind 0.0.0.0                # 測試環節,任何地址都可連接
port 6379                    # 修改成對應的端口號
daemonize yes                # 后台運行
pidfile /var/run/redis_6379.pid         # pid文件
logfile "./redis.log"            # 日志
dir /usr/local/redis/data               # 設置文件數據存儲路徑
rename-command FLUSHALL adminFLUSHALL    # 禁止危險命令
rename-command FLUSHDB adminFLUSHDB       # 禁止危險命令
# rename-command KEYS adminKEYS        # 禁止危險命令
rename-command SCAN adminSCAN          # 禁止危險命令
rename-command CONFIG ""        # 信息安全:防止redis被非法連接后,使用config命令對操作系統進行控制;另:要求redis使用非root帳號運行
maxclients 100000               # 集群支持的最大連接
timeout 60                  # 設置空閑連接超時時間
maxmemory 6000M             # Redis默認無限使用服務器內存,為防止極端情況下導致系統內存耗 盡,建議所有的Redis進程都要配置maxmemory, 要保證機器本身有30%左右的閑置內存
maxmemory-policy volatile-lru             # 內存剔除策略logfile “”  默認為空,則在控制台打印,否則輸出日志到指定的log文件
save ""                  # 通用配置,關閉RDB持久化,只使用AOF。
appendonly yes              # 開啟 aop 備份
masterauth 0NZcyqRqLUteci7D         # 設置 master 節點的認證密碼
requirepass 0NZcyqRqLUteci7D        # 設置 redis 連接密碼
appendfilename "appendonly-8379.aof"       # 設置持久化文件名稱
appendfsync always            # 每寫一條 備份 一次
cluster-enabled yes                # 開啟 Redis Cluster
cluster-config-file nodes-6379.conf        # 記錄集群信息,不用手動維護,Redis Cluster 會自動維護
cluster-node-timeout 2000           # Cluster 集群節點連接超時時間,如果集群規模小,都在同一個網絡環境下,可以配置的短些,更快的做故障轉移。
cluster-require-full-coverage no           # 設置為no,默認為yes,故障發現到自動完成轉移期間整個集群是不可用狀態,對於大多數業務無法容忍這種情況,因此要設置為no,當主節點故障時只影 響它負責槽的相關命令執行,不會影響其他主節點的可用性。只要有結點宕機導致16384個槽沒全被覆蓋,整個集群就全部停止服務,所以一定要改為no
no-appendfsync-on-rewrite yes           # 設置為yes表示rewrite期間對新寫操作不fsync,暫時存在內存中,等rewrite完成后再寫入,提高redis寫入性能
protected-mode no                    # 允許外部主機訪問

slowlog-log-slower-than 1000         # 慢查詢日志,用於性能分析,生產環境可設置為1000(微妙)
slowlog-max-len 1000             # 保存慢查詢的隊列長度 ,設置為1000
cluster-slave-validity-factor 0          # 設置為0,如果master slave都掛掉, slave跟master失聯又超過這個數值*timeout的數值, 就不會發起選舉了。如果設置為0,就是永遠都會嘗試發起選舉,嘗試從slave變為mater

==================================================================================================================
vim /usr/local/redis/conf/redis-8379.conf

bind 0.0.0.0
port 8379
daemonize yes
pidfile /var/run/redis_8379.pid
logfile "/usr/local/redis/logs/redis.log"
dir /usr/local/redis/data
rename-command FLUSHALL adminFLUSHALL
rename-command FLUSHDB adminFLUSHDB
# rename-command KEYS adminKEYS
rename-command SCAN adminSCAN
rename-command CONFIG ""
maxclients 100000
timeout 60
maxmemory 6000M
maxmemory-policy volatile-lru
save ""
appendonly yes
masterauth 0NZcyqRqLUteci7D
requirepass 0NZcyqRqLUteci7D
appendfilename "appendonly-8379.aof"
appendfsync always
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/nodes-8379.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
no-appendfsync-on-rewrite yes
protected-mode no
---------------------------------------------------------
vim /usr/local/redis/conf/redis-8380.conf

bind 0.0.0.0
port 8380
daemonize yes
pidfile /var/run/redis_8380.pid
logfile "/usr/local/redis/logs/redis.log"
dir /usr/local/redis/data
rename-command FLUSHALL adminFLUSHALL
rename-command FLUSHDB adminFLUSHDB
# rename-command KEYS adminKEYS
rename-command SCAN adminSCAN
rename-command CONFIG ""
maxclients 100000
timeout 60
maxmemory 6000M
maxmemory-policy volatile-lru
save ""
appendonly yes
masterauth 0NZcyqRqLUteci7D
requirepass 0NZcyqRqLUteci7D
appendfilename "appendonly-8380.aof"
appendfsync always
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/nodes-8380.conf
cluster-node-timeout 15000
cluster-require-full-coverage no
no-appendfsync-on-rewrite yes
protected-mode no
=========================================================

依次啟動6個 Redis 實例:
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-8379.conf
/usr/local/redis/bin/redis-server /usr/local/redis/conf/redis-8380.conf

啟動完畢之后,使用 Redis 源碼包中附帶的 Ruby 工具創建集群。

4 Redis-4.0 Cluster創建

4.1 ruby工具准備

因為要使用 Ruby 工具,所以要先保證有 Ruby 環境,並且安裝 Redis 插件。

cd /opt
gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3   7D2BAF1CF37B13E2069D6956105BD0E739499BDB

curl -L get.rvm.io | bash -s stable

 

source /usr/local/rvm/scripts/rvm

# 查看rvm庫中已知的ruby版本
rvm list known

# 安裝一個ruby版本
rvm install 2.4.0

# 使用一個ruby版本
rvm use 2.4.0

# 卸載一個已知版本
rvm remove 2.0.0

# 查看版本
ruby --version

# 再安裝redis就可以了
gem install redis

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

4.2 創建集群注意事項

注意:創建集群之前,如果配置文件中配置了密碼的,執行集群創建命令會報類似如下錯誤:
[root@aliy-prod-redis-server001 bin]# ./redis-trib.rb create --replicas 1 10.86.78.152:8379 10.86.78.152:8380 10.86.78.153:8379 10.86.78.153:8380 10.86.78.154:8379 10.86.78.154:8380
>>> Creating cluster
[ERR] Sorry, can't connect to node 10.86.78.152:8379

【解決方法】
vim /usr/local/rvm/gems/ruby-2.4.0/gems/redis-4.1.2/lib/redis/client.rb

class Client
DEFAULTS = {
:url => lambda { ENV["REDIS_URL"] },
:scheme => "redis",
:host => "127.0.0.1",
:port => 6379,
:path => nil,
:timeout => 5.0,
:password => "passwd123", # "0NZcyqRqLUteci7D"
:db => 0,
:driver => nil,
:id => nil,
:tcp_keepalive => 0,
:reconnect_attempts => 1,
:inherit_socket => false
}

注意:client.rb路徑可以通過find命令查找:find / -name 'client.rb'

4.3 創建redis集群

cd /usr/local/redis/bin/

./redis-trib.rb create --replicas 1 10.86.78.152:8379 10.86.78.152:8380 10.86.78.153:8379 10.86.78.153:8380 10.86.78.154:8379 10.86.78.154:8380

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
10.86.78.143:8379
10.86.78.144:8379
10.86.78.145:8379
Adding replica 10.86.78.144:8380 to 10.86.78.143:8379
Adding replica 10.86.78.145:8380 to 10.86.78.144:8379
Adding replica 10.86.78.143:8380 to 10.86.78.145:8379
M: 8bea76614c3793b90885820e4666461fe6a2d531 10.86.78.143:8379
slots:0-5460 (5461 slots) master
S: 2055b2f822afe3e71fbad7cf2817c87a7e089c2f 10.86.78.143:8380
replicates 3e2aa851ed39ad73bbbabf0a4e5deae2d8eafcf7
M: 1ea11299f4af26b1ff1306b8f2c2255e6dfdfda4 10.86.78.144:8379
slots:5461-10922 (5462 slots) master
S: d9f577ad6dd5589bf96f9f0589c7fd9717d4c94e 10.86.78.144:8380
replicates 8bea76614c3793b90885820e4666461fe6a2d531
M: 3e2aa851ed39ad73bbbabf0a4e5deae2d8eafcf7 10.86.78.145:8379
slots:10923-16383 (5461 slots) master
S: 4a4a38f6035003ec66764104661fac6094ff058f 10.86.78.145:8380
replicates 1ea11299f4af26b1ff1306b8f2c2255e6dfdfda4
Can I set the above configuration? (type 'yes' to accept): 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.86.78.143:8379)
M: 8bea76614c3793b90885820e4666461fe6a2d531 10.86.78.143:8379
slots:0-5460 (5461 slots) master
1 additional replica(s)
S: 4a4a38f6035003ec66764104661fac6094ff058f 10.86.78.145:8380
slots: (0 slots) slave
replicates 1ea11299f4af26b1ff1306b8f2c2255e6dfdfda4
M: 3e2aa851ed39ad73bbbabf0a4e5deae2d8eafcf7 10.86.78.145:8379
slots:10923-16383 (5461 slots) master
1 additional replica(s)
S: 2055b2f822afe3e71fbad7cf2817c87a7e089c2f 10.86.78.143:8380
slots: (0 slots) slave
replicates 3e2aa851ed39ad73bbbabf0a4e5deae2d8eafcf7
M: 1ea11299f4af26b1ff1306b8f2c2255e6dfdfda4 10.86.78.144:8379
slots:5461-10922 (5462 slots) master
1 additional replica(s)
S: d9f577ad6dd5589bf96f9f0589c7fd9717d4c94e 10.86.78.144:8380
slots: (0 slots) slave
replicates 8bea76614c3793b90885820e4666461fe6a2d531
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

看到如 [OK] All 16384 slots covered. 的提示說明集群創建成功。

仔細查看上面的日志信息,M:主節點。S:從節點。可以看到,自動把6個 Redis 分成了 3 個主節點和 3 個從節點,並且 3 個主節點所在服務器是不同的,而從節點的分布也是在三台服務器上各有一個,並且還不和其自己的主節點在同一個服務器,這樣做的好處是保證了集群的高可用性。

4.4 redis 集群狀態查看

隨便連接一個 Redis 進行查看集群操作,連接 Redis 記得使用 -c 參數,表示啟用集群模式,可以使用重定向等功能。
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Server
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Stats
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Clients
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Memory
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Persistence
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info Replication
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D info CPU
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D CLUSTER NODES
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D cluster nodes |grep master
/usr/local/redis/bin/redis-cli -c -p 8379 -a 0NZcyqRqLUteci7D cluster nodes |grep slave

上方信息展示說明如下:
- 節點ID
- IP:端口
- 標志:master,slave,myself,,fail,…
- 如果是個從節點,,這里是它的主節點的 NODE ID
- 集群最近一次向節點發送 PING 命令之后, 過去了多長時間還沒接到回復。.
- 節點最近一次返回 PONG 回復的時間。
- 節點的配置紀元(configuration epoch):詳細信息請參考 Redis 集群規范 。
- 本節點的網絡連接情況:例如:connected 。
- 節點目前包含的槽:例如 192.168.117.135:6379 目前包含號碼為 0 至 5460 的哈希槽。

4.5 Redis Cluster 常用命令

格式 說明
CLUSTER NODES 查看集群節點信息
CLUSTER REPLICATE <master-id> 進入一個從節點 Redis,切換其主節點
CLUSTER MEET <ip:port> 發現一個新節點,新增主節點
CLUSTER FORGET <id> 忽略一個節點,前提是他不能是有 Solts 的主節點
CLUSTER FAILOVER 手動故障轉移


CLUSTER FAILOVER 命令說明:
有時在主節點正常的情況下強制手動故障轉移也是必要的,如: 升級主節點的 Redis 進程,可以通過故障轉移將其轉為 Slave 再進行升級操作來避免對集群的可用性造成影響。

Redis 集群使用 CLUSTER FAILOVER 命令來進行故障轉移,不過要在被轉移的主節點的從節點上執行該命令;
手動故障轉移比主節點失敗自動故障轉移更加安全,因為手動故障轉移時客戶端的切換是在確保新的主節點完全復制了失敗的舊的主節點數據的前提下下發生的,所以避免了數據的丟失。

其基本過程如下:客戶端不再鏈接我們淘汰的主節點,
同時主節點向從節點發送復制偏移量,
從節點得到復制偏移量后故障轉移開始,
接着通知主節點進行配置切換,當客戶端在舊的 Master 上解鎖后重新連接到新的主節點上。

4.6 redis安全配置

# 訪問密碼:

如果集群已經創建好,也可以動態設置密碼
在集群的所有實例(包含主節點和從節點)中執行


設置集群密碼:
# 使用redis-cli連接redis集群
/usr/local/redis/bin/redis-cli -c -p 8379
/usr/local/redis/bin/redis-cli -c -p 8380

config set masterauth 0NZcyqRqLUteci7D
config set requirepass 0NZcyqRqLUteci7D

# 上面的配置 一定要每一個節點都配置執行一遍(包括主節點和從節點)
配置好上面的命令后,需要執行如下命令,將配置寫入配置文件,否則下次重啟密碼就失效了!!!!!
config rewrite


如果剛開始創建集群,可以在redis的配置文件中寫入下面兩行配置:
1.在集群創建時,配置文件中添加如下兩行
masterauth 0NZcyqRqLUteci7D
requirepass 0NZcyqRqLUteci7D


# 禁用危險命令
危險命令包括: keys * scan * config flushall flushdb

# 禁用命令
rename-command KEYS ""
rename-command SCAN ""
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""

# 重命名命令
rename-command KEYS "adminKEYS"
rename-command SCAN "adminSCAN"
rename-command FLUSHALL "adminFLUSHALL"
rename-command FLUSHDB "adminFLUSHDB"
rename-command CONFIG "adminCONFIG"

5 redis-trib.rb 常用命令

redis-trib.rb add-node

添加主節點:

redis-trib.rb add-node <new_ip:new_port> <exist_ip:exist_port>
使用 add-node 命令來添加節點,第一個參數是新節點的地址,第二個參數是任意一個已經存在的節點的IP和端口,這樣,新節點就會添加到集群中。
如:
redis-trib.rb add-node 10.86.87.111:6378 10.86.87.111:6379
注釋:
10.86.87.111:6378是新增的節點
10.86.87.111:6379集群任一個舊節點

添加從節點:

redis-trib.rb add-node –slave <new_ip:new_port> <exist_ip:exist_port>
此處的命令和添加一個主節點命令類似,此處並沒有指定添加的這個從節點的主節點,這種情況下系統會在其他的集群中的主節點中隨機選取一個作為這個從節點的主節點。
如:
redis-trib.rb add-node --slave --master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2 192.168.10.220:6385 192.168.10.219:6379
注釋:
--slave 表示添加的是從節點
--master-id 03ccad2ba5dd1e062464bc7590400441fafb63f2,主節點的node id,在這里是前面新添加的6378的node id
192.168.10.220:6385,新節點
192.168.10.219:6379 集群任一個舊節點


添加指定主節點 id 的從節點:redis-trib.rb add-node –slave –master-id <主節點id> <new_ip:new_port> <exist_ip:exist_port>
也可以使用 CLUSTER REPLICATE 命令,這個命令也可以改變一個從節點的主節點,要在從節點中使用哦。

刪除節點

redis-trib del-node
刪除節點:redis-trib del-node <exist_ip:exist_port> <node-id>
第一個參數是任意一個節點的地址(確定集群所在),第二個節點是你想要移除的節點地址。
使用同樣的方法移除主節點,不過在移除主節點前,需要確保這個主節點是空的(無 Solts)。如果不是空的,需要將這個節點的數據重新分片到其他主節點上。
替代移除主節點的方法是手動執行故障恢復,被移除的主節點會作為一個從節點存在,不過這種情況下不會減少集群節點的數量,也需要重新分片數據。

重新分配slot

redis-trib.rb reshard
從新分片:redis-trib.rb reshard <exist_ip:exist_port>

你只需要指定集群中其中一個節點的地址,redis-trib 就會自動找到集群中的其他節點。
目前 redis-trib 只能在管理員的協助下完成重新分片的工作,要讓 redis-trib 自動將哈希槽從一個節點移動到另一個節點,目前來說還做不到。

redis-trib.rb reshard 192.168.10.219:6378 //下面是主要過程
How many slots do you want to move (from 1 to 16384)? 1000 //設置slot數1000
What is the receiving node ID? 03ccad2ba5dd1e062464bc7590400441fafb63f2 //新節點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 #1:all //表示全部節點重新洗牌
Do you want to proceed with the proposed reshard plan (yes/no)? yes //確認重新分

新增加的主節點,是沒有slots的,
M: 03ccad2ba5dd1e062464bc7590400441fafb63f2 192.168.10.219:6378
slots:0-332,5461-5794,10923-11255 (0 slots) master
主節點如果沒有slots的話,存取數據就都不會被選中。
可以把分配的過程理解成打撲克牌,all表示大家重新洗牌;輸入某個主節點的node id,然后在輸入done的話,就好比從某個節點,抽牌。


查看集群節點情況:
redis-trib.rb check 192.168.10.219:6379


手動改變slave從節點所屬的master主節點(一個slave只能屬於一個master,而一個master可以有多個slave)
//查看一下6378的從節點
# redis-cli -p 6378 cluster nodes | grep slave | grep 03ccad2ba5dd1e062464bc7590400441fafb63f2

//將6385加入到新的master
# redis-cli -c -p 6385 -h 192.168.10.220
192.168.10.220:6385> cluster replicate 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052 //新master的node id
OK
192.168.10.220:6385> quit

//查看新master的slave
# redis-cli -p 6379 cluster nodes | grep slave | grep 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052


刪除節點
1)刪除從節點
# redis-trib.rb del-node 192.168.10.220:6385 '9c240333476469e8e2c8e80b089c48f389827265'

2)刪除主節點
如果主節點有從節點,將從節點轉移到其他主節點
如果主節點有slot,去掉分配的slot,然后在刪除主節點
# redis-trib.rb reshard 192.168.10.219:6378 //取消分配的slot,下面是主要過程
How many slots do you want to move (from 1 to 16384)? 1000 //被刪除master的所有slot數量
What is the receiving node ID? 5d8ef5a7fbd72ac586bef04fa6de8a88c0671052 //接收6378節點slot的master
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:03ccad2ba5dd1e062464bc7590400441fafb63f2 //被刪除master的node-id
Source node #2:done

Do you want to proceed with the proposed reshard plan (yes/no)? yes //取消slot后,reshard


新增master節點后,也進行了這一步操作,當時是分配,現在去掉。反着的。
# redis-trib.rb del-node 192.168.10.219:6378 '03ccad2ba5dd1e062464bc7590400441fafb63f2'

新的master節點被刪除了,這樣就回到了,就是這篇文章開頭,還沒有添加節點的狀態


復制遷移
在redis集群中通過"cluster replicate <master_node_id> "命令可以將一個slave節點重新配置為另外一個master的slave。
注意:這個只是針對slave節點,即登錄到slave節點的reids中,執行這個命令。

比如172.16.60.204:7003是172.16.60.202:7000主節點的slave節點,也可以把他設置成172.16.60.205:7004主節點的slave節點。
172.16.60.205:7004主節點的ID是48cbab906141dd26241ccdbc38bee406586a8d03

則操作為
[root@redis-new01 ~]# /data/redis-4.0.6/src/redis-cli -h 172.16.60.204 -c -p 7003
172.16.60.204:7003> cluster replicate 48cbab906141dd26241ccdbc38bee406586a8d03
OK
172.16.60.204:7003>

這樣172.16.60.204:7003節點就變成了172.16.60.205:7004主節點的slave節點,而不再是172.16.60.202:7000主節點的slave節點!

這樣可以自動的將一個復制節點從一個master下移動到另外一個master下。 這種情況下的復制節點的自動重配置被稱為復制遷移。
復制遷移可以提升系統的可靠性和抗災性。

在某種情況下,你想讓集群的復制節點從一個master遷移到另一個master的原因可能是:
集群的抗崩潰能力總是跟集群中master 擁有的平均slave數量成正比。
比如,如果一個集群中每個master只有一個slave,當master和slave都掛掉的時候這個集群就崩潰了。因為此時有一些哈希槽無法找到了。
雖然網絡分裂會把一堆節點從集群中孤立出來(這樣你一下就會知道集群出問題了),但是其他的更常見的硬件或者軟件的問題並不會在多台機器上同時發生,
所以很 可能在你的這個集群(平均每個master只有一個slave)有一個slave在早上4點掛掉,然后他的master在隨后的早上6點掛掉。這樣依然會 導致集群崩潰。

可以通過給每個master都再多加一個slave節點來改進系統的可靠性,但是這樣很昂貴。復制遷移允許只給某些master增加slave。比方說你的集群有20個節點,
10個master,每個master都有1個slave。然后你增加3個 slave到集群中並把他們分配給某幾個master節點,這樣某些master就會擁有多於1個slave。

當某個 master失去了slave的時候,復制遷移可以將slave節點從擁有富余slave的master旗下遷移給沒有slave的master。所以當 你的slave在早上4點掛掉的時候,
另一個slave會被遷移過來取代它的位置,這樣當master節點在早上5點掛掉的時候,依然有一個slave可 以被選舉為master,集群依然可以正常運行。

所以簡而言之,關於復制遷移應該注意下面幾個方面:
- 集群在遷移的時候會嘗試去遷移擁有最多slave數量的master旗下的slave。
- 想利用復制遷移特性來增加系統的可用性,你只需要增加一些slave節點給單個master(哪個master節點並不重要)。
- 復制遷移是由配置項cluster-migration-barrier控制的

升級節點

升級從服務器節點很簡單,因為你只需要停止節點然后用已更新的Redis版本重啟。如果有客戶端使用從服務器節點分離讀請求,它們應該能夠在某個節點
不可用時重新連接另一個從服務器。

升級主服務器要稍微復雜一些,建議的步驟是:
1)使用cluster failover來觸發一次手工故障轉移主服務器(請看本文檔的手工故障轉移小節)。
2)等待主服務器變為從服務器。
3)像升級從服務器那樣升級這個節點。
4)如果你想讓你剛剛升級的節點成為主服務器,觸發一次新的手工故障轉移,讓升級的節點重新變回主服務器。

可以按照這些步驟來一個節點一個節點的升級,直到全部節點升級完畢。

6 遇到的問題以及解決方案

新增節點直接變成從節點
這個是因為要新增的那個 Redis 節點中有原來殘留的數據信息,新增前請把 AOF 和 RDB 備份的文件都刪除掉,並且進入准備新增的 Redis 中執行一下下面兩條命令

127.0.0.1:6379> FLUSHALL
127.0.0.1:6379> CLUSTER RESET

雖然一主一從加哨兵可以解決普通場景下服務可用的問題,但是兩個節點分別存儲所有的緩存數據,這不僅導致容量受限,更是讓我們受限於機器配置最差的那一台,這就是木桶效應。硬件垂直擴容並不能解決日益龐大的緩存數據量和提供能搞得可用性。

在古老的Redis版本中,水平擴容的能力來自於發送命令的客戶端,由客戶端路由不同的key給到不同的節點,下次讀取的時候,也按照相同方式路由key到指定節點拿到數據。如果接下來還希望增加擴容節點的話,就要對歷史緩存數據做遷移,遷移過程中為保證數據一致性也要付出一定代價。為了解決節點的不斷擴容,設計初期可以預先設置很多節點,以備日后使用,所有設計的節點都參與到分片當中,鑒於初期數據較少,可單台服務器多個節點,在日后數據增多的情況下,只需要遷移節點到新的服務器。而不需要對數據進行重新分配等操作。但是這種做法依然讓我們覺得難維護,難遷移,難應對故障,遷移過程中也很難保證數據一致性,比如50個節點,任意一個節點想要停止並遷移服務器,都會引發數據不一致或者出現故障,只能停止集群,等待遷移完成后,集群上線。
Redis3.0提供了Cluster集群。這個集群的概念和前面提到的集群有所不同。前面的集群僅代表,多個節點間沒有相互的關系,只是根據客戶端路由分配key到不同的節點,所有節點共同分配所有數據。3.0的Cluster功能,擁有和單機實例相同的性能,幾乎支持所有命令,對於涉及多個鍵的命令,比如MGET,如果每一個鍵都在同一個節點則可以正常返回數據,否則提示錯誤。另外集群中限制了0號數據庫,如果切換數據庫則會提示錯誤。

哨兵和集群是兩個獨立的功能,但從特性來看哨兵可以視為集群的子集。當不需要數據分片或者已經利用客戶端分片的場景下哨兵已經足夠使用,如果需要水平擴容,Cluster是非常好的選擇。

每個集群至少三台主節點。

7 redis-4.0版本新特性

Redis4.0中增加了 UNLINK 命令(替換del命令),這個命令在刪除體積較大的鍵時,命令在后台線程里面執行,還有異步的 flushdb 和 flushall 命令分別是
flushdb async
flushall async

盡可能的避免了服務器阻塞。
增加了交換數據庫命令,比如SWAPDB 0 1 ,交換0庫和1庫
增加了memory命令,可以視察內存使用情況,通過help命令可以看到

127.0.0.1:6379> memory help

1) "MEMORY DOCTOR - Outputs memory problems report"
2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
3) "MEMORY STATS - Show memory usage details"
4) "MEMORY PURGE - Ask the allocator to release memory"
5) "MEMORY MALLOC-STATS - Show allocator internal stats"

MEMORY USAGE <key> 預估指定key所需內存
MEMORY STATS 視察內存使用詳情
MEMORY PURGE 向分配器索要釋放更多內存
MEMORY MALLOC-STATS 視察分配器內部狀態

另外還有一系列優化比如 LRU和PSYNC,還有模塊系統。

8 節點啟動/停止/重啟腳本

vim /etc/init.d/redis-8379
vim /etc/init.d/redis-8380


#!/bin/sh 
# chkconfig: 35 80 90 
# Simple Redis init.d script conceived to work on Linux systems 
# as it does use of the /proc filesystem. 

REDISPORT=8380
EXEC=/usr/local/redis/bin/redis-server 
CLIEXEC=/usr/local/redis/bin/redis-cli 

PIDFILE=/var/run/redis_${REDISPORT}.pid 
CONF="/usr/local/redis/conf/redis-${REDISPORT}.conf" 

case "$1" in 
start) 
if [ -f $PIDFILE ] 
then 
echo "$PIDFILE exists, process is already running or crashed" 
else 
echo "Starting Redis server..." 
$EXEC $CONF &
fi
if [ "$?" = "0" ]
then
echo "Redis is running..."
fi
;; 
stop) 
if [ ! -f $PIDFILE ] 
then 
echo "$PIDFILE does not exist, process is not running" 
else 
PID=$(cat $PIDFILE) 
echo "Stopping ..." 
$CLIEXEC -p $REDISPORT -a "0NZcyqRqLUteci7D" shutdown 
while [ -x /proc/${PID} ] 
do 
echo "Waiting for Redis to shutdown ..." 
sleep 1 
done 
echo "Redis stopped" 
fi 
;;
restart|force-reload)
${0} stop
${0} start
;;
*) 
echo "Usage: /etc/init.d/redis-${REDISPORT} {start|stop|restart|force-reload}" >&2
;; 
esac


chmod +x /etc/init.d/redis-*
ll /etc/init.d/redis-*

chkconfig --add redis-8379
chkconfig --add redis-8380

/etc/init.d/redis-8379 start 
/etc/init.d/redis-8380 start

9 redis集群密碼設置

9.1、密碼設置(推薦)

在配置redis個節點的時候,在所有Redis集群配置文件中的redis.conf文件加入:

masterauth passwd123
requirepass passwd123

說明:這種方式需要重新啟動各節點


9. 2.如果集群已經創建好,也可以動態設置密碼

在集群的所有實例(包含主節點和從節點)中執行

設置集群密碼:
# 使用redis-cli連接redis集群
/usr/local/redis/bin/redis-cli -c -p 8379
/usr/local/redis/bin/redis-cli -c -p 8380

config set masterauth 0NZcyqRqLUteci7D
config set requirepass 0NZcyqRqLUteci7D
config rewrite # 這一步驟一定要執行,用於將密碼配置寫入配置文件的,如果不執行會導致下次重啟redis時,密碼失效!!!

# 上面的配置 一定要每一個節點都配置執行一遍(包括主節點和從節點)
注意:各個節點密碼都必須一致,否則Redirected就會失敗, 推薦這種方式,這種方式會把密碼寫入到redis.conf里面去,且不用重啟。

9.3、設置密碼之后如果需要使用redis-trib.rb的各種命令

如:./redis-trib.rb check 127.0.0.1:7000,則會報錯ERR] Sorry, can’t connect to node 127.0.0.1:7000
解決辦法:vim /usr/local/rvm/gems/ruby-2.4.0/gems/redis-4.1.2/lib/redis/client.rb,然后修改passord

vim /usr/local/rvm/gems/ruby-2.4.0/gems/redis-4.1.2/lib/redis/client.rb

class Client
DEFAULTS = {
:url => lambda { ENV["REDIS_URL"] },
:scheme => "redis",
:host => "127.0.0.1",
:port => 6379,
:path => nil,
:timeout => 5.0,
:password => "passwd123", # "0NZcyqRqLUteci7D"
:db => 0,
:driver => nil,
:id => nil,
:tcp_keepalive => 0,
:reconnect_attempts => 1,
:inherit_socket => false
}

注意:client.rb路徑可以通過find命令查找:find / -name 'client.rb'

10 redis 監控工具安裝

./redis-stat --verbose --server=9000 5 10.86.78.144:8379 -a 0NZcyqRqLUteci7D &

./redis-stat 10.86.78.144:8379 -a 0NZcyqRqLUteci7D 1 10 --verbose

 

11 參考文檔

https://www.jianshu.com/p/1ff269e8869d
故障轉移
https://www.cnblogs.com/kevingrace/p/7910692.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM