Redis开启篇

504 阅读5分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

Redis简介

Redis(Remote Dictionary Server 远程数据服务)是一款内存高速缓存数据库,使用C语言编写,Redis是一个key-value存储系统,支持丰富的数据类型,如:String、list、set、zset、hash。

优点

  • 读写性能好:读110000次/s,写81000次/s。

  • 支持持久化:RDB全量,AOF增量。 RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复是将快照文件直接读到内存中。相当于快照。
优势:作为快照,文件比起增量逻辑日志,文件更小,能够快速进行全量恢复。
劣势:因为是快照,需要进行全量备份,比较消耗资源且执行时间相对增量而言长得多,所以是每隔一段时间进行的,因此间隔内出现宕机等异常情况,会丢失间隔时间内的所有数据。

AOF

以append的方式记录每个写操作的日志,为逻辑日志,有点像mysql的binary log,追加的方式会导致文件越来越大,为了避免这种情况新增了重写机制。
优势:因为维度为写操作,可以在每个写操作之后同步进行,也可以每秒进行异步记录,执行的时间肯定比全量备份快的多。
劣势:追加的日志,文件会越来越大,大小肯定不如全量备份的小。恢复上如果aof效率肯定没有rdb快,因为一个是对当前的数据进行的备份比如mysql中的insert但是aof可能会包含初始的insert和中间所有的update最终恢复数据。

混合模式

4.0及之后提供了混合模式,即全量+增量,前半段为RDB后半段为AOF,每隔一段时间重新备份一次清空AOF,这样既解决了RDB不具备短时间内频繁备份,又解决了AOF文件追加越来越大后面还会产生覆盖。

image.png

笔者笔记本上的6.0版本的是redis.conf默认是混合模式的,相关配置如下:

# save 3600 1
# save 300 100
# save 60 10000
aof-use-rdb-preamble yes
appendonly no

劣势:这种参杂RDB和AOF的文件,4.0之前的版本不能用于恢复,可读性也会变差。

  • 支持丰富的数据类型:String、list、set、zset、hash。

  • 支持高可用:主从、哨兵。

  • 支持集群:Redis Cluster。

  • 原子性:所有操作都是原子性的-比如set key value、set key value EX seconds NX,同时Redis还支持对几个操作全并后的原子性执行-lua脚本。

  • 丰富的特性:支持publish/subscribe,通知,key过期等特性。

缺点

  • 单机内存有限,扩展上限和磁盘不是一个数量级的。
  • 主从同步是异步的,宕机存在数据丢失风险。 其实这点是从结果来看是个缺点,但是也是因此redis的写效率才会这么高,不然同步的话效率肯定会低。

为啥这么快

  • 使用内存。 首先数据直接在内存中,不需要读写磁盘,没有次磁盘IO的开销。其次相比在磁盘上相同的复杂的数据结构,在内存中操作起来更简单,这样Redis可以做很多内部复杂性很强的事情。
  • 底层数据做了优化。
  • 非阻塞IO。 epoll提供了基于事件的回调机制,即针对于不同事件的发生,调用相应的处理函数。

epoll一旦监测到FD上有请求达到时,就会触发对应的事件。这些事件会被放进一个事件队列,Redis单线程对该事件队列不断进行处理。这样一来,Redis无需一直轮询是否有请求发生,就可以避免CPU资源浪费。同时,Redis在对事件队列中的事件进行处理时,会调用相应的处理函数,这样就实现了基于事件的回调。因为Redis一直在对事件队列进行处理,所以能及时响应客户端请求,提升Redis的响应性能。

  • 单线程(Redis 6.0以前) 避免了多个线程之间线程切换和锁资源争用的开销。 Redis在处理客户端请求时,包括获取(socket读)、解析、执行、内容返回(socket写)都是由一个顺序串行的主线程执行的,这就是所谓的单线程。但如果严格讲,从Redis4.0之后并不是单线程,除了线程之外,它也有后台线程在处理一些缓慢的操作,例如清理脏数据,无用链接释放,大key的删除,数据持久化bgsave,bgrewriteof等,都是在主线程之外的子线程单独执行的。

  • 构建了VM机制。 就是将冷数据从内存交换到磁盘中,这是一种扩容的策略。为了保证查找速度,只会将value交换出去,而key保留于内存中。所以它非常适合key很小,value很大的场景。redis自己构建了VM机制,不会像一般的系统会调用系统函数,会浪费一定的时间去移动和请求,具体参考此文

不过值得注意的是从Redis Version 2.4开始就被官方明确表示不再建议使用,Version 3.2版本中更找不到关于虚拟内存(VM)的任何配置范例,Redis的主要作者Salvatore Sanfilippo还专门写了一篇论文,来反思Redis对虚拟内存(VM)存储技术的支持问题。