java面试总结(八)redis

一、Memcache与Redis
1、Memcache

    优点
		Memcache 处理请求时使用多线程异步 IO 的方式,可以合理利用 CPU 多核的优势,性能非常优秀。
		Memcache 功能简单,使用内存存储数据。
		Memcache 对缓存的数据可以设置失效期,过期后的数据会被清除。
		Memcache失效的策略采用延迟失效,就是当再次使用数据时检查是否失效。
		Memcache当容量存满时,会对缓存中的数据进行剔除,剔除时除了会对过期 key 进行清理,还会按 LRU 策略对数据进行剔除。
	缺点
	    Memcache的 key 不能超过 250 个字节。
		Memcache的value 不能超过 1M 字节。
		Memcache的key 的最大失效时间是 30天 。
		Memcache只支持 简单的K-V 结构,不提供持久化和主从同步功能。

2、Redis

       Redis 采用单线程模式处理请求,这样做的原因有 两 个:一个是因为采用了非阻塞的异步事件处理机制;另一个是缓存数据都是内存操作 IO 时间不会太长,单线程可以避免线程上下文切换产生的代价。
	   Redis 支持持久化,可以将内存中数据保存在磁盘中,重启时加载,所以 Redis 不仅仅可以用作缓存,也可以用作 NoSQL 数据库。
	   Redis就是除了 K-V 之外,还支持多种数据格式,例如 list、set、sorted set、hash 等。
       Redis 提供主从同步机制,以及 Cluster 集群部署能力,能够提供高可用服务。
       Redis性能优秀,数据在内存中,读写速度非常快,支持并发 10W QPS。
       Redis可以用作分布式锁,可以作为消息中间件使用,支持发布订阅。

二、redis五种数据类型

  Redis 内部使用一个 redisObject 对象来表示所有的 key 和 value。
  redisObject 最主要的信息如上图所示:type 表示一个 value 对象具体是何种数据类型,encoding 是不同数据类型在 Redis 内部的存储方式。
  例如,当type=string 表示 value 存储的是一个普通字符串,那么 encoding 可以是 raw 或者 int。
  (1)String 是 Redis 最基本的类型,可以理解成与 Memcached一模一样的k-value类型,一个 Key 对应一个 Value。Value 不仅是 String,也可以是数字,String 类型是二进制安全的,意思是 Redis 的 String 类型可以包含任何数据,比如 jpg 图片或者序列化的对象。String 类型的值最大能存储 512M。
  (2)Hash是一个键值(key-value)的集合。Redis 的 Hash 是一个 String 的 Key 和 Value 的映射表,Hash 特别适合存储对象。常用命令:hget,hset,hgetall 等。
  (3)List 列表是简单的字符串列表,按照插入顺序排序,可以添加一个元素到列表的头部(左边)或者尾部(右边),List 就是链表(双向链表),增加删除快,可以用来当消息队列用,Redis 提供了 List 的 Push 和 Pop 操作,还提供了操作某一段的 API,可以直接查询或者删除某一段的元素 常用命令:lpush、rpush、lpop、rpop、lrange(获取列表片段)等。
  (4)Set 是 String 类型的无序集合。集合是通过 hashtable 实现的,Set 中的元素是没有顺序的,而且是没有重复的。常用命令:sdd、spop、smembers、sunion 等。
  (5)Zset 和 Set 一样是 String 类型元素的集合,且不允许重复的元素。常用命令:zadd、zrange、zrem、zcard 等。

三、与springboot结合使用的方式:

  (1)直接通过 RedisTemplate 来使用,pom中需要引入spring-boot-starter-data-redis,在 Spring Boot 2.x 以后底层不再使用 Jedis,而是换成了 Lettuce;commons-pool2:用作 Redis 连接池,如不引入启动会报错;spring-session-data-redis:Spring Session 引入,用作共享 Session。
  (2)结合Spring Cache 来使用,不仅能够使用 SPEL来定义缓存的 Key 和各种 Condition,还提供了开箱即用的缓存临时存储方案,也支持和主流的专业缓存如 EhCache、Redis、Guava 的集成。核心注解:@Cachable@CachePut@CacheEvict

四、Redis雪崩

  (1)举例,比如一些商家秒杀活动,一般缓存可能通过定时任务刷的,假设缓存失效时间为十个小时,当定时任务每十个小时去更新缓存时,此时缓存全部失效,且新的缓存数据并没有更新到redis,此时假设有一万个请求进来,没有了缓存,会直接查询数据库,此时可能会造成数据库崩溃,这就是redis雪崩。
  (2)解决方案:a、批量往 Redis 存数据的时候,把每个 Key 的失效时间都加个随机值就好了,这样可以保证数据不会再同一时间大面积失效。
               b、Redis 是集群部署,将热点数据均匀分布在不同的 Redis 库中也能避免全部失效。
               c、设置热点数据永不过期,有更新操作就更新缓存。

五、缓存穿透

  释义:缓存穿透是指缓存和数据库中都没有的数据,而用户或者黑客不断发起请求,这样可能会击透数据库。
  解决方案:可以在接口层增加校验,比如用户鉴权,参数做校验,不合法的校验直接 return,比如 id 做基础校验,id<=0 直接拦截;也可以使用布隆过滤器(Bloom Filter,判断这个key是否存在)这个也能很好的预防缓存穿透的发生。

六、redis采用的是单线程,为何使用单线程还这么快?

Redis 完全基于内存,绝大部分请求是纯粹的内存操作,非常迅速,数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度是 O(1)。
数据结构简单,对数据操作也简单。
采用单线程,避免了不必要的上下文切换和竞争条件,不存在多线程导致的 CPU 切换,        不用去考虑各种锁的问题,不存在加锁释放锁操作,没有死锁问题导致的性能消耗。
使用多路复用 IO 模型,非阻塞 IO。

七、持久化

RDB:快照形式是直接把内存中的数据保存到一个 dump 的文件中,定时保存,保存策略。
AOF:把所有的对 Redis 的服务器进行修改的命令都存到一个文件里,命令的集合。Redis 默认是快照 RDB 的持久化方式。
发布了11 篇原创文章 · 获赞 7 · 访问量 5033

猜你喜欢

转载自blog.csdn.net/rg201612/article/details/105227996