redis高可用集群(至少3台master,每个master必须至少一个slave)
redis主从也可达到高可用
redis主从复制=mysql主从同步
一主一从
一主多从
主从从
网络繁忙,网络传同步文件,(网络带宽)
系统繁忙,硬件资源匮乏,进程多(cpu)
[root@host51 ~]# redis-cli -h 192.168.4.51 -p 6351
192.168.4.51:6351> INFO replication #查看主从配置信息
# Replication
role:master #角色,默认都是master无需配置
connected_slaves:0 #连接slave个数
[root@host52 ~]# redis-cli -p 6352 -h 192.168.4.52
192.168.4.52:6352> SLAVEOF 192.168.4.51 6351 #手动设为从库,指定主库ip和端口(临时)
OK
192.168.4.52:6352> INFO replication
# Replication
role:slave
master_host:192.168.4.51
master_port:6351
master_link_status:up #down为无法同步
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:28
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:8c4883a674ceebb034c520f106e2b69ad684d55e
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
一重启主从失效
[root@host52 ~]# vim /etc/redis/6379.conf
282 slaveof 192.168.4.51 6351 #指主库信息
/etc/init.d/redis_6379 stop
/etc/init.d/redis_6379 start
192.168.4.52:6352> set v5 520
[root@host53 ~]# vim /etc/redis/6379.conf
282 slaveof 192.168.4.51 6351 #指主库信息
/etc/init.d/redis_6379 stop
/etc/init.d/redis_6379 start
[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353
192.168.4.53:6353> keys *
1) "v5"
192.168.4.53:6353> info replication
# Replication
role:slave
master_host:192.168.4.51
master_port:6351
master_link_status:up
master_last_io_seconds_ago:5
[root@host54 ~]# /etc/init.d/redis_6379 stop
[root@host54 ~]# sed -i "282c slaveof 192.168.4.53 6353" /etc/redis/6379.conf
[root@host54 ~]# /etc/init.d/redis_6379 start
[root@host54 ~]# redis-cli -h 192.168.4.54 -p 6354
192.168.4.54:6354> info replication
# Replication
role:slave
master_host:192.168.4.53
master_port:6353
master_link_status:up
master_last_io_seconds_ago:6
master_sync_in_progress:0
slave_repl_offset:1019
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:6647aa9b375be608892d25829fd9e69c2b813c39
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1019
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:992
repl_backlog_histlen:28
以53为例:
192.168.4.53:6353> SLAVEOF no one #手动设为主库
OK
192.168.4.53:6353> info replication
# Replication
role:master
[root@host53 ~]# sed -i "282c #slaveof 192.168.4.53 6353" /etc/redis/6379.conf
[root@host53 ~]# /etc/init.d/redis_6379 stop
[root@host53 ~]# /etc/init.d/redis_6379 start
[root@host55 ~]# vim /etc/redis/6379.conf
501 requirepass 123456
[root@host55 ~]# vim /etc/init.d/redis_6379
43 $CLIEXEC -p 6355 -h 192.168.4.55 -a 123456 shutdown
[root@host55 ~]# redis-cli -h 192.168.4.55 -p 6355 -a 123456 明文输密码
192.168.4.55:6355> auth 123456 命令行不加密码可进来auth加密码验证
OK
192.168.4.55:6355> ping
PONG
192.168.4.56:6356> info replication #先查看状态
# Replication
role:master
connected_slaves:0
master_replid:71382831b10e408f7c8fd836410e4347638687cf
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
[root@host56 ~]# vim /etc/redis/6379.conf
282 slaveof 192.168.4.55 6355 #指主库uip端口
289 masterauth 123456 #指定主库密码
[root@host56 ~]# /etc/init.d/redis_6379 stop
[root@host56 ~]# /etc/init.d/redis_6379 start
[root@host56 ~]# ss -nutlp | grep redis
tcp LISTEN 0 128 192.168.4.56:6356 *:* users:(("redis-server",pid=2693,fd=6))
[root@host56 ~]# redis-cli -h 192.168.4.56 -p 6356
192.168.4.56:6356> info replication
# Replication
role:slave
master_host:192.168.4.55
master_port:6355
master_link_status:up
[root@host55 ~]# /etc/init.d/redis_6379 stop #当55宕机后
[root@host56 ~]# redis-cli -h 192.168.4.56 -p 6356 #检查56从库是否正常同步数据
192.168.4.56:6356> info replication
# Replication
role:slave
master_host:192.168.4.55
master_port:6355
master_link_status:down
master_last_io_seconds_ago:-1
在主机58上运行哨兵服务
1.安装redis服务
2.创建配置哨兵服务文件(可参考源玛包里面的redis-4.0.8/sentinel.conf)
[root@host58 ~]# vim /etc/sentinel.conf
bind 0.0.0.0 使用所有ip地址与其他通信
port 26379
sentinel monitor redisser(主机名自定义) 192.168.4.55(被监视的master IP) 6355 1(哨兵服务有几台)
sentinel auth-pass redisser 123456(指连接主库密码)没密码可不指定
3.启动哨兵服务(会一直监视)
[root@host58 redis-4.0.8]# redis-sentinel /etc/sentinel.conf
3029:X 23 May 11:17:50.189 # +monitor master redisser 192.168.4.55 6355 quorum 1 #监视55
关掉55主库后.....
3029:X 23 May 11:38:45.148 # +sdown master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.148 # +odown master redisser 192.168.4.55 6355 #quorum 1/1
3029:X 23 May 11:38:45.148 # +new-epoch 1
3029:X 23 May 11:38:45.148 # +try-failover master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.196 # +vote-for-leader 72c5bb1c955e57a724f21141ced3ed929783bf1a 1
3029:X 23 May 11:38:45.196 # +elected-leader master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.196 # +failover-state-select-slave master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.251 # +selected-slave slave 192.168.4.56:6356 192.168.4.56 6356 @ redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.251 * +failover-state-send-slaveof-noone slave 192.168.4.56:6356 192.168.4.56 6356 @ redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.308 * +failover-state-wait-promotion slave 192.168.4.56:6356 192.168.4.56 6356 @ redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.596 # +promoted-slave slave 192.168.4.56:6356 192.168.4.56 6356 @ redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.596 # +failover-state-reconf-slaves master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.611 # +failover-end master redisser 192.168.4.55 6355
3029:X 23 May 11:38:45.611 # +switch-master redisser 192.168.4.55 6355 192.168.4.56 6356
3029:X 23 May 11:38:45.611 * +slave slave 192.168.4.55:6355 192.168.4.55 6355 @ redisser 192.168.4.56 6356
3029:X 23 May 11:39:15.618 # +sdown slave 192.168.4.55:6355 192.168.4.55 6355 @ redisser 192.168.4.56 6356
[root@host55 ~]# /etc/init.d/redis_6379 stop #停55主库服务
[root@host56 ~]# redis-cli -h 192.168.4.56 -p 6356
192.168.4.56:6356> info replication #查看56是否升为主库
role:master
connected_slaves:0
[root@host55 ~]# /etc/init.d/redis_6379 start
[root@host55 ~]# redis-cli -h 192.168.4.55 -p 6355 -a 123456
192.168.4.55:6355> info replication
# Replication
role:slave
master_host:192.168.4.56
master_port:6356
master_link_status:up
[root@host58 redis-4.0.8]# cat /etc/sentinel.conf #文件变化了
bind 0.0.0.0
port 26379
sentinel myid 72c5bb1c955e57a724f21141ced3ed929783bf1a
sentinel monitor redisser 192.168.4.56 6356 1
# Generated by CONFIG REWRITE
dir "/root/redis-4.0.8"
sentinel auth-pass redisser 123456
sentinel config-epoch redisser 1
sentinel leader-epoch redisser 1
sentinel known-slave redisser 192.168.4.55 6355
sentinel current-epoch 1
*把56宕机,看看55晋升主库
[root@host56 ~]# /etc/init.d/redis_6379 stop
[root@host55 ~]# redis-cli -h 192.168.4.55 -p 6355 -a 123456
192.168.4.55:6355> info replication
# Replication
role:master
connected_slaves:0
master_replid:5e79dac38e43f171b8ec3e7d58120b0b81198b8d
master_replid2:9dc06cba0b346b0607014cb3675da8be60968563
master_repl_offset:150496
second_repl_offset:149779
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:117515
repl_backlog_histlen:32982
192.168.4.55:6355> set abc 1314 #趁56宕机期间存数据
OK
192.168.4.55:6355> set plj 1902
OK
[root@host56 ~]# /etc/init.d/redis_6379 start #把56启动
[root@host56 ~]# redis-cli -h 192.168.4.56 -p 6356
192.168.4.56:6356> INFO replication
# Replication
role:slave #修好后自动升为55的从库
master_host:192.168.4.55
master_port:6355
master_link_status:up
master_last_io_seconds_ago:2
[root@host56 ~]# redis-cli -h 192.168.4.56 -p 6356 #查看数据
192.168.4.56:6356> keys *
文件,存储数据
按指定间隔时间,将内存中的数据集快照写入硬盘
专业术语:Snapshot快照
恢复时,将快照文件直接读入内存
[root@host51 ~]# redis-cli -h 192.168.4.51 -p 6351
192.168.4.51:6351> keys *
192.168.4.51:6351> set x 521
192.168.4.51:6351> set y 523
192.168.4.51:6351> set z 525
192.168.4.51:6351> keys *
1) "y"
2) "x"
3) "v5"
4) "z"
192.168.4.51:6351> save #手动立马把内存数据存在数据库目录
[root@host51 ~]# ls /var/lib/redis/6379/
dump.rdb
[root@host51 ~]# cp /var/lib/redis/6379/dump.rdb /root/
[root@host51 ~]# scp /root/dump.rdb [email protected]:/root #不要直接拷到对方数据库目录下
---------------------------------------------------------------------------------------------------------------
[root@host52 ~]# /etc/init.d/redis_6379 stop
[root@host52 ~]# rm -rf /var/lib/redis/6379/* #把之前的数据清空或者覆盖(操作之前先停服务)
[root@host52 ~]# cp dump.rdb /var/lib/redis/6379/
[root@host52 ~]# /etc/init.d/redis_6379 start
[root@host52 ~]# redis-cli -h 192.168.4.52 -p 6352
192.168.4.52:6352> keys *
1) "z"
2) "v5"
3) "x"
4) "y"
save # 存盘时不能写东西
bgsave #存盘时依然还能写东西
[root@host51 ~]# vim /etc/redis/6379.conf
219 save 900 1 900秒内且有1次修改
220 save 300 10 300秒内且有10次修改
221 save 60 10000 60秒内且有10000修改
254 dbfilename dump.rdb 文件名
如不想要dump.rd则把该行注释掉,把save注释去掉加 " " 表示禁用RDB
[root@host51 ~]# /etc/init.d/redis_6379 stop
[root@host51 ~]# vim /etc/redis/6379.conf
219 save 900 1
220 save 120 10
221 save 60 10000
[root@host51 ~]# rm -rf /var/lib/redis/6379/*
[root@host51 6379]# /etc/init.d/redis_6379 start
[root@host51 6379]# redis-cli -h 192.168.4.51 -p 6351
192.168.4.51:6351> set v1 1
192.168.4.51:6351> set v2 1
192.168.4.51:6351> set v3 1
.........随便存10个数据
192.168.4.51:6351> keys *
[root@host51 6379]# ls /var/lib/redis/6379/
dump.rdb #120s且10次修改自动存盘
优点
高性能:数据存盘时,把内存存进硬盘的时候创建新的程序来执行持久化;redis定期存盘,进程各处理各的(性能高)
高性能的持久化实现--------创建一个子进程来执行持久化,先将数据写入临时文件,持久化过程结束后,再用这个临时文件替换上次持久化好的文件;过程中主进程不做任何IO操作
适合大规模数据恢复
缺点:意外宕机时,最后一次持久化的数据会丢失
RDB和AOF同时启用,默认会用AOF
使用AOF文件恢复
AOF文件记录写操作的方式
appendfsync always #有新写操作立刻记录
appendfsync everysec #每秒记录一次
appendfsync no 只把数据操作写进文件,不写入磁盘,cpu不忙的时候才写入磁盘
[root@host51 6379]# vim /etc/redis/6379.conf
673 appendonly yes #启用aof文件,默认no
677 appendfilename "appendonly.aof" #定义文件名
703 appendfsync everysec #记录方式
[root@host51 6379]# /etc/init.d/redis_6379 stop
Stopping ...
Waiting for Redis to shutdown ...
Redis stopped
[root@host51 6379]# /etc/init.d/redis_6379 start
[root@host51 6379]# cat /var/lib/redis/6379/appendonly.aof
空
[root@host51 6379]# redis-cli -h 192.168.4.51 -p 6351
192.168.4.51:6351> keys *
#aof和rdb同时使用则开启服务时默认读aof文件,aof文件空则数据也为空
192.168.4.51:6351> set j 99
192.168.4.51:6351> set i 88
192.168.4.51:6351> set x 520
192.168.4.51:6351> keys *
[root@host51 6379]# cat /var/lib/redis/6379/appendonly.aof
[root@host51 6379]# cp /var/lib/redis/6379/appendonly.aof /root #先备份
[root@host51 6379]# scp ~/appendonly.aof 192.168.4.52:/root
[root@host52 6379]# /etc/init.d/redis_6379 stop
[root@host52 6379]# vim /etc/redis/6379.conf #修改配置把aof开启
673 appendonly yes #启用aof文件,默认no
677 appendfilename "appendonly.aof" #定义文件名
703 appendfsync everysec #记录方式
[root@host52 ~]# rm -f /var/lib/redis/6379/* #清空数据库目录(非必要操作)
[root@host52 ~]# cp /root/appendonly.aof /var/lib/redis/6379/ #拷贝到数据库目录下启动时加载该文件
[root@host52 6379]# /etc/init.d/redis_6379 start
[root@host52 ~]# redis-cli -h 192.168.4.52 -p 6352
192.168.4.52:6352> keys * #查看时候恢复成功
1) "j"
2) "x"
3) "i"
[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353
192.168.4.53:6353> set v5 520
192.168.4.53:6353> set x 521
192.168.4.53:6353> set y 522
192.168.4.53:6353> keys *
1) "x"
2) "v5"
3) "y"
192.168.4.53:6353> config set appendonly yes # 启用AOF
192.168.4.53:6353> config rewrite # 写进配置文件
192.168.4.53:6353> save #保存
[root@host53 ~]# ls /var/lib/redis/6379/
appendonly.aof dump.rdb
[root@host53 ~]# cat /var/lib/redis/6379/appendonly.aof
[root@host53 ~]# /etc/init.d/redis_6379 stop
[root@host53 ~]# /etc/init.d/redis_6379 start
[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353
192.168.4.53:6353> keys *
1) "y"
2) "x"
3) "v5"
[root@host53 ~]# cat /var/lib/redis/6379/appendonly.aof
[root@host53 ~]# vim +673 /etc/redis/6379.conf 查看
[root@host53 ~]# vim /var/lib/redis/6379/appendonly.aof
随便乱改一些内容
[root@host53 ~]# /etc/init.d/redis_6379 stop
[root@host53 ~]# /etc/init.d/redis_6379 start #启动失败,但生成了pid文件(一执行此脚本就生成pid文件)
redis-cli -h 192.168.4.53 -p 6353 #登陆失败,服务没启
Could not connect to Redis at 192.168.4.53:6353: Connection refused
[root@host53 ~]# redis-check-aof --fix /var/lib/redis/6379/appendonly.aof #修复AOF文件
0x 4: Expected prefix '$', got: 'b'
AOF analyzed: size=215, ok_up_to=0, diff=215
This will shrink the AOF from 215 bytes, with 215 bytes, to 0 bytes
Continue? [y/N]: y
Successfully truncated AOF
[root@host53 ~]# rm -rf /var/run/redis_6379.pid
[root@host53 ~]# /etc/init.d/redis_6379 start
[root@host53 ~]# rm -rf /var/run/redis_6379.pid
[root@host53 ~]# /etc/init.d/redis_6379 start
[root@host53 ~]#ss -nutlp | grep redis
tcp LISTEN 0 128 192.168.4.53:6353 *:* users:(("redis-server",pid=6263,fd=6))
[root@host53 ~]# redis-cli -h 192.168.4.53 -p 6353
192.168.4.53:6353> keys *
(empty list or set)
redis会记录上次重写的AOF文件大小,默认配置AOF文件是上次rewrite后大小的1倍且文件大于63M时触发
[root@host53 ~]# vim /etc/redis/6379.conf
744 auto-aof-rewrite-percentage 100
745 auto-aof-rewrite-min-size 64mb #首次瘦身的容量(初值)
灵活设置持久化
同步持久化appendfsync always
异步持久化appendfsync exerysec
意外宕机仅可能丢失1秒数据
缺点:持久化文件体积会大于RDB方式,逐行执行,恢复数据会慢
SET key value 过期时间[EX seconds秒] [PX milliseconds毫秒] [NX不覆盖|XX覆盖]
setrange key n value 从偏移量开始复写key的特定位的值(从第n位后替换value值)
strlen key 统计字串长度
get key 返回key存储的字符串值,不存在则返回null(只能处理字符串)
getrange key 起始值 结束值 #0起算,倒数-1表示,返回字串值中的子字串(截取值部分)
mset key 定义多个变量 空格分隔
mget key 取多个key的值,空格分隔
append key value 追加值,返回长度
decr key 值-1 #字减
decrby key 减量n #将key值减去减量n
setbit key offset(0~2^32之间) value(0/1) #对key所存储字串,设置或清除特定偏移量上的位(bit)
bitcount key #统计被设置为1的比特数量
incr key #key值+1
incrby key n #key值增加n
incrbyfloat key 小数值 #为key中所储存的值加上浮点数增量
让变量可以存储多个值,输出时先进后出
lpush key value #将一个或多个值value插入到列表key的表头,key不存在则创建
lrange key 起始位置 结束位置 #从开始位置读取key值到结束位置
lpop key #移除并返回列表头的元素数据,key不存在则返回nil
llen key #返回列表key的长度
lindex key n #返回列表中的第n个值(0起算)
lset key n value #将key中第n位置的值修改为value
rpush key 值1 值2... #将值插入key的末尾
rpop key #删除并返回key末尾的值
string的列和值的映射表
一个变量可对应多个列表,一个列表对应一个值
比使用字符类型存储更节省内存
hset key 列 值 #定义一个变量和对应的列和值
hget key 列 #取该变量的列的值
hmset key 列 值 列 值 列 值... #定义变量的多个列和值
hmget key 列 ....... #取该变量的多个列的值
hkeys key #返回bash表中所有列
hgetall key #返回hash表中所有key名和对应的列表值
hvals key 返回hash表中所有key值(不包含列)
hdel key 列... #删除hash表中多个列的值,不存在则忽略