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的情况:

  • 需要处理非结构化数据,如字符串、哈希、列表、集合、有序集合等。
  • 需要将所有数据都存储在内存中,以提高数据访问速度。
  • 不需要进行复杂的查询操作,只需要进行简单的键值对操作。
  • 不需要持久化数据,因为数据可以存储在内存中,即使系统故障也不会丢失。
相关推荐
一个处女座的程序猿O(∩_∩)O11 小时前
从InfluxDB到金仓:时序数据库性能拐点已至?
数据库·时序数据库
青云交11 小时前
Java 大视界 -- 基于 Java+Flink 构建实时电商交易风控系统实战(436)
java·redis·flink·规则引擎·drools·实时风控·电商交易
数据和云11 小时前
Oracle没有退路
数据库·oracle·vr
破烂pan11 小时前
Python 整合 Redis 哨兵(Sentinel)与集群(Cluster)实战指南
redis·python·sentinel
Gauss松鼠会11 小时前
【openGauss】让gsql和sqlplus输出包含有SQL及数据的完全一致的文本文件
数据库·sql·database·opengauss
盛世宏博北京11 小时前
分布式库房集中管!云端 “八防” 监控平台,多站点统一可视化运维
大数据·网络·数据库·档案温湿度
言之。11 小时前
向量数据库
数据库
Debroon12 小时前
Graphiti:Cypher与SQL的“同声传译“,一个让图数据库和关系数据库握手言和的验证器
数据库·sql
SoleMotive.12 小时前
redis和mysql有什么区别,以及redis和mysql都有什么缺点,以及什么地方redis不如mysql?
数据库·redis·mysql
代码代码快快显灵12 小时前
Android跨应用数据共享:ContentProvider详解
jvm·数据库·oracle