缓存设计 你的名字 2022-12-21 13:58 66阅读 0赞 ### 目录 ### * * 一:缓存介绍: * * 1:缓存架构: * 2:缓存粒度: * 三:缓存的过期和淘汰: * * 1: 缓存过期: * 2:缓存淘汰: * 面试题: * 四:缓存问题: * * 1:缓存更新 * 2:缓存穿透: * 3: 缓存雪崩: * 五:缓存模式: ## 一:缓存介绍: ## * 缓存的优点:减小数据库的访问压力, 提高并发能力。 ### 1:缓存架构: ### * 1: 对于查询来说,可以增加缓存。用户发送请求,现在缓存中查询,查询到直接返回数据,查询不到,查询Mysql数据库,然后回填缓存,返回数据。 * 2:多级缓存: * 2.1: 前端也可以搭建缓存,使用浏览器,cache,sqlite3,搭建前端缓存。 * 2.2:后端一级缓存:使用代码中的大字典,或者全局变量,速度非常快。 * 2.3:二级缓存,使用内存型数据库Redis等,一般存储所有的数据,每一个小时清除一次缓存。 * 2.4:三级缓存,使用内存型数据库Redis等,一般存储热点数据,每5小时清除一次缓存。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 1] ### 2:缓存粒度: ### 1: 缓存某个数值: > 应用场景:验证码,使用字符串存储。根据key获取值就可以了。 2:缓存数据对象: > 应用场景:用户,文章的数据,使用哈希类型存储。 3: 缓存数据集合: > 应用场景:数据库的结果集,文章/关注列表。 > 如果需要排序,比如文章/关注列表,需要对文章/用户列表排序,可以使用zset存储。 > 如果需要去重可以使用set存储,如果只是存储,可以使用list存储。 注意:使用集合存储数据对象的形式,被称为redis二级索引。原因:因为我适应set/zset存储的只是用户的user\_id,通过这个user\_id,在缓存中还可以找到用户的其他信息,所以称为二级缓存。 4:缓存视图响应: > 如果一个视图经常被使用,可以将url地址作为key,返回的响应作为内容。 ## 三:缓存的过期和淘汰: ## ### 1: 缓存过期: ### * 1:设置有效期的优点:节约空间,做到弱一致性,有效期失效以后,保证数据一致。 * 2:定时过期:给每个过期的key都设置一个定时器,到了过期时间就立即清除。缺点:占用大量的CPU资源计时和处理过期数据,影响缓存的响应时间和吞吐量。 * 3:惰性过期:只有当这个值使用的时候才判断是否过期,过期清除。节省了CPU但是消耗大量的内存空间。 * 4: 定期过期:每个一定的时间,扫描一部分键值对是否过期,如果过期则清除。是个折中的方案。 注意: **redis中同时使用惰性过期和定时过期两种策略。** > 1: 默认每100秒检测一次。 > 2:读或写一个key时,触发惰性过期。 ### 2:缓存淘汰: ### ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 2] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 3] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 4] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 5] ### 面试题: ### * 1: 预估20w数据在redis数据库中的内存用量,然后设置redis内存最大上限值=内存用量。 * 2:开启内存淘汰策略LFU,将2000w数据读取到mysql中,当redis超过20w数据量后,开启淘汰策略,最后留下的就是热点数据。 ![在这里插入图片描述][20201117114533256.png_pic_center] * 1:使用dbsize查看当前数据库中有多少个键值对。 * 2:使用info Memory 查看Redis分配的内存总量。 * 3:内存总量/键的个数 \* 20w,粗略估计出20w数据占用的内存总量。 * 4:修改配置文件。 > $ sudo vi redis.conf > maxmemory 1048576 \# 最大使用内存数量, 以字节为单位 如服务器内存10G, 最多给redis分配9G > maxmemory-policy volatile-lfu \# 淘汰策略 方案二:使用第三方工具精确计算: # 安装工具 git clone https://github.com/sripathikrishnan/redis-rdb-tools cd redis-rdb-tools sudo python3 setup.py install # 将Redis持久化的数据导出, 其中 /path/dump.rdb 为Redis持久化的数据文件路径 $ rdb -c memory /path/dump.rdb > ~/redis_memory_report.csv $ cat ~/Desktop/redis_memory_report.csv # 库号, 类型, 键名, 占用空间, 编码方式, 元素个数, 最大元素占用的空间, 过期时间 database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry 0,sortedset,user:all:art_count,89,ziplist,3,8, 0,sortedset,list2,63,ziplist,1,8, ## 四:缓存问题: ## ### 1:缓存更新 ### * 1: 解决方案一:设计使用分布式锁(redis setnx)使用消息队列顺序执行。 * 1.1: * 2:解决方案二:更新数据到mysql数据库时,先删除缓存。 * 2.1:如果使用缓存,缓存的是用户对象,字典,或者哈希,可以删除缓存。 * 2.2:如果使用缓存,缓存的是集合,比如粉丝列表,考虑更新缓存,而不是删除缓存。删除缓存成本太高了。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 6] ### 2:缓存穿透: ### * 缓存只是为了缓解数据库压力而添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,频繁去访问缓存中没有的数据,那么缓存就失去了存在的意义,瞬间所有请求的压力都落在了数据库上,这样会导致数据库连接异常。 * 解决方案一:对于数据库不存在的值,也在缓存中设置Null。 * 解决方案二:设置布隆过滤器。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 7] > 描述:当第一次请求数据库中没有这个值,则在redis中设置一个值为空的数据,下次再次请求这个数据的时候,redis中直接返回一个NULL类型的数据,就不会访问MYSQL数据库了,防止了黑客的频繁攻击数据库。一般来说,为了不占用redis数据库资源,设置的时间比较短。当缓存过期了,数据库存在了这个数据,用户再次访问,则mydsl数据,直接回填缓存即可。 布隆过滤器的设置: > pip install pybloomfiltermmap3 > ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 8] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 9] ### 3: 缓存雪崩: ### * 如果大量缓存数据都在同一个时间过期, 那么很可能出现 缓存集体失效, 会导致所有的请求都直接访问数据库, 导致数据库压力过大。 * 方案1: 设置过期时间时添加随机值, 让过期时间进行一定程度分散,避免同一时间集体失效。 > 比如以前是设置10分钟的超时时间,那每个Key都可以随机8-13分钟过期,尽量让不同Key的过期时间不同。 * 方案2: 采用多级缓存,不同级别缓存设置的超时时间不同,即使某个级别缓存都过期,也有其他级别缓存兜底。 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 10] ## 五:缓存模式: ## ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 11] ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 12] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center]: /images/20221120/6025b44d7cbe42fd92a50284d98589b9.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 1]: /images/20221120/74a20bf68b034e6fbf6e8719ebc09924.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 2]: /images/20221120/f67d6d92673344aca8c9594968cc790b.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 3]: /images/20221120/c97dd8c578c748c4a414b2b0f9a11f0d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 4]: /images/20221120/ec02f5455a2f48c7b19f880259dca2eb.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 5]: /images/20221120/31cb362ce8d54e62b25d181c16b17213.png [20201117114533256.png_pic_center]: /images/20221120/a17194ac3caf41428d04b9c22a954996.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 6]: /images/20221120/8d3ead576f8a481db76e17a23b1706a1.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 7]: /images/20221120/417ef06a18c1402583e71bed8ff79fe7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 8]: /images/20221120/decc05bf86be4df5ad70bb5e39219a16.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 9]: /images/20221120/22c30c6674444e11842efa2e2d25a8fd.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 10]: /images/20221120/abfa225314f54c30b9b410fad23e4001.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 11]: /images/20221120/17eb2a8509894887bf9fb717fc0dc639.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMzQxNzU3_size_16_color_FFFFFF_t_70_pic_center 12]: /images/20221120/db5f1f22e39342dcb55592f5492bd2ed.png
还没有评论,来说两句吧...