Redis常见问题

1、什么是redis?

Redis 是 C 语言开发的一个开源的高性能键值对(key-value)的内存数据库,可以用作数据库、缓存、消息中间件等。它是一种 NoSQL的数据库。

性能优秀,数据在内存中,读写速度非常快,支持并发 10W QPS。

单进程单线程,是线程安全的,采用 IO 多路复用机制。

丰富的数据类型,支持字符串、散列、列表、集合、有序集合等。

支持数据持久化。可以将内存中数据保存在磁盘中,重启时加载。

主从复制,哨兵,高可用。

可以用作分布式锁。

可以作为消息中间件使用,支持发布订阅。

2、redis的数据类型都有哪些?

redis有以下几种常用的基本类型。

string:常用命令:set,get,setnx 功能:缓存。

list:常用命令:lpush(压入元素),linsert(指定元素前后插入元素),lset 功能:是一个双向链表,可以通过 lpush 和 rpop 写入和读取消息,做简单的消息队列。

hash:常用命令:hset,hget 功能:单点登录,存储用户信息。

set:常用命令:sadd(添加元素),scard()获取成员的数量 功能:全局去重功能,可以实现交集、并集等操作,从而实现共同好友等功能。

sorted Set(和set类似但是可以排序):常用命令:zadd,zcard 功能:有序性操作,可以对数据进行排序,可应用于排行榜等。

Bitmap:位图,Redis的位图是一种特殊的字符串数据类型,它可以存储一系列二进制位。位图可以进行位操作,如设置、获取和计数位的操作。它适用于一些特定的应用场景,如统计用户在线状态、记录用户活跃度等。

3、redis的缓存雪崩、缓存穿透、缓存击穿和哨兵?

缓存雪崩

什么是雪崩:缓存一般都是定时任务去刷新,假如redis的数据在同一时刻全部失效,这个时候正好有大量用户涌入,造成数据库崩溃。

如何避免雪崩:在批量往redis中存数据的时候,把每个key的失效时间都加一个随机值。

如果是集群,将数据均匀的分布到不同的redis库也可避免。

或者是设置热点数据永不过期。

缓存穿透:当查询的数据在redis和数据库中都不存在的时候-----解决:将空值设置到缓存,并设置较短的过期时间或者是在业务前进行验证脏数据。

缓存击穿:频繁的去查询访问一个热点数据,当这个数据失效的时候,会有一大批请求访问数据库,造成数据库挂机----解决:可以设置热点数据永不过期,或者是加互斥锁。

哨兵:通过发送命令,让redis服务器返回监控及运行状态,包括主服务器和从服务器。当哨兵检测到master宕机,会自动将从切换成主,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机。

4、redis为什么快?

(1)完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销。

(2)数据结构简单,对数据操作也简单。Redis中的数据结构是专门进行设计的,每种数据结构都有一种或多种数据结构来支持。Redis正是依赖这些灵活的数据结构,来提升读取和写入的性能。

(3)采用单线程,省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,也不会出现死锁而导致的性能消耗。

(4)使用基于IO多路复用机制的线程模型,可以处理并发的链接。

5、redis的持久化

redis的持久化有两种方式:

  • RDB(快照)方式持久化(默认)

  • AOF持久化

6、RDB的持久化是怎么实现的?

RDB的持久化是将某个时间点的所有数据都放到磁盘上,他的缺点是:如果系统发生故障,将会丢失最后一次创建快照之后的数据。如果数据量很大,保存快照的时间会很长。

快照方式在redis的配置如下:

java 复制代码
#在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 900 1              

#在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 300 10            

#在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 60 10000      

创建快照的方式有以下几种:

**BGSAVE命令 :**客户端向Redis发送 BGSAVE命令 来创建一个快照。对于支持BGSAVE命令的平台来说(基本上所有平台支持,除了Windows平台),Redis会调用fork来创建一个子进程,然后子进程负责将快照写入硬盘,而父进程则继续处理命令请求。

**SAVE命令 :**客户端还可以向Redis发送 SAVE命令 来创建一个快照,接到SAVE命令的Redis服务器在快照创建完毕之前不会再响应任何其他命令。SAVE命令不常用,我们通常只会在没有足够内存去执行BGSAVE命令的情况下,又或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令。

**save选项 :**如果用户设置了save选项(一般会默认设置),比如 save 60 10000,那么从Redis最近一次创建快照之后开始算起,当"60秒之内有10000次写入"这个条件被满足时,Redis就会自动触发BGSAVE命令。

**SHUTDOWN命令 :**当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器。

**一个Redis服务器连接到另一个Redis服务器:**当一个Redis服务器连接到另一个Redis服务器,并向对方发送SYNC命令来开始一次复制操作的时候,如果主服务器目前没有执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE命令。

7、AOF的持久化是怎么实现?

AOF持久化是将写命令添加到AOF文件的末尾。

与快照持久化相比,AOF持久化 的实时性更好,因此已成为主流的持久化方案。默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:

复制代码
appendonly yes

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof

8、如何选择合适的持久化方式?

一般来说, 如果想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。在这种情况下,当 Redis 重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

如果非常关心数据, 但仍然可以承受数分钟以内的数据丢失,那么可以只使用RDB持久化。

有很多用户都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的bug。

如果只希望数据在服务器运行的时候存在,也可以不使用任何持久化方式。

9、redis过期key的删除策略?

**立即删除:**立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力。

而且目前redis事件处理器对时间事件的处理方式--无序链表,查找一个key的时间复杂度为O(n),所以并不适合用来处理大量的时间事件。

**惰性删除:**惰性删除是指,某个键值过期后,此键值不会马上被删除,而是等到下次被使用的时候,才会被检查到过期,此时才能得到删除。所以惰性删除的缺点很明显:浪费内存。dict字典和expires字典都要保存这个键值的信息。

举个例子,对于一些按时间点来更新的数据,比如log日志,过期后在很长的一段时间内可能都得不到访问,这样在这段时间内就要拜拜浪费这么多内存来存log。这对于性能非常依赖于内存大小的redis来说,是比较致命的。

**定时删除:**从上面分析来看,立即删除会短时间内占用大量cpu,惰性删除会在一段时间内浪费内存,所以定时删除是一个折中的办法。定时删除是:每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对cpu的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。

相关推荐
问简3 分钟前
MISCONF Errors writing to the AOF file: Bad file descriptor
redis
小尔¥11 分钟前
MySQL故障排查与优化
运维·数据库·mysql
独断万古他化12 分钟前
抽奖系统性能负载测试:基于 JMeter 的梯度加压与本地缓存优化全流程
java·redis·jmeter·缓存·压力测试·测试·负载测试
rrrjqy16 分钟前
Redis常见问题(一)
数据库·redis·缓存
Humbunklung17 分钟前
WMO 天气代码(Code Table 4677)深度解析与应用报告
开发语言·数据库·python
道清茗27 分钟前
【MySQL知识点问答题】锁机制、索引优化与数据库恢复方法
数据库·mysql
hero.fei39 分钟前
排查redis出现报错ERR redis temporary failure
数据库·redis·缓存
福大大架构师每日一题1 小时前
ollama v0.19.0 发布!Web 搜索插件上线、多模型兼容修复、MLX 与 KV 缓存全面优化,本地大模型体验再升级
缓存·ollama
野犬寒鸦1 小时前
MySQL复习记录Day01
数据库·后端
ward RINL1 小时前
Spring boot启动原理及相关组件
数据库·spring boot·后端