Redis(一)面试总结精讲

redis精讲

1、Redis是什么?

  • Redis是一个基于内存且支持持久化的key-value的NoSQL数据库,其中每个key和value都是使用对象表示的,具有以以下特征:多样数据类型、持久化、主从同步。

  • 和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。

  • 在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的使用RDB快照的方式,把更新的数据写入磁盘或者使用类似MySQL的AOF日志方式把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。 Redis支持将数据同步到多台从数据库上,这种特性对提高读取性能非常有益。

  • Redis3.0版本允许单点故障,它没有中心节点,各个节点地位一样,扩展性很好,节点间的采用二进制通信,节点与客户端采用ascII协议通信。
    在这里插入图片描述

综上所述,Redis可用于缓存、数据库、消息中间件。

2、为什么使用redis

主要是以下两点:

1、性能

如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。
在这里插入图片描述

2、并发

如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。
在这里插入图片描述

3、使用redis有什么缺点

详细介绍一下四个问题:

1、缓存和数据库双写一致性问题

  • 对于要求强一致性的,尽量不要使用缓存,只能采取合适的策略来降低缓存和数据库不一致的概率。

  • 解决方案:首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

2、缓存雪崩问题

  • 缓存在同一时间内大量的key过期的同时,又有大批的落入数据库中的。

  • 解决方案:使用互斥锁。

  • 这里要注意,分布式环境中要使用分布式锁,单机的话用普通的锁(synchronized、Lock)就够了.

3、缓存击穿问题

  • 缓存击穿是用户恶意模拟请求很多缓存中不存在的数据,由于缓存中都没有,导致这些请求短时间内直接落在了数据库上,导致数据库异常。

  • 解决方案:使用互斥锁。

4、缓存的并发竞争问题

  • 多个redis的client同时set key引起的并发问题。其实redis自身就是单线程操作,多个client并发操作,先到的先执行,其余的阻塞。另外的解决方案是把redis.set操作放在队列中使其串行化,必须的一个一个执行。

4、单线程的redis为什么这么快

这个问题其实是对redis内部机制的一个考察。

主要是以下三点:

1、纯内存操作

2、单线程操作,避免了频繁的上下文切换

3、采用了非阻塞I/O多路复用机制

下面类比到真实的redis线程模型,如图所示:
在这里插入图片描述
简单来说,就是我们的redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。

另外,redis还提供了select、epoll、evport、kqueue等多路复用函数库

5、redis的数据类型,以及每种数据类型的使用场景

详细介绍以下五种类型:

1、String

  • 最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。

2、hash

  • 这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。

3、list

  • 使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。

4、set

  • 因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。

  • 另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。

5、sorted set

  • sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。

6、redis的过期策略以及内存淘汰机制

redis采用的是定期删除+惰性删除策略

1、何为定时删除策略?

  • 定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.

2、定期删除+惰性删除是如何工作的呢?

  • 定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。

  • 于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

3、采用定期删除+惰性删除是否有其他问题?

  • 有,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。

在redis.conf中有一行配置就是配内存淘汰策略的

# maxmemory-policy volatile-lru

下面给大家介绍几个当内存不足以容纳新写入数据时的函数:

  • 1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。

  • 2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用。

  • 3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。

  • 4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐

  • 5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。不推荐

  • 6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐

注意: 如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_42566251

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值