redis入门

一、为什么使用Redis

 

1、性能

当我们碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。 这样,后面的请求就可以去

缓存中读取,使得请求能够迅速响应

2、并发

在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。 这时候,就需要Redis做一个缓冲操作,让请求先

访问Redis,而不是直接访问数据库

 

二、Redis的使用缺点

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

2、缓存雪崩问题

3、缓存击穿问题

4、缓存的并发竞争问题

 

三、单线程的Redis为什么快

1、纯内存操作

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

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

简单来说,就是Redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/O多路复用程序,将其

放入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。

 

四、Redis的数据类型,及其应用场景

1、string

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

2、hash

value存放值是结构化的对象,比较方便的就是操作其中的某个字段。

3、list

可以做简单的消息队列功能,也可以使用lrange命令,做基于Redis的分页功能

4、set

可以做全局去重的功能,可以做些交集、并集、差集

5、sorted set

多了一个权重参数score,集合的元素能够按score进行排列。可以做排行榜应用

 

五、Redis的过期策略以及内存淘汰机制

Redis采用的是定期删除+惰性删除策略。 Redis默认每100ms检查,是否右过期的key, 有的话则删除。

注意并不是每100ms将所有的key检查一次,而是随机抽取进行检查。 因此,如果使用定期删除的话,

会导致很多key到时间没有删除。 于是,惰性删除在获取到某个key的时候,Redis会检查一下,如果设置

了过期时间,那么是否已过期,如果过期则删除。

如果定期删除没有删除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, 那么volatile-lru  volatile-random  volatile-ttl策略的行为和noeviction基本上

一致

 

六、Redis和数据库双写一致性问题

采取正确更新策略,先更新数据库,再删除缓存。 其次,因为可能在删除缓存失败的问题,提供一个补偿

措施即可,例如使用消息队列

 

七、换成穿透和缓存雪崩解决方案

1、利用互斥锁,缓存失效的时候,先去获得锁,得到锁,再去请求数据库,没得到锁,则休眠一段时间重试

2、采用异步更新策略,无论key是否取得值,都直接返回。 value值中维护一个缓存失效时间,缓存如果过期,

异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作

3、提供一个能迅速判断请求是否有效的拦截机制, 比如可以利用布隆过滤器,内部维护一系列合法有效的key

 

缓存雪崩

1、给缓存的失效时间,加上一个随机值,避免集体失效

2、使用互斥锁,吞吐量下降明显

3、双缓存。 缓存A的失效时间为20分钟,缓存B不设置失效时间。 先做缓存预热操作。 先从缓存A读数据库,有

则直接返回,缓存A没有数据的话,直接从缓存B读取数据,直接返回,并且异步启动一个更新线程, 更新线程

更新缓存A和缓存B

 

八、Redis的并发竞争key问题

1、如何对这个key操作,不要求顺序,准备一个分布式锁,抢到锁就做set操作

2、如果对这个key操作,要求顺序。 假设有一个key,系统A需要设置value-1, 系统B设置value-2, 系统C设置

value-3,那么顺序应该是value-1、value-2、value-3。 这种情况下,在数据写入数据库的时候就需要保存一个时间戳

value-1 10:00  value-2 10:05  value-3 10:10。 假设,系统B会先抢到锁,将key设置为value-2 10:05, 这时系统A设值

的时候,发现自己的时间戳值早于缓存中的时间戳,那就不要set操作

posted @ 2018-06-15 10:39  秋水秋色  阅读(158)  评论(0编辑  收藏  举报