Redis深入分析

Redis作为常用的缓存中间件,在各种程序开发中被广泛应用,在不考虑数据存储在程序内存情况下,可以说应用起来大大减少了IO时间。Redis的通信协议是自己的定义的RESP,RESP是Redis序列化协议(Redis Serialization Protocol)的简写。它是一种直观的文本协议,优势在于实现过程异常简单,解析性能极好。避免其他数据形式的时间消耗,提高效率和性能。

一、Redis的IO模型和数据存储

首先,Redis是一个单线程程序,但是因为Redis的数据是存在程序内存中的,所以即便是单线程,在数据获取时间最大的时间开销是网络,这也就是Redis为什么作为一个单线程程序,运算却是如此之快。

二、Redis的并发

其次,在实际引用中,Redis并不是单一连接的,它是存在并发的,处理机制在于Redis采用的是非阻塞IO,另外加上了多路复用技术(可以看一下多路复用技术大概了解一下),从而大大提高了数据传输能力。也是由于单线程,Redis的消息以队列形式解析,先到先得。Redis为每个客户端套接字都关联一个响应队列。Redis服务器通过响应队列来将指令返回给客户端。在select事件轮询函数中,若响应队列为空当前客户端的描述符可从write_fds移出来,有数据后再放进去,避免select频繁返回空内容,引起CPU消耗飙升。有兴趣的可以看一下多路复用中的select,pselecy,poll,epoll等对FD的处理。

三、Redis的持久化

Redis的数据全部在内存里,需要持久化机制来防止因突然宕机而导致的数据丢失,持久化时进行的IO操作十分耗费资源,Redis主节点需要承受客户端请求的压力,因此持久化应当主要在从节点进行。
Redis持久化机制有两种,第一种是RDB快照,第二种是AOF日志。

RDB快照

  • 快照是一次全量备份
  • 快照是内存数据的二进制序列化形式,在存储上非常紧凑
  • 内存快照要求Redis必须进行文件IO,但文件IO操作不能使用多路复用API,会严重拖累服务器性能。
  • Redis需要一边持久化一边响应请求。为了防止即将持久化的内容被改动,需要使用操作系统的多进程COW(copy on write)机制来实现快照持久化。Redis持久化时会调用fork函数产生一个子进程
    子进程做数据持久化,不会修改现有的内存数据结构,它只对数据结构进行遍历读取,然后序列化写到磁盘中
    父进程不断服务客户端请求,数据段是有很多操作系统的页面组合而成,在修改数据时会用COW机制将需要修改的页面复制一份分离出来,然后在这个副本上修改,子进程的相应页面没有变化

AOF日志

  • AOF日志是连续的增量备份
  • AOF日志存储的是Redis服务器的顺序指令序列,只记录对内存修改的指令记录
  • AOF日志是先执行指令再记录日志。Redis在收到修改指令后,进行参数校验,逻辑处理,通过后才可存储。后记录日志是为了防止过多无效错误的指令增大日志文件大小。
  • AOF日志记录的是内存数据修改的指令记录文本,长期运行后日志会变得无比庞大,需定期进行AOF重写,给AOF日志瘦身
    Redis 提供了bgrewriteaof指令进行AOF日志瘦身。原理是开辟一个子进程对内存遍历,转换成一系列Redis操作指令,序列化到新的AOF日志中。序列化后再将操作期间发生的增量AOF追加到新AOF日志中,追加完成后立即用新日志替代旧日志
  • AOF日志是以文件形式存在,程序对日志进行写操作时,实际上是先将内容写到内核为文件描述符分配的内存缓存,然后内核异步将脏数据刷回磁盘。为了防止宕机,可使用linux的glibc提供的fsync(int fd) 函数将指定文件强制从缓存刷回磁盘。
    fsync函数是磁盘IO操作,速度很慢,在生产环境中通常是配置Redis每隔1s执行一次fsync操作

混合持久化

重启Redis恢复数据时,使用rdb会丢失大量数据,使用aof重放会花费很长时间。Redis4.0提供了混合持久化。重启时,先加载rdb内容,再重放增量AOF日志(自持久化开始到持久化结束的增量),重启效率大幅提升。

Redis的读写操作采用的是管道形式,管道操作的本质是调整读写次数,减少网络来回的次数来节省IO时间。在多个操作时间保证尽量少的使用网络开销。

Redis的事务可保证连续多个操作的原子性,但Redis事务比较简单,不具备真正的原子性,遇到错误指令后会继续执行剩下指令。
MULTI【开启事务】
EXEC【执行事务】
DISCARD【抛弃事务】
WATCH key [key …]【对其添加CAS乐观锁,WATCH的键受到监控,以检测其变化。如果在EXEC命令之前修改了至少一个监视键,则整个事务将中止,并且EXEC返回Null答复以通知该事务失败】

四、Redis广播

Redis是支持消息多播的消息队列,但是在Redis5.0之前不能持久化,一旦停机或者重启数据就会丢失,在5.0之后使用提供的Stream数据结构可以实现。

五、Redis的内存压缩

如果Redis管理的几何数据结构很小,它会使用紧凑存储形式压缩存储。当集合对象的元素不断增加,或者key或value值过大,则会从小对象结构变成标准结构

Redis并不总是将空闲内存立即返回给操作系统。操作系统是以页为单位回收内存的,一页上有许多的key,只有一页上所有的key被删除了才会回收此页。Redis虽然无法保证立即回收已删除key的内存,但会重新使用未回收的空闲内存。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值