Redis面试

redis是什么?

定义: redis是用C语言开发的一个开源的高性能键值对(key-value)的内存数据库 。可以用作数据库、缓存、消息中间件等。它是一种NoSQL(not-only sql,泛指非关系型数据库)的数据库。
Redis作为一个内存数据库有如下特点:
1.性能优秀,数据在内存中,读写速度非常快,支持并发10w QPS;
2.单进程单线程,是线程安全的,采用IO多路复用机制;
3.丰富的数据类型,支持字符串、哈希、列表、集合、有序集合等;
4.支持数据持久化。可以将内存中数据保存在磁盘中,重启时加载;
5.主从复制,哨兵,高可用;
6.可以用作分布式锁;
7.可以作为消息中间件使用,支持发布订阅
五种数据类型
【Redis面试】String(字符串):value不仅是string,也可以是数字。string类型是二进制安全的,意思是redis的string类型可以包含任何数据,比如jpg图片或者序列化的对象。string类型的值最大能存储512M。

Hash(哈希):redis的hash是一个string的key和value的映射表,Hash特别适合存储对象。常用命令:hget,hset,hgetall等

List(列表):list列表是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边) 常用命令:lpush、rpush、lpop、rpop、lrange(获取列表片段)等。应用场景:关注列表、消息队列等

Set(集合):set是string类型的无序集合。集合是通过hashtable实现的。set中的元素是没有顺序的,而且是没有重复的。常用命令:sdd、spop、smembers、sunion等

Sorted Set(有序集合):zset和set一样是string类型元素的集合,且不允许重复的元素。常用命令:zadd、zrange、zrem、zcard等。
数据类型应用场景总结
String(字符串):可以包含任何数据,比如jpg图片或者序列化对象

Hash(哈希):适合存储对象,并且可以像数据库中的update一个属性一样只修改某一项属性值

List(列表):最新消息排行;消息队列

Set(集合):共同好友;利用唯一性,统计访问网站的所有Ip

Sorted Set(有序集合):排行榜;带权重的消息队列
Redis缓存java中如何使用
1.RedisTemplate

2.Jedis

3.Redission
缓存问题
缓存和数据库数据一致性问题

分布式环境下非常容易出现缓存和数据库间数据一致性问题,针对这一点,如果项目对缓存的要求是强一致性的,那么就不要使用缓存。我们只能采取合适的策略来降低缓存和数据库间数据不一致的概率,而无法保证两者间的强一致性。合适的策略包括合适的缓存更新策略,更新数据库后及时更新缓存、缓存失败时增加重试机制。

缓存雪崩

概念:同一时间key大面积失效,瞬间Redis跟没有一样,那这个数量级别的请求直接打到数据库几乎是灾难性的,你想想如果挂的是一个用户服务的库,那其他依赖他的库所有接口几乎都会报错,如果没做熔断等策略基本上就是瞬间挂一片的节奏

应对方案:在批量往Redis存数据的时候,把每个Key的失效时间都加个随机值就好了,这样可以保证数据不会再同一时间大面积失效。
如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效。或者设置热点数据永不过期,有更新操作就更新缓存就好了(比如运维更新了首页商品,那你刷下缓存就好了,不要设置过期时间)

缓存穿透

概念:缓存穿透是指缓存和数据库中都没有的数据,而用户(黑客)不断发起请求,举个栗子:我们数据库的id都是从1自增的,如果发起id=-1的数据或者id特别大不存在的数据,这样的不断攻击导致数据库压力很大,严重会击垮数据库。

应对方案:1.在接口层增加校验,比如用户鉴权,参数做校验,不合法的校验直接return,比如id做基础校验,id<=0直接拦截。2.布隆过滤

缓存击穿

概念:这个跟缓存雪崩有点像,但是又有一点不一样,缓存雪崩是因为大面积的缓存失效,打崩了DB,而缓存击穿不同的是缓存击穿是指一个Key非常热点,在不停地扛着大量的请求,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发直接落到了数据库上,就在这个Key的点上击穿了缓存。

应对方案:设置热点数据永不过期,或者加上互斥锁就搞定了
Redis为何这么快
第一:Redis完全基于内存,绝大部分请求是纯粹的内存操作,非常迅速,数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度是O(1)。第二:数据结构简单,对数据操作也简单。第三:采用单线程,避免了不必要的上下文切换和竞争条件,不存在多线程导致的CPU切换,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。第四:使用多路复用IO模型,非阻塞IO。
Redis和Memcached的区别
1、存储方式上:memcache会把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。redis有部分数据存在硬盘上,这样能保证数据的持久性。

2、数据支持类型上:memcache对数据类型的支持简单,只支持简单的key-value,,而redis支持五种数据类型。

3、使用底层模型不同:它们之间底层实现方式以及与客户端之间通信的应用协议不一样。redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

4、value的大小:redis可以达到1GB,而memcache只有1MB。
淘汰策略
volatile-lru 从已设置过期时间的KV集中优先对最近最少使用(less recently used)的数据淘汰

volitile-ttl 从已设置过期时间的KV集中优先对剩余时间短(time to live)的数据淘汰

volitile-random 从已设置过期时间的KV集中随机选择数据淘汰

allkeys-lru 从所有KV集中优先对最近最少使用(less recently used)的数据淘汰

allKeys-random 从所有KV集中随机选择数据淘汰

noeviction 不淘汰策略,若超过最大内存,返回错误信息
持久化
RDB(Redis DataBase):快照形式是直接把内存中的数据保存到一个dump的文件中,定时保存,保存策略。

优点:1 适合大规模的数据恢复。
2 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
缺点:1 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
2 备份时占用内存

AOF(Append Only File):把所有的对Redis的服务器进行修改的命令都存到一个文件里,命令的集合。

优点:数据的完整性和一致性更高
缺点:
因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢

参考《Redis 持久化之RDB和AOF》
主从复制
参考《Redis主从复制和集群配置》
哨兵
参考《深入学习Redis(4):哨兵》
总结
基本上都围绕着这些问题:Redis是什么,Redis的特点和功能,Redis缓存的使用,Redis为什么能这么快,Redis缓存的淘汰策略,持久化的两种方式,Redis高可用部分的主从复制和哨兵的基本原理,平时多积累积累。

    推荐阅读