解决缓存穿透问题

本文探讨了如何通过C++ STL的unordered_map高效存储并利用布隆过滤器减少缓存穿透问题。重点讲解了unordered_map的哈希表原理、冲突解决策略,以及布隆过滤器的工作原理及其在解决缓存穿透中的应用。
摘要由CSDN通过智能技术生成


前言

缓存穿透:某个数据redis不存,mysql也不存在,而且一直尝试读,数据最终压力依然堆积在mysql,可能造成mysql不堪重负而崩溃

读取步骤:
1.先访问redis,如果存在,直接返回,不存在走2
2.访问mysql,如果不存在,直接返回,如存在走3
3.将mysql存在的key写回redis


一、STL::SET和STL::MAP?

  • C++标准库(STL)中的set和map结构都是采用红黑树实现,它增删改查的时间是O(logN)
  • 优点:存储效率高,访问速度高效
  • 解决缓存穿透不是使用理由:字符串太长,比较效率也比较低

二、STL::unordered_map?

  • C++标准库(STL)中采用hashtable实现,增删改查的效率是O(1)
  • 构成:数组+hash函数
  • hash函数的作用:避免插入的时候字符串的比较,函数计算出来的值通过对数组长度的取模能随机分布在数组当中
  • 选取hash函数:1选取计算速度快 2哈希相似字符串能保持强随机分布性(murmurhash1,murmurhash2,murmurhash3,siphash)
  • 负载因子:数组存储元素的个数/数组长度;负载因子越小,冲突越小;负载因子越大,冲突越大
  • hash冲突解决方案:
    • 链表法:冲突的链表过长,可以将这个链表转换为红黑树
    • 开放寻址法:将所有的元素放在哈希表的数组中,不使用额外的数据结构;一般使用线性探查的思路解决。
    • 线性探查
      • 插入新元素时,使用哈希函数定位位置
      • 检查是否已经存在,不存在,插入,否则3
      • 在2检测的是槽位索引上加一定步长接着,检查2
      • 加步长分为几种:
        • 1.i+1,i+2, i+3, i+4…i+n
        • 2.i-1^2, i+2^2
      • 这两种会导致同类hash聚集
      • 使用双重哈希 hash1+k*hash2
    • 优点:访问速度更快,不需要进行字符串比较
    • 缺点:需要引入策略避免冲突,存储效率不高,空间换时间

三、布隆过滤器

  • 定义:概率型数据结构,他的特点是高效的插入和查询,能明确告知某个字符串一定不存在或者可能存在
  • 缺点:概率性返回,结果存在误差,不支持删除操作
  • 原理:元素加入位图时,通过k个hash函数将这个元素映射到位图的k个点,并把它们置为1;当检索时,再通过k个hash函数运算检测位图的k个点是否都为1;如果有不为1的点,那么认为不存在;如果全部为1,则可能存在(存在误差)
n      -- 布隆过滤器中元素的个数,如上图    只有str1和str2 两个元素    那么 n=2 
p      -- 假阳率,在0-1之间  0.000000
m      -- 位图所占空间 k      -- hash函数的个数
公式如下:
n = ceil(m / (-k / log(1 - exp(log(p) / k)))) ;
p = pow(1 - exp(-k / (m / n)), k);
m = ceil((n * log(p)) / log(1 / pow(2, log(2)))); 
k = round((m / n) * log(2));
选值网站:https://hur.st/bloomfilter/

四、解决

1.发现MySQL不存在,将redis设置为<key,nil>设置过期时间 下次访问key的时候 不再访问mysql 容易造成redis缓存很多无效数据
2.布隆过滤器,将mysql当中已经存在的key,写入布隆过滤器,不存在的直接pass掉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
布隆过滤器是一种数据结构,用于判断一个元素是否存在于集合中,它可以高效地过滤掉一部分不可能存在的元素。在解决缓存穿透问题中,可以利用布隆过滤器在缓存层面进行数据的预先过滤。 具体来说,布隆过滤器包含一个位数组和多个哈希函数。当有一个元素需要查询时,将该元素经过多个哈希函数计算得到多个哈希值,然后将对应的位数组位置置为1。当查询一个元素时,同样经过多个哈希函数计算得到多个哈希值,如果对应的位数组位置全为1,则说明该元素可能存在于集合中;如果有一个或多个位置为0,则说明该元素一定不存在于集合中。 在缓存穿透问题中,可以将请求的参数经过哈希函数计算得到哈希值,然后查询布隆过滤器。如果布隆过滤器判断该参数对应的位数组位置全为1,则说明该参数可能存在于缓存中;如果有一个或多个位置为0,则说明该参数一定不存在于缓存中,可以直接返回缓存未命中的结果,避免了无效的查询请求到达数据库。 需要注意的是,布隆过滤器有一定的误判率,即可能会将不存在的元素误判为存在。因此,在使用布隆过滤器时,需要根据实际情况权衡误判率和内存使用,选择合适的参数配置。同时,布隆过滤器只能提供一种快速的“可能存在”或“一定不存在”的判断,不能提供具体的数据值,因此在使用过程中需要结合其他机制来补充完整的缓存逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值