一,redis安装
Redis介绍:
redis是一个高性能的key-value存储系统。和Memcached类似,但它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis还支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类keyvalue存储的不足,在部分场合可以对关系数据库起到很好的补充作用。
系统环境:CentOS 6.5 mini
软件版本:redis-2.8.19
一、redis安装
1:安装相关依赖包
# yum -y install gcc make
# cd /main/
# tar zxvf redis-2.8.19.tar.gz
# mv redis-2.8.19/ redis/
# cd redis/
# make && make install
至此redis安装完毕,此时进入/main/redis/src目录会发现存在如下可执行文件
mkreleasehdr.sh
redis-benchmark
redis-check-aof
redis-check-dump
redis-cli #redis-cli用于进入Redis客户端
redis-sentinel #启动sentinel服务
redis-server #启动Redis服务
3:修改配置文件
# mkdir /main/redis/logs
# vi /main/redis/redis.conf
daemonize yes
logfile "/main/redis/logs/redis.log"
#注:其他参数根据实际情况来配置,daemonize yes表示设置服务为后台开启,这样服务开启后就不会占用当前session。logfile是指定日志的路径
4:关闭防火墙
# service iptables stop
# chkconfig iptables off
#此处可以关闭防火墙,也可以开放相应的端口,否则远端将无法连接
5:启动redis
5.1:启动redis
# /main/redis/src/redis-server /main/redis/redis.conf
#注:启动redis需指定配置文件,如不指定则加载默认配置文件
5.2:查看启动情况
# netstat -tunpl | grep 6379
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 4928/redis-server *
tcp 0 0 :::6379 :::* LISTEN 4928/redis-server *
由于redis默认使用的是6379端口,因此如显示现如上,则表示redis启动成功
6:设置开机启动
# echo "/main/redis/src/redis-server /main/redis/redis.conf" >> /etc/rc.local
二,redis 主从配置
Redis主从配置(Master-Slave)
一、 Redis Replication的特点:
1):一个Master可以同步多个Slave
2):不仅Master可以同步多个Slave,Slave也可以同步其它Slave,可以构成一个图形结构,同时还能分担Master的同步压力
3):Redis Replication使用的是异步复制。从2.8开始,Slave会周期性发起一个Ack确认replication stream被处理进度
4):复制在Master Server是以非阻塞模式完成数据同步。即使多个Master-Slave同时同步,Master Server仍然可以提供查询或修改
5):复制在Slave Server也是以非阻塞的方式完成数据同步。在同步期间,Slave Server可以提供数据查询,但返回的是同步之前的数据,同时还能配置当Master与Slave失去联系时,让Slave返回客户端一个错误提示
6):Slave Server可以为客户端提供只读操作的服务,但写服务仍然必须由Master来完成,这样可以分载Master的读操作压力,在分压的同时还供了数据冗余,同时还可以通过增加Slave进行只读操作来提升扩展性
7):可以通过修改Master Server的redis.config配置文件来将持久化操作交给Slave Server去操作
注:Slave是只读的,只可以读取数据,而不能写入数据
二、Redis Replication工作原理:
1):Slave启动后,无论是第一次连接还是重连到Master,它都会主动发出一个SYNC命令
2):当Master收到SYNC命令之后,将会执行BGSAVE(后台存盘进程),即在后台保存数据到磁盘(rdb快照文件),同时收集所有新收到的写入和修改数据集的命令存入缓冲区(非查询类)
3):Master在后台把数据保存到快照文件完成后,会传送整个数据库文件到Slave
4):Slave接收到数据库文件后,会把内存清空,然后加载该文件到内存中以完成一次完全同步
5):然后Master会把之前收集到缓冲区中的命令和新的修改命令依次传送给Slave
6):Slave接受到之后在本地执行这些数据修改命令,从而达到最终的数据同步
7):之后Master与Slave之间将会不断的通过异步方式进行命令的同步,从而保证数据的时时同步
8):如果Master和Slave之间的链接出现断连,Slave可以自动重连Master。根据版本的不同,断连后同步的方式也不同:
2.8之前:重连成功之后,一次全量同步操作将被自动执行
2.8之后:重连成功之后,进行部分同步操作
部分同步:
从2.8开始,当Master和Slave之间的连接断开重连后,他们之间可以采用持续复制处理方式替代完全重同步操作。部分重同步会用到PSYNC的命令,2.8之后的版本才有此命令,之前的只有SYNC命令。只要Slave是2.8或以上的版本,Slave就会根据Master的版本来决定到底是使用PSYNC还是SYNC
部分同步工作原理如下:
1):Master为被发送的复制流创建一个内存缓冲区(in-memory backlog),记录最近发送的复制流命令
2):Master和Slave之间都记录一个复制偏移量(replication offset)和当前Master ID(Master run id)
3):当出现网络断开,Slave会重新连接,并且向Master请求继续执行原来的复制进程
4):如果Slave中断网前的MasterID和当前要连的MasterID相同,并且从断开时到当前时刻Slave记录的偏移量所指定的数据仍然保存在Master的复制流缓冲区里面,则Master会向Slave发送缺失的那部分数据,Slave执行后复制工作可以继续执行
5):否则Slave就执行完整重同步操作
三、配置:
系统环境:CentOS 6.5 mini
软件版本:redis-2.8.19
IP地址:
节点1:192.168.100.211
节点2:192.168.100.212
节点3:192.168.100.213
1:指定Slave(在Slave节点配置)
# vi /main/redis/redis.conf
slaveof 192.168.100.211 6379
#注:有这一行表示为Slave,没有则表示为Master。这里的IP地址为Master的IP地址,后面的端口号也是为Master的端口号
2:设置认证密码(三个节点)
可以设置,也可以不设置
# vi /main/redis/redis.conf
masterauth 1234567890
requirepass 1234567890
#注:如果Master端通过requirepass设置了密码,则Slave需要通过masterauth配置密码
到此配置就完毕了
四、测试:
1:在命令行界面进行查看(三个节点):
# /main/redis/src/redis-cli
127.0.0.1:6379> info replication
节点1显示如下(master):
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.100.212,port=6379,state=online,offset=41663,lag=1
slave1:ip=192.168.100.213,port=6379,state=online,offset=41663,lag=1
master_repl_offset:41963
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:41962
节点2显示如下(slave1):
# Replication
role:slave
master_host:192.168.100.211
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:41520
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
节点3显示如下(slave2):
# Replication
role:slave
master_host:192.168.100.211
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:42106
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
Master
# /main/redis/src/redis-cli -a 1234567890 set hello doiido
Slave1
# /main/redis/src/redis-cli -a 1234567890 get hello
"doiido"
Slave2
# /main/redis/src/redis-cli -a 1234567890 get hello
"doiido"
Slave2
# /main/redis/src/redis-cli -a 1234567890 set hello2 doiido2
(error) READONLY You can't write against a read only slave.
从上面的操作中可以看出,从Master中写入数据后,Slave是会同步数据的,而在Slave中是无法写入数据的
到这里Redis的主从配置完毕,但是这个时候是不会自动切换的。想要其自动切换,需要进行Sentinel配置
三,redis 主从自动切换Sentinel
Redis Sentinel
Sentinel(哨兵)是用于监控redis集群中Master状态的工具,其已经被集成在redis2.4+的版本中
一、Sentinel作用:
1):Master状态检测
2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
3):Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线
5):在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有Master,Slave发送 INFO 命令
6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
若 Master 重新向 Sentinel 的 PING 命令返回有效回复, Master 的主观下线状态就会被移除。
主观下线和客观下线
主观下线:Subjectively Down,简称 SDOWN,指的是当前 Sentinel 实例对某个redis服务器做出的下线判断。
客观下线:Objectively Down, 简称 ODOWN,指的是多个 Sentinel 实例在对Master Server做出 SDOWN 判断,并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后,得出的Master Server下线判断,然后开启failover.
SDOWN适合于Master和Slave,只要一个 Sentinel 发现Master进入了ODOWN, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
ODOWN只适用于Master,对于Slave的 Redis 实例,Sentinel 在将它们判断为下线前不需要进行协商, 所以Slave的 Sentinel 永远不会达到ODOWN。
三、配置:
1:指定监听Master(三个节点)
# vi /main/redis/sentinel.conf
port 26379
daemonize yes
sentinel monitor mymaster 192.168.100.211 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 900000
logfile "/main/redis/logs/sentinel.log"
#上面配置文件说明如下:
#第一行指定sentinel端口号
#第二行指定sentinel为后台启动
#第三行指定Sentinel去监视一个名为 mymaster 的Master,Master的IP地址为192.168.100.211,端口号为6379,最后的2表示当有2个Sentinel检测到Master异常时才会判定其失效,即只有当2个Sentinel都判定Master失效了才会自动迁移,如果Sentinel的数量不达标,则不会执行自动故障迁移。
#第四行指定Sentinel判定Master断线的时间。(单位为毫秒,判定为主观下线SDOWN)
#第五行指定在执行故障转移时,最多可以有多少个Slave同时对新的Master进行同步。这个数字设置为1,虽然完成故障转移所需的时间会变长,但是可以保证每次只有1个Slave处于不能处理命令请求的状态
2:启动sentinel(三个节点):
# /main/redis/src/redis-sentinel /main/redis/sentinel.conf
3:设置开机启动(三个节点)
# echo "/main/redis/src/redis-sentinel /main/redis/sentinel.conf" >> /etc/rc.local
四、注意点:
1):首次启动时,必须先启动Master
2):Sentinel 只在 server 端做主从切换,app端要自己开发(例如Jedis库的SentinelJedis,能够监控Sentinel的状态)
3):若Master已经被判定为下线,Sentinel已经选择了新的Master,也已经将old Master改成Slave,但是还没有将其改成new Master。若此时重启old Master,则Redis集群将处于无Master状态,此时只能手动修改配置文件,然后重新启动集群
四,redis 启动脚本
Redis启动脚本:
# vi /etc/init.d/redis
#!/usr/bin/env bash
#
# redis start up the redis server daemon
#
# chkconfig: 345 99 99
# description: redis service in /etc/init.d/redis \
# chkconfig --add redis or chkconfig --list redis \
# service redis start or service redis stop
# processname: redis-server
# config: /main/redis/redis.conf
PATH=/usr/local/bin:/sbin:/usr/bin:/bin
REDISPORT=6379
EXEC=/main/redis/src/redis-server
REDIS_CLI=/main/redis/src/redis-cli
PIDFILE=/var/run/redis.pid
CONF="/main/redis/redis.conf"
#make sure some dir exist
#if [ ! -d /var/lib/redis ] ;then
# mkdir -p /var/lib/redis
# mkdir -p /var/log/redis
#fi
case "$1" in
status)
ps -A|grep redis
;;
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed"
else
echo "Starting Redis server..."
$EXEC $CONF
fi
if [ "$?"="0" ]
then
echo "Redis is running..."
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE does not exist, process is not running"
else
PID=$(cat $PIDFILE)
echo "Stopping ..."
$REDIS_CLI -p $REDISPORT SHUTDOWN
while [ -x ${PIDFILE} ]
do
echo "Waiting for Redis to shutdown ..."
sleep 1
done
echo "Redis stopped"
fi
;;
restart|force-reload)
${0} stop
${0} start
;;
*)
echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
exit 1
esac
设置开机自启动redis
# chkconfig --add redis# chkconfig --list redis
# service redis start