面试题redis

本文详细介绍了Redis这一高性能的key-value存储系统,涵盖了其数据类型、功能特性、与Memcached的区别、单线程设计原理、缓存穿透解决方案、数据一致性保证、持久化方式、分布式锁实现及常见性能问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

redis是什么?

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string、list、set、zset(有序集合)和hash。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序和算法。 与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件(RDB和AOF两种方式),并且在此基础上实现了master-slave(主从)同步,机器重启后能通过持久化数据自动重建内存,使用Redis作为Cache时机器宕机后热点数据不会丢失。

Redis丰富的数据结构也使其拥有更加丰富的应用场景。Redis的命令都是原子性的,可以简单地利用INCR和DECR实现计数功能。使用list可以实现获取最近N个数的操作。sort set支持对数据排序,可以应用在排行榜中。set集合可以应用到数据排重。Redis还支持过期时间设置,可以应用到需要设定精确过期时间的应用。只要可以使用Redis支持的数据结构表示的场景,就可以使用Redis进行存储。

redis 有哪些功能?

Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。Redis支持数据的备份,即master-slave模式的数据备份。 Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。

redis 和 memecache 有什么区别?

   1)、存储方式 Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。 Redis有部份存在硬盘上,这样能保证数据的持久性。    2)、数据支持类型 Memcache对数据类型支持相对简单。 Redis有复杂的数据类型。    3)、使用底层模型不同 它们之间底层实现方式 以及与客户端之间通信的应用协议不一样。 Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

redis 为什么是单线程的?

因为CPU不是Redis的瓶颈。Redis的瓶颈最有可能是机器内存或者网络带宽。(以上主要来自官方FAQ)既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。采用队列模式将并发访问变为串行访问。 需要注意的是,单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),其他模块仍用了多个线程。

什么是缓存穿透?怎么解决?

在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该key对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。 可以通过下面的几种常用方式来避免缓存传统问题: 1、缓存空对象
对查询结果为空的对象也进行缓存,如果是集合,可以缓存一个空的集合(非null),如果是缓存单个对象,可以通过字段标识来区分。这样避免请求穿透到后端数据库。这种方式实现起来成本较低。
如果后面某个为空的记录在数据库中有数据了,该如何处理? 可以提前设置缓存的时效性,等过期之后自然会到后端刷新新数据。 如果时效性要求很高的话,那就采用数据库与缓存双写的模式来实现。 如果时效性要求不高的话,可以设置一个消息队列,专门用来接收数据库记录变更的消息,然后由专门的缓存服务去取出新数据并更新到缓存中。
2、单独过滤处理
对所有可能对应数据为空的key进行统一的存放,并在请求前做拦截,这样避免请求穿透到后端数据库。这种方式实现起来相对复杂。

redis支持哪些类型

redis支持的五种数据类型:

1、string(字符串)
2、hash(哈希)
  Redis hash 是一个键值(key=>value)对集合。
  Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
3、list(列表)
  Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
4、set(集合)
  Redis的Set是string类型的无序集合。
5、zset(sorted set:有序集合)
  Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
  不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
  zset的成员是唯一的,但分数(score)却可以重复。
  

redis 支持的 java 客户端都有哪些? 

  Redisson,Jedis,lettuce等等,官方推荐使用Redisson。   

jedis 和 redisson 有哪些区别?

1.Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。 Jedis中的方法调用是比较底层的暴露的Redis的API,也即Jedis中的Java方法基本和Redis的API保持着一致,了解Redis的API,也就能熟练的使用Jedis。而Redisson中的方法则是进行比较高的抽象,每个方法调用可能进行了一个或多个Redis方法调用。

2.Jedis使用阻塞的I/O,且其方法调用都是同步的,程序流需要等到sockets处理完I/O才能执行,不支持异步。Jedis客户端实例不是线程安全的,所以需要通过连接池来使用Jedis。 Redisson使用非阻塞的I/O和基于Netty框架的事件驱动的通信层,其方法调用是异步的。Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作。

3.Jedis仅支持基本的数据类型如:String、Hash、List、Set、Sorted Set。
Redisson不仅提供了一系列的分布式Java常用对象,基本可以与Java的基本数据结构通用,还提供了许多分布式服务,其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service)。
在分布式开发中,Redisson可提供更便捷的方法。

怎么保证缓存和数据库数据的一致性?

通常来说,在我们的系统中会把数据永久保存在DB中,并且冗余一份数据在缓存中。读请求优先从缓存读取数据,没有再从DB读取,读取之后然后在缓存中放置一份。在数据变更时,先淘汰缓存,再写db。(先写db,然后淘汰缓存)这样能保证基础的一致性,但是当情况变得复杂时,数据还是会出现不一致的情况。
(a)发生了写请求A,A的第一步淘汰了cache

(b)A的第二步写数据库,发出修改请求

(c)发生了读请求B,B的第一步读取cache,发现cache中是空的

(d)B的第二步读取数据库,发出读取请求,此时A的第二步写数据还没完成,读出了一个脏数据放入cache,即在数据库层面,后发出的d比先发出的b先完成了,读出了脏数据,脏数据又入了缓存,缓存与数据库中的数据不一致出现了. 这种情况的话,其实就是要将对同一片数据的操作串行起来,即做到一个服务上,且使用同一个db连接,使得在数据库上时串行的。

redis 持久化有几种方式?

RDB和AOF RDB每次进行快照方式会重新记录整个数据集的所有信息。RDB在恢复数据时更快,可以最大化redis性能,子进程对父进程无任何性能影响。

AOF有序的记录了redis的命令操作。意外情况下数据丢失甚少。他不断地对aof文件添加操作日志记录,你可能会说,这样的文件得多么庞大呀。是的,的确会变得庞大,但redis会有优化的策略,比如你对一个key1键的操作,set key1 001 , set key1 002, set key1 003。那优化的结果就是将前两条去掉咯,那具体优化的配置在配置文件中对应的是

前者是指超过上一次aof重写aof文件大小的百分之多少,会再次优化,如果没有重写过,则以启动时为主。后者是限制了允许重写的最小aof文件大小。bgrewriteaof命令是手动重写命令,会fork子进程,在临时文件中重建数据库状态,对原aof无任何影响,当重建旧的状态后,也会把fork发生后的一段时间内的数据一并追加到临时文件,最后替换原有aof文件,新的命令继续向新的aof文件中追加。

使用redis实现分布式锁

分布式锁一般有三种实现方式,数据库乐观锁(加版本号的),zookeeper,redis。 为什么要用分布式锁?记得之前看过关于淘宝秒杀的,直接用redis保存库存的,这种情形的话,直接在进行主业务逻辑前,对库存进行扣减,按照这种方式理论上是没问题的,但是在一些极端情况,或者这种非库存类的问题,还是存在问题的,所以这个时候就是用分布式锁,对资源进行锁定,这种可以避免数据库的传统的锁的开销,提高并发能力。

redis 分布式锁有什么缺陷?

实现复杂,需要考虑超时、原子性、误删等情形。没有等待锁的队列,只能在客户端自旋来等锁、效率低下。

redis怎么做内存优化

一. redisObject对象 二. 缩减键值对象 三. 共享对象池 四. 字符串优化 五. 编码优化 六. 控制key的数量

yq.aliyun.com/articles/61…

redis 淘汰策略有哪些?

noeviction:达到内存限额后返回错误,客户尝试可以导致更多内存使用的命令(大部分写命令,但DEL和一些例外)
allkeys-lru:为了给新增加的数据腾出空间,驱逐键先试图移除一部分最近使用较少的(LRC)。
volatile-lru:为了给新增加的数据腾出空间,驱逐键先试图移除一部分最近使用较少的(LRC),但只限于过期设置键。
allkeys-random: 为了给新增加的数据腾出空间,驱逐任意键
volatile-random: 为了给新增加的数据腾出空间,驱逐任意键,但只限于有过期设置的驱逐键。
volatile-ttl: 为了给新增加的数据腾出空间,驱逐键只有秘钥过期设置,并且首先尝试缩短存活时间的驱逐键

redis 常见的性能问题有哪些?该如何解决?

https://blog.youkuaiyun.com/tanga842428/article/details/52764608

转载于:https://juejin.im/post/5c83ba505188257e3e47f4a3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值