主從模式是Redis三種集群模式中最簡(jiǎn)單的,在主從復(fù)制中,數(shù)據(jù)庫(kù)分為兩類:主數(shù)據(jù)庫(kù)(master)和從數(shù)據(jù)庫(kù)(slave)。其中,主從復(fù)制有如下特點(diǎn):
- 主數(shù)據(jù)庫(kù)可以進(jìn)行讀寫操作,當(dāng)讀寫操作導(dǎo)致數(shù)據(jù)變化時(shí)會(huì)自動(dòng)將數(shù)據(jù)同步給從數(shù)據(jù)庫(kù);
- 從數(shù)據(jù)庫(kù)一般是只讀的,并且接收主數(shù)據(jù)庫(kù)同步過來(lái)的數(shù)據(jù);
- 一個(gè)master可以擁有多個(gè)slave,但是一個(gè)slave只能對(duì)應(yīng)一個(gè)master;
- slave掛了不影響其他slave的讀和master的讀和寫,重新啟動(dòng)后會(huì)將數(shù)據(jù)從master同步過來(lái);
- master掛了以后,不影響slave的讀,但redis不再提供寫服務(wù),master重啟后redis將重新對(duì)外提供寫服務(wù);
- master掛了以后,不會(huì)在slave節(jié)點(diǎn)中重新選一個(gè)master;
下面是主從模式的工作示意圖。
工作機(jī)制:
- 當(dāng)slave啟動(dòng)后,主動(dòng)向master發(fā)送SYNC命令。master接收到SYNC命令后在后臺(tái)保存快照(RDB持久化)和緩存保存快照這段時(shí)間的命令,然后將保存的快照文件和緩存的命令發(fā)送給slave。slave接收到快照文件和命令后加載快照文件和緩存的執(zhí)行命令。
- 復(fù)制初始化后,master每次接收到的寫命令都會(huì)同步發(fā)送給slave,保證主從數(shù)據(jù)一致性。
#環(huán)境說(shuō)明
為了方便演示主從模式,我們需要準(zhǔn)備至少3臺(tái)機(jī)器(虛擬機(jī))。
IP | 主機(jī)名 | 角色 |
---|---|---|
192.168.182.110 | local-168-182-110 | master |
192.168.182.111 | local-168-182-111 | slave1 |
192.168.182.112 | local-168-182-112 | slave2 |
下載解壓Redis安裝包
接下來(lái),就是下載Redis的安裝包,下載地址:http://download.redis.io/releases/
cd /opt/software
wget http://download.redis.io/releases/redis-7.0.3.tar.gz
# 解壓
tar -xf redis-7.0.3.tar.gz
cd redis-7.0.3
# 設(shè)置環(huán)境變量
echo "export REDIS_HOME=/opt/software/redis-7.0.3">> /etc/profile
source /etc/profile
#編譯安裝
接下來(lái)是,編譯安裝所有的節(jié)點(diǎn)。
cd $REDIS_HOME
yum -y install gcc gcc++
make && make install
# 默認(rèn)安裝目錄 /usr/local/bin
#配置服務(wù)
安裝節(jié)點(diǎn)之后,為了方便后期啟動(dòng)和維護(hù)服務(wù), 需要對(duì)安裝的節(jié)點(diǎn)進(jìn)行服務(wù)的配置。
cat << EOF > /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis persistent key-value database
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/redis-server /usr/local/redis/redis.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown
Type=forking
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
LimitNOFILE=65536
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
下面是配置的相關(guān)描述和說(shuō)明:
- Description: # 描述服務(wù)
- After: # 描述服務(wù)類別
- [Service] # 服務(wù)運(yùn)行參數(shù)的設(shè)置
- Type=forking # 是后臺(tái)運(yùn)行的形式
- ExecStart # 為服務(wù)的具體運(yùn)行命令
- ExecReload # 為重啟命令
- ExecStop # 為停止命令
- LimitNOFILE=65536 # 打開文件數(shù)和進(jìn)程數(shù)有限制,默認(rèn)限制為1024,如果不設(shè)置,或者設(shè)置為L(zhǎng)imitNOFILE=unlimited(不識(shí)別),則得到了1024
- PrivateTmp=True # 表示給服務(wù)分配獨(dú)立的臨時(shí)空間
【注意】[Service]的啟動(dòng)、重啟、停止命令全部要求使用絕對(duì)路徑 [Install] #運(yùn)行級(jí)別下服務(wù)安裝的相關(guān)設(shè)置,可設(shè)置為多用戶,即系統(tǒng)運(yùn)行級(jí)別為3
重載系統(tǒng)服務(wù):systemctl daemon-reload。以下是配置,位于/usr/libexec/redis-shutdown路徑下。
#!/bin/bash
#
# Wrapper to close properly redis and sentinel
test x"$REDIS_DEBUG" != x && set -x
REDIS_CLI=/usr/local/bin/redis-cli
# Retrieve service name
SERVICE_NAME="$1"
if [ -z "$SERVICE_NAME" ]; then
SERVICE_NAME=redis
fi
# Get the proper config file based on service name
CONFIG_FILE="/usr/local/redis/$SERVICE_NAME.conf"
# Use awk to retrieve host, port from config file
HOST=`awk '/^[[:blank:]]*bind/ { print $2 }' $CONFIG_FILE | tail -n1`
PORT=`awk '/^[[:blank:]]*port/ { print $2 }' $CONFIG_FILE | tail -n1`
PASS=`awk '/^[[:blank:]]*requirepass/ { print $2 }' $CONFIG_FILE | tail -n1`
SOCK=`awk '/^[[:blank:]]*unixsocket\s/ { print $2 }' $CONFIG_FILE | tail -n1`
# Just in case, use default host, port
HOST=${HOST:-127.0.0.1}
if [ "$SERVICE_NAME" = redis ]; then
PORT=${PORT:-6379}
else
PORT=${PORT:-26739}
fi
# Setup additional parameters
# e.g password-protected redis instances
[ -z "$PASS" ] || ADDITIONAL_PARAMS="-a $PASS"
# shutdown the service properly
if [ -e "$SOCK" ] ; then
$REDIS_CLI -s $SOCK $ADDITIONAL_PARAMS shutdown
else
$REDIS_CLI -h $HOST -p $PORT $ADDITIONAL_PARAMS shutdown
fi
經(jīng)過上面的處理后,就可以使用systemctl命令來(lái)啟停redis了。
授權(quán)啟動(dòng)服務(wù)
接下來(lái),是授權(quán)啟動(dòng)服務(wù)需要用到的一些命令:
chmod +x /usr/libexec/redis-shutdown
useradd -s /sbin/nologin redis
mkdir /usr/local/redis ; cp $REDIS_HOME/redis.conf /usr/local/redis/ && chown -R redis:redis /usr/local/redis
mkdir -p /opt/software/redis-7.0.3/data && chown -R redis:redis /opt/software/redis-7.0.3/data
yum install -y bash-completion && source /etc/profile # 命令補(bǔ)全
systemctl daemon-reload
systemctl enable redis
#修改linux內(nèi)核參數(shù)
# 臨時(shí)生效
sysctl -w vm.overcommit_memory=1
# 永久生效
echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf && sysctl -p
### 可選值:0,1,2。
# 0,:表示內(nèi)核將檢查是否有足夠的可用內(nèi)存供應(yīng)用進(jìn)程使用;如果有足夠的可用內(nèi)存,內(nèi)存申請(qǐng)?jiān)试S;否則,內(nèi)存申請(qǐng)失敗,并把錯(cuò)誤返回給應(yīng)用進(jìn)程。
# 1:表示內(nèi)核允許分配所有的物理內(nèi)存,而不管當(dāng)前的內(nèi)存狀態(tài)如何。
# 2: 表示內(nèi)核允許分配超過所有物理內(nèi)存和交換空間總和的內(nèi)存。
#節(jié)點(diǎn)配置
#master節(jié)點(diǎn)配置
首先,我們打開master節(jié)點(diǎn)文件,文件位于vi/usr/local/redis/redis.conf目錄下,然后修改配置如下:
bind 192.168.182.110 # 監(jiān)聽ip,多個(gè)ip用空格分隔
daemonize yes # 允許后臺(tái)啟動(dòng)
logfile "/usr/local/redis/redis.log" # 日志路徑
dir /opt/software/redis-7.0.3/data # 數(shù)據(jù)庫(kù)備份文件存放目錄
masterauth 123456 # slave連接master密碼,master可省略
requirepass 123456 # 設(shè)置master連接密碼,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目錄生成appendonly.aof文件,將每一次寫操作請(qǐng)求都追加到appendonly.aof 文件中
#slave1節(jié)點(diǎn)配置
接著,我們打開slave1節(jié)點(diǎn)文件,文件位于vi/usr/local/redis/redis.conf,修改配置如下:
bind 192.168.182.111 # 監(jiān)聽ip,多個(gè)ip用空格分隔
daemonize yes # 允許后臺(tái)啟動(dòng)
logfile "/usr/local/redis/redis.log" # 日志路徑
dir /opt/software/redis-7.0.3/data # 數(shù)據(jù)庫(kù)備份文件存放目錄
# replicaof用于追隨某個(gè)節(jié)點(diǎn)的redis,被追隨的節(jié)點(diǎn)為主節(jié)點(diǎn),追隨的為從節(jié)點(diǎn)。就是設(shè)置master節(jié)點(diǎn)
replicaof 192.168.182.110 6379
masterauth 123456 # slave連接master密碼,master可省略
requirepass 123456 # 設(shè)置master連接密碼,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目錄生成appendonly.aof文件,將每一次寫操作請(qǐng)求都追加到appendonly.aof 文件中
#slave2節(jié)點(diǎn)配置
打開slave2的節(jié)點(diǎn)文件,文件位于vi/usr/local/redis/redis.conf,修改配置如下:
bind 192.168.182.112 # 監(jiān)聽ip,多個(gè)ip用空格分隔
daemonize yes # 允許后臺(tái)啟動(dòng)
logfile "/usr/local/redis/redis.log" # 日志路徑
dir /opt/software/redis-7.0.3/data # 數(shù)據(jù)庫(kù)備份文件存放目錄
# replicaof用于追隨某個(gè)節(jié)點(diǎn)的redis,被追隨的節(jié)點(diǎn)為主節(jié)點(diǎn),追隨的為從節(jié)點(diǎn)。就是設(shè)置master節(jié)點(diǎn)
replicaof 192.168.182.110 6379
masterauth 123456 # slave連接master密碼,master可省略
requirepass 123456 # 設(shè)置master連接密碼,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目錄生成appendonly.aof文件,將每一次寫操作請(qǐng)求都追加到appendonly.aof 文件中
#啟動(dòng)Redis服務(wù)
systemctl start redis
systemctl status redis
#查看集群
然后,使用下面的命令查看集群的一些數(shù)據(jù):
# 交互式
redis-cli -h 192.168.182.110 -a 123456
192.168.182.110:6379> info replication
# 交互式
redis-cli -h 192.168.182.110
192.168.182.110:6379> auth 123456
192.168.182.110:6379> info replication
# 非交互式
redis-cli -h 192.168.182.110 -a 123456 info replication
如果一切配置都沒有問題,Redis的主數(shù)據(jù)庫(kù)會(huì)不定時(shí)的向從數(shù)據(jù)庫(kù)同步數(shù)據(jù),如下圖所示。