Redis笔记

初识Redis

特征:

  1. 键值型,value支持多种不同数据结构,功能丰富
  2. 单线程,每个命令具备原子性
  3. 低延迟,速度快(基于内存,IO多路复用,良好的编码)
  4. 支持数据持久化
  5. 支持主从集群,分片集群

Redis通用命令

常见指令:

  1. KEYS : 查看符合模版的所有KEY,不建议在生产环境设备上使用
  2. DEL:删除一个指定的KEY
  3. EXISTS: 判断key是否存在
  4. EXPIRE: 给一个key设置有效期,有效期到期时key会被自动删除
  5. TTL: 查看一个KEY的剩余有效期
    通过help[command]可以查看一个命令的具体做法,如 help keys

String类型:

Key的层级格式:

Hash类型:

List类型:可看作一个双向链表结构,可支持正向检索和反向检索

Set类型: value为null的HashMap

SortedSet类型: 一个可排序的set集合,每一个元素都带有一个score属性,可基于此属性对元素排序,底层实现是一个跳表(SkipList)+hash表

分布式缓存

单点Redis的问题

在这里插入图片描述

持久化

RDB

redis数据备份文件(redis数据快照),内存中所有数据都记录到磁盘中。redis实例故障重启后,从磁盘读取快照文件,恢复数据。
bgsave基本流程

  1. 开始时会fork主进程得到子进程,子进程共享主进程的内存数据;
  2. 完成fork后子进程读取内存数据并写入RDB文件;
  3. 用新RDB文件替换旧的RDB文件;

fork采用的是copy-on-write技术:

  1. 当主进程执行读操作时,访问共享内存。
  2. 当主进程执行写操作时,则会拷贝一份数据,执行写操作。
    在这里插入图片描述
    通过虚拟内存 映射实现共享内存数据

RDB执行时机? save 60 1000 ?
  默认服务停止时执行,60秒内至少执行1000次i需改则触发RDB
RDB缺点?
  RDB执行间隔时间长,两次RDB间写入数据有丢失风险
  fork子进程、压缩、写出RDB文件都比较耗时

AOF

追加文件,Redis处理的每一个写命令都会记录在AOF文件,可以看作是命令日志文件
因为记录命令,所以比RDB文件大得多,且会记录对同一个key的多次写操作,但只有最后一次写操作才有意义,通过执行bgewriteaof命令,可让AOF文件执行重写功能,用最少的命令达到相同效果。Redis也会在触发阈值时自动去重写AOF文件。
在这里插入图片描述

AOF对比RDB

在这里插入图片描述

Redis 主从

搭建主从架构

实现读写分离
在这里插入图片描述
数据同步原理
主从第一次同步时全量同步
在这里插入图片描述

全量同步流程:

  1. slave节点请求增量同步
  2. master节点判断replid,发现不一致,拒绝增量同步
  3. master将完整内存数据生成RDB,发送RDB到slave
  4. slave清空本地数据,加载master的RDB
  5. master将RDB期间的命令记录在repl_baklog, 并持续将log中的命令发送给slave
  6. slave 执行接收到的命令,保持与master之间的同步

如果slave重启后同步,则执行增量同步
在这里插入图片描述

Redis哨兵

Redis 原理

IO多路复用

无论是阻塞IO还是非阻塞IO ,用户应用在一阶段都需要调用recvfrom来获取数据,差别在于无数据时的处理方案:

  1. 如果调用rcvfrom时,恰好没有数据,阻塞IO会使进程阻塞,非阻塞IO使CPU空转,都不能充分发挥CPU的作用
  2. 如果调用recvfrom时,恰好有数据,则用户进程可以直接进入第二阶段,读取并处理数据

FD文件描述符:从0开始递增的无符号整数,用来关联linux中的一个文件;
IO多路复用:利用单个线程来同时监听多个FD,并在某个FD可读、可写时得到通知,从而避免无效的等待,充分利用cpu资源
select poll epoll
差异:

  1. select和poll只会通知用户进程有FD就绪,但不确定具体是哪个FD,需要用户进程逐个遍历FD来确认;
  2. epoll则会在通知用户进程FD就绪的同时,把已就绪的FD写入用户空间;

poll

  1. 创建pollfd数组,向其中添加关注的fd信息,数组大小自定义;

  2. 调用poll函数,将pollfd数组拷贝到内核空间,转链表存储,无上限;

  3. 内核遍历fd,判断是否就绪;

  4. 数据就绪或超时后,拷贝pollfd数组到用户空间,返回就绪fd数量n;

  5. 用户进程判断n是否大于0;

  6. 大于0则遍历pollfd数组,找到就绪的fd;
    对比select:

  7. select模式中的fd_set大小固定为1024,而pollfd在内核中采用链表,理论上无上限;

  8. 监听fd越多,每次遍历消耗时间也越久,性能反而会下降;

epoll

总结:
select模式存在的三个问题?
1)能监听的FD最大不超过1024
2)每次select都需要把所有要监听的FD都拷贝到内核空间
3)每次都要遍历所有的FD来判断就绪状态

poll模式的问题?
1)利用链表解决了select中监听FD上限的问题,但依然要遍历所有FD,如果监听较多,性能会下降;

epoll模式中如何解决这些问题?
1)基于epoll实例中的红黑树保存要监听的FD,理论上无上限,而且增删改查效率都非常高,性能不会随监听的FD数量增多而下降
2)每个FD只需要执行一次epoll_ctl添加到红黑树, 以后每次epoll_wait无需传递任何参数,无需重复拷贝FD到内核空间
3)内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有FD就能知道就绪的FD是谁

IO多路复用-事件通知机制

FD有数据可读时,调用epoll_wait就可以得到通知,由两种:

  1. LT,有数据可读时,会重复通知多次,直至数据处理完成,时Epoll的默认模式;
  2. ET,…………,只会被通知一次,不管数据是否处理完成;
    惊群现象(所有进程都被唤醒)

信号驱动IO

信号驱动IO时与内核简历SIGIO的信号关联并设置回调,内核有FD就绪时,会发出SIGIO信号通知用户,期间用户应用可以执行其他业务,无需阻塞等待
在这里插入图片描述

异步IO

在这里插入图片描述
全部交给内核,然后啥玩意也不管,在高并发下,相当于领导不管下属死活,导致内存过多系统崩溃。

Redis网络模型

reids到底是多线程还是单线程?
  仅聊redis的核心业务部分(命令处理): 单线程
  聊整个redis: 多线程

为什么redis要选择单线程?
1.抛开持久化不谈,redis时纯内存操作,执行速度很快,性能瓶颈时网络延迟而不是执行速度,因此多线程不会带来很大的性能提升。
2. 多线程导致过多的上下文切换,有不必要的开销
3. 引入多线程面临线程安全问题,必然要引入线程锁这样的安全手段,实现复杂度高,且性能会打折扣

内容均来自B站黑马程序员redis视频,若有侵权,联系删除!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值