一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种自定义hash防止缓存穿透的方法及系统与流程

2021-12-15 01:34:00 来源:中国专利 TAG:


1.本发明涉及计算机通讯技术领域,特别是一种自定义hash防止缓存穿透的方法及系统。


背景技术:

2.缓存是为了缓解数据库压力而在数据库查询之前添加的一层保护层,当从缓存中查询不到我们需要的数据就要去数据库中查询。但如果规则被攻击者利用,通过仿照请求地址,不断访问不存在的数据,那么系统就会因为取不到缓存里的数据,穿透过缓存不断请求数据库,最后导致数据库崩溃,这就是缓存穿透。现有解决缓存穿透的方式是在读取不到数据库中的数据时存储一个空标识null到缓存中,如果在缓存中取到null即代表数据不存在,则不继续读取数据库,直接返回数据为空。但这个方法虽然避免查询穿透至数据库,但会导致缓存中存储大量无用的null,造成资源浪费。


技术实现要素:

3.为克服上述问题,本发明的目的是提供一种能够通过hash函数生成多个hash值,来表示数据是否存在,有效的解决缓存穿透给缓存和数据库带来流量压力的方法。
4.本发明采用以下方案实现:一种自定义hash防止缓存穿透的方法,所述方法包括以下步骤:
5.步骤s1、准备多个不同的hash函数,生成多个不同的hash值来标识商品;
6.步骤s2、根据商品的商品码得到需要hash函数次数n;
7.步骤s3、循环执行n次hash函数得到对应的n个hash值;
8.步骤s4、判断n个hash值是否存在bigset二进制数组中;
9.步骤s5、读取商品redis缓存;
10.步骤s6、读取商品数据库;
11.步骤s7、将商品数据库中的商品数据存入redis缓存中;
12.步骤s8、返回商品数据信息给用户,从而实现解决缓存穿透给缓存和数据带来的流量压力。
13.进一步的,所述步骤s1进一步具体为:准备多个不同的hash函数,增加生成的hash值,多个不同的hash值来标识一个商品是否存在,hash函数得出的值不同,表示hash函数的种子seed不同。
14.进一步的,所述步骤s2进一步具体为:根据用户的访问地址得到商品码,用商品码进行hash函数得到数值,调用hash函数,传入hash函数的种子,得出需要hash函数的次数。
15.进一步的,所述步骤s3进一步具体为:得到需要hash函数的次数后,对商品码执行hash函数的次数,得到hash函数次数的hash值。
16.进一步的,所述步骤s4进一步具体为:判断n个hash值是否存在bigset二进制数组中,是,则进入步骤s5,否,则返回用户数据不存在。
17.进一步的,所述步骤s5进一步具体为:得到商品码存在,组织商品的缓存key密钥,执行读取redis缓存命令,商品码存在返回用户商品数据。
18.进一步的,所述步骤s6进一步具体为:读取redis缓存,判断商品数据是否存在redis缓存中,是,则获取商品数据,否,则执行spl语句,得到商品数据。
19.进一步的,所述步骤s8进一步具体为:系统从bigset二进制数组中判断商品的商品码是否存在,从数据库中读取到商品数据保存至redis缓存,返回商品信息给用户。
20.本发明还提供了一种自定义hash防止缓存穿透的系统,包括生成模块、确定次数模块、执行模块、判断模块、第一读取模块、第二读取模块、存入模块和返回模块;所述生成模块,即准备多个不同的hash函数,生成多个不同的hash值来标识商品;所述确定次数模块,即根据商品的商品码得到需要hash函数次数n;所述执行模块,即循环执行n次hash函数得到对应的n个hash值;所述判断模块,即判断n个hash值是否存在bigset二进制数组中;所第一读取模块,即读取商品redis缓存;所述第二读取模块,即读取商品数据库;所述存入模块,即将商品数据库中的商品数据存入redis缓存中;所述返回模块,即返回商品数据信息给用户,从而实现解决缓存穿透给缓存和数据带来的流量压力。
21.进一步的,所述生成模块进一步具体为:准备多个不同的hash函数,增加生成的hash值,多个不同的hash值来标识一个商品是否存在,hash函数得出的值不同,表示hash函数的种子seed不同。
22.进一步的,所述确定次数模块进一步具体为:根据用户的访问地址得到商品码,用商品码进行hash函数得到数值,调用hash函数,传入hash函数的种子,得出需要hash函数的次数。
23.进一步的,所述执行模块进一步具体为:得到需要hash函数的次数后,对商品码执行hash函数的次数,得到hash函数次数的hash值。
24.进一步的,所述判断模块进一步具体为:判断n个hash值是否存在bigset二进制数组中,是,则进入第一读取模块,否,则返回用户数据不存在。
25.进一步的,所述第一读取模块进一步具体为:得到商品码存在,组织商品的缓存key密钥,执行读取redis缓存命令,商品码存在返回用户商品数据。
26.进一步的,所述第二读取模块进一步具体为:读取redis缓存,判断商品数据是否存在redis缓存中,是,则获取商品数据,否,则执行spl语句,得到商品数据。
27.进一步的,所述返回模块进一步具体为:系统从bigset二进制数组中判断商品的商品码是否存在,从数据库中读取到商品数据保存至redis缓存,返回商品信息给用户。
28.本发明的有益效果在于:本发明能够利用小容量的二进制数组来判断商品是否真实存在,如果存在再进行真正的数据读取行为,有效的解决缓存穿透给缓存和数据库带来的流量压力。
附图说明
29.图1是本发明的方法流程示意图。
30.图2是本发明的系统原理框图。
具体实施方式
31.下面结合附图对本发明做进一步说明。
32.请参阅图1所示,本发明的一种自定义hash防止缓存穿透的方法,所述方法包括以下步骤:
33.步骤s1、准备多个不同的hash函数,生成多个不同的hash值来标识商品;
34.步骤s2、根据商品的商品码得到需要hash函数次数n;
35.步骤s3、循环执行n次hash函数得到对应的n个hash值;
36.步骤s4、判断n个hash值是否存在bigset二进制数组中;
37.步骤s5、读取商品redis缓存;
38.步骤s6、读取商品数据库;
39.步骤s7、将商品数据库中的商品数据存入redis缓存中;
40.步骤s8、返回商品数据信息给用户,从而实现解决缓存穿透给缓存和数据带来的流量压力。
41.下面通过一具体实施例对本发明作进一步说明:
42.我们以商城系统为例,用户通过浏览器访问商品详情www.xxx.com/detail/1001.html访问商品详情,但为了避免商品信息被恶意采集,所以我们不采用商品id的形式来标识商品,我们利用创建商品时生成的商品码来标识商品,那商品详情地址是www.xxx.com/detail/s4xduk35.html。以此地址规则举例如何防止商品信息的缓存穿透。
43.步骤1、准备5个hash函数
44.准备多个不同的hash函数是为了增加生成的hash值,多个不同的hash值来标识一个商品是否存在。下面会描数如何使用hash函数,我们首先先准备好这些hash函数,编写一个方法名为hash的方法,接收待商品标识goodscode参数和种子seed参数,返回值是一个uint类型,在方法中定义一个容量变量cap,初始值是2的25次方,再定一个计算结果变量result,初始为0,接着循环获取goodscode字符串的每一个字符,每个字符会被强转uint(字符)为一个uint类型,再加上当前计算结果result与种子seed的乘积,循环里每次的计算都会使得result结果发生变化,循环结束后用得到的result与定义好的容量cap

1进行

&与运算’,可以得到cap容量内的一个数字,这个数字就是我们得到的hash值。让hash函数得到的值不一样,其实只要其中的种子seed不同即可。代码如下
[0045][0046]
5个种子seed我们定为7,11,13,31,37,5个种子没有什么讲究,只要不同即可。
[0047]
步骤2、根据商品码得到需要hash次数n
[0048]
通过用户的访问地址得到商品码goodscode=s4xduk35,用商品码进行hash得到一个数值i,调用hash方法,传入种子seed=0,i=hash(goodscode,0)。用i对2进行取模得到一个0

2之间的数字r,r=i%3,那么需要hash的次数n=5

r,那么n的范围就是3

5,不会超过我们准备的5个hash函数。最后的公式是n=5

(hash1(goodscode,0)%3),此步骤根据商品码经过1次hash来得到需要hash的次数n。根据公式商品码s4xduk35得到的i=53,r=2,n=3。
[0049]
步骤3、循环执行n次hash函数得到对应n个hash值
[0050]
步骤2得到的n=3,那么就需要对商品码进行3次hash,得到3个hash值,代码如下
[0051]
h1:=hash(goodscode,7)
[0052]
h2:=hash(goodscode,11)
[0053]
h3:=hash(goodscode,13)
[0054]
结果是h1=9038477,h2=13571233,h3=24564631。
[0055]
步骤4、判断n个hash值是否存在bigset中
[0056]
bigset是一个二进制数组,如果数组中对应的hash值的索引的任何一个位置的值是0,则表示商品码s4xduk35不存在,则不继续下面步骤,返回用户数据不存在。如果数组中对应的hash值的索引位置都是1,那么表示商品码s4xduk35存在,那么就继续下面的读取商品数据的步骤。代码如下:
[0057]
if bigset[h1]==0||bigset[h2]==0||bigset[h3]==0{
[0058]
return"数据不存在"
[0059]
}
[0060]
步骤5、读取商品redis缓存
[0061]
经过步骤4我们能得知此商品码s4xduk35是真实存在的,组织商品的缓存key,goods:s4xduk35,执行读取redis命令get goods:s4xduk35,如果存在则直接返回用户商品数据。
[0062]
步骤6、读取商品数据库
[0063]
步骤5中读取redis缓存,如果数据不存在缓存中,则会从数据库中读取商品数据,执行sql语句select*from goods_tb where goods_code="s4xduk35",得到商品数据goodsinfo;这里是关系型数据库mysql。
[0064]
步骤7、商品数据存入redis
[0065]
为了避免商品数据重复从数据库中读取,系统把商品数据存于redis缓存之中,根据步骤5组织一样的缓存key密钥,goods:s4xduk35,执行存储redis命令set goods:s4xduk35 goodsinfo,再设置一个过期时间,expire goods:s4xduk3586400,设置key86400秒后过期,就是存储一天。
[0066]
步骤8、返回商品数据
[0067]
经过以上步骤,系统从bigset中判断到商品码s4xduk35存在,从数据库中读取到商品数据goodsinfo后保住至redis中,最后返回商品信息给用户。
[0068]
总之,本发明主要思路是采用一个很长的二进制数组,通过一系列的自定义规则的hash函数,生成多个hash值,存储至数组中,通过多个hash值共同来表示数据是否存在。虽然此方法有可能存在小概率的误判,但是可以极大降低无效null值存储至redis里的困扰,一个长度仅25的二进制数组就可以表示3000多万种可能。
[0069]
本发明还提供了一种自定义hash防止缓存穿透的系统,包括生成模块、确定次数模块、执行模块、判断模块、第一读取模块、第二读取模块、存入模块和返回模块;所述生成模块,即准备多个不同的hash函数,生成多个不同的hash值来标识商品;所述确定次数模块,即根据商品的商品码得到需要hash函数次数n;所述执行模块,即循环执行n次hash函数得到对应的n个hash值;所述判断模块,即判断n个hash值是否存在bigset二进制数组中;所第一读取模块,即读取商品redis缓存;所述第二读取模块,即读取商品数据库;所述存入模块,即将商品数据库中的商品数据存入redis缓存中;所述返回模块,即返回商品数据信息给用户,从而实现解决缓存穿透给缓存和数据带来的流量压力。
[0070]
所述生成模块进一步具体为:准备多个不同的hash函数,增加生成的hash值,多个不同的hash值来标识一个商品是否存在,hash函数得出的值不同,表示hash函数的种子seed不同。
[0071]
所述确定次数模块进一步具体为:根据用户的访问地址得到商品码,用商品码进行hash函数得到数值,调用hash函数,传入hash函数的种子,得出需要hash函数的次数。
[0072]
所述执行模块进一步具体为:得到需要hash函数的次数后,对商品码执行hash函数的次数,得到hash函数次数的hash值。
[0073]
所述判断模块进一步具体为:判断n个hash值是否存在bigset二进制数组中,是,则进入第一读取模块,否,则返回用户数据不存在。
[0074]
所述第一读取模块进一步具体为:得到商品码存在,组织商品的缓存key密钥,执行读取redis缓存命令,商品码存在返回用户商品数据。
[0075]
所述第二读取模块进一步具体为:读取redis缓存,判断商品数据是否存在redis缓存中,是,则获取商品数据,否,则执行spl语句,得到商品数据。
[0076]
所述返回模块进一步具体为:系统从bigset二进制数组中判断商品的商品码是否存在,从数据库中读取到商品数据保存至redis缓存,返回商品信息给用户。
[0077]
以上所述仅为本发明的较佳实施例,凡依本发明申请专利范围所做的均等变化与修饰,皆应属本发明的涵盖范围。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献