1.Redis常见使用场景

数据高并发的读写,海量数据的读写,对扩展性要求高的数据

2.Redis为什么是单线程,速度为什么快

因为cpu不是redis的瓶颈,Redis的瓶颈最有可能是机器内存或者是网络带宽。既然单线程容易实现,而且cpu也不会成为瓶颈,就采用单线程。

速度原因:纯内存操作;单线程操作,避免了频繁的上下文切换;采用了非阻塞I/O多路复用机制。

3.缓存击穿、缓存雪崩、缓存预热、缓存更新、缓存降级等问题

缓存击穿:指的是查询一个一定不存在的数据,由于缓存是不命中时需要从数据库中查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都将去数据库中查询,造成缓存击穿

解决方案:一:如果有一个查询返回的数据为空(不管是数据不存在还是系统故障造成),我们就把这个空结果进行缓存,但是它的过期时间会很短,一般不超过五分钟。通过这个直接设置的默认值放到缓存中,这样第二次到缓存去取值时就不会继续访问数据库了。

                二:布隆过滤器(Bloom-Filter),将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据一定会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。

缓存雪崩:我们可以简单理解为由于原有的缓存过期时间已到,新的缓存还未存储。(例如:我们设置缓存是采用了相同的过期时间,在这同一时期出现大面积的缓存过期)原本所有应该访问缓存的请求这时候直接去访问数据库了,这样就对数据库cpu和内存造成巨大的压力,严重时会导致数据库宕机,从而导致一系列连锁反应,造成整个系统崩溃。

解决方案:大多数系统设计者会考虑加锁(最多的解决方案)或采用队列的方式保证不会有大量的线程对数据库进行一次性的读写,从而避免失效时大量的并发请求一次性落到底层存储系统上。还有一个最简单的方案就是将缓存失效的时间分开

缓存预热:是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后将数据存储的问题。这样用户就可以直接查询事先被预热的缓存数据!思路:一:直接写个缓存刷新页面,上线时手工操作

        二:数据量不大,可以在项目启动时候自动进行加载

        三:定时刷新缓存。

缓存更新:除了缓存服务器自带的缓存失效策略之外,我们可以根据具体的业务需求进行自定义的缓存淘汰:一:定时去清理过期的缓存

                  二:当有用户请求过来是,在判断这个请求的缓存是否过期,过期的话就去底层存储系统得到新数据并进行更新缓存。

两者各有优劣,第一种的缺点是维护大量缓存的key是比较麻烦的,第二种的缺点是每次用户请求过的都要判断缓存是否失效,逻辑相对比较复杂。

缓存降级:当访问量剧增,服务出现问题(如响应时间慢或者不响应)或核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统根据一些关键数据进行自动升级,也可以配置开关实现人工降级。降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(比如加入购物车、结算)。

以参考日志级别设置预案:一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级

                                        警告:有些服务在一段时间内成功率有波动,可自动降级或人工降级,并发送警告,

                                        错误:比如可用率低于90%,或者数据库的连接池被打爆了或者访问量突然猛增到系统能承受的最大阈值,此时可以根据情况自动降级或人工降级

                                        严重错误:为了防止redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可采取服务降级策略,例如一个比较常见的做法就是,redis出现问题,不去数据库查询,而是直接返回默认值给用户。 

4.Redis支持的数据类型有哪些

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

list:使用list的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用large命令,做基于redis的分页功能,性能极佳,用户体验好。

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

set:set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用jvm自带的Set进行去重?因为我们的系统一般都是集群部署,使用jvm自带的Set,比较麻烦。

zset:相较于set是有序的。可以做排行榜应用取top值。

5.redis支持度java客户端有哪些

Redisson、Jsdis、lettuce等等,官方推荐Redisson

6.Jedis和redisson有哪些区别

Jedis是Redis的java实现的客户端,其api提供了比较全面的Redis命令的支持、

Redisson实现了分布式和可扩展性的java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持事务、管道、分区等redis特性。Redisson的宗旨是促进使用者对redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

7.怎么保证缓存和数据库数据保持一致

合理设置缓存的过期时间

新增、更改、删除数据库操作时间同步更新redis,可以使用事务机制保证数据的一致性。

8.redis持久化有几种方式

RDB:指定的时间间隔能对你的数据进行快照存储

AOF:每一个收到的写命令都通过write函数追加到文件中

9.redis怎么实现分布式锁

redis分布式锁本质上就是在系统里面占一个“坑”,其他程序也要占“坑”的时候,占用成功了就可以继续执行,失败率就只能放弃或稍后再试。

占坑一般使用setnx(set if not exists)指令,只允许被一个程序占有,使用完调用del释放锁。

10.redis分布式锁有什么缺陷

redis分布式锁不能解决超时问题,分布式锁有一个超时时间,程序的执行时间如果超过了锁的超时时间就会出现问题。

11.redis如何做内存优化

尽可能使用散列表(hashes),散列表(是说里面存储的数少)使用的内存非常少,所以尽可能的将数据模型抽象到一个散列表里面。

比如你的web系统里面有一个用户对象,不要为这个用户的名称、姓氏、邮箱、密码单独设置key,而是把这个对象的所有信息存储到一个散列表里面。

12.redsi的淘汰策略有哪些

volatile-Irc:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰.

volatile-ttl:从已设置过期的时间的数据集中挑选已经过期的数据淘汰

volatile-random:从已设置过期时间的数据集中任意选择数据淘汰

allkeys-Irc:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集中任意挑选数据淘汰

no-enviction:禁止驱逐数据。

13.redis常见的性能问题有哪些

主服务器写内存快照,会阻塞主线程的工作,当快照比较大的时对性能影响是比较大的,会间断性暂停服务,所以主服务器最好不要写内存快照。

redis主从复制的性能问题,为了主从服从复制的速度和连接的稳定性,主从复制最好在同一个局域网内。