首页 > 其他分享 >缓存穿透及解决方案

缓存穿透及解决方案

时间:2023-01-15 10:07:27浏览次数:54  
标签:缓存 解决方案 数据库 布隆 穿透 哈希 过滤器 数据


缓存只是为了缓解数据库压力而添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询了。如果被黑客利用,频繁去访问缓存中没有的数据,那么缓存就失去了存在的意义,瞬间所有请求的压力都落在了数据库上,这样会导致数据库连接异常。

针对缓存穿透的常见解决方案有以下两种:

方案1: 对于数据库中不存在的数据, 也对其在缓存中设置默认值Null, 为避免占用资源, 一般过期时间会比较短

方案2: 可以设置一些过滤规则, 如布隆过滤器

方案1相对简单, 但是也容易破解, 比如 攻击者通过分析数据格式, 不重复的请求数据库不存在数据, 那这样方案1就等于失效的. 相对而言, 方案2则更加稳定, 接下来就主要讲解一下方案2的实现方式.

缓存穿透及解决方案_java

方案2的设计思路是通过设置过滤规则, 在数据库查询之前将数据进行过滤, 如果发现数据不存在, 则不再进行数据库查询, 以此来减小数据库的访问压力

方案2中过滤规则目前主流的一种的载体就是布隆过滤器. 布隆过滤器是一种概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”.

相比于传统的 List、Set、Map 等数据结构,布隆过滤器是一个bit数组, 它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

缓存穿透及解决方案_数据结构_02

如果我们要映射一个值到布隆过滤器中,我们需要使用多个不同的哈希函数生成多个哈希值,并对每个生成的哈希值指向的 bit 位置 1,例如针对值 “zhangsan” 和三个不同的哈希函数分别生成了哈希值 1、4、7

缓存穿透及解决方案_数据库_03

我们现在再存一个值 “lisi”,如果哈希函数返回 4、5、8 的话,图继续变为:

缓存穿透及解决方案_python_04

当我们想要判断布隆过滤器是否记录了某个数据时,布隆过滤器会先对该数据进行同样的哈希处理, 比如 “wangwu”的哈希函数返回了 2、5、8三个值,结果我们发现 2 这个 bit 位上的值为 0,说明没有任何一个值映射到这个 bit 位上,因此我们可以很确定地说 “wangwu” 这个数据不存在。

但是同时我们会发现,4 这个 bit 位由于”zhangsan”和”lisi”的哈希函数都返回了这个 bit 位,因此它被覆盖了。那么随着布隆过滤器保存的数据不断增多, 重复的概率就会不断增大, 所以当我们过滤某个数据时, 如果发现其三个哈希值都在过滤器中进行了记录, 那么也只能说明过滤器中可能包含了该数据, 并不能绝对肯定, 因为可能是其他数据的哈希值对结果产生了影响.这也就解释了上文所说的 布隆过滤器只能说明“某样东西一定不存在或者可能存在”.至于为什么采用三种不同的哈希函数取值, 因为三个哈希值只要有一个不存在就说明数据一定不在过滤器中, 这样做是可以减小因哈希碰撞(两个数据的哈希值相同)产生的错误概率.

布隆过滤器在很多语言中都有封装的工具包, 下边以python的工具包 `pybloomfiltermmap3 为例演示一下代码

import pybloomfilter

# 创建过滤器(数据容量, 错误率, 存储文件) 错误率越低, 文件越大
filter = pybloomfilter.BloomFilter(1000000, 0.01, 'words.bloom')

# 添加数据
filter.update(('bj', 'sh', 'gz'))

# 判断是否包含
if 'bj' in filter:
print('包含')
else:
print('不包含')

标签:缓存,解决方案,数据库,布隆,穿透,哈希,过滤器,数据
From: https://blog.51cto.com/u_8238263/6008213

相关文章

  • .NetCore下基于FreeRedis实现的Redis6.0客户端缓存之缓存键条件优雅过滤
    前言众所周知内存缓存(MemoryCache)数据是从内存中获取,性能表现上是最优的,但是内存缓存有一个缺点就是不支持分布式,数据在各个部署节点上各存一份,每份缓存的过期时间不一......
  • Redis 高可用: twemproxy实现缓存服务器分片集群
    Twemproxy又称nutcracker,是一个memcache、redis协议的轻量级代理,一个用于sharding的中间件。有了Twemproxy,客户端不直接访问Redis服务器,而是通过twemproxy代理中间件......
  • (11)SpringBoot整合EhCache做缓存
      摘要:本文介绍在SpringBoot项目中,如何使用EhCache做缓存。EhCache简介:EhCache是一个纯Java的进程内缓存框架,是Hibernate中默认的CacheProvider;其缓存的数据可以存放......
  • 行缓存、全缓存
    发问原因是,用fputs写普通文件时,写入"hellolinux\n",有\n符号,按什么时候输出缓存,应该要写入到普通文件中,但是却没有写入到普通文件?因为打开的是普通文件,如果写到输出设备,遇......
  • Leetcode——双向链表和哈希表实现LRU缓存和LFU缓存
    一、Leetcode146.LRU缓存1.使用STLlist和unordered_map实现usingKV=pair<int,int>;classLRUCache{private:intcacheCapacity;list<KV>cacheList;......
  • SAP 交货单与HU指派关系数据不一致问题的解决方案
    SAP交货单与HU指派关系数据不一致问题的解决方案  我所在的项目是一个超大型的GlobalSAP项目,客户是一家跨国企业巨头,其SAP系统早已实施十几年了。除了SAP系统,客户还......
  • 用Java写一个分布式缓存——缓存淘汰算法
    前言之前也用过一些缓存中间件,框架,也想着自己是不是也能用Java写一个出来,于是就有了这个想法,打算在写的过程中同步进行总结。源码:weloe/Java-Distributed-Cache(github.......
  • 华为云数据查询加速解决方案,助力企业数据“流通”
    华为云数据查询加速解决方案,助力企业数据“流通”数字经济时代,全球数据量激增,各行各业对数据库的需求持续增长。然而,伴随业务的增长,数据量的增大,单一的数据库可能无法满足数......
  • 哲讯科技SAP医疗器械行业ERP解决方案
    哲讯科技SAP医疗器械行业ERP解决方案主要体现在以预测为指导,计划为执行的管理理念,完全做到实时的全过程的质量管理和质量跟踪。并且通过灵活的质量管理模块大大降低因实施GM......
  • 前端页面加载速度优化解决方案
    随着前端各种框架的日益完善,一些基本的性能优化和加载优化都已经很完善了,但是有些必要的优化还是得开发者自己去做。vue.js是一个比较流行的前端框架,与react.js、angular.js......