Redis安装-主从复制

478 阅读14分钟
作者 日期 节日
元公子 2020-01-29(周三) 年初五,迎财神,吃韭菜蒸饺

你知道的越少,你不知道的就越少

没有朋友的点赞,就没法升级打怪

一、闲聊

Redis从部署层面来讲的话,目前应该有这四种策略:单机硬抗、主从复制、哨兵和集群。 单机的意思是,一台服务器只安装了一个redis,给应用客户端提供全方位的读写服务。服务异常重启后,数据丢失也无所谓,只当个与Memcached类似的缓存或者分布式锁来使用。

主从复制和哨兵,最好要配合着使用。如果半夜服务挂了,您就这么想亲力亲为来处理的话,那就不使用哨兵,满足您的任性。

集群呢,他一方面可以单独部署使用,提供高并发、高可用的分布式读写缓存服务,也就是单机的pro版本。另一方面,可以与主从复制和哨兵一起来组成最完美的战队,增强数据持久化方面的能力。

考虑到全部放一篇来讲的话,篇幅会比较长。写的累,亲们看的也烦躁。这里计划拆为三篇来讲,一切出发点都是为了更好地服务好各位好汉。

二、自觉是关键点的总结

RDB文件:在shutdown redis服务或者执行save、bgsave等命令时才会生成,启动时不生成。

AOF文件:在start redis服务或者开启其功能时(config set appendonly yes)生成,shutdown redis服务不生成。随时启用AOF都没问题,它会把内存中的值转换为RDB存在AOF文件开头。

在启动redis服务时,如已开启AOF ,会读AOF文件。 如没有开启,只开启了RDB, 会读dump文件。总之,AOF优先级最高,而且只读一种文件。

如果所有服务都关闭重启,如AOF没有设置,需手工修改conf配置文件,追加一行appendonly yes后,才可启动服务,正常读取AOF文件。启动后再删除此行。注意:启动后再开启AOF,会重新覆盖生成aof文件,导致丢失原aof文件内容

从节点当同步完成后,需要删除旧数据集,加载新数据,这个时候才会暂停对外服务。

redis在写RDB文件的时候不会执行AOF rewrite,在执行AOF rewrite的时候不会生成新的RDB。如果redis正在生成新的RDB文件,此时用户执行bgrewriteaof命令手动重写AOF文件,那么需等RDB快照生成之后,才会去执行AOF rewrite。

当主库宕机时候,需要将从节点中的某一台提升为主库。我们需要在所有从节点中找到当前的offset最大值的从库(这样代表该库相对其他从库数据较全),然后执行slaveof no one将该从库提升为主库,开启AOF日志,最后将所有其他重库依次执行slaveof ip port(ip和port是新主库的IP地址和端口),最后完成故障切换。

backlog_size = 重启从实例时长 * 主实例offset每秒写入量。调整方式通过config set repl-backlog-size <字节数>

三、开始安装

部署的目标:一个主节点(master),两个复制节点(replica),主节点给两个复制节点发送备份数据。(replica节点也可以连接其它replica节点)这里演示是把三个节点部署在一台机器,但生产环境最好分开。区别上就是各节点信息基本上都是同个copy,改改与IP有关的参数即可,规划如下:

IP地址 属性 端口号 服务 RDB AOF 配置文件路径
192.168.0.2 主节点 6380 默认读写 开启 默认禁用,命令开启 ~/redis/leader-follower/6380.conf
192.168.0.2 从节点 6381 默认读 开启 默认禁用 ~/redis/leader-follower/6381.conf
192.168.0.2 从节点 6382 默认读 开启 默认禁用 ~/redis/leader-follower/6382.conf
  1. 软件部署在/soft/redis目录。安装可参考官方GitHub描述
# 在任一目录下解压文件,但不要在/soft目录下。
[root@hadoop-master /root/download]# tar -xvzf redis-5.0.7.tar.gz
[root@hadoop-master /root/download]# cd redis-5.0.7
# 编译源码
[root@hadoop-master /root/download/redis-5.0.7]# make
[root@hadoop-master /root/download/redis-5.0.7]# cd src
# 安装到/soft/redis目录
# 如执行出错,需安装gcc。参考命令:yum -y install gcc gcc-c++ automake autoconf libtool make
[root@hadoop-master /root/download/redis-5.0.7/src]# make install PREFIX=/soft/redis
  1. 生成默认的配置文件和自启动服务

使用官方提供的向导方式生成配置文件。(也可以选择使用该目录下redis.conf配置文件的方式)

# 首先,创建存放配置文件的目录
[root@hadoop-master /root/download/redis-5.0.7/src]# mkdir -p ~/redis/leader-follower
[root@hadoop-master /root/download/redis-5.0.7/src]# ../utils/install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
# 端口号,回车及使用[]中的内容默认同意。
Please select the redis port for this instance: [6379] 6380
# 配置文件所在路径
Please select the redis config file name [/etc/redis/6380.conf] /root/redis/leader-follower/6380.conf
# 日志文件所在路径
Please select the redis log file name [/var/log/redis_6380.log] /root/redis/leader-follower/logs/redis_6380.log
# 数据文件所在路径
Please select the data directory for this instance [/var/lib/redis/6380] 
/root/redis/leader-follower/data/6380
# 启动命令所在路径
Please select the redis executable path [] /soft/redis/bin/redis-server
Selected config:
Port           : 6380
Config file    : /root/redis/leader-follower/6380.conf
Log file       : /root/redis/leader-follower/logs/redis_6380.log
Data dir       : /root/redis/leader-follower/data/6380
Executable     : /soft/redis/bin/redis-server
Cli Executable : /soft/redis/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
# 自启动服务所在路径(redis的客户体验点赞)
Copied /tmp/6380.conf => /etc/init.d/redis_6380
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
# 查看进程已启动
[root@hadoop-master /root/download/redis-5.0.7/src]# ps -aux | grep redis
[root@hadoop-master /root/download/redis-5.0.7/src]# service redis_6380 stop
  1. 设置环境变量
[root@hadoop-master /root/download/redis-5.0.7/src]# vi /etc/profile
export REDIS_HOME=/soft/redis
export PATH=$PATH:$REDIS_HOME/bin
执行保存: Esc :wq
[root@hadoop-master /root/download/redis-5.0.7/src]# source /etc/profile
[root@hadoop-master /root/download/redis-5.0.7/src]# redis-server -v
Redis server v=5.0.7 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=1f9ee37ab6425904
  1. 整理每个节点的配置文件

这里的做法是,先提取一些有共性的内容形成单独的配置文件,其它的配置文件按需引此文件

参数项源码路径:redis/src/config.c

  • common.conf(公共配置)
[root@hadoop-master /root/download/redis-5.0.7/src]# vi ~/redis/common.conf
# 守护线程方式,默认no
daemonize yes
# 密码,默认为无
requirepass redis
# replica输入master的认证口令
masterauth redis
# 数据文件名称,默认dump.rdb
dbfilename dump.rdb
# 保存RDB机制:每多少秒有多少条修改记录触发保存,例如第一行:每900秒 有1个修改记录
# 如果只存在save "",则禁止本地保存数据(取消定时任务)
save 900 1
#save 300 10
#save 60 10000

# 重要:快照同步的超时时间。如RDB文件大,需调高时间。默认60秒
repl-timeout 60
# 最近一次save操作失败则停止写操作,默认yes
stop-writes-on-bgsave-error no
# 是否开启主从节点复制数据的延迟机制,默认no(开启延迟)。适用于主从网络环境复杂或带宽紧张的场景。
# 如果主从之间的网络带宽好,可调整为yes(禁用延迟)。
repl-disable-tcp-nodelay yes
# 重要:backlog环形缓冲区队列大小,默认1mb。backlog设置的越大,replica可以失连的时间就越长。单位:b、k、kb、m、mb、g、gb,不区分大小写。
repl-backlog-size 5mb
# 重要:backlog环形缓冲区队列存活时长(所有replica不可用时,保留repl_backlog多长时间,单位:秒)
repl-backlog-ttl 3600
# 无盘复制,默认no
repl-diskless-sync yes
# 无盘复制的延迟时间,默认为5s。等待一个上车批次的replica加入进来。后来的replica,还需创建新快照。
repl-diskless-sync-delay 5
# replica和master的心跳时间,默认10s
repl-ping-replica-period 10

# 重要:Redis的一个保护机制,输出缓冲限制:通过客户端返回值大小,来决定是否关闭客户端的连接。
# 硬限制,当某一个客户端的缓冲区超过某一个大小值时,直接关闭这个客户端的连接;
# 软限制,当某一个客户端的缓冲区持续一段时间占用过大空间时,会直接关闭客户端连接。
# 普通客户端、发布/订阅模式、replica客户端
# replica客户端大小限制是256M,持续性限制是当客户端缓冲区大小持续60秒超过64M。
client-output-buffer-limit replica 256mb 64mb 60

# master对外提供服务的条件:当一个master端的可用replica少于N个,延迟时间大于M秒时,不接收写操作。
# replica的数量小于这个配置设置的值,将拒绝对外提供服务。0代表不管replica,永远提供服务,除非自己挂掉。。。
min-slaves-to-write 1
# replica与主节点心跳时间,单位秒。
min-slaves-max-lag 10
# master挂了或者主从同步中,从节点是否对外提供服务。
slave-serve-stale-data yes

# AOF文件名称,默认"appendonly.aof"
appendfilename "appendonly.aof"
# AOF写入磁盘策略:默认每秒钟刷写一次。always:有新数据则马上刷写,no:按OS自身的刷写策略(看操作系统的心情决定)。
appendfsync everysec
# 指定是否在后台aof文件rewrite期间调用fsync,默认为no,表示appendfsync会被阻塞。此操作不会丢失数据,但是要忍受阻塞的问题(IO频繁)。
# 重要:设置为yes,非阻塞,表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入。按操作系统的默认设置,最多会丢失30s的数据,同appendfsync no。
no-appendfsync-on-rewrite no
# 重要:bgrewriteaof重写AOF的机制(整理压缩)。percentage:以上一次文件的大小比较
# auto-aof-rewrite-percentage 0 设置为0,重写功能则会关闭。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# AOF不完整是否加载,默认yes,加载。no:报错
aof-load-truncated yes
# 混合持久化开关,默认yes
aof-use-rdb-preamble yes

执行保存: Esc :wq
  • 6380.conf(主节点)
[root@hadoop-master /root]# mv ~/redis/leader-follower/6380.conf ~/redis/leader-follower/6380.conf.bak 
[root@hadoop-master /root]# vi ~/redis/leader-follower/6380.conf
# 本机IP,不能使用域名
bind 192.168.0.2
# 监听端口
port 6380
# 日志文件路径
logfile /root/redis/leader-follower/logs/redis_6380.log
# 进程文件路径,默认/var/run/redis_端口号.pid
pidfile /root/redis/leader-follower/run/redis_6380.pid
# 数据文件路径
dir /root/redis/leader-follower/data/6380

include /root/redis/common.conf

执行保存: Esc :wq
  • 6381.conf 、6382.conf(从节点)
# 通过命令快速生成配置文件,替换端口号
[root@hadoop-master /root]# sed "s/6380/6381/g" ~/redis/leader-follower/6380.conf > ~/redis/leader-follower/6381.conf 
[root@hadoop-master /root]# sed "s/6380/6382/g" ~/redis/leader-follower/6380.conf > ~/redis/leader-follower/6382.conf 
  1. 新增另外两个节点的自启动服务
# 修改启动服务文件
[root@hadoop-master /root]# vi /etc/init.d/redis_6380
# 找到PIDFILE=/var/run/redis_6380.pid行,替换为下面内容
#PIDFILE=/var/run/redis_6380.pid
PIDFILE=/root/redis/leader-follower/run/redis_6380.pid
# 修改stop分支的脚本
    stop)
        if [ ! -f $PIDFILE ]
        then
            echo "$PIDFILE does not exist, process is not running"
        else
            PID=$(cat $PIDFILE)
            echo "Stopping ..."
            $CLIEXEC -h 192.168.146.131 -p $REDISPORT -a redis shutdown 2>/dev/null
            while [ -x /proc/${PID} ]
            do
                echo "Waiting for Redis to shutdown ..."
                sleep 1
            done
            rm -f $PIDFILE
            echo "Redis stopped"
        fi
        ;;
执行保存: Esc :wq

[root@hadoop-master /root]# sed "s/6380/6381/g" /etc/init.d/redis_6380 > /etc/init.d/redis_6381
[root@hadoop-master /root]# sed "s/6380/6382/g" /etc/init.d/redis_6380 > /etc/init.d/redis_6382
[root@hadoop-master /root]# chmod +x /etc/init.d/redis_6381
[root@hadoop-master /root]# chmod +x /etc/init.d/redis_6382

[root@hadoop-master /root]# chkconfig --add /etc/init.d/redis_6381
[root@hadoop-master /root]# chkconfig redis_6381 on
[root@hadoop-master /root]# chkconfig --add /etc/init.d/redis_6382
[root@hadoop-master /root]# chkconfig redis_6382 on

[root@hadoop-master /root]# mkdir -p /root/redis/leader-follower/data/6381
[root@hadoop-master /root]# mkdir -p /root/redis/leader-follower/data/6382
[root@hadoop-master /root]# mkdir -p /root/redis/leader-follower/run

其它关联指令:

  • 启动:service redis_6380 start
  • 停止:service redis_6380 stop
  • 重启:service redis_6380 restart
  • 关闭自启动:chkconfig redis_6380 off
  • 删除自启动:chkconfig --del redis_6380

四、启动测试

先按第五节内容处理下三个常见的启动警告问题后,再启动服务。注意:手动配置的方式,信息保留在内存,重启服务后失效

[root@hadoop-master /root]# service redis_6380 start
[root@hadoop-master /root]# service redis_6381 start
[root@hadoop-master /root]# service redis_6382 start
# 手动开启主节点AOF
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis config set appendonly yes

# 设置从节点,6381和6382服务连接到6380主节点服务
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6381 -a redis replicaof 192.168.0.2 6380
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6382 -a redis replicaof 192.168.0.2 6380

# 查看信息
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=192.168.0.2,port=6381,state=online,offset=84,lag=1
slave1:ip=192.168.0.2,port=6382,state=online,offset=84,lag=1
master_replid:7e3e3e84596a7908b0c46412bb934a157ed844bd
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:84
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:5242880
repl_backlog_first_byte_offset:1
repl_backlog_histlen:84
# 连接主节点,新增笔数据
[root@hadoop-master /root/redis/leader-follower/data/6380]# redis-cli -h 192.168.0.2 -p 6380 -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.2:6380> set a 1
OK
# 连接一个从节点,读取数据。只读模式,不能写入
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6381 -a redis
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
192.168.0.2:6381> get a
"1"
192.168.0.2:6381> set c 1
(error) READONLY You can't write against a read only replica.

辅助命令

# 检查RDB文件
[root@hadoop-master /root]# redis-check-rdb /root/redis/leader-follower/data/dump.rdb
# 检查AOF文件
[root@hadoop-master /root]# redis-check-aof /root/redis/leader-follower/data/6380/appendonly.aof
# 修复AOF文件
[root@hadoop-master /root]# redis-check-aof --fix /root/redis/leader-follower/data/6380/appendonly.aof

# 关闭RDB功能  
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis config set save "" 
# 查看配置信息
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis config get *append*
# 偏移量
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis info replication | grep master_repl
# 查看持久化信息
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis info persistence
# 查看状态信息
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis info stats
# 查看runid
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis info | grep run
# save当前的rdb文件,并清空当前数据库,重新加载rdb(会阻塞当前 Redis 节点主线程)
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis debug reload

# 重写AOF
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis bgrewriteaof
# 生成新rdb
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis bgsave
# 或者
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6380 -a redis save

# 从节点可写
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6381 -a redis config set slave-read-only no
# 取消从节点
[root@hadoop-master /root]# redis-cli -h 192.168.0.2 -p 6381 -a redis replicaof no one

五、偶遇的坑

Redis启动三个常见的警告问题

  1. WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

    描述为:高负载下tcp连接数小

    #在最后面增加
    [root@hadoop-master /root]# vi /etc/sysctl.conf
    net.core.somaxconn=1024
    执行保存: Esc :wq
    # 永久生效
    [root@hadoop-master /root]# sysctl -p
    
  2. WARNING overcommit_memory is set to 0! Background save may fail under low memory condition.

    描述为:在内存不足的情况下,后台程序保存数据服务(猜测是快照RDB)可能失败

    # 1表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
    [root@hadoop-master /root]# vi /etc/sysctl.conf
    vm.overcommit_memory=1
    执行保存: Esc :wq
    # 永久生效
    [root@hadoop-master /root]# sysctl -p
    
  3. WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis.

    描述为:使用了透明大页,可能导致redis延迟和内存使用问题(猜测是与vm功能有关)

    # 增加开机时执行的脚本
    [root@hadoop-master /root]# vi /etc/rc.local
    # 添加以下内容:禁用THP
    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    执行保存: Esc :wq
    [root@hadoop-master /root]# source /etc/rc.local
    

附录:

官方文档:

资料检索: