一、Redis相关知识
1. Redis中的五大数据结构
答:
① String:简单的key-value模式,value不仅可以是string也可以是数字。
② Hash:hash是一个string类型的key,再加一个value,适合存储对象。
③ List:链表,适合存储消息列表、粉丝列表、关注列表等。
④ Set:一个可以排除重复的集合,适用于共同关注、共同好友等功能。
⑤ Sorted Set:与Set类型相比,Sorted Set添加了一个score权重参数,可以按照权重进行有序排序。适用于各种排行榜(礼物排行榜)、弹幕集合等。
2. Redis的过期是怎么实现的?
答:定期删除 + 惰性删除 + 内存淘汰机制
- 定期删除:Redis每隔100ms会抽取一部分的key,看其是否过期,若过期,就删除掉。能删除掉的过期key很有限。
- 惰性删除:当查询某个key时,检测其是否过期,若过期,就删除。能删除掉的过期key很有限。
- 内存淘汰机制:我们发现,通过定期删除+惰性删除,能删除掉的过期key,其实很有限。这就要通过我们Redis的内存淘汰机制来删除过期的key。
3. Redis的内存淘汰机制有哪些?
答:
① volatile-lru:在设置了过期时间的数据集中,挑选最近最少使用的key淘汰。
② volatile-ttl:在设置了过期时间的数据集中,挑选将要到过期时间的key淘汰。
③ volatile-random:在设置了过期时间的数据集中,随机淘汰key。
④ allkeys-lru:在内存不足的情况下,挑选最近最少使用的key淘汰。(最常用)
⑤ allkeys-random:在所有数据中(不管设没设置过期时间),随机淘汰key。
⑥ no-eviction:在内存不足的情况下,拒绝新的数据写入。
Redis 4.0后又添加了下面两种策略。
⑦ volatile-lfu:在设置了过期时间的数据集中,选择最不经常使用的key淘汰。
⑧ allkeys-lfu:在内存不足的情况下,选择最不经常使用的key淘汰。
4. Redis的两种持久化方式
答:快照方式-RDB和只追加文件方式-AOF
-
快照方式-RDB:Redis可以通过创建快照,获取指定时间点内存中的数据。快照可以备份,可以传递给其他服务器使用,也可留在本地用于重启服务器后恢复数据。
快照方式是Redis默认的持久化方式,在redis.conf配置文件中默认有如下配置:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
-
只追加文件方式-AOF:与快照持久化相比,AOF持久化方式的实时性更好,因此已经成为Redis主流的持久化方案。
Redis默认是使用快照方式,如果要使用AOF方式,需要通过appendonly参数开启:
appendonly yes
开启AOF方式后,每执行一条更改数据的命令后,都会把该命令写入到AOF文件中。AOF文件存放的位置与RDB相同,都是通过dir参数指定的,默认名称是appendonly.aof。
但是每执行一条更改数据的命令后,就把该命令写入到AOF文件中的操作太过频繁,会影响性能,下面是AOF持久化的3种策略:
appendfsync always #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no #让操作系统决定何时进行同步
为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。
5. 缓存雪崩的解决方案
什么是缓存雪崩?答:缓存在同一时间大面积失效,导致大部分请求直接落在了数据库上,致使数据库崩溃。
那么有哪些解决方案?
- 事前:保证Redis集群的高可用,发现有宕机的服务器及时补上。选择合适的内存淘汰机制。
- 事中:使用本地ehcache或hystrix限流降级,避免数据库崩掉。
- 事后:通过Redis持久化的文件进行恢复数据。
6. 缓存穿透的解决方案
什么是缓存穿透?答:大量的请求没有命中缓存,直接访问了数据库。可能是误操作,也可能是黑客攻击。
那么有哪些解决方案?答:一般可以采用布隆过滤器。布隆过滤器的原理就是:将缓存的数据放入布隆过滤器中,请求过来时,先去布隆过滤器查找数据,如果包含,那么可以继续进行下去。如果不包含,那将返回错误信息给调用方。示意图如下:
7. Redis每秒的并发量
答:大约11万/秒的写操作(SET),8.1万/秒的读操作。
8. 通俗地解释什么是锁
答:一种用来解决多线程访问共享资源时错误和数据不一致的工具。
如果把一台服务器比作一间房子,把不同的住户比作不同的线程,当他们去上厕所时(房子里只有一个厕所),如果不加锁,可是会出大问题的…
9. Redis哨兵是什么
答:看图↓
上图包括两种类型不同的节点:
- 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的Redis节点,不存储数据。
- 数据节点:包括主节点和从节点,存储数据。
哨兵的作用?
- 监控:哨兵会不断地监控主节点和从节点是否正常运作。
- 自动故障转移:当一个主节点宕机时,哨兵会自动从所有从节点中选举出一个新的主节点,并且让其他从节点从新的主节点进行主从复制。
- 配置提供者客户端在初始化时,通过连接哨兵,获取主节点的地址。
- 通知:哨兵可以把故障转移的结果通知给客户端。
10. Redis分布式锁
答:
比如说,苹果这个商品的id是1。
redisson.lock(“product_1_stock”)
key的业务语义,就是针对product_id = 1的商品的库存,也就就是苹果的库存,进行加锁
product_1_stock: { “xxxx”: 1 }
生存时间:30s
watchdog,Redisson框架后台执行一段逻辑,每隔10s去检查一下这个锁是否还被当前客户端持有,如果是的话,重新刷新一下key的生存时间为30s
其他客户端尝试加锁,这个时候发现“product_1_stock”这个key已经存在了,里面显示被别的客户端加锁了,此时他就会陷入一个无限循环,阻塞住自己,不能干任何事情,必须在这里等待
第一个客户端加锁成功了,此时有两种情况,第一种情况,这个客户端操作完毕之后,主动释放锁;第二种情况,如果这个客户端宕机了,那么这个客户端的redisson框架之前启动的后台watchdog线程,就没了
此时最多30s,key-value就消失了,自动释放了宕机客户端之前持有的锁