【个人笔记】【剑指Java面试-Offer直通车】【三】【Redis】
本帖最后由 小公主々 于 2021-5-3 09:27 编辑补充一点:7熔断即当IO存储发生故障时,可以直接将其对接缓存,不管是否能查询到数据。
Memcached和Redis的区别
M: 1.支持简单数据存储 2.不支持数据持久化,即宕机即丢 3.不支持主从 4.不支持分片
R: 1.五种数据类型 2.支持数据磁盘持久化 3.支持主从 4.支持分片
QPS:每秒内查询次数,Redis为100000+QPS
1.完全基于内存,单线程c语言编写
2.键值对数据结构,非关系型,所以不用维护关系
3.单线程可以处理高并发,想多核就多实例。并发非并行,还是流程化执行
4.跑满qps时,cpu未跑满,非制约因素
5.使用多路io复用模型,非阻塞io
非阻塞
引入FD文件描述符概念:
阻塞:当文件描述符不可读或不可写时,则停止服务
采用多路复用函数负责去监听文件描述符状态,一般是Select,其它函数效率较高,但灵活运用
五种数据类型:1.String 2.Hash 3.List(分左右存取操作)4.Set(判重无序)5.SortSet(有序Set,依靠Rank等级分数去排序)
扩展-底层数据类型基础:简单动态字符串、链表、字典、跳跃表、整数集合、压缩列表、对象
数据量比较大时,Keys * 会消耗时间很长,通过什么办法解决?
SCAN cursor
ex: scan 0 match k1* count 10
该指令会返回两组数据,第一组数据为指针,第二组为查询到的数据,不一定符合count,可以循环调用该指定,传入最新的指针数。同时,返回结果中存在重复数据,注意去重。
Redis分布式锁
分布式锁解决的问题:
1.互斥性 2.安全性 3.死锁 4.容错
实现方式
1.setnx key value,代表存储数据,如果不存在则存储,返回1。如果存在则返回0,可以用来检测是否有别的线程在操作目标数据。
2.结合expire给key设置有效时间,例如当上述结果返回1时,则设置有效期,同时可以继续执行独占资源逻辑。
3.该种方式存在的问题:原子性得不到满足,两步骤则非原子性,如果第一步成功执行,而第二步在执行前发生异常,则未给key设置有效期,该Key会被永久占用。
4.Redis内部进行优化,推出新命令方式解决该问题。
SET key value
5.一般存储的数据为requestid或者线程标识
6.偶发问题:大量key同时过期,由于清除大量key很耗时,出现短暂卡顿。
可通过在设置过期时间时加上随机值。
Redis模拟异步队列
1.利用rpush去生产消息,利用lpop去消费消息
2.该种方式的缺点是:没有去阻塞等待队列,达到有值就消费的效果。可以通过应用层里引入sleep去调用lpop重试;也可以通过制定指令去实现:
BLPOP key timeout:阻塞直到队列中有消息或超时
ex: blpop key 30
3.该种方式的缺点是只能供单个消费者消费
4.利用Redis的pub/sub主题订阅模式,发送者(pub)发送消息,订阅者(sub)订阅消息,订阅者可以订阅任意数量的频道
5.subscribe命令以及publish命令实现,缺点为:消息发布是无状态的,无法保证可达(例如发送消息时某个实例刚好下线,再上线之后没办法收到该消息),若要解决该问题,还需使用专业队列例如kafka等。
RDB持久化
RDB持久化(快照存储):将符合操作频率的数据键值对以二进制的形式存储到rdb文件中,是Redis默认持久化方案;配置解释即900s至少有一个key发生了变化
在程序中可定时调用BGSAVE命令,并在“lastsave"(查看上次保存所用时间)命令返回值发生改变值视为已完成,将其重新以时间戳命名文件。即实现某个时间点的全量备份文件
自动化触发RDB方式:1.根据redis.con配置里的SAVE m n定时触发(BGSAVE方式)
2.主从复制时,主节点自动触发
3.执行Debug Reload
4.执行Shutdown且没有开启AOF持久化
Copy-on-write(COW):同时操作相同资源时,获取相同指针指向资源,真正修改时,才会分配副本给该调用者;Redis就是采用该机制,fork出子进程去存储数据,实际上子进程此时操作的是副本,当完成之后会将该副本内容替换到主线程操作资源中,实现copy-on-write并行处理模式。
缺点:
第二点解释:一定时间内才调用一次快照存储方案,可能因为实例宕机而丢失记录。如果要求不能丢失任意修改,则需采用AOF持久化方式
AOF持久化
AOF持久化存储的是执行的指令,包括增量的数据。举例当Redis存储连续调用增加一百次的数据结果,实际上只存储最后一次即可,而aof会存储所有的指令记录。这样会导致AOF文件不断变大。解决该问题如下,同样是COPY-ON-WRITE机制。该文件重写机制是服务器定期执行的。
现在默认采用RDB-AOF混合持久化方式:BGSAVE做镜像全量持久化,AOF做增量持久化。比如Redis重启时会先恢复Rdb文件,再恢复AOF近期指令
Redis的Pipeline
类似mysql的批处理,原本是需要单次请求并响应,Pipeline是批量执行命令,节省多次IO往返的时间
Redis的同步机制
Master用于写,多个Slave用于读操作。
主从同步和从从同步:主节点首先执行BGSAVE操作,并将后续修改数据等操作记录到Buffer中,完成后将AOF文件全量同步到从节点,从节点将数据同步到缓存中并通知主节点将期间操作的数据记录同步过来。即两个过程,全同步和增量同步过程,
弊端:主从不具备高可用,当主机宕机之后,将不能对外提供服务。
Redis Sentinel
哨兵机制:解决主机宕机,实现主从切换。
作用1.定时检查主从服务器是否允许正常
2.通过api向管理员等及时发送故障通知
3.自动故障迁移,即主从切换(例如会重新返回给客户端新master的地址)
Redis集群原理(一致性hash算法)
1.分片,按照某种规则去划分数据,分散存储在多个节点上。
2.常规的hash划分无法实现节点的动态增减
3.引入一致性hash算法:对2的32次方进行取模,将哈希值空间组织成虚拟的圆环,即该圆环由2的32次方个点组成,一般可以通过主机名或者主机ip去计算hash,确定数据分布在哪个节点(将数据key通过相同的函数hash计算出哈希值)。
4.当某节点发生宕机时,该节点原有的数据会顺时针选择下个节点进行换位存储;同样,当增加某个节点之后,该节点与上个节点中间的数据会换位存储到新节点上。综上,实现适配节点的增减。即只影响小部分数据,保证数据的一致性和容错性
5.存在问题:Hash环的数据倾斜问题,由图可知,当两个节点时,数据容易将单个节点撑爆,因此,通过虚拟节点来解决该问题,即分配相同数量的虚拟节点指向a和b,当数据虚存储到指向a的虚拟节点时,那么该数据则存储到a。虚拟节点一般设置32个
本章总结
1.缓存数据库2.主流应用架构3.多路I/O复用4.常用类型5.海量数据筛选某一固定值的key6.实现简单的分布式锁7.模拟异步队列8.持久化三种方案(RDB/AOF/混合)9.Redis主从10.Redis哨兵11.Redis集群
ps:1.发帖之前排版好好的,发完直接全乱了,重新全弄了一下,再不行就不排版了。
2.有正在看该课程的小伙伴有问题可以问。
感谢分享。 长知识了{:1_921:} 学到知识了,感谢分享 问下楼主,算法需要学吗? 初级程序员想往上升级,没有一个具体的路线 jws6994 发表于 2021-5-28 15:42
问下楼主,算法需要学吗? 初级程序员想往上升级,没有一个具体的路线
1. 如果你问的是需不需要学就能会,那肯定是不可能的,什么东西都要学。
2. 如果你问的是有没有学的必要性。算法的话,算扩充人的思维逻辑能力,你如果只用到CRUD,那么你就不用学;如果你想更深层发展,比如研究底层的东西,链表红黑树等等结构的话,那么你如果算法基础不错,理解起来会轻松一点。 小公主々 发表于 2021-5-28 15:47
1. 如果你问的是需不需要学就能会,那肯定是不可能的,什么东西都要学。
2. 如果你问的是有没有学的必要 ...
第二种,扩充思维能力,我发现作为一个程序员是非常不合格的在这一方面,现在学起来是比较痛苦的,只能是慢慢磨,找书看,写demo 学习学习 就很nice 感谢分享
页:
[1]