搭建高可用Redis缓存

搭建高可用Redis缓存

前言

  • 什么是Redis

Redis:Remote Dictionary Server(远程字典服务器)。是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSQL数据库之一,也被人们称为数据结构服务器。

  • Redis与其他key - value缓存产品有以下三个特点:

1、Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

2、Redis不仅仅支持简单的key - value类型的数据,同时还提供list、set、zset、hash等数据结构的存储。

3、Redis支持数据的备份,即master - slave模式的数据备份。

Redis是一个高性能的key-value数据库,现时越来越多企业与应用使用Redis作为缓存服务器。在Linux服务器上搭建Redis,怎么可以不会呢?下面就开始依次搭建:Redis单机服务器 -> Redis主从复制 -> Redis-Sentinel高可用。逐步搭建出高可用的Redis缓存服务器。

搭建Redis

\1. 下载并解压

首先从Redis官网下载Redis并解压,使用的版本是4.0.2。依次执行如下命令:

cd /usr/local/src

wget http://download.redis.io/releases/redis-5.0.2.tar.gz

# tar zxvf redis-5.0.2.tar.gz

如果没有安装gcc依赖包,则安装对应依赖包

yum install -y gcc-c++ tcl

\2. 编译并安装

下载并解压完毕后,则对源码包进行编译安装,的Redis安装路径为/usr/local/redis,可以自行修改语句:make install PREFIX=你想要安装的路径

# mkdir /usr/local/redis

cd /usr/local/src/redis-5.0.2/

make install PREFIX=/usr/local/redis

复制Redis相关命令到/usr/sbin目录下,这样就可以直接执行这些命令,不用写全路径

[root@localhost redis]# cd /usr/local/redis/bin/

sudo cp redis-cli redis-server redis-sentinel /usr/sbin/

\3. 建立Redis配置文件

安装完成之后将 Redis 配置文件拷贝到系统配置目录/etc/下,redis.conf 是 Redis 的配置文件,redis.conf 在 Redis 源码目录,port默认 6379。

[root@localhost bin]# cp -rf /usr/local/src/redis-5.0.2/redis.conf /etc/ ##可以把配置文件里需要的信息留下

Redis配置文件主要参数解析参考

[root@localhost etc]# egrep -v '^$|^#' redis.conf 
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
  • 一个覆盖的方法
#先进行复制.bak文件,进行备份
[root@localhost etc]# cp -rf /etc/redis.conf{,.bak}
#截取有用部分,直接覆盖至源文件
[root@localhost etc]# egrep -v '^#|^$' /etc/redis.conf.bak >/etc/redis.conf
#参数说明
daemonize no       

 #redis进程是否以守护进程的方式运行,yes为是,no为否(不以守护进程的方式运行会占用一个终端)

pidfile /var/run/redis.pid    #指定redis进程的PID文件存放位置

port 6379       #redis进程的端口号

bind 127.0.0.1      #绑定的主机地址

timeout 300      #客户端闲置多长时间后关闭连接,默认此参数为0即关闭此功能

loglevel verbose     #redis日志级别,可用的级别有debug.verbose.notice.warning

logfile stdout      #log文件输出位置,如果进程以守护进程的方式运行,此处又将输出文件设置为stdout的话,就会将日志信息输出到/dev/null里面去了

databases 16      #设置数据库的数量,默认为0可以使用select <dbid>命令在连接上指定数据库id

save <seconds> <changes>   #指定在多少时间内刷新次数达到多少的时候会将数据同步到数据文件;

rdbcompression yes     #指定存储至本地数据库时是否压缩文件,默认为yes即启用存储;

dbfilename dump.db     #指定本地数据库文件名

dir ./        #指定本地数据问就按存放位置;

slaveof <masterip> <masterport> #指定当本机为slave服务时,设置master服务的IP地址及端口,在redis启动的时候他会自动跟master进行数据同步

masterauth <master-password>  #当master设置了密码保护时,slave服务连接master的密码;

requirepass footbared    #设置redis连接密码,如果配置了连接密码,客户端在连接redis是需要通过AUTH<password>命令提供密码,默认关闭

maxclients 128      #设置同一时间最大客户连接数,默认无限制;redis可以同时连接的客户端数为redis程序可以打开的最大文件描述符,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息

maxmemory<bytes>      #指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的vm机制,会把Key存放内存,Value会存放在swap区

appendonly no      #指定是否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no

appendfilename appendonly.aof  #指定跟新日志文件名默认为appendonly.aof

appendfsync everysec    #指定更新日志的条件,有三个可选参数no:表示等操作系统进行数据缓存同步到磁盘(快),always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全), everysec:表示每秒同步一次(折衷,默认值);

3.1 设置后端启动:

由于Redis默认是前端启动,必须保持在当前的窗口中,如果使用ctrl + c退出,那么Redis也就退出,不建议使用。

vi /etc/redis.conf

修改Redis配置文件把旧值daemonize no 改为 新值daemonize yes

3.2 设置访问:

Redis默认只允许本机访问,可是有时候我们也需要 Redis 被远程访问。

vi /etc/redis.conf

找到 bind 那行配置,默认是: # bind 127.0.0.1

去掉#注释并改为: bind 0.0.0.0 此设置会变成允许所有远程访问。如果想指定限制访问,可设置对应的IP。

3.3 配置Redis日志记录:

找到logfile那行配置,默认是:logfile "",改为logfile /var/log/redis_6379.log

3.4 设置 Redis 请求密码:

vi /etc/redis.conf

找到默认是被注释的这一行:# requirepass foobared

去掉注释,把 foobared 改为你想要设置的密码,比如我打算设置为:123456,所以我改为:requirepass "123456"

修改之后重启下服务

/usr/local/redis/bin/redis-server /etc/redis.conf

有了密码之后,进入客户端,就得这样访问:redis-cli -h 127.0.0.1 -p 6379 -a 123456

\4. Redis常用操作

4.1 启动

/usr/local/redis/bin/redis-server /etc/redis.conf

4.2 关闭

/usr/local/redis/bin/redis-cli -h 127.0.0.1 -p 6379 shutdown

4.3 查看是否启动

ps -ef | grep redis

4.4 进入客户端

redis-cli

4.5 关闭客户端

redis-cli shutdown

4.6 设置开机自动启动配置

echo "/usr/local/redis/bin/redis-server /etc/redis.conf" >> /etc/rc.local

4.7 开放防火墙端口

添加规则:iptables -I INPUT -p tcp -m tcp --dport 6379 -j ACCEPT

保存规则:service iptables save

重启 iptables:service iptables restart

\5. 将Redis注册为系统服务

在/etc/init.d目录下添加Redis服务的启动,暂停和重启脚本:

vi /etc/init.d/redis

脚本内容如下:

#!/bin/sh
#  
# redis - this script starts and stops the redis-server daemon  
#  
# chkconfig:   - 85 15  
# description:  Redis is a persistent key-value database  
# processname: redis-server  
# config:      /usr/local/redis/bin/redis-server
# config:      /etc/redis.conf  
# Source function library.  
. /etc/rc.d/init.d/functions  
# Source networking configuration.  
. /etc/sysconfig/network  
# Check that networking is up.  
[ "$NETWORKING" = "no" ] && exit 0  
redis="/usr/local/redis/bin/redis-server" 
prog=$(basename $redis)  
REDIS_CONF_FILE="/etc/redis.conf" 
[ -f /etc/sysconfig/redis ] && . /etc/sysconfig/redis  
lockfile=/var/lock/subsys/redis 
start() {  
   [ -x $redis ] || exit 5  
   [ -f $REDIS_CONF_FILE ] || exit 6  
   echo -n $"Starting $prog: "  
   daemon $redis $REDIS_CONF_FILE  
   retval=$?  
   echo  
   [ $retval -eq 0 ] && touch $lockfile  
   return $retval  
}  
stop() {  
   echo -n $"Stopping $prog: "  
   killproc $prog -QUIT  
   retval=$?  
   echo  
   [ $retval -eq 0 ] && rm -f $lockfile  
   return $retval  
}  
restart() {  
   stop  
   start  
}  
reload() {  
   echo -n $"Reloading $prog: "  
   killproc $redis -HUP  
   RETVAL=$?  
   echo  
}  
force_reload() {  
   restart  
}  
rh_status() {  
   status $prog  
}  
rh_status_q() {  
   rh_status >/dev/null 2>&1  
}  
case "$1" in  
   start)  
       rh_status_q && exit 0  
       $1  
       ;;  
   stop)  
       rh_status_q || exit 0  
       $1  
       ;;  
   restart|configtest)  
       $1  
       ;;  
   reload)  
       rh_status_q || exit 7  
       $1  
       ;;  
   force-reload)  
       force_reload  
       ;;  
   status)  
       rh_status  
       ;;  
   condrestart|try-restart)  
       rh_status_q || exit 0  
   ;;  
   *)  
       echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart| reload|orce-reload}"  
       exit 2  
esac

赋予脚本权限

chmod 755 /etc/init.d/redis

启动并查看状态

[root@localhost init.d]# /etc/init.d/redis status
● redis.service - SYSV: Redis is a persistent key-value database
  Loaded: loaded (/etc/rc.d/init.d/redis)
  Active: active (exited) since 三 2020-02-12 05:05:54 CST; 1min 42s ago
    Docs: man:systemd-sysv-generator(8)
 Process: 8572 ExecStart=/etc/rc.d/init.d/redis start (code=exited, status=0/SUCCESS)

2月 12 05:05:53 localhost.localdomain systemd[1]: Starting SYSV: Redis is a persistent key-val.....
2月 12 05:05:54 localhost.localdomain systemd[1]: Started SYSV: Redis is a persistent key-valu...e.
Hint: Some lines were ellipsized, use -l to show in full.

[root@localhost init.d]# /etc/init.d/redis status
● redis.service - SYSV: Redis is a persistent key-value database
  Loaded: loaded (/etc/rc.d/init.d/redis)
  Active: active (exited) since 三 2020-02-12 05:05:54 CST; 1min 42s ago
    Docs: man:systemd-sysv-generator(8)
 Process: 8572 ExecStart=/etc/rc.d/init.d/redis start (code=exited, status=0/SUCCESS)

2月 12 05:05:53 localhost.localdomain systemd[1]: Starting SYSV: Redis is a persistent key-val.....
2月 12 05:05:54 localhost.localdomain systemd[1]: Started SYSV: Redis is a persistent key-valu...e.
Hint: Some lines were ellipsized, use -l to show in full.

设置开机自启

echo "/usr/local/redis/bin/redis-server /etc/redis.conf" >> /etc/rc.local

启动、停止和重启:

service redis start

service redis stop

service redis restart

至此,Redis单机服务器已搭建完毕,下面我们看看主从架构如何搭建。

以上主服务器就搭建好了,然后再创建一个虚拟机进行搭建从服务器

从主服务器上复制redis.tar.gz 包

[root@localhost src]# scp /usr/local/src/redis-5.0.2.tar.gz  192.168.200.120:/root/
The authenticity of host '192.168.200.120 (192.168.200.120)' can't be established.
ECDSA key fingerprint is 26:9d:b1:37:68:e4:45:bd:22:f7:31:d2:59:c7:71:9d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.200.120' (ECDSA) to the list of known hosts.
root@192.168.200.120's password: 
redis-5.0.2.tar.gz                                                100% 1907KB   1.9MB/s   00:00 

从节点的配置文件

[root@localhost etc]# cat redis.conf
bind 0.0.0.0             #从节点需要更改
protected-mode no        #从节点需要更改
slaveof 192.168.200.160  #从节点需要增加
masterauth 123456        #从节点需要增加
port 6379   #从节点需要增加,这个端口是多少,等会登陆进redis的时候,-p后面加的端口就得是多少,redis-cli -h 127.0.0.1 -p 6379 -a 123456
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes            #从节点需要增加
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

然后把主节点的 /etc/init.d/redis 复制到 从节点里

[root@localhost src]# scp  /etc/init.d/redis 192.168.200.120:/etc/init.d/redis
root@192.168.200.120's password: 
redis                                                             100% 1944     1.9KB/s   00:00  

之后进行启动从节点

[root@localhost ~]# ps -ef |grep redis
root      38351   3688  0 23:58 pts/1    00:00:00 grep --color=auto redis

[root@localhost ~]# /usr/local/redis/bin/redis-server /etc/redis.conf
38361:C 28 Dec 2019 23:58:58.200 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
38361:C 28 Dec 2019 23:58:58.200 # Redis version=5.0.2, bits=64, commit=00000000, modified=0, pid=38361, just started
38361:C 28 Dec 2019 23:58:58.200 # Configuration loaded

[root@localhost ~]# /etc/init.d/redis status
Unit redis.service could not be found.

[root@localhost ~]# ps -ef |grep redis                               
root      38362      1  0 23:58 ?        00:00:00 /usr/local/redis/bin/redis-server 0.0.0.0:6380
root      38379   3688  0 23:59 pts/1    00:00:00 grep --color=auto redis

[root@localhost ~]# /etc/init.d/redis status
Unit redis.service could not be found.

[root@localhost ~]# /etc/init.d/redis stop
Reloading systemd:                                         [  确定  ]
Stopping redis (via systemctl):                            [  确定  ]

[root@localhost ~]# /etc/init.d/redis status
● redis.service - SYSV: Redis is a persistent key-value database
   Loaded: loaded (/etc/rc.d/init.d/redis; bad; vendor preset: disabled)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)

[root@localhost ~]# /etc/init.d/redis start
Starting redis (via systemctl):                            [  确定  ]

[root@localhost ~]# /etc/init.d/redis status
● redis.service - SYSV: Redis is a persistent key-value database
   Loaded: loaded (/etc/rc.d/init.d/redis; bad; vendor preset: disabled)
   Active: active (exited) since 六 2019-12-28 23:59:54 CST; 49s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 38448 ExecStart=/etc/rc.d/init.d/redis start (code=exited, status=0/SUCCESS)

12月 28 23:59:54 localhost.localdomain systemd[1]: Starting SYSV: Redis is a persistent key-va.....
12月 28 23:59:54 localhost.localdomain systemd[1]: Started SYSV: Redis is a persistent key-val...e.
Hint: Some lines were ellipsized, use -l to show in full.


#修改配置要重启服务
[root@localhost ~]# /etc/init.d/redis restart               

查看

#查看主节点
[root@localhost etc]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.200.120,port=6380,state=online,offset=336,lag=1
master_replid:f34e55b755b64c119beed991cf0031f7aac63d60
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:336
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:336

#查看从节点
[root@localhost ~]# redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> INFO replication
# Replication
role:slave
master_host:192.168.200.160
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:546
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:f34e55b755b64c119beed991cf0031f7aac63d60
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:546
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:449
repl_backlog_histlen:98

搭建Redis主从架构

\1. redis-server说明

192.168.100.30:6379 主

192.168.100.60:6379 从

\2. Redis主从架构配置

编辑从机的 Redis 配置文件,找到 210 行(大概),默认这一行应该是注释的: # slaveof

我们需要去掉该注释,并且填写我们自己的主机的 IP 和 端口,比如:slaveof 192.168.100.30 6379,如果主机设置了密码,还需要找到masterauth 这一行,去掉注释,改为masterauth 主机密码。

配置完成后重启从机Redis 服务

重启完之后,进入主机的 redis-cli 状态下redis-cli -h 127.0.0.1 -p 6379 -a 123456,输入:INFO replication 可以查询到当前主机的 Redis处于什么角色,有哪些从机已经连上主机。

主机信息192.168.100.30

# Replication

role:master

connected_slaves:1

slave0:ip=192.168.100.60,port=6379,state=online,offset=28,lag=1

master_replid:625ae9f362643da5337835beaeabfdca426198c7

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:28

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:28

从机信息192.168.100.60

# Replication

role:slave

master_host:192.168.100.30

master_port:6379

master_link_status:up

master_last_io_seconds_ago:3

master_sync_in_progress:0

slave_repl_offset:210

slave_priority:100

slave_read_only:1

connected_slaves:0

master_replid:625ae9f362643da5337835beaeabfdca426198c7

master_replid2:0000000000000000000000000000000000000000

master_repl_offset:210

second_repl_offset:-1

repl_backlog_active:1

repl_backlog_size:1048576

repl_backlog_first_byte_offset:1

repl_backlog_histlen:210

此时已经完成了主从配置,我们可以测试下: 我们进入主机的 redis-cli 状态,然后 set 某个值,比如:set myblog YouMeek.com

我们切换进入从机的 redis-cli 的状态下,获取刚刚设置的值看是否存在:get myblog,此时,我们可以发现是可以获取到值的。

\3. Redis主从架构总结

需要注意的是:从库不具备写入数据能力,不然会报错。 从库只有只读能力。

主从架构的优点:除了减少主库连接的压力,还有可以关掉主库的持久化功能,把持久化的功能交给从库进行处理。

第一个从库配置的信息是连上主库,后面的第二个从库配置的连接信息是连上第一个从库, 假如还有第三个从库的话,我们可以把第三个从库的配置信息连上第二个从库上,以此类推。

Redis Sentinel高可用架构搭建

\1. 自动故障转移

虽然使用主从架构配置Redis做了备份,看上去很完美。但由于Redis目前只支持主从复制备份(不支持主主复制),当主Redis挂了,从Redis只能提供读服务,无法提供写服务。所以,还得想办法,当主Redis挂了,让从Redis升级成为主Redis。

这就需要自动故障转移,Redis Sentinel带有这个功能,当一个主Redis不能提供服务时,Redis Sentinel可以将一个从Redis升级为主Redis,并对其他从Redis进行配置,让它们使用新的主Redis进行复制备份。

注意:搭建Redis Sentinel推荐至少3台服务器,但由于偷懒,下面用例只用了2台服务器。

Redis Sentinel的主要功能如下:

监控:哨兵不断的检查master和slave是否正常的运行。

通知:当监控的某台Redis实例发生问题时,可以通过API通知系统管理员和其他的应用程序。

自动故障转移:如果一个master不正常运行了,哨兵可以启动一个故障转移进程,将一个slave升级成为master,其他的slave被重新配置使用新的master,并且应用程序使用Redis服务端通知的新地址。

配置提供者:哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址。

默认情况下,每个Sentinel节点会以每秒一次的频率对Redis节点和其它的Sentinel节点发送PING命令,并通过节点的回复来判断节点是否在线。

如果在down-after-millisecondes毫秒内,没有收到有效的回复,则会判定该节点为主观下线。

如果该节点为master,则该Sentinel节点会通过sentinel is-master-down-by-addr命令向其它sentinel节点询问对该节点的判断,如果超过个数的节点判定master不可达,则该sentinel节点会将master判断为客观下线。

这个时候,各个Sentinel会进行协商,选举出一个领头Sentinel,由该领头Sentinel对master节点进行故障转移操作。

故障转移包含如下三个操作:

在所有的slave服务器中,挑选出一个slave,并将其转换为master。

让其它slave服务器,改为复制新的master。

将旧master设置为新master的slave,这样,当旧的master重新上线时,它会成为新master的slave。

\2. 搭建Redis Sentinel高可用架构

这里使用两台服务器,每台服务器上开启一个redis-server和redis-sentinel服务。

redis-server说明

192.168.100.30:6379 主

192.168.100.60:6379 从

redis-sentinel说明

192.168.100.30:26379

192.168.100.60:26379

2.1 建立Redis配置文件

如果要做自动故障转移,则建议所有的redis.conf都设置masterauth,因为自动故障只会重写主从关系,即slaveof,不会自动写入masterauth。如果Redis原本没有设置密码,则可以忽略。

Redis程序上面已经安装过了,我们只需增加redis-sentinel的相关配置即可,将 redis-sentinel的配置文件拷贝到系统配置目录/etc/下,sentinel.conf 是 redis-sentinel的配置文件,sentinel.conf 在 Redis 源码目录。

cp /usr/local/redis-4.0.2/sentinel.conf /etc/

修改sentinel.conf配置文件内容如下:

vi /etc/sentinel.conf

protected-mode no

sentinel monitor mymaster 192.168.100.30 6379 2

# redis在搭建时设置了密码,所以要进行密码配置

sentinel auth-pass mymaster “123456“

#5秒内mymaster没有响应,就认为SDOWN

sentinel down-after-milliseconds mymaster 5000

sentinel failover-timeout mymaster 15000

在配置最后加上

logfile /var/log/sentinel.log

pidfile /var/run/sentinel.pid

daemonize yes

配置文件说明:

1.port :当前Sentinel服务运行的端口

2.dir : Sentinel服务运行时使用的临时文件夹

3.sentinel monitor master001 192.168.110.10163792:Sentinel去监视一个名为master001的主redis实例,这个主实例的IP地址为本机地址192.168.110.101,端口号为6379,而将这个主实例判断为失效至少需要2个 Sentinel进程的同意,只要同意Sentinel的数量不达标,自动failover就不会执行

4.sentinel down-after-milliseconds master001 30000:指定了Sentinel认为Redis实例已经失效所需的毫秒数。当实例超过该时间没有返回PING,或者直接返回错误,那么Sentinel将这个实例标记为主观下线。只有一个 Sentinel进程将实例标记为主观下线并不一定会引起实例的自动故障迁移:只有在足够数量的Sentinel都将一个实例标记为主观下线之后,实例才会被标记为客观下线,这时自动故障迁移才会执行

5.sentinel parallel-syncs master001 1:指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例,在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长

6.sentinel failover-timeout master001 180000:如果在该时间(ms)内未能完成failover操作,则认为该failover失败

7.sentinel notification-script :指定sentinel检测到该监控的redis实例指向的实例异常时,调用的报警脚本。该配置项可选,但是很常用

2.2 开放防火墙端口

添加规则:iptables -I INPUT -p tcp -m tcp --dport 26379 -j ACCEPT

保存规则:service iptables save

重启 iptables:service iptables restart

2.3 启动redis-sentinel

redis-sentinel /etc/sentinel.conf

在任意一台机子均可查看到相关服务信息

redis-cli -h 127.0.0.1 -p 26379

INFO sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=mymaster,status=ok,address=192.168.100.30:6379,slaves=1,sentinels=2

\3. 自动故障转移测试

3.1 停止主Redis

redis-cli -h 192.168.100.30 -p 6379 -a 123456 shutdown

3.2 查看redis-sentinel的监控状态

# Sentinel

sentinel_masters:1

sentinel_tilt:0

sentinel_running_scripts:0

sentinel_scripts_queue_length:0

sentinel_simulate_failure_flags:0

master0:name=mymaster,status=ok,address=192.168.100.60:6379,slaves=1,sentinels=2

发现从库提升为主库。

3.3 注意事项

如果停掉master后,Sentinel显示足够数量的sdown后,没有出现odown或try-failover,则检查密码等配置是否正确

如果停掉master后,试图切换的时候,发现日志出现 failover-abort-not-elected,则分2种情况分别解决:

如果Redis实例没有配置

protected-mode yes

bind 192.168.100.30

则在Sentinel 配置文件加上protected-mode no即可

如果Redis实例有配置

protected-mode yes

bind 192.168.100.30

则在Sentinel配置文件加上

protected-mode yes

bind 192.168.100.30

至此,redis的高可用方案已经搭建完成。

原文链接: https://www.cnblogs.com/function123/p/13336123.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    搭建高可用Redis缓存

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/368253

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午6:18
下一篇 2023年3月2日 下午6:19

相关推荐