Redis为单线程
1、Redis 有哪些数据类型
- String
- 哈希
- list
- set
- 有序set
2、Redis 内部结构
参考:https://www.cnblogs.com/chenpingzhao/archive/2017/06/10/6965164.html
3、Redis 使用场景
缓存,会话缓存,时效性,访问频率,计数器,社交列表,记录用户判定信息,交集、并集和差集,热门列表与排行榜,最新动态等。
4、Redis 持久化机制
- 快照(snapshotting):将整个Redis内存中的所有的数据遍历一遍存储到一个扩展名为rdb的数据文件中。
- AOF(Append onlyfile):在使用aof时,redis会将每一个收到的写命令都通过write函数追加到文件中,当redis重启时会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。
更详细的说明参考:https://blog.csdn.net/u013905744/article/details/52787413
5、Redis 为什么是单线程
Redis操作的对象是内存中的数据结构。如果在多线程中操作,那就需要为这些对象加锁。最终来说,多线程性能有提高,但是每个线程的效率严重下降了。而且程序的逻辑严重复杂化。Redis的数据结构并不全是简单的Key-Value,还有列表,hash,map等等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除一个对象,等等。这些操作还可以合成MULTI/EXEC的组。这样一个操作中可能就需要加非常多的锁,导致的结果是同步开销大大增加。这还带来一个恶果就是吞吐量虽然增大,但是响应延迟可能会增加。
6、缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
- 缓存雪崩:由于原有缓存失效,新缓存未到期间所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。
- 缓存穿透:是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空(相当于进行了两次无用的查询)。采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
- 缓存预热:系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
- 缓存更新:除了redis自带的6种策略(参考本文的第8条),可以根据业务需求自定义清除缓存。
- 缓存降级:当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。
详解参考:https://blog.csdn.net/xlgen157387/article/details/79530877
7、使用缓存的合理性问题
- 热点数据,缓存才有价值。
- 频繁修改的数据,看情况考虑使用缓存。
- 数据的不一致
- 缓存更新机制
- 缓存可用性
- 缓存服务降级
- 缓存预热
- 缓存穿透
详细解析参考:https://blog.csdn.net/diyhzp/article/details/54892358
8、Redis常见的回收策略
- volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
- allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰。
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
- no-enviction(驱逐):禁止驱逐数据