乐趣区

关于redis:Redis知识点整理

Redis 介绍

Redis 是一个应用 C 语言开发的数据库,Redis 数据存储在内存中,所以读写速度十分快。

利用场景

  • 数据(热点)⾼并发的读写
  • 海量数据的读写
  • 对扩展性要求⾼的数据

分布式缓存和本地缓存的区别

分布式缓存

本地缓存

缓存一致性

较好

较弱,每个实例都有本人的缓存

堆内存占用

不占用

占用,影响垃圾回收

速度

较慢,因为须要网络传输和序列化

较快

应用场景

要求数据一致性,访问量大的场景

对数据一致性没有特地高的要求,且拜访次数多的场景

本地缓存的实现:

  • 应用特定数据结构,比方 ConcurrentHashMap
  • 使⽤开源的缓存框架 Ehcache,Ehcache 封装了对于内存操作的性能
  • Guava Cache 是 Google 开源的⼯具集,提供了缓存的边界操作⼯具、

Redis 和 Memcache 的区别

Redis

Memcache

存储形式

长久化

断电失落

反对数据类型不同

String,hash,list,set,zset

只反对 key-value

速度

缓存解决流程

常见数据结构

  • String(字符串)

最大容量为 512M

  • list(列表)

list 是字符串列表,依照插⼊程序排序。元素能够在列表的头部(右边)或者尾部(左边)进⾏增加。最大容量为 2^32-1 个。能够做音讯队列。

  • hash(哈希)

Re­dis hash 是⼀个键值对(key-value)汇合。Re­dis hash 是⼀个 String 类型的 field 和 value 的映射表,hash 特地适宜⽤于存储对象。最大容量为 2^32-1 个。

  • set(汇合)

Re­dis 的 set 是 String 类型的⽆序汇合。最大容量为 2^32-1 个。

  • zset(sorted set:有序汇合)

Re­dis zset 和 set ⼀样也是 String 类型元素的汇合,且 不容许反复的成员。不同的 zset 是每个元素都会关联⼀个 dou­ble 类型的分数。zset 通过这个分数来为汇合中所有元素进⾏从⼩到⼤的排序。zset 的成员是唯⼀的,但分数(score)却能够反复。最大容量为 2^32-1 个。适宜做排行榜。

zset 底层实现

跳表,这篇文章对跳表进行了具体的解说:

www.jianshu.com/p/dc252b5ef…

过期删除策略

常见的删除策略:

  • 定时删除:设置过期工夫的同时,创立一个 timer,过期工夫一到就被动删除
  • 惰性删除:放任不管,每次获取时,才判断是否过期,过期就删除,属于被动删除
  • 定期删除:每隔一段时间就对数据库进行一次删除过期键的操作

Re­dis 采纳惰性删除 + 定期删除的形式治理键。既减小 cpu 压力的同时,也保障了数据的准确性。

内存淘汰机制

因为可能产生,既没有被惰性删除也没有被定期删除,但内存很快满了的状况呈现,所以须要肯定的内存淘汰机制。有 6 中淘汰策略:

  • no-eviction:不会持续服务 写申请 读申请 能够持续进行。这样能够保障不会失落数据,然而会让线上的业务不能继续进行。这是默认的淘汰策略。
  • volatile-lru:尝试 淘汰设置了过期工夫 的 key,起码应用的 key 优先被淘汰。没有设置过期工夫的 key 不会被淘汰,这样能够保障须要长久化的数据不会忽然失落。(这个是应用最多的)
  • volatile-ttl:跟下面一样,除了淘汰的策略不是 LRU,而是 key 的残余寿命 ttl 的值,ttl 越小越优先被淘汰, 即 淘汰将要过期的数据
  • volatile-random:从已设置过期工夫的数据集(server.db[i].expires)中 随机 抉择数据淘汰。
  • allkeys-lru:区别于 volatile-lru,这个策略要淘汰的 key 对象是整体的 key 汇合,而不只是过期的 key 汇合。这意味着没有设置过期工夫的 key 也会被淘汰。
  • allkeys-random:从整体的 key 汇合(server.db[i].dict)中任意抉择数据淘汰。

长久化机制

  • RDB:将 Redis 在内存中的数据库记录定时 dump 到磁盘上的 RDB 长久化。
  • AOF:将 Redis 的操作日志以追加的形式写入文件。

RDB

RDB 长久化是指在指定的工夫距离内将内存中的数据集快照写⼊磁盘,实际操作过程是 fork ⼀个⼦过程,先将数据集写⼊长期⽂件,写⼊胜利后,再替换之前的⽂件,⽤⼆进制压缩存储。

长处:

  1. RDB 是紧凑的⼆进制⽂件,⽐较适宜备份,全量复制等场景
  2. RDB 复原数据远快于 AOF

毛病:

  1. 无奈实现实时或者秒级长久化
  2. 新老版本无奈兼容 RDB

AOF

AOF 长久化以⽇志的模式记录服务器所解决的每⼀个写、删除操作,查问操作不会记录,以⽂本的⽅式记录,能够关上⽂件看到具体的操作记录。

长处:

  1. 更好地爱护数据不失落
  2. append-only 模式写入性能比拟高
  3. 适宜做灾难性的误删除紧急复原

毛病:

  1. 对于同一份文件,AOF 文件要比 RDB 快照大
  2. 会对 QPS 有所影响
  3. 数据库复原慢,不适宜做冷备

缓存穿透

查问缓存中没有,数据库也没有的数据会导致缓存穿透。

解决办法:

  • 布隆过滤

将所有查问的参数都存储到一个 bitmap 中,查问之前先去 bitmap 外面验证,如果存在就进行底层缓存的数据查问;如果不存在就进行拦挡。

能够用于实现数据字典,进行数据的判重,汇合求交加。

  • 缓存空对象

间接缓存一个空对象,然而会有两个问题:

  1. 缓存将存储更多的键值对,可能会受到歹意攻打,至于内存空间的节约;能够通过设置过期工夫来管制。
  2. DB 与缓存数据不统一,能够通过异步音讯来进行数据更新的告诉。

缓存雪崩

一段时间内,大量的缓存生效,导致数据库压力忽然增大,导致缓存雪崩。

解决办法:

  • 扩散生效工夫
  • DB 拜访限度,进行限流
  • 多级缓存设计

缓存击穿

缓存中没有,然而数据库中油的数据,这时因为并发用户多,就会造成数据库压力霎时增大。

解决办法:

  1. 设置热点数据永不过期
  2. 加互斥锁,使写数据的只有一个线程执行:

缓存更新策略

先更新数据库,再更新缓存

  • 会导致线程平安问题

两个线程一起更新数据,就会造成脏数据的问题。

  • 更新缓存的复杂度绝对较高

因为个别存入缓存的数据都要通过一系列的计算。

先删除缓存,再更新数据库

可能会导致数据不统一的问题,比方,刚删掉缓存,另一个线程马上读取申请,缓存还是旧的。

解决办法只能是写数据胜利后,再更新一次缓存。

先更新数据库,再删除缓存

可能会造成短暂的数据不统一,在更新数据库胜利后和删除缓存之前,会有肯定的数据不统一景象,不过能够承受。

参考:《2020 最新 Java 根底精讲视频教程和学习路线!》
链接:https://juejin.cn/post/693720…

退出移动版