一、簡介
1.1 Redis是什么
Redis是一個開源的,使用ANSI C 編寫,高性能的Key-Value的NoSQL數據庫。
1.2 Redis特點
(1)基於內存
(2)可持久化數據
(3)具有豐富的數據結構類型,適應非關系型數據的存儲需求
(4)支持絕大多數主流開發語言,如C、C++、Java、Python、R、JavaScript等。
(5)支持集群模式,高效、穩定。
1.3 數據模型(重點)
(1)鍵值對形式。
(2)Redis的數據結構類型,指的就是Redis值的結構類型。
1.4 Redis作用
(1)本質是數據庫,能存儲數據。
Redis能靈活處理非關系型數據的讀、寫問題,是對MySQL等關系型數據庫的補充。
新浪微博就是使用Redis集群做數據庫。
(2)緩存數據。
所謂緩存,就是將數據加載到內存中后直接使用,而不是每次都通過IO流從磁盤上讀取。好處:讀寫效率高。
而Redis則是將數據直接存儲在內存中,只有當內存空間不足時,將部分數據持久化到磁盤上。
二、安裝
1.1 說明
Redis官方只提供了源碼,並沒有提供經過編譯之后的安裝包。
因此,安裝Redis,要先編譯、后安裝。(即源碼安裝方式)
1.2 redis安裝步驟
# 安裝步驟
cd /usr/local/src
wget http://download.redis.io/releases/redis-5.0.4.tar.gz
tar -zxv -f redis-5.0.4.tar.gz
cd /usr/local/src/redis-5.0.4/
make MALLOC=libc (或者直接make,不用./configure)
make install (安裝到指定目錄:make PREFIX=/usr/local/redis install,不指定的話默認安裝到/usr/local/bin目錄下,也可以執行該步驟,也就是安裝)
# 不安裝的話命令執行文件路徑是:/usr/local/src/redis-5.0.4/src
# 配置文件:/usr/local/src/redis-5.0.4/redis.conf
# 優化配置,使用root賬號操作
# vim /etc/sysctl.conf
vm.overcommit_memory = 1
net.core.somaxconn = 2048
# sysctl -p
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 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
# chmod +x /etc/rc.d/rc.local
# vim /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
# 啟動
[sandu@bogon ~]# ./src/redis-server ./redis.conf
1270:C 02 Aug 2019 16:27:19.274 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1270:C 02 Aug 2019 16:27:19.275 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=1270, just started
1270:C 02 Aug 2019 16:27:19.275 # Configuration loaded
_._
_.-``__ ''-._
_.-`` `. `_. ''-._ Redis 5.0.4 (00000000/0) 64 bit
.-`` .-```. ```\/ _.,_ ''-._
( ' , .-` | `, ) Running in standalone mode
|`-._`-...-` __...-.``-._|'` _.-'| Port: 6379
| `-._ `._ / _.-' | PID: 1270
`-._ `-._ `-./ _.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' | http://redis.io
`-._ `-._`-.__.-'_.-' _.-'
|`-._`-._ `-.__.-' _.-'_.-'|
| `-._`-._ _.-'_.-' |
`-._ `-._`-.__.-'_.-' _.-'
`-._ `-.__.-' _.-'
`-._ _.-'
`-.__.-'
1270:M 02 Aug 2019 16:27:19.277 # Server initialized
1270:M 02 Aug 2019 16:27:19.277 * Ready to accept connections
# 使用自帶的客戶端連接,默認沒有密碼直接連接
[sandu@bogon ~]# ./src/redis-cli
127.0.0.1:6379> ping # 檢測redis服務是否啟動
PONG
127.0.0.1:6379> set a 1111
OK
127.0.0.1:6379> get a
"1111"
127.0.0.1:6379> quit # 退出
# 密碼連接
# redis-cli -h host -p port -a password
[sandu@bogon ~]# ./src/redis-cli
127.0.0.1:6379> auth foobar2000
OK
127.0.0.1:6379> set b 222222
OK
127.0.0.1:6379> get b
"222222"
127.0.0.1:6379> exit
1.3 redis.conf常用配置說明
-
bind:允許訪問該redis的主機
-
protected-mode:保護模式,默認開啟。若設置外部網絡連接redis服務,設置方式如下:
1、關閉protected-mode模式,此時外部網絡可以直接訪問
2、開啟protected-mode保護模式,需配置bind ip或者設置訪問密碼,或者bind ip和密碼都設置
-
requirepass:設置密碼
-
databases:Redis默認有16個數據庫,尋址角標從0開始。默認連接db0。客戶端使用select命令,切換數據庫
-
port :指定redis的服務端口,默認6379.
-
daemonize:Redis默認關閉后台進程模式,改成yes,redis服務在后台啟動。
-
loglevel :日志等級
-
logfile:Redis日志輸出目錄,默認不輸出日志到文件。
-
dbfilename:指定數據持久化的文件名
-
dir :指定數據持久化的文件存放目錄,也是集群node.con文件存放目錄
-
cluster-enabled:是否啟用集群
-
cluster-config-file:集群文件
1.4 redis啟動方式
- 直接啟動
進入redis根目錄,執行命令,加上‘&’號使redis以后台程序方式運行
./src/redis-server &
- 通過指定配置文件啟動
可以為redis服務啟動指定配置文件,例如配置為/etc/redis/6379.conf
./src/redis-server /etc/redis/6379.conf
進入redis根目錄,輸入命令,如果更改了端口,使用redis-cli
客戶端連接時,也需要指定端口,例如:
redis-cli -p 6380
# redis-cli -h host -p port -a password
- 使用redis啟動腳本設置開機自啟動,有問題,只能啟動和停止,不能查看狀態,也不能重載,還有就是關閉的話貌似關不掉,不予考慮該腳本
啟動腳本 redis_init_script 位於位於Redis的 /utils/ 目錄下,redis_init_script腳本代碼如下:
#!/bin/sh
#
# Simple Redis init.d script conceived to work on Linux systems
# as it does use of the /proc filesystem.
# chkconfig: 2345 90 10
### BEGIN INIT INFO
# Provides: redis_6379
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Redis data structure server
# Description: Redis data structure server. See https://redis.io
### END INIT INFO
#redis服務器監聽的端口
REDISPORT=6379
#服務端所處位置
EXEC=/usr/local/bin/redis-server
#客戶端位置
CLIEXEC=/usr/local/bin/redis-cli
#redis的PID文件位置,根據實際情況修改
PIDFILE=/var/run/redis_${REDISPORT}.pid
#redis的配置文件位置,需將${REDISPORT}修改為文件名
CONF="/etc/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
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$CLIEXEC -p $REDISPORT shutdown
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
*)
echo "Please use start or stop as first argument"
;;
esac
將啟動腳本復制到/etc/init.d目錄下,本例將啟動腳本命名為redisd(通常都以d結尾表示是后台自啟動服務)
cd
cp redis_init_script /etc/init.d/redisd
chkconfig redisd on
service redisd start|stop
1.5 redis關閉
- 第一種關閉方式
# 斷電,非正常關閉,容易導致數據丟失
ps -ef | grep redis
kill -9 PID
- 第二種關閉方式
# 正常關閉,數據保存
redis-cli shutdown # 關閉redis服務,通過客戶端進行shutdown
# 如果redis設置了密碼,則需要先用客戶端登錄,然后再進行shutdown
redis-cli -a password
127.0.0.1:6379> shutdown
# 重新啟動redis服務,使用客戶端連接,會發現數據還在
三、持久化
Redis持久化,就是將內存中的數據,永久保存到磁盤上。
Redis持久化有兩種方式:RDB(Redis DB)、AOF(AppendOnlyFile)
Redis 可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啟時, 它會優先使用 AOF 文件來還原數據集, 因為 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整。
3.1 RDB(快照模式)
在默認情況下,Redis 將數據庫快照保存在名字為dump.rdb的二進制文件中,可以在redis.conf配置文件中修改持久化信息。
save 900 1 表示在900秒內,至少更新了1條數據。Redis就將數據持久化到硬盤
save 300 10 表示在300內,至少更新了10條數據,Redis就會觸發將數據持久化到硬盤
save 60 10000 表示60秒內,至少更新了10000條數據,Redis就會觸發將數據持久化到硬盤
3.1.1 策略
- 自動:BGSAVE
按照配置文件中的條件滿足就執行BGSAVE;
非阻塞,Redis服務正常接收處理客戶端請求;
Redis會folk()一個新的子進程來創建RDB文件,子進程處理完后會向父進程發送一個信號,通知它處理完畢;
父進程用新的dump.rdb替代舊文件。
- 手動:SAVE
客戶端(redis-cli)發起SAVE命令;
阻塞Redis服務,無法響應客戶端請求;
創建新的dump.rdb替代舊文件。
3.1.2 優點
-
執行效率高;
-
恢復大數據集速度較AOF快。
3.1.3 缺點
-
會丟失最近寫入、修改的而未能持久化的數據;
-
folk過程非常耗時,會造成毫秒級不能響應客戶端請求。
3.2 AOF(追加模式、文本重演)
AOF默認關閉,需要在配置文件中手動開啟。
記錄所有的寫操作命令,在服務啟動的時候使用這些命令就可以還原數據庫。
Append only file,采用追加的方式保存,默認文件appendonly.aof。
3.2.1 寫入機制
AOF機制,添加了一個內存緩沖區(buffer):
- 將內容寫入緩沖區
- 當緩沖區被填滿、或者用戶手動執行fsync、或者系統根據指定的寫入磁盤策略自動調用fdatasync命令,才將緩沖區里的內容真正寫入磁盤里
- 在緩沖區里的內容未寫入磁盤之前,可能會丟失
3.2.2 寫入磁盤的策略
appendfsync選項,這個選項的值可以是always、everysec或者no
- always:服務器每寫入一個命令,就調用一次fdatasync,將緩沖區里面的命令寫入到硬盤。這種模式下,服務器出現故障,也不會丟失任何已經成功執行的命令數據
- everysec(默認):服務器每一秒重調用一次fdatasync,將緩沖區里面的命令寫入到硬盤。這種模式下,服務器出現故障,最多只丟失一秒鍾內的執行的命令數據
- no:服務器不主動調用fdatasync,由操作系統決定何時將緩沖區里面的命令寫入到硬盤。這種模式下,服務器遭遇意外停機時,丟失命令的數量是不確定的,no 選項並不能給服務器性能帶來多大的提升,而且也會增加系統奔潰時數據丟失的數量。
運行速度:always的速度慢,everysec和no都很快
3.2.3 重寫機制
AOF文件過大,合並重復的操作,AOF會使用盡可能少的命令來記錄
- 重寫過程
(1)folk一個子進程負責重寫AOF文件
(2)子進程會創建一個臨時文件寫入AOF信息
(3)父進程會開辟一個內存緩沖區接收新的寫命令
(4)子進程重寫完成后,父進程會獲得一個信號,將父進程接收到的新的寫操作由子進程寫入到臨時文件中
(5)新文件替代舊文件
重寫的本質:就是將操作同一個鍵的命令,合並。從而減小AOF文件的體積
- 重寫觸發機制
(1)手動:
客戶端向服務器發送BGREWRITEAOF命令
(2)自動:
配置文件中的選項,自動執行BGREWRITEAOF命令
- auto-aof-rewrite-min-size
:觸發AOF重寫所需的最小體積:只要在AOF文件的體積大於等於size時,才會考慮是否需要進行AOF重寫,這個選項用於避免對體積過小的AOF文件進行重寫 - auto-aof-rewrite-percentage
:指定觸發重寫所需的AOF文件體積百分比:當AOF文件的體積大於auto-aof-rewrite-min-size指定的體積,並且超過上一次重寫之后的AOF文件體積的percent %時,就會觸發AOF重寫。(如果服務器剛剛啟動不久,還沒有進行過AOF重寫,那么使用服務器啟動時載入的AOF文件的體積來作為基准值)。將這個值設置為0表示關閉自動AOF重寫。
- 優點
-
寫入機制,默認fysnc(手工同步)每秒執行,性能很好不阻塞服務,最多丟失一秒的數據;
-
重寫機制,優化AOF文件;
-
如果誤操作了(FLUSHALL等),只要AOF未被重寫,停止服務移除AOF文件尾部FLUSHALL命令,重啟Redis,可以將數據集恢復到FLUSHALL 執行之前的狀態。
- 缺點
-
相同數據集,AOF文件體積較RDB大了很多;
-
恢復數據庫速度較RDB慢(文本,命令重演)
四、集群
4.1 redis集群簡介
4.1.1 集群的概念
所謂的集群,就是通過添加服務器的數量,提供相同的服務,從而讓服務器達到一個穩定、高效的狀態。
4.1.1.1 使用redis集群的必要性
問題:我們已經部署好了redis,並且能啟動一個redis,實現數據的讀寫,為什么還要學習redis集群?
答:(1)單個redis存在不穩定性。當redis服務宕機了,就沒有可用的服務了。
(2)單個redis的讀寫能力是有限的。
總結:redis集群是為了強化redis的讀寫能力。
4.1.1.2 如何學習redis集群
說明:(1)redis集群中,每一個redis稱之為一個節點。
(2)redis集群中,有兩種類型的節點:主節點(master)、從節點(slave)。
(3)redis集群,是基於redis主從復制實現。
所以,學習redis集群,就是從學習redis主從復制模型開始的。
4. 2 redis主從復制
4.2.1 概念
主從復制模型中,有多個redis節點。
其中,有且僅有一個為主節點Master。從節點Slave可以有多個。
只要網絡連接正常,Master會一直將自己的數據更新同步給Slaves,保持主從同步。
4.2.2 特點
(1)主節點Master可讀、可寫.
(2)從節點Slave只讀。(read-only)
因此,主從模型可以提高讀的能力,在一定程度上緩解了寫的能力。因為能寫仍然只有Master節點一個,可以將讀的操作全部移交到從節點上,變相提高了寫能力。
4.2.3 基於配置實現
- 需求
- 主節點:6380
- 從節點:6381、6382
- 配置步驟
(1)在/usr/local目錄下,創建一個/redis/master-slave目錄
mkdir -p /usr/local/redis/master-slave
(2)在master-slave目錄下,創建三個子目錄6380、6381、6382
mkdir 6380 6381 6382
(3)依次拷貝redis解壓目錄下的redis.conf配置文件,到這三個子目錄中
cp /usr/local/src/redis-5.0.4/redis.conf 6380/
cp /usr/local/src/redis-5.0.4/redis.conf 6381/
cp /usr/local/src/redis-5.0.4/redis.conf 6382/
(4)進入6380目錄,修改redis.conf,將port端口修改成6380即可
(5)進入6381目錄,修改redis.conf,將port端口改成6381,同時指定開啟主從復制
# 主節點ip 主節點端口
replicaof 127.0.0.1 6380
(6)進入6382目錄,修改redis.conf,將port端口改成6382,同時指定開啟主從復制
- 測試
(1)打開三個shell窗口,在每一個窗口中,啟動一個redis節點。查看日志輸出。(不要改成后台模式啟動,看不到日志,不直觀)
(2)另外再打開三個shell窗口,在每一個窗口中,登陸一個redis節點
(3)在主節點6380上,進行讀寫操作,操作成功
(4)在從節點6381上,讀操作執行成功,並且成功從6380上同步了數據;寫操作執行失敗。(從節點,只能讀,不能寫)
# 寫操作執行失敗提示
(error) READONLY You can't write against a read only replica.
4.3 Sentinel哨兵模式
4.3.1 主從模式的缺陷
當主節點宕機了,整個集群就沒有可寫的節點了。
問:由於從節點上備份了主節點的所有數據,那在主節點宕機的情況下,如果能夠將從節點變成一個主節點,是不是就可以解決這個問題了呢?
答:是的,這個就是Sentinel哨兵的作用。
4.3.2 哨兵的任務
Redis 的 Sentinel 系統用於管理多個 Redis 服務器(instance), 該系統執行以下三個任務:
-
監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
-
提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
-
自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會進行選舉,將其中一個從服務器升級為新的主服務器, 並讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器。
4.3.2.1 監控(Monitoring)
(1)Sentinel可以監控任意多個Master和該Master下的Slaves。(即多個主從模式)
(2)同一個哨兵下的、不同主從模型,彼此之間相互獨立。
(3)Sentinel會不斷檢查Master和Slaves是否正常。
4.3.2.1 自動故障切換(Automatic failover)
監控同一個Master的Sentinel會自動連接,組成一個分布式的Sentinel網絡,互相通信並交換彼此關於被監視服務器的信息。
疑問:為什么要使用sentinel網絡呢?
答:當只有一個sentinel的時候,如果這個sentinel掛掉了,那么就無法實現自動故障切換了。
在sentinel網絡中,只要還有一個sentinel活着,就可以實現故障切換。
4.3.2.2 故障切換的過程
(1)投票(半數原則)
當任何一個Sentinel發現被監控的Master下線時,會通知其它的Sentinel開會,投票確定該Master是否下線(半數以上,所以sentinel通常配奇數個)。
(2)選舉
當Sentinel確定Master下線后,會在所有的Slaves中,選舉一個新的節點,升級成Master節點。
其它Slaves節點,轉為該節點的從節點。
(3)原Master重新上線
當原Master節點重新上線后,自動轉為當前Master節點的從節點。
4.3.3 哨兵模式部署
4.3.3.1 需求
前提:已經存在一個正在運行的主從模式。
另外,配置三個Sentinel實例,監控同一個Master節點
4.3.3.2 配置Sentinel
(1)在/usr/local目錄下,創建/redis/sentinels/目錄
cd /usr/local/redis
mkdir sentinels
(2)在sentinels目錄下,依次創建s1、s2、s3三個子目錄中
cd sentinels
mkdir s1 s2 s3
(3)依次拷貝redis解壓目錄下的sentinel.conf文件,到這三個子目錄中
cp /usr/local/src/redis-5.0.4/sentinel.conf s1/
cp /usr/local/src/redis-5.0.4/sentinel.conf s2/
cp /usr/local/src/redis-5.0.4/sentinel.conf s3/
(4)依次修改s1、s2、s3子目錄中的sentinel.conf文件,修改端口,並指定要監控的主節點。(從節點不需要指定,sentinel會自動識別)
# s1 哨兵配置
port 26379
sentinel monitor mymaster 127.0.0.1 6380 2
# mymaster為主節點別名,127.0.0.1為主節點IP,6380為主節點端口,2為觸發故障切換的最少哨兵數量
# s2 哨兵配置
port 26380
sentinel monitor mymaster 127.0.0.1 6380 2
# s3 哨兵配置
port 26381
sentinel monitor mymaster 127.0.0.1 6380 2
(5)再打開三個shell窗口,在每一個窗口中,啟動一個哨兵實例,並觀察日志輸出
進入redis的安裝目錄,/usr/local/bin/,也可以不用進,因為前面的那個目錄在環境變量中。
對於用redis-server啟動哨兵的方式如下:
核心日志輸出:
4.3.4 測試
(1)先關閉6380節點(kill掉)。發現,確實重新指定了一個主節點
(2)再次上線6380節點。發現,6380節點成為了新的主節點的從節點。
4.3.5 結論
Sentinel哨兵模式,確實能實現自動故障切換。提供穩定的服務。
4.3.6 注意事項
如果哨兵和redis節點不在同一台服務器上,注意IP綁定的問題。
(1)主從模型,所有的節點,使用ip綁定
(2)所有的哨兵,也都使用ip去綁定主機
(3)所有的哨兵,都是通過主節點的ip,去監控主從模型
五、 Redis-cluster集群
5.1 哨兵模式的缺陷
在哨兵模式中,仍然只有一個Master節點。當並發寫請求較大時,哨兵模式並不能緩解寫壓力。
我們知道只有主節點才具有寫能力,那如果在一個集群中,能夠配置多個主節點,是不是就可以緩解寫壓力了呢?
答:是的。這個就是redis-cluster集群模式。
5.2 Redis-cluster集群概念
(1)由多個Redis服務器組成的分布式網絡服務集群;
(2)集群之中有多個Master主節點,每一個主節點都可讀可寫;
(3)節點之間會互相通信,兩兩相連;
(4)Redis集群無中心節點。
5.3 集群節點復制
在Redis-Cluster集群中,可以給每一個主節點添加從節點,主節點和從節點直接遵循主從模型的特性。
當用戶需要處理更多讀請求的時候,添加從節點可以擴展系統的讀性能。
5.4 故障轉移
Redis集群的主節點內置了類似Redis Sentinel的節點故障檢測和自動故障轉移功能,當集群中的某個主節點下線時,集群中的其他在線主節點會注意到這一點,並對已下線的主節點進行故障轉移。
集群進行故障轉移的方法和Redis Sentinel進行故障轉移的方法基本一樣,不同的是,在集群里面,故障轉移是由集群中其他在線的主節點負責進行的,所以集群不必另外使用Redis Sentinel。
5.5 集群分片策略
Redis-cluster分片策略,是用來解決key存儲位置的。
集群將整個數據庫分為16384個槽位slot,所有key-value數據都存儲在這些slot中的某一個上。一個slot槽位可以存放多個數據,key的槽位計算公式為:slot_number=crc16(key)%16384,其中crc16為16位的循環冗余校驗和函數。
集群中的每個主節點都可以處理0個至16383個槽,當16384個槽都有某個節點在負責處理時,集群進入上線狀態,並開始處理客戶端發送的數據命令請求。
5.6 集群redirect轉向
由於Redis集群無中心節點,請求會隨機發給任意主節點;
主節點只會處理自己負責槽位的命令請求,其它槽位的命令請求,該主節點會返回客戶端一個轉向錯誤;
客戶端根據錯誤中包含的地址和端口重新向正確的負責的主節點發起命令請求。
5.7 集群搭建
5.7.1 准備工作
redis5.0版本之后可以直接使用redis-cli
命令創建集群,不使用redis-trib.rb
命令了。
5.7.2 集群規划
(1)Redis集群最少需要6個節點,3主3從,可以分布在一台或者多台主機上。
真集群:6台主機,每台主機的redis服務使用的IP不同,端口號隨意,一樣不一樣都可以
假集群,一台主機,redis服務使用的IP相同,端口號不同
本例子是在一台主機上創建假集群,不同的端口表示不同的redis節點,如下:
主節點:127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003
從節點:127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
后期新加的主節點:127.0.0.1:7007
后期新家的從節點:127.0.0.1:7008
(2)在/usr/local/src/redis-5.0.4/下創建cluster目錄,其下創建7001、7002…7006目錄,如下:
(3)將redis解壓路徑下的配置文件redis.conf,依次拷貝到每個700X目錄內,並修改每個700X目錄下的redis.conf配置文件:
# cd /usr/local/src/redis-5.0.4/cluster
# mkdir {7001,7002,7003,7004,7005,7006}
# mkdir -p /var/log/redis/{7001,7002,7003,7004,7005,7006}
# redis.conf文件示例
bind 127.0.0.1
port 7001
daemonize yes
pidfile /var/run/redis_7001.pid
dir "./" # node.conf文件保存路徑
logfile "/var/log/redis/7001/redis.log"
appendonly yes
appendfsync always
cluster-enabled yes
cluster-config-file nodes-7001.conf # 該文件中包含集群信息
# 其他配置文件類似,把端口號修改一下就行了
5.7.3 啟動每個節點redis服務
批量啟動腳本:
# vim s/usr/local/src/redis-5.0.4/cluster/ctart_cluster.sh
#!/bin/bash
cd ./7001 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7002 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7003 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7004 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7005 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ../7006 && /usr/local/src/redis-5.0.4/src/redis-server ./redis.conf
cd ..
# chmod +x start_cluster.sh
注意:一定要進入700X目錄中啟動,因為它會自動在當前目錄中創建cluster-config,即nodes.conf。因為你在哪個目錄下執行這個命令,則node.conf文件就會在該目錄下創建。
但是若是在配置文件中配置dir
為其他目錄,則該文件會創建在dir
指定目錄下
或者把redis-server程序文件依次拷貝到每個700x目錄下,然后使用不同目錄的redis-server程序文件啟動
關閉腳本:
# vim /usr/local/src/redis-5.0.4/cluster/shutdown_cluster.sh
#!/bin/bash
pgrep redis-server | xargs -exec kill -9
# chmod +x shutdown_cluster.sh
執行啟動腳本批量啟動:
# ./start_cluster.sh
5.7.4 執行創建集群命令
進入到redis源碼存放目錄/usr/local/src/redis-5.0.4/src下,把redis-cli文件拷貝到/usr/local/bin/目錄下
cd /usr/local/src/redis-5.0.4/cluster
/usr/local/src/redis-5.0.4/src/redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
# --cluster-replicas 1 表示主從配置比,1表示的是1:1,前三個是主,后三個是從
# 若配置文件中設置的密碼,則還需要加上-a passwod
......
Can I set the above configuration? (type 'yes' to accept): yes
......
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
5.7.5 查詢集群信息
注意:查詢集群信息需要加上-c
參數
或者直接執行命令查詢,如下面所示;或者登陸到其中一個集群節點,使用命令cluster nodes
進行查詢
# /usr/local/src/redis-5.0.4/src/redis-cli -c -h 127.0.0.1 -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564918712465 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564918714483 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564918713000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564918713474 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564918713000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564918712000 2 connected 5461-10922
參數說明:
- -c:表示以集群方式連接惹redis
- -h:指定IP地址
- -p:指定端口
- cluster nodes:查詢集群節點信息
- cluster info:查詢集群狀態信息
其他查詢方法:
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster check 127.0.0.1:7001
127.0.0.1:7001 (4dad696e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (bbe8b703...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (59b65974...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:7001)
M: 4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004
slots: (0 slots) slave
replicates 59b6597448b668a355d85dcc7a0623bc36263e5f
M: bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005
slots: (0 slots) slave
replicates bbe8b7035bfd31c47bec7d612acc112cd2869368
S: 5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006
slots: (0 slots) slave
replicates 4dad696ede24995a57c5fd790faa95c72c187a22
M: 59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster info 127.0.0.1:7001
127.0.0.1:7001 (4dad696e...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7003 (bbe8b703...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:7002 (59b65974...) -> 0 keys | 5462 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
5.7.6 redis cluster集群重新啟動
因為集群已經創建過了,若是關機等原因關閉了redis服務,則只需要執行批量啟動腳本即可,就會自動開啟集群,因為有node.conf文件的存在
5.7.7 redis-cli集群命令幫助
# /usr/local/src/redis-5.0.4/src/redis-cli --cluster help
Cluster Manager Commands:
create host1:port1 ... hostN:portN
--cluster-replicas <arg>
check host:port
--cluster-search-multiple-owners
info host:port
fix host:port
--cluster-search-multiple-owners
reshard host:port
--cluster-from <arg>
--cluster-to <arg>
--cluster-slots <arg>
--cluster-yes
--cluster-timeout <arg>
--cluster-pipeline <arg>
--cluster-replace
rebalance host:port
--cluster-weight <node1=w1...nodeN=wN>
--cluster-use-empty-masters
--cluster-timeout <arg>
--cluster-simulate
--cluster-pipeline <arg>
--cluster-threshold <arg>
--cluster-replace
add-node new_host:new_port existing_host:existing_port
--cluster-slave
--cluster-master-id <arg>
del-node host:port node_id
call host:port command arg arg .. arg
set-timeout host:port milliseconds
import host:port
--cluster-from <arg>
--cluster-copy
--cluster-replace
help
For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
5.8 集群管理
5.8.1 添加新主節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-master-id node_id
5.8.2 hash槽重新分配
添加完新節點后,需要對新添加的主節點進行hash槽重新分配,這樣該主節點才能存儲數據,redis共有16384個槽。
redis-cli --cluster reshard host:port --cluster-from node_id --cluster-to node_id --cluster-slots <args> --cluster-yes
5.8.2 添加新從節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id node_id
5.8.3 刪除節點
redis-cli --cluster del-node host:port node_id
5.8.4 集群常用命令
# 創建集群
redis-cli --cluster create host1:port1 ... hostN:portN --cluster-replicas <arg>
# 例子
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
# 例子說明
host1:port1 ... hostN:portN表示的是要添加的集群的節點IP和端口,
--cluster-replicas <arg>表示的是主從節點比例,參數1表示前三個是主節點,后三個是從節點
也就是說7001,7002,7003端口對應的節點是主節點,7004,7005,7006對應的節點是從節點
# 查詢集群節點信息
redis-cli -c -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564923261350 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564923263366 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564923262000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564923260000 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564923263000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564923262358 2 connected 5461-10922
# 說明:以下的操作均是以上面這個為參數示例
# 給集群添加一個新主節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-master-id node_id
# 例子
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7003 --cluster-master-id bbe8b7035bfd31c47bec7d612acc112cd2869368
# 例子說明
new_host:new_port為要新添加的主節點IP和端口,此處是127.0.0.1:7007
existing_host:existing_port表示的是已存在的最后一個主節點的IP和端口,這個可以從上述的節點信息中查看到,根據slots槽數,7003端口對應的節點槽數是10923-16383,16383表示的是最后的槽數
--cluster-master-id表示的是最后一個主節點的節點id,表示的是新添加的主節點要在這個節點后面
# 再次查看集群信息
redis-cli -c -p 7001 cluster nodes
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564923261350 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564923263366 3 connected 10923-16383
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564923260344 0 connected
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564923262000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564923260000 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564923263000 1 connected 0-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564923262358 2 connected 5461-10922
# 會發現7007端口對應的節點已經加入到集群中,是主節點,但是沒有從節點,也沒有分配槽數
# 給新添加的主節點分配slots槽數
redis-cli --cluster reshard host:port --cluster-from node_id --cluster-to node_id --cluster-slots 500 --cluster-yes
# 例子
redis-cli --cluster reshard 127.0.0.1:7007 --cluster-from 4dad696ede24995a57c5fd790faa95c72c187a22 --cluster-to 7020c8df9423686727783c60bd2f0e367634ba84 --cluster-slots 500
# 例子說明
host:port表示的是新添加的那個主節點IP和端口,此處表示的是127.0.0.1:7007
--cluster-from node_id表示的是集群第一個主節點的節點id,這個可以現有集群的slots槽數分配看出,此處表示的是7001端口對應的節點
--cluster-to node_id表示的是集群最后一個主節點的節點id,也就是新添加的那個主節點id,此處表示的是7007端口對應的節點
--cluster-slots 500表示的是給新主節點分配多少,此處500表示是分配從0-499個slots槽數,若不加上這個會讓手動輸入
--cluster-yes表示的是自動應答為yes,若不加上這個會讓手動輸入yes,表示同意此次分配
# 再次查看集群信息
/redis-cli -c -p 7001 cluster nodes 7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564924042000 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564924042157 3 connected 10923-16383
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564924040140 7 connected 0-499
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564924040000 5 connected
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564924041149 6 connected
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564924040000 1 connected 500-5460
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564924043166 2 connected 5461-10922
# 會發現7007端口對應的主節點已經有slots槽數了,並且是從0開始的
# 給集群中某個主節點再添加一個從節點
redis-cli --cluster add-node new_host:new_port existing_host:existing_port --cluster-slave --cluster-master-id node_id
# 例子
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7008 --cluster-slave --cluster-master-id 7020c8df9423686727783c60bd2f0e367634ba84
# 例子說明
new_host:new_port表示的是要添加的那個從節點的IP和端口,此處表示的是127.0.0.1:7008
existing_host:existing_port表示的是要給哪個主節點添加從節點,此處表示的是127.0.0.1:7007
--cluster-slave表示的是要添加從節點,否則則是添加主節點了
--cluster-master-id node_id表示要給哪個主節點添加從節點的該主節點節點id
# 再次查看集群信息
redis-cli -c -p 7001 cluster nodes 7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564924845000 7 connected 0-499
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564924843000 1 connected 500-5460
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564924845214 6 connected
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564924843195 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564924844205 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564924845000 5 connected
415db07121ba946b202bca98e15cbdffc60bc18a 127.0.0.1:7008@17008 slave 7020c8df9423686727783c60bd2f0e367634ba84 0 1564924846224 7 connected
c3e04f0e8710c25d59703374a224ee8bec776e43 :0@0 master,fail,noaddr - 1564924804548 1564924802833 0 disconnected
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564924844000 2 connected 5461-10922
# 會發現7008端口對應的節點已經是7007端口對應的從節點
# 從集群中刪除一個從節點
redis-cli --cluster del-node host:port node_id
# 例子
redis-cli --cluster del-node 127.0.0.1:7008 415db07121ba946b202bca98e15cbdffc60bc18a
# 例子說明
host:port表示的是要刪除的那個節點的IP和端口,此處是127.0.0.1:7008
node_id表示的是刪除的那個節點的節點id
# 其他命令有待補充
5.9 注意事項
5.9.1 防火牆端口放行
若是允許Redis集群被外網用戶訪問,除了需要修改配置文件外,還需要修改防火牆,開放集群中reids節點的端口。
說明:如果要開放一個范圍的端口,可以使用冒號來分割,即: 7001:7004,表示開放7001-7004之間所有的端口
5.9.2 登錄節點問題
若是登錄的是集群中的節點,需要加上-c
參數;否則不用加該參數
# 登錄集群節點的命令
redis-cli -c -h ip -p port -a password
# 登錄一般節點或者從節點的命令
redis-cli -h ip -p port -a password
5.9.3 如何刪除集群中無效的節點
redis-cli -c -p 7001 cluster nodes
7020c8df9423686727783c60bd2f0e367634ba84 127.0.0.1:7007@17007 master - 0 1564925352648 7 connected 0-499
4dad696ede24995a57c5fd790faa95c72c187a22 127.0.0.1:7001@17001 myself,master - 0 1564925349000 1 connected 500-5460
5612ffbb0407dbda50828b505a16b39ede51168b 127.0.0.1:7006@17006 slave 4dad696ede24995a57c5fd790faa95c72c187a22 0 1564925351000 6 connected
7d388cc31df969d3e1715ce9644318bfd48317b1 127.0.0.1:7004@17004 slave 59b6597448b668a355d85dcc7a0623bc36263e5f 0 1564925354665 4 connected
bbe8b7035bfd31c47bec7d612acc112cd2869368 127.0.0.1:7003@17003 master - 0 1564925353657 3 connected 10923-16383
456921ae96af71d8183101f798cf5ceda4b0381e 127.0.0.1:7005@17005 slave bbe8b7035bfd31c47bec7d612acc112cd2869368 0 1564925349000 5 connected
c3e04f0e8710c25d59703374a224ee8bec776e43 :0@0 master,fail,noaddr - 1564924804548 1564924802833 0 disconnected
59b6597448b668a355d85dcc7a0623bc36263e5f 127.0.0.1:7002@17002 master - 0 1564925352000 2 connected 5461-10922
# 如上集群中有一個無效的節點信息,要如何刪除,這個還不知道咋操作。