redis单机版
redis是一个高性能单线程的的nosql数据库
高性能是由于是基于内存的
主从复制
主机数据更新后更具配置和策略,自动同步到备机的master/slave机制,master已写为主,slave以读为主
redis单机系统存在的问题:
- 单机故障
- 容量瓶颈
- qps瓶颈
用来做什么:
- 读写分离
- 容灾备份
方式:
- 一主多从:一个主节点,多个从节点
- 一主一从:从机作为下一个从机的主机
全量复制消耗:
- bgsave时间
- rdb文件网络传输
- 从节点请求数据时间
- 从节点加载rdb时间
- 可能的aof重写
缺点:
- 由于搜有的写操作都先在master上操作,然后同步更新到slave上,所以从master同步到slave机器有延迟,当系统繁忙时,延迟问题会更加严重,slave及其数量增加也会是这个问题加重
- 当主机宕机后,将不能进行写操作,需手动将从机升级为主机,从机需要重新指定master
一个master可以有多个slave
一个slave只能有一个master
流量是单向的,从主到从
主从复制流程图:
全量复制流程图
搭建主从复制模式:
redis.conf:
bind 0.0.0.0
port 8000
daemonize yes
#save “”
#save 900 1
#save 300 10
#save 60 10000
pidfile “/var/run/redis_8000.pid”
dbfilename dump8000.rdb
appendonly yes (aof持久化开启, 主机可以不开启)
dir “/root/redis/redis8000”
#replicaof 主节点ip 主节点端口(主节点不需要配置,从节点需要配置)
masterauth 主节点认证密码(所有节点一致,与requirepass一致)
requirepass “123456”(所有节点一致)
查看主从信息:
登录客户端后使用info replication命令
动态指定主机:slaveof 从机ip 端口
脱离该主节点:slaveof no one
哨兵模式
为了解决主从复制中需要认为切换主机与从机,引入哨兵模式
哨兵模式的核心功能是主节点的自动故障转移
主要功能:
1、监控:哨兵会不断检查主节点和从节点是否运作正常
2、自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效的主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点
3、配置提供者:客户端在初始化时,通过连接哨兵来获取当前redis服务的主节点地址
4、通知:哨兵可以讲故障转移的结果发送给客户端
其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现
架构:
1、哨兵节点:哨兵系统有一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据
2、数据节点:主节点和从节点都是数据节点
主节点可以读写,从节点只能读不能写
搭建哨兵模式:
sentinel.conf:
bind 0.0.0.0
protected-mode no
port 28000
daemonize yes
pidfile “/var/run/redis-sentinel28000.pid”
logfile “sentinel28000.log”
sentinel monitor 哨兵名称(所有哨兵一致) 主节点ip 主节点端口 一般为哨兵数量/2 + 1
sentinel auth-pass 哨兵名称(所有哨兵一致) 密码(与主节点密码一致)
redis.conf:
bind 0.0.0.0
port 8000
daemonize yes
pidfile “/var/run/redis_8000.pid”
#save “”
#save 900 1
#save 300 10
#save 60 10000
appendonly yes (aof持久化开启, 主机可以不开启)
#replicaof 主节点ip 主节点端口(主节点不需要配置,从节点需要配置)
masterauth 主节点认证密码(所有节点一致,与requirepass一致)
requirepass “123456”(所有节点一致)
python连接哨兵模式:
from redis.sentinel import Sentinel
连接主节点
master = sentinels.master_for(‘mymaster’, socket_timeout=10, password=‘123456’)
连接从节点
slave = sentinels.slave_for(‘mymaster’, socket_timeout=10, password=‘123456’)
master.set(“k1”, “v1”)
slave.get(“k1”)