Redis必会知识点

Redis是一款使用C语言编写、可基于内存也可以持久化的日志型、Key-Value型开源数据库。它可以用作:数据库、缓存和消息中间件。

数据结构

redis支持的5种基本数据类型:

数据类型 定义 使用场景
字符串(String) Redis的基本数据类型,一个Key对应一个Value 缓存、计数器、分布式锁等
哈希(Hash) Hash是一个string类型的key和value的映射表,特别适合用于存储对象 用户信息、Hash 表等
列表(List) List是简单的字符串列表,按照插入顺序排序。可以添加一个元素导列表的头部(左边)或者尾部(右边)。相当于链表 链表、队列、微博关注人时间轴列表等
集合(Set) Set是string类型的无序集合捕鱼必须重复,通过哈希表实现,添加,删除,查找的复杂度都是O(1) 去重、赞、踩、共同好友等
有序集合(Zset) zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。通过分数来为集合中的成员进行从小到大的排序 访问量排行榜、点击量排行榜等

以及,范围查询,Bitmaps,Hyperloglogs 和地理空间(Geospatial)索引半径查询

Redis为什么快?

Redis采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,官方提供的数据是可以达到 100000+ 的QPS(每秒内查询次数)

原因分析:

  1. 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);

  2. 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的,如SDS,跳跃表等等

  3. 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗

  4. 使用多路I/O复用模型,非阻塞IO;

  5. 使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

Redis与Memcached区别

  1. Redis支持服务器端的数据操作:Redis相比Memcached来说,拥有更多的数据结构和并支持更丰富的数据操作,通常在Memcached里,你需要将数据拿到客户端来进行类似的修改再set回去。这大大增加了网络IO的次数和数据体积。在Redis中,这些复杂的操作通常和一般的GET/SET一样高效。所以,如果需要缓存能够支持更复杂的结构和操作,那么Redis会是不错的选择。
  2. 内存使用效率对比:使用简单的key-value存储的话,Memcached的内存利用率更高,而如果Redis采用hash结构来做key-value存储,由于其组合式的压缩,其内存利用率会高于Memcached。
  3. 性能对比:由于Redis只使用单核,而Memcached可以使用多核,所以平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。
  4. 集群模式:memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是redis目前是原生支持cluster模式的,redis官方就是支持redis cluster集群模式的,比memcached来说要更好。

缓存雪崩

redis缓存的key在同一时间大量的失效,导致大量的请求同事打到数据库,造成数据库压力过大
解决方案:

  • 合理地设置缓存的过期时间,过期时间加上随机值
  • 热点数据永不过期,定时刷新缓存数据
  • 互斥锁,拿到锁再去访问数据库,性能有影响

缓存穿透

大量请求Redis并不存在的数据,导致请求大量的打到数据库,可能是攻击页可能是非法参数
解决方案:

  • 互斥锁,拿到所再去访问数据库,性能有影响
  • 返回null,异步更新
  • 合法参数校验, 布隆过滤器
  • 数据库查询为空的对象也放入缓存,但是过期时间设置的比较短

缓存击穿

热点key过期,导致大量请求直接达到数据库,造成数据库压力剧增
解决方案:

  • 互斥锁,分布式锁,只有一个线程能够抢到这个锁,也就只有一个线程能够进入到数据库,然后将数据放到缓存,其他线程就能从缓存拿到这个数据
  • 永不过期,定时刷新缓存

持久化

bgsave
手动,太麻烦

rdb配置文件配置持久化策略

省心
还是可能会会丢失数据

AOF

配置appendonly yes
有点:实时记录命令
文件大,时间长文件会很大

可以和rdb结合使用

主从同步

主从复用,读写分离

发布订阅模式

哨兵模式

主服务器挂掉之后,重新选出一个主服务器进行读写,主服务器恢复之后还是能作为集群的节点

key的过期淘汰机制

虽然Redis可以对缓存的key设置过期时间,但是并不是过期时间到了缓存的数据就一定会被淘汰

定期删除

默认每秒钟扫描10次,也就是每100ms扫描一次,过期扫描不会扫描全部数据(扫描全部性能小消耗太大),而是采用一种很简单的贪心策略:

  • 从过期字典中随机选择20个key
  • 删除这些key中的过期key
  • 如果删除的元素超过1/4就继续重复步骤1和2

惰性删除

查询的时候会看key是否过期,过期的话删除数据,不返回任何内容
弥补了定期删除的不足,可能有很多已经过期的key在定期删除的时候并没有被成功地删掉
定期删除是集资红处理,惰性删除则是零散处理

内存淘汰策略

不管是定期删除还是惰性删除,都不是一个完全精准的删除,还是会有key没有被删除的情况存在,于是就需要内存淘汰策略

  1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键
  2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键
  3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的
  4. allkeys-random:加入键的时候如果过限,从所有key随机删除
  5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐
  6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键
  7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键
  8. allkeys-lfu:从所有键中驱逐使用频率最少的键

Guess you like

Origin blog.csdn.net/crazyjack1/article/details/119190528