redis常见的一些问题

1.Redis支持的数据类型?
2.什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?
3.Redis 有哪些架构模式?讲讲各自的特点
4.使用过Redis分布式锁么,它是怎么实现的?
5.使用过Redis做异步队列么,你是怎么用的?有什么缺点?
6.什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?
7.为什么Redis 单线程却能支撑高并发?
8.说说Redis的内存淘汰策略
9.Redis的并发竞争问题如何解决?

1.Redis支持的数据类型?

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

2.什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?

由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。
Redis提供两种持久化方式,RDB和AOF,AOF可以完整记录整个数据库,RDB只是数据库某一时刻的快照
1.RDB
配置方式 ** # save 60 1000 **
(bgsave命令执行过程中,只有fork子进程时会阻塞服务器;而对于save命令,整个过程都会阻塞服务器;因此save已基本被废弃,线上环境要杜绝save的使用 )
RDB是一个紧凑压缩的二进制文件 ,表示在n秒内,如果redis发生了M次的修改,则redis的数据会被存储到内存中。不难看出这是一个周期性的持久化
缺点:
(1).因为是周期性的,那么当系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
优点:
(1)对 redis 对外提供的读写服务,影响非常小,可以让 redis 保持高性能,
(2) 相对于 AOF 持久化机制来说,直接基于 RDB 数据文件来重启和恢复 redis 进程,更加快速。
2.AOF
配置 方式:
appendfsync always #每次有数据修改发生时都会写入AOF文件。
appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。
appendfsync no #从不同步。高效但是数据不会被持久化。

以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。 在恢复数据时,可以直接读取该文件进行数据恢复
Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。
缺点:
(1)由于AOF一般每秒都在存储,可能对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快
优点:
(1)保存的数据额更加完整,能够更好的通过文件完成数据的重建
AOF更加倾向于数据的完整性,而RDB系统的性能会比AOF好一点
3.混合持久化 Redis4.0
配置方式 # aof-use-rdb-preamble yes
如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重启效率大幅得到提升。

3.Redis 有哪些架构模式?讲讲各自的特点

Redis主要有四种架构模式,单机模式,主从模式,哨兵模式,集群模式。每种模式都有其特定的特点和适用场景。以下是详细的介绍:
单机模式(Standalone)
Redis作为一个独立的服务运行在单个服务器上,所有读写操作都在同一个Redis实例中进行。
优点:部署简单,启动方便,没有网络延迟,适合快速开发和测试。同时,在单机模式下,Redis能提供毫秒级别的访问速度,非常适合小规模的缓存、会话存储等场景。
缺点:没有高可用性,存在单点故障的风险。一旦服务器出现故障,服务将不可用。此外,单机模式还受限于单机的存储和处理能力,无法扩展到更大规模。
主从模式(Master-Slave Replication)
有一个主节点(Master)负责处理写操作,一个或多个从节点(Slave)复制主节点的数据,只负责读操作。
优点:实现了读写分离,可以提高读操作的性能。同时,通过从节点提供数据副本(备份),提高了数据的可用性。这种架构为高并发读取提供了更好的支持,同时通过冗余数据的方式增强了可用性。
缺点:主节点仍然是单点故障源,如果主节点出现故障,整个系统将失去写入能力,虽然从节点可以提供只读服务,但故障转移需要手动进行,这会影响系统的可用性和稳定性。
哨兵模式(Sentinel Mode)
哨兵模式是在主从模式的基础上增加了哨兵(Sentinel)进程,用于监控Redis主从节点的状态,并在主节点故障时自动进行故障转移。
优点:提供了自动故障转移功能,当主节点出现故障时,哨兵会自动选择一个从节点提升为主节点,并通知其他从节点重新同步数据,从而保证了系统的持续可用性。同时,哨兵还可以监控多个Redis节点的健康状态,及时发现并处理故障。
缺点:配置相对复杂,需要设置哨兵节点的数量、监控的主从节点信息、故障转移的策略等。此外,在故障转移过程中可能会有短暂的服务中断和数据不一致的风险。
集群模式(Cluster Mode)
Redis集群模式是一种分布式部署方式,数据被分割成多个片段(slots),分布在不同的节点上。每个节点既可以是主节点也可以是从节点,节点之间相互协调,共同提供服务。
优点:实现了真正的分布式存储,提高了存储容量和处理能力。同时,集群模式还支持自动进行故障转移和动态扩容,进一步提高了系统的可用性和稳定性。此外,集群模式还支持跨节点的数据访问和负载均衡,提高了系统的性能和可扩展性。
缺点:配置和运维相对复杂,需要设置节点的数量、分片规则、故障转移策略等。同时,集群模式不支持跨节点的事务和某些复杂操作,这可能会限制一些应用场景的使用。
综上所述,Redis的四种架构模式各有优缺点和适用场景。在选择合适的架构模式时,需要根据具体的业务需求、数据规模、可用性要求和运维能力来决定。

5.使用过Redis做异步队列么,你是怎么用的?有什么缺点?

Redis是一个高性能的键值存储数据库,支持多种数据类型,如字符串、列表、集合、哈希表和有序集合等。利用其List数据类型、Pub/Sub功能或Sorted Set数据类型,我们可以很方便地实现异步队列。
在实际应用中,通常会将需要异步处理的任务(如发送邮件、短信通知、数据同步等)放入Redis队列中,然后由后台的消费者进程从队列中取出任务并执行。Redis异步队列的优点在于其高性能和灵活性,能够很好地满足大多数异步任务处理的需求。

然而,Redis做异步队列也存在一些缺点,具体如下:
写入和读取性能瓶颈:由于Redis队列存储在内存中,如果消息积压过多,应用程序的性能可能会急剧下降。当生产者向队列中写入大量消息时,可能会因为内存限制而导致写入速度变慢;同样,当消费者从队列中读取大量消息时,也可能会因为处理不过来而导致读取速度变慢。
缺乏ack保证:Redis的消息队列不是专业的消息队列,它没有ack(acknowledgement,确认字符)保证机制。这意味着消费者在处理完消息后,如果因为某种原因(如程序崩溃、网络问题等)没有向队列发送确认消息,那么这条消息可能会被其他消费者重复处理,或者丢失(如果队列采用了某种形式的自动删除机制)。
高可用性问题:Redis队列只能在单个实例上实现最高可用性。如果Redis服务器发生故障,消息队列中的数据将会丢失,应用程序将处于不可控状态。虽然可以通过主从复制、哨兵(Sentinel)和集群(Cluster)等机制来提高Redis的高可用性,但这些机制并不能完全解决消息丢失的问题。
缺乏安全措施:Redis队列缺乏完整的安全功能,如访问控制、数据加密和审计日志等。如果应用程序数据具有较高的敏感性,Redis队列可能不适合作为常规消息队列的安全性方案。
因此,在使用Redis做异步队列时,需要充分评估应用程序的可伸缩性和可靠性要求,以及消息的敏感性和安全性需求。如果Redis无法满足这些要求,可能需要考虑使用其他更专业、更可靠的消息队列系统

6.什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

缓存穿透

缓存穿透是指查询一个缓存和数据库中都不存在的数据,导致每次查询都直接打到数据库,给数据库带来压力。

为了避免缓存穿透,可以采取以下几种方法
布隆过滤器:布隆过滤器是一种空间效率很高的概率型数据结构,用于判断一个元素是否在一个集合中。它允许存在一定的误判率,但不会漏判。在数据放入缓存之前,先使用布隆过滤器进行判断,如果该数据不存在于布隆过滤器中,则直接返回,不进行数据库查询。布隆过滤器可以显著减少缓存穿透攻击。
缓存空值或默认值:当数据库查询结果为空时,也将这个空结果(或默认值)缓存起来,并设置一个较短的过期时间。这样,当再次查询这个不存在的数据时,可以直接从缓存中返回空结果,而不会再次查询数据库。但这种方法需要合理设置过期时间,避免缓存中长时间存储大量无用的空值或默认值。
使用更复杂的key:对于某些场景,可以通过改变查询的key来避免缓存穿透。比如,对用户的查询加上用户ID作为前缀,或者对查询的参数进行加密、哈希等处理,确保每个查询的key都是唯一的,从而避免恶意构造不存在的key进行攻击。
限制访问频率:通过IP地址、用户ID等维度对访问频率进行限制。当某个IP或用户查询不存在数据的次数达到阈值时,暂时禁止其继续查询,从而保护系统不被过度请求压垮。
数据合法性校验:在查询之前,先对数据的合法性进行校验,比如检查用户ID、商品ID等是否合法。对于不合法的查询,直接返回错误,不进行后续处理。

缓存雪崩

缓存雪崩是指在某一时刻,大量缓存同时失效导致所有请求都去查询数据库,导致数据库压力过大甚至崩溃的情况。

为了避免缓存雪崩,可以采取以下几种方法
缓存存储高可用:使用如Redis集群等分布式缓存系统,防止某台缓存服务器挂掉之后所有缓存丢失导致的雪崩问题。
缓存失效时间设计:为不同的数据设置不同的有效期,尽量保证不要在同一时间失效。可以统一规划有效期,让失效时间分布均匀。
热门数据持续读取:对于持续被读取的热门数据,可以采取定时更新的方式来刷新缓存,避免自动失效。
服务限流和接口限流:通过限流机制控制请求的总量,使系统能够在缓存全部失效时仍然保持响应,不至于挂掉或影响整个系统。
加锁控制:在从数据库获取缓存需要的数据时加锁控制,可以使用本地锁或者分布式锁。这样可以保证在缓存失效时,只有少量请求能够穿透到数据库进行查询,从而减轻数据库的压力。

缓存击穿

缓存击穿是指在高并发访问下,某个热点数据失效后,大量请求同时涌入后端存储(通常是数据库),导致后端存储负载增大、响应时间变慢,甚至瘫痪。

为了避免缓存击穿,可以采取以下几种方法
互斥锁:在访问热点数据时,使用互斥锁或分布式锁来控制并发请求。当一个请求获取到锁后,可以查询数据库并更新缓存;其他请求则需要等待锁释放后才能继续。这样可以保证在热点数据失效时,只有一个请求能够穿透到数据库进行查询。
热点数据预加载:在系统启动或缓存数据失效之前,提前将热点数据预先加载到缓存中。这样可以确保在大量请求进入系统时,热点数据已经在缓存中可用,从而避免缓存击穿。
自动刷新机制:为热点数据设置自动刷新机制,在缓存失效前主动从数据库中获取新数据并更新缓存。这样可以确保缓存中的数据始终是最新的,并减少因数据失效而导致的缓存击穿风险。
综上所述,缓存穿透、缓存雪崩和缓存击穿都是缓存使用过程中可能遇到的问题。通过合理的策略和方法,可以有效地避免这些问题对系统性能和数据库稳定性的影响。

7.为什么Redis 单线程却能支撑高并发?

Redis虽然是单线程的,但它能够支持高并发业务,这主要归因于以下几个关键因素:

非阻塞I/O:Redis使用了非阻塞的I/O处理方式。在执行输入输出操作时,Redis会向操作系统发出非阻塞式的系统调用(如epoll或kqueue),这样可以在等待数据准备就绪的同时,继续处理其他请求,从而提高了系统的并发处理能力。
基于内存的数据存储:Redis的数据存储在内存中,这使得其读写速度非常快,远远超过了基于磁盘的数据库系统。内存中的数据访问速度比磁盘快得多,因此在单线程模型下,Redis也能快速地处理大量的读写请求。
避免了线程切换开销:与多线程模型相比,Redis的单线程模型避免了线程切换带来的开销,如上下文切换、锁竞争等。这些开销在高并发场景下尤为显著,而Redis通过单线程模型有效地避免了这些问题。
高效的数据结构和算法:Redis内置了丰富的数据结构和高效的算法,如哈希表、跳表等,这使得在处理数据时效率极高。这些高效的数据结构和算法进一步提升了Redis在高并发场景下的性能。
多路复用技术:通过多路复用技术(如select、poll、epoll等),Redis能够同时监听多个文件描述符(sockets),从而实现对多个客户端的并发响应。这种技术使得Redis能够高效地处理多个并发连接,进一步提升了其并发处理能力。
综上所述,Redis通过非阻塞I/O、基于内存的数据存储、避免线程切换开销、高效的数据结构和算法以及多路复用技术等因素,实现了在单线程模型下支持高并发业务的能力。这些因素共同作用,使得Redis在高并发场景下仍能保持出色的性能表现。

8.说说Redis的内存淘汰策略

Redis的内存淘汰策略是指在Redis的内存达到最大限制时,为了继续存储新的数据而采取的一种机制,用于选择并删除一些已存在的数据以释放内存空间。Redis提供了多种内存淘汰策略,以适应不同的应用场景和需求,以下是对这些策略的详细解释:
针对设置了过期时间的键的策略
volatile-lru:使用LRU(Least Recently Used,最近最少使用)算法从设置了过期时间的键中淘汰最久未使用的键。
volatile-lfu:使用LFU(Least Frequently Used,最少使用)算法从设置了过期时间的键中淘汰最不常使用的键。LFU算法会追踪键值对的访问频率,并淘汰访问频率最低的键值对。
volatile-random:随机从设置了过期时间的键中淘汰一个键值对。
volatile-ttl:根据键的剩余过期时间(TTL)进行淘汰,剩余生存时间越短的键越优先被淘汰。这种方式适用于对数据时效性要求较高的场景,如缓存实时数据,可以及时清理过期的数据。
针对所有键的策略
allkeys-lru:使用LRU算法从所有键中淘汰最久未使用的键。
allkeys-lfu:使用LFU算法从所有键中淘汰最不常使用的键。
allkeys-random:随机从所有键中淘汰一个键值对。
不淘汰策略
noeviction:当内存不足以容纳新写入数据时,不会淘汰任何键值对,而是直接返回错误(DEL请求和部分特殊请求除外)。这是Redis的默认行为(在Redis 3.0及之后版本),旨在保护数据不被意外删除。
策略选择与应用
在选择内存淘汰策略时,需要根据应用程序的访问模式、数据的重要性和对性能的要求来综合考虑。例如:
如果应用程序的数据访问模式符合LRU特性(即最近使用的数据更有可能再次被访问),那么选择volatile-lru或allkeys-lru可能是一个好的选择。
如果希望避免误淘汰重要数据,并且对数据的时效性有一定要求,那么volatile-ttl可能更适合。
如果不确定数据访问模式或希望简单随机淘汰数据,那么可以选择volatile-random或allkeys-random策略。
此外,Redis允许在运行时动态修改内存淘汰策略,并使用Redis的info命令输出来监控缓存未命中和命中的数量,以便根据实际情况调整策略设置。

综上所述,Redis的内存淘汰策略是一种灵活且强大的机制,能够帮助开发者在内存受限的情况下有效地管理数据,确保系统的正常运行。

9.Redis的并发竞争问题如何解决?

Redis的并发竞争问题是指在多线程或多进程并发读写Redis时可能出现的数据竞争和竞争条件问题,具体表现为多个线程或进程同时对同一个Redis实例进行读写操作,导致数据不一致或逻辑错误的情况。为了解决Redis的并发竞争问题,可以采取以下几种方法:

使用事务
Redis支持事务操作,通过MULTI和EXEC命令可以将一系列操作作为一个原子操作执行,从而避免了并发竞争。在事务执行期间,其他客户端对键的读写会被阻塞,直到事务完成。事务块中的所有命令都是原子执行的,要么全部执行成功,要么全部失败。

使用乐观锁
乐观锁是一种轻量级的锁机制,它通过比较版本号或时间戳的方式来实现并发控制。在Redis中,乐观锁一般使用WATCH命令和CAS(Compare and Set)操作来实现。客户端发送WATCH命令来监视一个或多个键,如果在事务执行之前这些键被其他客户端修改,则事务执行时会失败,客户端可以根据返回的结果进行重试或其他操作。

使用分布式锁
分布式锁是一种通过加锁机制来保护共享资源的方法。在Redis中,可以使用SETNX命令或Redlock算法来实现分布式锁。SETNX命令用于设置键的值,如果键不存在则设置成功并返回1,如果键已存在则设置失败并返回0。通过SETNX命令,可以在写操作前锁定该资源,从而避免并发竞争。Redlock算法则是一种更复杂的分布式锁实现,它提供了更高的可靠性和容错性。

优化连接管理
在高并发场景下,连接竞争也可能导致性能问题。为了优化连接管理,可以使用连接池来管理Redis连接。连接池可以预先创建并维护一定数量的连接,供客户端在需要时获取和释放。这样可以避免频繁地创建和关闭连接,从而减少连接竞争并提高性能。

数据分割与增加节点
如果单个Redis实例无法满足高并发需求,可以考虑将数据分割成多个小的Redis实例,并将并发访问分散到多个实例上。这样可以减轻单个实例的负担并提高并发性能。另外,也可以通过增加Redis实例和节点的方式来提升并发性能和容量。

综上所述,解决Redis的并发竞争问题需要综合考虑多个方面的因素,并根据具体的应用场景和需求选择合适的解决方案。在实际操作中,可以根据系统的性能监控和测试结果来不断调整和优化这些策略,以确保Redis在高并发场景下的稳定性和可靠性。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 金九银十即将到来,整理了20道经典Redis面试题,希望对大家有帮助。 1. 什么是Redis?它主要用来什么的?...
    学编程的小屁孩阅读 1,545评论 0 1
  • 什么是Redis? Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息...
    零一间阅读 152评论 0 1
  • 什么是Redis? Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息...
    零一间阅读 480评论 0 0
  • 本文的面试题如下: Redis 持久化机制 缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等问题 热点数据和冷数...
    不怕天黑_0819阅读 1,446评论 1 21
  • 1. Redis有哪些数据结构? 2. 使用过Redis分布式锁么,它是什么回事? 3. 假如Redis里面有1亿...
    xuxw阅读 103评论 0 0