Redis 主从复制

redis高可用集群(至少3台master,每个master必须至少一个slave)

redis主从也可达到高可用

 

redis主从复制=mysql主从同步

 

  • redis主从复制结构

一主一从

一主多从

主从从

 

  • 工作原理

 

  1. 从库向主库发送sync命令
  2. 主库启动后台存盘进程,并收集所有修改的命令放在数据库目录下,
  3. 完成后台存盘后再把数据文件传给从库,
  4. 从库收到加载到自己的内存里(首次完全同步),
  5. 后续有新数据产生时,主库继续将新的数据收集到的修改命令依次传给从库,完成同步 (累加的)

 

  • 缺点:

网络繁忙,网络传同步文件,(网络带宽)

系统繁忙,硬件资源匮乏,进程多(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
 

一重启主从失效

  • 修改配置为永久,一主一从(52做51的从)

[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 

  • 一主多从(把53配为51的从库)

[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
 

 

  • 主从从(54做53的从,53原是51的从)

[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
 

 

  • 把从服务器恢复为独立的服务器[192.168.4.52-54]

以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
 

 

  • 配有密码的redis 服务器  [192.168.4.55]

[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
 

  • 把56设为55的从库

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
 

 

 

 

 

 

  • 把55redis服务起来

[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 *
 


二、数据持久化

 

RDB 实现数据持久化

  • 介绍

文件,存储数据

按指定间隔时间,将内存中的数据集快照写入硬盘

专业术语:Snapshot快照

恢复时,将快照文件直接读入内存

 

 

 

 

  • 使用RDB文件恢复

[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"
 

  • 与RDB文件相关配置

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次修改自动存盘
 

 

  • 使用RDB实现数据持久化的优点和缺点

优点

高性能:数据存盘时,把内存存进硬盘的时候创建新的程序来执行持久化;redis定期存盘,进程各处理各的(性能高)

 

高性能的持久化实现--------创建一个子进程来执行持久化,先将数据写入临时文件,持久化过程结束后,再用这个临时文件替换上次持久化好的文件;过程中主进程不做任何IO操作

适合大规模数据恢复

 

缺点:意外宕机时,最后一次持久化的数据会丢失

 

 

AOF实现数据持久化

  • 介绍
  1. 类似mysql的binlog日志
  2. 记录所有redis服务写操作(以追加方式的记录)
  3. 不断的将新的写操作,追加到文件的末尾
  4. 使用cat可以查看文本内容

RDB和AOF同时启用,默认会用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 

 

 

  • 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"
 

 

  • 在命令行启AOF(不会覆盖已有数据),不需重启服务覆盖掉之前文件

[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   查看
 

 

  • 把AOF数据文件改坏是否能修复

[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                   #首次瘦身的容量(初值)
 

 

 

 

  • 使用AOF实现数据持久化的优点和缺点

灵活设置持久化

同步持久化appendfsync always

异步持久化appendfsync exerysec

意外宕机仅可能丢失1秒数据

 

缺点:持久化文件体积会大于RDB方式,逐行执行,恢复数据会慢

 

 

 

 

 

 

 

三、数据类型

  1. 集合
  2. 有序集合
  3. String字符串
  4. list列表
  5. hash表

 

 

1.字符串String

 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中所储存的值加上浮点数增量

 

 

 

 

 

2.list列表

让变量可以存储多个值,输出时先进后出

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末尾的值

 

 

 

 

 

3.hash表

string的列和值的映射表

一个变量可对应多个列表,一个列表对应一个值

比使用字符类型存储更节省内存

 

hset key  列   值    #定义一个变量和对应的列和值

 

hget  key  列       #取该变量的列的值

 

hmset  key  列 值  列 值  列 值...    #定义变量的多个列和值

 

hmget  key  列 .......            #取该变量的多个列的值

 

hkeys  key       #返回bash表中所有列     

 

hgetall  key     #返回hash表中所有key名和对应的列表值

 

hvals key  返回hash表中所有key值(不包含列)

 

hdel key 列...    #删除hash表中多个列的值,不存在则忽略

 

 

 

  

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(数据库)