准备条件
系统版本 | 内核版本 | Redis版本 |
---|---|---|
CentOS release 6.4 (Final) | 2.6.32-358.el6.x86_64 | redis-2.8.9 |
硬件服务器配置:
Cpu | 内存 | 硬盘 |
---|---|---|
4c 2.1GHZ | 6G | 200G |
部署规划
主节点:172.16.0.1
从节点:172.16.0.2
一 Redis 主从复制
主从复制是指将一台 Redis 服务器的数据,复制到其它的 Redis 服务器。
前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台 Redis 服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
主从复制的作用:
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,但实际上是一种服务的冗余
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量
高可用:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础
1、Redis配置步骤
本次实现1主1从节点部署 (以下配置需两台同样操作)
1.1首先确认系统中是否存在c语言的编译环境
#gcc --version
或者#g++ --version
yum -y install gcc
1.2下载redis
wget http://download.redis.io/releases/redis-2.8.9.tar.gz
1.3 解压
# tar zxvf redis-2.8.9.tar.gz
# mv redis-2.8.9 /usr/local/redis
# cd redis
1.4安装
# make
# make test
遇到报错1
.Executing test client: NOREPLICAS Not enough good slaves to write..
可以修改文件tests/integration/replication-2.tcl,将after 1000改为after 10000以延长等待时间。
报错2
make[1]: Entering directory/usr/local/redis/src' You need tcl 8.5 or newer in order to run the Redis test make[1]: *** [test] Error 1 make[1]: Leaving directory
/usr/local/redis/src'
解决2 wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz
tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/
cd /usr/local/tcl8.6.1/unix/
./configure
make
make install
# make test
# make install PREFIX=/usr/local/redis PREFIX安装指定目录 否则安装到/usr/local/bin里面了
1.5修改配置文件
vim /usr/local/redis/redis.conf
bind 0.0.0.0
port 6379
timeout 0
daemonize yes
pidfile /var/run/redis6379.pid
loglevel debug
logfile /var/log/redis6379.log
1.6 启动
# cd /usr/local/redis/bin
# ./redis-server ../redis.conf &
检查端口是否运行
netstat -unltp | grep redis
连接redis
redis-cli
quit
2、redis主从部署
1.1配置master
vim /usr/local/redis/redis.conf
daemonize yes
pidfile "/var/run/redis6379.pid"
port 6379
bind 0.0.0.0
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/var/log/redis6379.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename "dump_6379.rdb"
#dir /usr/local/redis/dir/redis_6379"
maxmemory 4gb
slave-read-only yes
slave-serve-stale-data yes
repl-disable-tcp-nodelay no
slave-priority 100
appendonly no
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
杀掉之前的redis
netstat -unltp | grep redis #查看进程pid号
kill -9 pid号
启动master的redis
# cd /usr/local/redis/bin
# ./redis-server ../redis.conf &
netstat -unltp |grep redis
验证是否为master
redis-cli -p 6379 info | grep role
1.2 配置slave
vim /usr/local/redis/redis.conf
#配置和主配置一样,需要在下面添加
slaveof 172.16.0.1 6379 #指定主节点服务器
slaveof <masterip> <masterport> 永久为从
在配置文件中直接修改 slaveof 属性,直接配置主服务器的ip 地址,和端口号,如果这里主服务器有配置连接密码可以通过配置masterauth 来设置连接密码
杀掉之前的redis
netstat -unltp | grep redis #查看进程pid号
kill -9 pid号
启动master的redis
# cd /usr/local/redis/bin
# ./redis-server ../redis.conf &
netstat -unltp |grep redis
验证是否为master
redis-cli -p 6379 info | grep role
验证主从是否同步(1:6379和2:6379)
# redis-cli -h 172.16.0.1 -p 6379
172.16.0.1:6379> set ma right
OK
172.16.0.1:6379> set Li class2
OK
172.16.0.1:6379> keys *
1) "ma"
2) "Li"
172.16.0.1:6379>
[root@bogon redis]# redis-cli -h 172.16.0.2 -p 6379
172.16.0.2:6379> keys *
1) "ma"
2) "Li"
3) "fangchan"
172.16.0.2:6379>
主从同步正常
从库默认是只读的
172.16.0.1:6379> set lll beaty
(error) READONLY You can't write against a read only slave.
3 redis主从切换测试
172.16.0.1:6379 主,172.16.0.2:6379从
步骤 1、停止主库redis
# redis-cli -h 172.16.0.1 -p 6379 shutdown
步骤 2、将从172.16.0.2 redis设为主redis
[root@bogon redis]# redis-cli -h 172.16.0.2 -p 6379 slaveof NO ONE
OK
步骤 3、测试从redis是否切换为主redis
[root@bogon redis6379]# redis-cli -h 172.16.0.2 -p 6379
172.16.0.2:6379> set apu new
OK
172.16.0.2:6379> get apu
"new"
172.16.0.2:6379>
从库可以写入,切换成功
步骤 4、原来的主redis重新恢复正常,需要重新切换回去
1.将现在的主redis数据进行保存
[root@bogon redis]# redis-cli -h 172.16.0.2 -p 6379
172.16.0.2:6379> set apu new
OK
172.16.0.2:6379> get apu
"new"
172.16.0.2:6379> save
2.将现在的主172.16.0.2 redis数据目录下dump.rdb文件拷贝覆盖原来主172.16.0.1 redis 数据目录下面
3.启动原来的172.16.0.1 redis
# cd /usr/local/redis
# bin/redis-server redis.conf &
4.将现在的主172.16.0.2 redis切换为从库
[root@]# redis-cli -h 172.16.0.2 -p 6379 slaveof 172.16.0.1 6379
OK
步骤 5、查看主库redis是否正常
之前在从库中添加的key,此时在主库6379中都可以查看
步骤 6、验证主从同步是否正常
主172.16.0.1 redis写入,从172.16.0.2 redis可正常同步;
从redis只支持读,不支持写入
二 哨兵模式
假设我们的主机宕机了,此时没有主机了,我们需要手动去配置,这样无疑是很复杂的,此时redis给出的解决方案就是哨兵模式(sentinel)
1、什么是哨兵模式
Redis-sentinel是Redis的作者antirez,因为Redis集群的被各大公司使用,每个公司要写自己的集群管理工具,于是antirez花了几个星期写出了Redis-sentinel。
Sentinel集群拓扑图
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance),Redis 的 Sentinel 为Redis提供了高可用性。使用哨兵模式创建一个可以不用人为干预而应对各种故障的Redis部署。
于是,在 Redis 2.8 版本开始,引入了哨兵(Sentinel)这个概念,在主从复制的基础上,哨兵实现了自动化故障恢复。如上图所示,哨兵模式由两部分组成,哨兵节点和数据节点:
哨兵节点:哨兵节点是特殊的 Redis 节点,不存储数据;
数据节点:主节点和从节点都是数据节点。
该系统执行以下三个任务:
监控(Monitoring):Sentinel会不断地检查你的主服务器和从服务器是否允许正常。
提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover):
(1)当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,他会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;
(2)客户端试图连接失败的主服务器时,集群也会向客服端返回新主服务器的地址,是的集群可以使用新主服务器代替失效服务器。
2、实现原理:
哨兵启动后会与要监控的主数据库建立两条连接
和主数据库连接建立完成后,哨兵会使用连接2发送如下命令:
每10秒钟哨兵会向主数据库和从数据库发送INFO 命令
每2秒钟哨兵会向主数据库和从数据的sentinel:hello频道发送自己的消息。
每1秒钟哨兵会向主数据、从数据库和其他哨兵节点发送PING命令。
首先,发送INFO命令会返回当前数据库的相关信息(运行id,从数据库信息等)从而实现新节点的自动发现,前面提到的配置哨兵时只需要监控Redis主数据库即可,因为哨兵可以借助INFO命令来获取所有的从数据库信息(slave),进而和这两个从数据库分别建立两个连接。在此之后哨兵会每个10秒钟向已知的主从数据库发送INFO命令来获取信息更新并进行相应的操作。 接下来哨兵向主从数据库的sentinel:hello 频道发送信息来与同样监控该数据库的哨兵分享自己的信息。发送信息内容为:
<哨兵的地址>,<哨兵的端口>,<哨兵的运行ID>,<哨兵的配置版本>,<主数据库的名字>,<主数据库的地址>,<主数据库的端口>,<主数据库的配置版本>
哨兵通过监听的sentinel:hello频道接收到其他哨兵发送的消息后会判断哨兵是不是新发现的哨兵,如果是则将其加入已发现的哨兵列表中并创建一个到其的连接(哨兵与哨兵只会创建用来发送PING命令的连接,不会创建订阅频道的连接)。
3、配置redis哨兵
1.1新增配置文件
哨兵模式是在redis 主从基础上添加配置文件
vim /usr/local/redis/sentinel.conf
daemonize yes
bind 0.0.0.0
port 26379
sentinel monitor mymaster 172.16.0.1 6379 1
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
1.2 启动redis-sentinel
(主从服务器全部启动)
redis-sentinel /usr/local/redis/sentinel.conf #指定redis-sentinel配置文件
或者:
# cd /usr/local/redis/bin
# ./redis-server ../sentinel.conf --sentinel &
1.3 附加项(哨兵使用)
连接哨兵
redis-cli -p 26379
命令:
sentinel的基本状态信息
INFO
列出所有被监视的主服务器,以及这些主服务器的当前状态
SENTINEL masters
列出给定主服务器的所有从服务器,以及这些从服务器的当前状态
SENTINEL slaves
返回给定名字的主服务器的 IP 地址和端口号
SENTINEL get-master-addr-by-name
重置所有名字和给定模式 pattern 相匹配的主服务器。重置操作清除主服务器目前的所有状态, 包括正在执行中的故障转移, 并移除目前已经发现和关联的, 主服务器的所有从服务器和 Sentinel 。
SENTINEL reset
当主服务器失效时, 在不询问其他 Sentinel 意见的情况下, 强制开始一次自动故障迁移,但是它会给其他sentinel发送一个最新的配置,其他sentinel会根据这个配置进行更新
SENTINEL failover
1.4 测试
[root@redis_1 ~ ] redis-cli -p 6379
<127.0.0.1:6379> info replication
role:master
connected_slaves:1
[root@redis_1 ~ ] kill -9 pid号 #只kill掉redis的进程就可以
[root@redis_2 ~ ] redis-cli -p 6379
<127.0.0.1:6379>info replication
role:master
connected_slaves:0
可以清晰的看到slave升到了master,证明哨兵没有问题,再来启动原主看看
[root@redis_1 ~ ] nohup redis-server /usr/local/redis/bin/redis.conf &> /tmp/redis.log &
[root@redis_2 ~ ] redis-cli -p 6379
<127.0.0.1:6379>info replication
role:slave
[root@redis_1 ~ ] redis-cli -p 6379
<127.0.0.1:6379>info replication
role:master
connected_slaves:1