Redis相关知识点

1.什么是Redis

Redis (REmote DIctionary Server) 是用 C 语言开发的一个开源的高性能键值对(key-value)数据库,它支持网络,可基于内存亦可持久化,并提供多种语言的API。Redis具有高效性、原子性、支持多种数据结构、持久化、高并发读写等特点。

特征:

1.数据间没有必然的关联关系

2.内部采用单线程机制进行工作

3.高性能,官方提供测试数据,50个并发执行100000 个请求,读的速度是110000 次/s,写的速度是 81000次/s。

4.多数据类型支持

5.持久化支持。可以进行数据灾难恢复

2.Redis数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted_set:有序集合)。

  1. String(字符串):这是Redis最基本的数据类型,一个key对应一个value,并且是二进制安全的,可以包含任何数据,例如jpg图片或者序列化的对象。
  2. Hash(哈希):哈希是一个键值(key=>value)对集合,是string类型的field和value的映射表,适合用于存储对象,比将每个字段都存储为string更节省内存。
  3. List(列表):列表是一个简单的字符串列表,按照插入顺序进行排序,可以添加一个元素到列表的头部或者尾部。
  4. Set(集合):Set是一个无序的字符串集合,其元素是唯一的,但本身不保证顺序。
  5. Zset(sorted_set:有序集合):Zset是有序的字符串集合,其元素是唯一的,但元素会根据提供的分数进行排序。每个元素都会关联一个double类型的分数,通过分数来为集合中的元素进行从小到大的排序。

3.什么是乐观锁和悲观锁

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每 次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里 边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。

乐观锁(Optimistic Lock) 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。 乐观锁适用于多读的应用类型,这样可以提高吞吐量。Redis就是利用这种check-and-set(CAS)机制实现事务的

4.Redis的持久化机制有哪些?

持久化的方案有两种,分别是RDB和AOF,根据不同的场景,可以选择只使用其中一个或者一起使用。

RDB是通过保存快照的方式来对数据进行持久化处理,所保存的数据的本身,默认使用的是bgsave来保存快照数据。

RDB的优缺点:

优点:

  • 基于二进制文件完成数据备份,占用空间少,便于文件传输
  • 能够自定义规则,根据Redis繁忙状态进行数据备份

缺点:

  • 无法保证数据完整性,会丢失最后一次快照后的所有数据
  • bgsave执行每次执行都会阻塞Redis服务进程创建子线程,频繁执行影响系统吞吐量

RDB方式会出现数据丢失的问题,对于这个问题,可以通过Redis中另一个持久化方式解决:AOF

当AOF持久化开启后,Redis会将客户端发送的所有更改数据的命令保存至磁盘中,通过读取AOF文件,按照顺序获取所记录的数据命令,来达到恢复数据的效果。

AOF写数据三种策略(appendfsync)

  • always(每次):每次写入操作均同步到AOF文件中,该方式效率最高,数据零误差,安全性最高,但是十分浪费资源。
  • everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,并且每隔一秒同步到磁盘当中一次,数据准确性较高,性能较高 在系统突然宕机的情况下丢失1秒内的数据。
  • no(系统控制):由操作系统控制每次同步到AOF文件的周期,将同步操作交给系统来做,整体过程不可控,改方式最快,但是最不安全。

|------------|-----------|-----------|
| 持久化方式 | RDB | AOF |
| 占用存储空间 | 小(数据级:压缩) | 大(指令级:重写) |
| 存储速度 | 慢 | 快 |
| 恢复速度 | 快 | 慢 |
| 数据安全性 | 会丢失数据 | 依据策略决定 |
| 资源消耗 | 高/重量级 | 低/轻量级 |
| 启动优先级 | 低 | 高 |

将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据 (RDB);

将数据的操作过程进行保存,日志形式,存储操作过程,关注点在数据的操作过程(AOF);

RDB默认开启的,AOF需要手动开启 ;

RDB存储某个时刻的数据快照,AOF存储写命令;

RDB在配置触发状态会丢失最后一次快照以后更改所有的数据,AOF默认使用everysec,每秒保存一次;

5.Redis 删除策略

定时删除

  • 创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除 操作
  • 优点:节约内存,到时就删除,快速释放掉不必要的内存占用
  • 缺点:CPU压力很大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指 令吞吐量
  • 总结:用处理器性能换取存储空间(拿时间换空间)

惰性删除

  • 数据到达过期时间,不做处理。等下次访问该数据时 如果未过期,返回数据 发现已过期,删除,返回不存在
  • 优点:节约CPU性能,发现必须删除的时候才删除
  • 缺点:内存压力很大,出现长期占用内存的数据
  • 总结:用存储空间换取处理器性能(拿空间换时间)

定期删除

  • 定期删除是对定时删除和惰性删除做了平衡,redis默认每秒运行10次对具有过期时间的key进行次扫描,但是不会扫描全部的key,因为这样会大大延长扫描时间,每次默认只会扫描20个key,同时删除这20个key中已经过期的key,如果这20个key中过期key的比例超过25%,则继续扫描

  • 周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删 除频度

  • 优点1:CPU性能占用设置有峰值,检测频度可自定义设置

  • 优点2:内存压力不是很大,长期占用内存的冷数据会被持续清理

  • 总结:周期性抽查存储空间 (随机抽查,重点抽查)

    |------|----------|------------------|-----------|
    | 定时删除 | 节约内存,无占用 | 不分时段占用CPU资源,频度高 | 拿时间换空间 |
    | 惰性删除 | 内存占用严重 | 延时执行,CPU利用率高 | 拿空间换时间 |
    | 定期删除 | 内存定期随机清理 | 每秒花费固定的CPU资源维护内存 | 随机抽查,重点抽查 |

6.Redis缓存淘汰策略

Redis的内存参数配置,在64位操作系统中,如果未设置或设置0,代表无限制,而在32位系统中,默认内存大小为3GB。但是在实际生产环境下,一般会设置物理内存的四分之三左右。当客户端执行命令添加数据时Redis会检查内存空间大小,如果超过最大内存,则会触发内存淘汰策略。淘汰策略分为以下三种八类:
1.对设置了过期时间数据淘汰:

  • 设置了过期时间,且最近最久没有使用的数据进行淘汰
  • 设置了过期时间,且最近最少没有使用的数据进行淘汰
  • 设置了过期时间,且即将过期的数据进行淘汰
  • 设置了过期时间的数据进行随机淘汰

2.对所有数据淘汰:

  • 从所有数据中,删除最近最久没有被使用的数据进行淘汰
  • 从所有数据中,删除最近最少没有被使用的数据进行淘汰
  • 从所有的数据中,随机删除

3.不淘汰: (默认)

  • 当内存空间不足时,直接返回错误信息

7.什么是缓存雪崩

缓存雪崩的情况往往是由两种情况产生:

  • 情况1:由于大量key设置了相同的过期时间(数据在缓存和数据库都存在),一旦达到过期时间点,这些key集体失效,造成访问这些key的请求全部进入数据库
  • 情况2:Redis实例宕机,大量请求进入数据库

解决方案:

  • 情况1的解决方案
    • 错开过期时间:在过期时间上加上随机值
    • 服务降级:暂停非核心数据查询缓存,返回预定义信息
  • 情况2的解决方案
    • 事前预防:搭建高可用集群
    • 构建多级缓存(实现成本较高)
    • 熔断:通过监控一旦雪崩出现,暂停缓存访问待实例恢复,返回预定义信息
    • 限流:通过监控一旦发现数据库访问量过阈值,限制访问数据库的请求数

**8.**什么是缓存击穿

缓存击穿问题也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击。

常见的解决方案有两种:

  • 使用互斥锁:当一个线程查询缓存未命中后,使用锁来阻塞其他线程对数据库的访问,直到锁被释放。这样可以避免同时有多个线程去查询数据库,从而降低数据库的访问压力。

  • 逻辑过期:对于一些查询频率较高的数据,可以设置一个逻辑过期时间,当缓存过期后,先查询数据库,然后再将查询到的数据设置回缓存。这样可以保证在一段时间内只有一个线程去查询数据库,其他线程仍然可以从缓存中获取数据。

    |------|----------------------|----------------------|
    | 解决方案 | 优点 | 缺点 |
    | 互斥锁 | 没有额外的内存消耗 保证一致性 实现简单 | 线程需要等待,性能受影响 可能有死锁风险 |
    | 逻辑过期 | 线程无需等待,性能较好 | 不保证一致性 有额外内存消耗 实现复杂 |

9.什么是缓存穿透

缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库。

常见的解决方案有两种:

  • 缓存空对象
    • 优点:实现简单,维护方便
    • 缺点: 额外的内存消耗,可能造成短期的不一致
  • 布隆过滤
    • 优点:内存占用较少,没有多余key
    • 缺点: 实现复杂,存在误判可能

10.Redis为什么被设计成单线程

  1. 实现简单:单线程模型简化了Redis的代码实现,降低了维护成本,也减少了潜在的复杂性。
  2. 避免多线程的上下文切换和竞争条件:单线程避免了不必要的上下文切换和竞争条件,避免了CPU资源的浪费。同时,由于Redis是基于内存的操作,CPU不是Redis的瓶颈,因此单线程不会成为性能瓶颈。
  3. 避免死锁:在单线程情况下,不需要考虑各种锁的问题,不存在加锁、释放锁操作,也没有因为可能出现死锁而导致的性能消耗。
  4. 避免多进程导致的切换和消耗:采用单线程、多进程的集群方案可以避免多进程导致的切换和消耗,提高效率。
  5. 异步非阻塞IO:Redis使用非阻塞IO,即多路复用IO,一个线程可以服务多个IO流。传统的网络IO是阻塞式的,服务器线程会一直在监听数据传输的管道,一直阻塞在那里,直到有客户端发送数据。非阻塞IO可以提高Redis的吞吐量。

11.Redis为什么那么快

  1. 内存存储:Redis将所有数据存储在内存中,这使得它能够快速地读写数据。与传统的磁盘存储相比,内存存储的访问速度更快。
  2. 单线程架构:Redis是单线程的,Redis不需要进行上下文切换,也不需要考虑线程同步和枷锁等问题,从而避免了这些常见的多线程问题所带来的开销。
  3. 异步非阻塞I/O:Redis使用了事件驱动机制,并采用了异步非阻塞I/O模型,这使得Redis能够处理大量的并发连接请求,提高了系统的吞吐量。
  4. 基于内存的操作:Redis的所有操作都是基于内存的,这使得Redis能够在微秒级别完成大部分操作,从而提高了系统的响应速度

12.MySQL和Redis的区别

  1. **数据结构:**MySQL是关系型数据库,支持表和行等结构化数据类型,而Redis是键值对存储系统,支持字符串、哈希、列表、集合、有序集合等非结构化数据类型。
  2. **数据存储方式:**MySQL将数据存储在硬盘上,而Redis将数据存储在内存中。
  3. **数据查询:**MySQL支持复杂的查询操作,可以使用SQL语言进行查询,而Redis只支持简单的键值对操作,不支持复杂的查询操作。
  4. **数据持久化:**MySQL可以通过日志和备份文件来持久化数据,而Redis可以通过配置持久化策略来持久化数据。

使用MySQL的情况:

  • 需要处理结构化数据,如表格和行。
  • 需要进行复杂的查询操作,如联接、子查询等。
  • 数据量较大,但不需要将所有数据都存储在内存中。
  • 需要持久化数据,以确保数据不会因为系统故障而丢失。

使用Redis的情况:

  • 需要处理非结构化数据,如字符串、哈希、列表、集合、有序集合等。
  • 需要将所有数据都存储在内存中,以提高数据访问速度。
  • 不需要进行复杂的查询操作,只需要进行简单的键值对操作。
  • 不需要持久化数据,因为数据可以存储在内存中,即使系统故障也不会丢失。
相关推荐
gma9997 分钟前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️9 分钟前
华为ASP与CSP是什么?
服务器·前端·数据库
Yz98761 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
wkj0011 小时前
php操作redis
开发语言·redis·php
苏-言1 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
Ljw...1 小时前
索引(MySQL)
数据库·mysql·索引
菠萝咕噜肉i1 小时前
超详细:Redis分布式锁
数据库·redis·分布式·缓存·分布式锁
长风清留扬1 小时前
一篇文章了解何为 “大数据治理“ 理论与实践
大数据·数据库·面试·数据治理
OpsEye2 小时前
MySQL 8.0.40版本自动升级异常的预警提示
数据库·mysql·数据库升级
Ljw...2 小时前
表的增删改查(MySQL)
数据库·后端·mysql·表的增删查改