redis的主从同步和集群类型
redis连接,首先创建一对socket用于连接通信。采用的是nio多路复用模型(一个线程监听所有的传入请求,使用轮询策略去接收)---非阻塞多路复用--创建文件事件监听客户端socket的数据发送
redis单线程,因为是在内存里操作。多线程需要CPU的上下文切换,会增加耗时,单线程就在一个cpu上执行
主从同步:
优点:提升读性能,数据备份,异步进行
原理:从服务器--->SYNC指令--->主服务器--->BGSAVE指令--->创建子进程进行数据持久化---写入RDB文件--->写指令存入内存--->RDB文件发送给从服务器--->从服务器存入硬盘--->在读取到内存--->主将写指令以redis协议的格式--->从
注意点:多个从服务器同时发来SYNC指令,主服务器也只会执行一次BGSAVE,然后把持久化好的RDB文件发给多个从服务器。
2.8版本之后--->增量同步
主服务器缓冲区----存放发给从的内容---网络中断---从再次尝试和主连接---连接成功---主发送增量内容---需要支持PSYNC指令
Redis 5.0之后,replicaof已经替换slaveof(从配置的内容)
>replicaof no one #手动取消从服务器,数据还在
>info replication #查看主从服务状态
哨兵模式:
Sentinel(哨兵)是用于监控redis集群中Master状态的工具,支持高可用,可以进行故障切换
作用:
1)Master状态检测
2)如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将之前的Master作为Slave
3)Master-Slave切换后,sentinel.conf的监控目标会随之调换
原理:
1):每个Sentinel以1/s的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令
2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds (配置-毫秒)选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线(sdown)。
3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以1/s次的频率确认Master的确进入了主观下线状态。
4):当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 (odown)。odown之后会开启failover(故障转移)
--哨兵的配置文件是动态调整的
--哨兵需要先选出自己的leader(raft算法),再去执行主从切换
--哨兵通过订阅机制进行互相通信
--带有epoch的参数,每次选举,都会加1
哨兵的常用命令(连接哨兵)
>sentinel masters: 查看被监控的Redis主服务器
>sentinel get-master-addr-by-name 查看指定Redis实例的master地址
>info 查看所有信息
集群模式:
redis的集群模式(cluster),使用数据分片引入哈希槽
1、集群把所有节点映射到【0-16384】slot槽上,集群负责维护node<-->slot<-->value
2、集群内置16384个哈希槽,有key-value插入时,先将key用crc16算法算出值,再和16384取余,对应的结果放到对应哈希槽的节点上,集群之间通过特殊二进制协议通信
3、哈希槽均匀分布在节点上,如3节点-->[0-5460]1,[5461-10921]2,[10922-16384]3
工作中的问题总结:
redis默认16个库,不选择时默认进0库
redis的keys * 查询当数据量很大的时候会直接卡死,因为redis是单线程,且keys命令是遍历算法
时间复杂度是0(N)。Keys命令和Smember命令都可能会让redis堵塞
SCAN 命令是一个基于游标的迭代器,每次被调用之后, 都会向用户返回一个新的游标, 用户在下次迭代时需要使用这个新游标作为 SCAN 命令的游标参数, 以此来延续之前的迭代过程可以分次进行查询
可以分批查询,较大数据量时可以使用。游标设置为0时,迭代将开始,服务器返回的游标为0时,迭代将终止
scan 0 match * count 100
#查询100列内容,*是匹配所有,正则匹配时*只能放最后匹配,无法指定字符匹配
redis -cli -h ip -p port -a pass -n 1 --scan --pattern 1*TD (测试只有这种可以使用正则匹配)
#可以匹配特定字符,-n是指库
redis -cli -h ip -p port -a pass -n 1 --scan --pattern 1*TD | xargs redis -cli -h ip -p port -a pass -n 1 del
#遍历后删除
往redis写入数据时,为了减少io的消耗,可以使用redis的pipeline功能
redis-cli的pipeline(管道功能),是非原子性的,可以批量一次读入reids,之后再去执行,减少网络开销,原生redis命令是原子性的
浙公网安备 33010602011771号