Redis
1 介绍一下Redis ?
Redis 的全称是:Remote Dictionary.Server,本质上是一个 Key-Value 类型的内存数据库
整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据 flush 到硬盘上进行保存。
因为是纯内存操作,Redis 的性能非常出色,每秒可以处理超过 10 万次读写操作,是已知性能最快的Key-Value DB。
Redis 的出色之处不仅仅是性能,Redis 最大的魅力是支持保存多种数据结构
可以用他的 List 来做 FIFO 双向链表,实现一个轻量级的高性 能消息队列服务
可以用他的 Set 做高性能的 tag 系统。
另外 Redis 也可以对存入的 Key-Value 设置 expire 过期时间。
Redis 的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此 Redis 适合的场景主要局限在较小数据量的高性能操作和运算上
2 Redis的数据类型都有哪些?
常用的有5种,分别是String , Hash , List , Set , ZSet
- String-键值对类型
- Hash-1个大key,然后就是多组key value , 可以存储用户信息
- List-队列先进后出,栈先进先出集合,可以实现排队,插队,消息队列等
- Set-也是1个集合,不过是1个去重的集合,相同的元素只会存在1个,可以实现投票,好友推荐等
- ZSet-也是去重集合具有Set的功能,多了1个自动排序,默认是顺序查询,相当于权重,可以用来实现抽奖,限流,排行榜等。
新版本中扩展了更多类型,有BitMaps , Hyperlogloss ,Geospatial ,Streams等
- BitMaps-只存0和1,可以节省存储空间,可以用来记录用于一年的打卡情况。打卡为1,未打卡为0
- Hyperlogloss-海量数据统计 统计过程中不记录独立元素,可以用来统计每日或没有的UV数。
- Geospatial-用于存储和操作地理空间数据
- Streams-发布订阅
3 Redis 有哪几种数据淘汰策略?
noeviction:返回错误当内存限制达到,并且客户端尝试执行会让更多内存被使用的命令。
allkeys-lru: 尝试回收最少使用的键(LRU),使得新添加的数据有空间存放。
volatile-lru: 尝试回收最少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
allkeys-random: 回收随机的键使得新添加的数据有空间存放。
volatile-random: 回收随机的键使得新添加的数据有空间存放,但仅限于在过期集合的键。
volatile-ttl: 回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。
4 Redis 有哪些适合的场景?
- 会话缓存(Session Cache),最常见的Redis应用。
- 全页缓存(FPC)
- 消息队列,Reids 在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得 Redis 能作为一个很好的消息队列平台来使用。
- 排行榜/计数器,Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(SortedSet)也使得我们在执行这些操作的时候变的非常简单,Redis 只是正好提供了这两种数据结构。
- 发布/订阅,Steams类型可以实现发布/订阅
5 Redis是单进程单线程的吗?
Redis 是单进程单线程的,redis 利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。
6 为什么 Redis 单线程模型效率也能那么高?
1. C语言实现,效率高
2. 纯内存操作
3. 基于非阻塞的IO复用模型机制
4. 单线程的话就能避免多线程的频繁上下文切换问题
5. 丰富的数据结构(全称采用hash结构,读取速度非常快,对数据存储进行了一些优化,比如亚索表,跳表等)
7 Redis 持久化方式有哪些?以及有什么区别?
Redis 提供两种持久化机制 RDB 和 AOF 机制:
RDB 持久化方式
是指用数据集快照的方式半持久化模式)记录 redis 数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复。
优点:
- 只有一个文件 dump.rdb ,方便持久化。
- 容灾性好,一个文件可以保存到安全的磁盘。
- 性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能)
- 相对于数据集大时,比 AOF 的启动效率更高。
缺点:
- 数据安全性低。 RDB 是间隔一段时间进行持久化,如果持久化之间 Redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候
AOF=Append-only file 持久化方式
是指所有的命令行记录以 Redis 命令请求协议的格式完全持久化存储,保存为 AOF 文件。优点:
- 数据安全, AOF 持久化可以配置 appendfsync 属性,有 always,每进行一次命令操作就记录到 AOF 文件中一次。
- 通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
- AOF 机制的 rewrite 模式。 AOF 文件没被 rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall )
缺点:
- AOF 文件比 RDB 文件大,且恢复速度慢。
- 数据集大的时候,比 RDB 启动效率低。
8 说说你对Redis事务的理解?
Redis事务的原理
Redis 中的事务是一组命令的集合,是 Redis 的最小执行单位。它可以保证一次执行多个命令,每个事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行。服务端在执行事务的过程中,不会被其他客户端发送来的命令请求打断。
它的原理是先将属于一个事务的命令发送给 Redis,然后依次执行这些命令。
Redis 事务的注意事项
- Redis 事务是不支持回滚的,不像 MySQL 的事务一样,要么都执行要么都不执行;
- Redis 服务端在执行事务的过程中,不会被其他客户端发送来的命令请求打断。直到事务命令全部执行完毕才会执行其他客户端的命令。
Redis 事务回滚
Redis 的事务不支持回滚,但是执行的命令有语法错误,Redis 会执行失败,这些问题可以从程序层面捕获并解决。但是如果出现其他问题,则依然会继续执行余下的命令。这样做的原因是因为回滚需要增加很多工作,而不支持回滚则可以保持简单、快速的特性。
9 描述一下Redis的事务机制
Redis的事务机制允许将多个操作打包成一个原子操作,即要么所有操作都成功执行,要么全部都不执行。Redis的事务机制是通过MULTI、EXEC、DISCARD和WATCH等命令来实现的。以下是Redis事务机制的基本概念和命令:
MULTI: 事务的开始,该命令标记一个事务块的开始。
EXEC: 执行事务,将之前在MULTI和EXEC之间的命令执行为一个原子操作。
DISCARD: 放弃事务,取消事务块,清除之前在MULTI和EXEC之间的命令。
WATCH: 监视一个或多个键,如果在事务执行期间这些键被修改,则事务会被取消。
事务的使用步骤如下:
1. 使用MULTI命令开始一个事务块。
2. 在MULTI和EXEC之间,执行要包含在事务中的命令,这些命令不会立即执行,而是在EXEC命令执行时一起执行。
3. 如果需要取消事务,可以使用DISCARD命令。
4. 如果需要提交事务,可以使用EXEC命令,Redis会依次执行在MULTI和EXEC之间的命令。
5. 如果在事务执行期间,被监视的键发生了变化,事务会被取消。
需要注意的是,Redis的事务机制并不同于传统数据库的事务,它不支持回滚和隔离级别。事务块中的命令在EXEC执行时会一次性执行,但如果在事务执行过程中发生了错误,错误信息会被记录,但不会影响后续命令的执行。
10 说一说对Redis 的同步机制的了解?
Redis 支持主从同步、从从同步。如果是第一次进行主从同步,主节点需要使用 bgsave 命令,再将后续修改操作记录到内存的缓冲区,等 RDB 文件全部同步到复制节点,复制节点接受完成后将RDB 镜像记载到内存中。等加载完成后,复制节点通知主节点将复制期间修改的操作记录同步到复制节点,即可完成同步过程。
11 redis 过期键的删除策略?
(1)定时删除:在设置键的过期时间的同时,创建一个定时器 timer。
让定时器在键的过期时间来临时,立即执行对键的删除操作。
(2)惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。
(3)定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。
12 Redis怎么实现分布式锁
在Redis中实现分布式锁是一个常见的应用场景,可以确保在分布式环境下只有一个客户端可以访问共享资源。可以使用Redis的SETNX命令实现分布式锁:
- 获取锁: 客户端通过执行SETNX命令(SET if Not eXists)来设置一个特定的键作为锁,只有在键不存在的情况下才会设置成功,表示获取锁成功。客户端可以设置一个过期时间,以免锁因为某种原因没有被释放而永远占用。
- 释放锁: 当客户端完成任务后,通过删除该键来释放锁,以允许其他客户端获取锁。
这种实现方法的关键在于 SETNX 命令的原子性,它保证只有一个客户端可以成功地设置锁。然而,这种简单的实现方法可能会存在一些问题,如死锁、误解锁等。因此,在使用分布式锁时需要考虑以下一些因素:
- 锁超时: 设置锁时可以设置一个超时时间,确保即使持有锁的客户端发生故障,锁也会在一定时间后自动释放。
- 防止误解锁: 可以在锁的值中加入唯一的标识,以确保只有持有锁的客户端才能释放锁。
- 续约机制: 在锁的有效期内,可以定期延长锁的超时时间,以避免任务执行时间过长导致锁自动释放。
- 分布式环境下的时间问题: 由于分布式系统的时钟不一致,锁的超时时间和判断是否持有锁的操作需要使用相对时间或者使用更加精确的时钟同步方法。
总之,通过Redis的SETNX命令可以实现基本的分布式锁。然而,在实际应用中需要考虑分布式环境的复杂性和一致性问题,以确保分布式锁的正确性和可靠性。如果需要更加稳定和复杂的分布式锁实现,可以考虑使用基于Redis的分布式锁库,如Redlock、Redission等。
13 Redis的主从模式
Redis的主从模式是一种用于数据复制和高可用性的架构,允许多个Redis实例之间建立一个主从关系,其中一个实例充当主服务器(master),而其他实例充当从服务器(slaves)。主从模式有助于数据备份、故障恢复和读写分离等需求。
Redis主从模式的主要特点和工作方式:
数据复制: 主服务器将数据写入到自己的数据库中,然后通过异步的方式将写操作传播到从服务器,使从服务器的数据与主服务器保持一致。
读写分离: 通过将主服务器用于写操作,从服务器用于读操作,可以分摊读写压力,提高系统的读写性能。
高可用性: 如果主服务器发生故障,从服务器可以接管成为新的主服务器,从而实现故障转移,提高系统的可用性。
数据备份: 从服务器可以用于备份数据,以防止主服务器数据丢失。
异步复制: 默认情况下,Redis主从复制是异步的,即主服务器写入数据后,并不立即等待从服务器确认。这可以提高性能,但可能导致主从数据不一致。
全量复制和增量复制: 初次复制时,从服务器会进行全量复制,即复制所有主服务器的数据。之后的复制是增量复制,只复制发生变化的数据。
复制链: 从服务器也可以充当其他从服务器的主服务器,从而构建复制链。这种链式复制可以在多个级别上实现数据的传播。
可配置性: Redis主从复制可以配置为只复制特定的数据库、特定的数据类型等,以满足不同需求。
需要注意的是,Redis主从复制是异步的,这意味着从服务器可能会因为网络故障或其他原因导致数据滞后,从而导致数据不一致。为了确保数据一致性,可以使用Redis的复制延迟监控、持久化等手段。另外,Redis 6.0版本引入了支持半同步复制的功能,以提高数据可靠性。
14 Redis的哨兵模式
Redis的哨兵模式是一种用于监控和自动故障转移的架构,用于提高Redis系统的高可用性。在哨兵模式中,有一组特殊的Redis实例称为"哨兵",它们负责监控主服务器和从服务器的状态,当主服务器发生故障时,哨兵可以自动将一个从服务器提升为新的主服务器,以实现故障转移。
以下是Redis哨兵模式的主要特点和工作方式:
监控: 哨兵会周期性地检查所有主服务器和从服务器的状态,包括是否存活、是否正常运行等。
自动故障转移: 当哨兵检测到主服务器不可用时,它会选举一个新的主服务器,然后将其他从服务器切换为新的主服务器的从服务器,从而实现故障转移。
配置更新: 如果主服务器发生故障,哨兵会更新所有客户端的连接配置,以指向新的主服务器,从而实现无感知的故障切换。
多哨兵支持: 可以在Redis集群中部署多个哨兵,这些哨兵会协同工作来监控和管理主从服务器。
提供监控信息: 哨兵可以提供有关主从服务器状态、故障转移历史等信息,以供监控和管理。
配置自动化: 哨兵模式可以在一定程度上实现自动化的故障转移和节点管理,减少人工干预。
需要注意的是,哨兵模式虽然提供了一定的高可用性,但在故障转移过程中仍然可能出现数据不一致或数据丢失的情况。为了进一步提高可靠性,可以使用持久化、数据备份等手段。另外,哨兵模式适用于较小规模的Redis集群,对于更大规模的集群,可以考虑使用Redis Cluster。
15 Redis的集群模式
Redis的集群模式是一种用于构建高可用性和分布式的数据存储架构,通过将多个Redis节点组成一个集群,实现数据分片、负载均衡和故障转移等功能。Redis Cluster提供了自动分片和节点管理功能,使得在分布式环境下使用Redis更加方便和可靠。
Redis集群模式的主要特点和工作方式:
自动分片: Redis Cluster会将数据自动分成多个槽(slot),每个槽对应一个节点。这样,集群中的每个节点都只负责管理一部分数据,实现了数据分片。
节点故障转移: 当某个节点发生故障时,Redis Cluster会自动进行故障转移,将故障节点的槽分配给其他正常节点,从而实现高可用性。
负载均衡: 客户端可以通过Redis Cluster提供的路由机制,将请求均匀地分发到集群中的不同节点上,实现负载均衡。
节点管理: Redis Cluster支持自动添加和移除节点,使得集群的扩展和缩减变得更加容易。新节点加入集群后,数据会自动迁移。
数据复制: Redis Cluster中的每个节点都有多个复制节点,用于实现数据的备份和高可用性。每个主节点会有1个或多个从节点,实现数据冗余。
节点通信: 集群中的节点通过Gossip协议进行通信,用于检测节点状态、故障检测和配置更新等。
客户端支持: 使用Redis Cluster,客户端可以透明地访问集群中的不同节点,而无需手动管理节点。
Redis集群模式在处理大规模数据、提高系统可用性和性能方面具有很大优势,但在配置和管理时也需要考虑到数据一致性、故障转移的延迟等问题。使用Redis Cluster可以有效地构建分布式系统,但也需要了解其特性和限制,以适应不同的业务需求
16 什么是缓存穿透,缓存击穿和缓存雪崩?
缓存穿透
缓存的穿透是指当查询一个不存在的数据时,由于缓存中没有该数据,导致查询透过缓存直接查数据库,从而增加数据库的负担。
通常解决缓存穿透的方法是
1、对于查询不到的数据也将其缓存起来,并设置一个较短的过期时间。
2、使用布隆过滤器来过滤掉查询不存在数据的请求。
缓存穿透
缓存击穿是指某个热点数据过期或者被删除,导致大量请求直接绕过缓存访问数据库,导致数据库压力瞬间升高,甚至崩溃。
解决缓存击穿的方法是
- 使用互斥锁(Mutex),只允许一个请求进入数据库查询,其他请求等待。
- 使用分布式锁,保证同一时间只有一个进程能够访问共享资源
- 使用缓存预热,将热点数据提前加载到缓存
- 设置热点数据永不过期
- 使用限流策略
缓存雪崩
缓存雪崩是指在某个时间段,缓存集中过期失效,导致大量请求直接访问数据库,造成短时间内数据库请求量骤增,压力过大,可能造成数据库崩溃。
缓存雪崩的解决方案有以下几种
- 缓存预加载,在正式流量到来前,提前将可能会用到的数据加载到缓存中,避免在流量高峰期间查询数据库
- 缓存高可用,使用多级缓存,如本地缓存和分布式缓存。如果某一个缓存出现了问题,可以快速切换到另一级缓存上
- 缓存限流,通过限制访问频率,降低缓存的压力
- 数据预热,在系统启动时,将所有需要缓存的数据直接加载到缓存中,避免在查询时缓存未命中
- 将缓存的失效时间设置为随机值,避免缓存同时失效导致数据库压力过大
- 数据库容,建立数据库的主从复制和故障转移机制,避免数据库出现单点故障
- 限制并发查询,避免过多的查询同时落在数据库上
- 缓存数据分片,避免单个缓存的失效影响整个缓存系统