欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

redis

程序员文章站 2022-03-10 09:16:30
...

redis是一个key-value存储系统,为了保证效率,数据都是缓存在内存中。
1.为什么要用redis?
从两个方面去答:性能和并发。当然,redis还具备做分布式锁等其它功能,但如果只是为了分布式锁等其它功能,完全还有其它中间件(如zookeeper等代替)。因此,这个问题主要从性能和并发两个角度去答。
(1)性能
如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。
redis
题外话:忽然想聊一下这个迅速响应的标准。其实根据交互效果的不同,这个响应时间没有固定标准。不过曾经有人这么告诉我:”在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。另外,超过一弹指的耗时操作要有进度提示,并且可以随时中止或取消,这样才能给用户最好的体验。”
(二)并发
如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现一个连接异常。这个时候,需要redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。
2.使用redis有什么缺点?
常见有以下四个问题:
(一)缓存和数据库双写一致性问题
(二)缓存雪崩问题
(三)缓存击穿问题
(四)缓存的并发竞争问题
3.单线程的redis为什么快
1.纯内存操作
2.单线程操作,避免了频繁的上下文切换
3.采用了非阻塞I/O多路复用机制
4.redis的数据类型,以及每种数据类型的使用场景
(1)String
最常规的get/set操作,value可以是string也可以是数字。一般做一些复杂的计数功能的缓存
(2)hash
value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟类似session的效果
(3)list
使用list的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用Irange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。
(4)set
因为set堆放的是一堆不重复值的集合,所以可以做全局去重的功能。为什么不用JVM自带的set进行全局去重?因为我们系统一般都是集群部署,使用jvm自带的set,比较麻烦
另外,利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。
(5)sorted set
sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。

5.redis的过期策略和内存淘汰机制
分析:这个问题其实相当重要,比如你的redis只能存5G数据,但你写了10G,那么会删5G的数据。怎么删的?还有,如果你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,思考过原因么?
redis采用定期删除+惰性删除策略

为什么不用定时删除策略?

定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.
定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。

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

采用定期删除+惰性删除就没其他问题了么?

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

在redis.conf中有一行配置

 maxmemory-policy volatile-lru

该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己)

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。

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

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。

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

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

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

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


引用:
Redis精讲

相关标签: redis