主从模式是Redis三种集群模式中最简单的,在主从复制中,数据库分为两类:主数据库(master)和从数据库(slave)。其中,主从复制有如下特点:
- 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库;
- 从数据库一般是只读的,并且接收主数据库同步过来的数据;
- 一个master可以拥有多个slave,但是一个slave只能对应一个master;
- slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来;
- master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务;
- master挂了以后,不会在slave节点中重新选一个master;
下面是主从模式的工作示意图。
工作机制:
- 当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。
- 复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。
#环境说明
为了方便演示主从模式,我们需要准备至少3台机器(虚拟机)。
IP | 主机名 | 角色 |
---|---|---|
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安装包
接下来,就是下载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
# 设置环境变量
echo "export REDIS_HOME=/opt/software/redis-7.0.3">> /etc/profile
source /etc/profile
#编译安装
接下来是,编译安装所有的节点。
cd $REDIS_HOME
yum -y install gcc gcc++
make && make install
# 默认安装目录 /usr/local/bin
#配置服务
安装节点之后,为了方便后期启动和维护服务, 需要对安装的节点进行服务的配置。
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
下面是配置的相关描述和说明:
- Description: # 描述服务
- After: # 描述服务类别
- [Service] # 服务运行参数的设置
- Type=forking # 是后台运行的形式
- ExecStart # 为服务的具体运行命令
- ExecReload # 为重启命令
- ExecStop # 为停止命令
- LimitNOFILE=65536 # 打开文件数和进程数有限制,默认限制为1024,如果不设置,或者设置为LimitNOFILE=unlimited(不识别),则得到了1024
- PrivateTmp=True # 表示给服务分配独立的临时空间
【注意】[Service]的启动、重启、停止命令全部要求使用绝对路径 [Install] #运行级别下服务安装的相关设置,可设置为多用户,即系统运行级别为3
重载系统服务: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
经过上面的处理后,就可以使用systemctl命令来启停redis了。
#授权启动服务
接下来,是授权启动服务需要用到的一些命令:
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 # 命令补全
systemctl daemon-reload
systemctl enable redis
#修改linux内核参数
# 临时生效
sysctl -w vm.overcommit_memory=1
# 永久生效
echo 'vm.overcommit_memory=1' >> /etc/sysctl.conf && sysctl -p
### 可选值:0,1,2。
# 0,:表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
# 1:表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
# 2: 表示内核允许分配超过所有物理内存和交换空间总和的内存。
#节点配置
#master节点配置
首先,我们打开master节点文件,文件位于vi/usr/local/redis/redis.conf目录下,然后修改配置如下:
bind 192.168.182.110 # 监听ip,多个ip用空格分隔
daemonize yes # 允许后台启动
logfile "/usr/local/redis/redis.log" # 日志路径
dir /opt/software/redis-7.0.3/data # 数据库备份文件存放目录
masterauth 123456 # slave连接master密码,master可省略
requirepass 123456 # 设置master连接密码,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中
#slave1节点配置
接着,我们打开slave1节点文件,文件位于vi/usr/local/redis/redis.conf,修改配置如下:
bind 192.168.182.111 # 监听ip,多个ip用空格分隔
daemonize yes # 允许后台启动
logfile "/usr/local/redis/redis.log" # 日志路径
dir /opt/software/redis-7.0.3/data # 数据库备份文件存放目录
# replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点。就是设置master节点
replicaof 192.168.182.110 6379
masterauth 123456 # slave连接master密码,master可省略
requirepass 123456 # 设置master连接密码,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中
#slave2节点配置
打开slave2的节点文件,文件位于vi/usr/local/redis/redis.conf,修改配置如下:
bind 192.168.182.112 # 监听ip,多个ip用空格分隔
daemonize yes # 允许后台启动
logfile "/usr/local/redis/redis.log" # 日志路径
dir /opt/software/redis-7.0.3/data # 数据库备份文件存放目录
# replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点。就是设置master节点
replicaof 192.168.182.110 6379
masterauth 123456 # slave连接master密码,master可省略
requirepass 123456 # 设置master连接密码,slave可省略
appendonly yes # 在/opt/software/redis-7.0.3/data目录生成appendonly.aof文件,将每一次写操作请求都追加到appendonly.aof 文件中
#启动Redis服务
systemctl start redis
systemctl status redis
#查看集群
然后,使用下面的命令查看集群的一些数据:
# 交互式
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的主数据库会不定时的向从数据库同步数据,如下图所示。
进一步,感兴趣的小伙伴可以再学习一下Redis的哨兵模式和Cluster模式。