发明内容
本发明的目的在于提供一种可持久化的Java堆外缓存系统及方法,能够高效的对缓存数据进行读写操作及持久化存储,解决缓存重启数据丢失及高并发访问大体量缓存时频繁回收垃圾,导致业务应用抖动的问题。
本发明实施例提供了一种可持久化的Java堆外缓存系统,所述系统包括:
缓存容器,用于提供调用方的缓存访问接口,根据接收到的请求类型,分别在本地存储库和内存中对待处理数据进行与所述请求类型对应的处理,以使所述本地存储库中存储的数据与所述内存中缓存的数据保持一致;
本地存储库,用于持久化存储缓存于所述内存中的数据,以在所述缓存容器宕机或重启后,为所述缓存容器提供初始化数据;
其中,缓存于所述内存中的数据和存储于所述本地存储库中的数据均以键值对方式存储,
所述内存中缓存的数据按照预设数据存储结构缓存,以使所述缓存容器在所述内存中对所述待处理数据进行处理时,根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理。
作为本发明进一步的改进,所述预设数据存储结构包括:
多个分段,每个分段有多个节点组成的节点数组,所述节点数组中的每个节点存储一个线性表的地址,第一键哈希值相同的数据存储于一个分段中;
线性表,一个分段内第二键哈希值相同的数据存储于同一个线性表中,所述线性表的数据结构包括实体个数和按顺序排列的多个实体地址,实体的数据结构包括过期时间、上一实体地址、下一实体地址、键长度、键内容、值长度和值内容;
双向访问链表,一个线性表的地址对应的所有实体组成一个双向访问链表,所述双向访问链表记录访问的实体顺序,并采用头插法将最新访问的实体插入至所述双向访问链表的头部。
作为本发明进一步的改进,所述根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理,包括:
根据第一键哈希值确定所述待处理数据的键所在的目标分段,其中,所述第一键哈希值根据所述待处理数据的键求哈希值得到;
根据第二键哈希值确定所述目标分段的目标节点中目标线性表的地址,其中,所述第二键哈希值根据所述第一键哈希值求哈希值得到;
根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
确定所述双向访问链表中是否存在所述待处理数据的键对应的当前实体,并在存在所述当前实体时,所述当前实体进行与所述请求类型对应的处理。
作为本发明进一步的改进,所述请求类型包括插入请求、查询请求和删除请求,所述待处理数据包括待缓存数据、待查询数据和待删除数据,
调用方的插入请求发送的插入数据包括基本类型和对象类型,当所述插入数据的类型是对象类型时,将所述插入数据序列化成字节数组得到所述待缓存数据,当所述待查询数据的类型是基本类型时,将所述待查询数据直接进行反变换后返回;
所述待查询数据的类型包括基本类型和对象类型,当所述待查询数据的类型是基本类型时,将所述待查询数据直接进行反变换后返回,当所述待查询数据的类型是对象类型时,将所述待查询数据反序列化后返回。
作为本发明进一步的改进,键的数据结构包括键长度和键内容,值的数据结构包括过期时间、值长度和值内容。
作为本发明进一步的改进,所述本地存储库采用KV存储引擎对数据进行存储。
作为本发明进一步的改进,所述缓存容器还用于定期清理所述内存中的过期数据。
本发明实施例还提供了一种可持久化的Java堆外缓存方法,缓存于内存中的数据和存储于本地存储库中的数据均以键值对方式存储,所述方法包括:
缓存容器根据缓存访问接口接收到的调用方的请求类型,分别在本地存储库和内存中对待处理数据进行与所述请求类型对应的处理,以使所述本地存储库中存储的数据与所述内存中缓存的数据保持一致,其中,所述内存中缓存的数据按照预设数据存储结构缓存,以使所述缓存容器在所述内存中对所述待处理数据进行处理时,根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理;
所述本地存储库持久化存储缓存于所述内存中的数据,以在所述缓存容器宕机或重启后,为所述缓存容器提供初始化数据。
作为本发明进一步的改进,所述请求类型包括插入请求、查询请求和删除请求,所述待处理数据包括待缓存数据、待查询数据和待删除数据,
当所述缓存容器接收到所述插入请求时,初始化所述缓存容器,在初始化成功后,所述缓存容器将所述待缓存数据存储于所述本地存储库中,并将所述待缓存数据缓存于所述内存中,所述待缓存数据由所述调用方发送的插入数据直接变换或序列化成字节数组得到;
当所述缓存容器接收到所述查询请求时,所述缓存容器从所述内存中查询所述待查询数据,得到查询结果,并将所述待查询数据直接反变换或反序列化后返回调用方;
当所述缓存容器接收到所述删除请求时,所述缓存容器从所述本地存储库中删除所述待删除数据,并从所述内存中删除所述待删除数据。
作为本发明进一步的改进,初始化所述缓存容器,包括:
S11,在所述缓存容器中创建实例;
S12,检查所述本地存储库是否存在数据,如果不存在,则结束流程,反之检查所述本地存储库中存储的数据是否过期,如果存在过期数据,则从所述本地存储库中删除过期数据,反之遍历所述本地存储库中存储的数据并将所述本地存储库中存储的数据依次填充至所述缓存容器;
S13,构造实体数据,调整双向访问链表中地址的引用关系,并采用头插法将构造的实体数据插入双向访问链表的头部,并将所述实体数据插入所述缓存容器中;
S14,重复S12-S13直至所述本地存储库中存储的数据遍历完毕。
作为本发明进一步的改进,所述缓存容器将所述待缓存数据存储于所述本地存储库中,并将所述待缓存数据缓存于所述内存中,包括:
S21,将所述待缓存数据存储在所述本地存储库中,如果在所述本地存储库中存储失败,直接返回失败状态并结束流程,反之执行S22;
S22,将所述待缓存数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待缓存数据的键所在的目标分段;
S23,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S24,确定所述目标线性表的地址是否为空,如果为空,则执行S26,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S25,确定所述待缓存数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则调整所述双向访问链表中地址的引用关系,将所述当前实体插入所述双向访问链表的头部,反之执行S26;
S26,在所述双向访问链表中构建所述当前实体,调整所述当前实体的地址引用关系使所述当前实体插入所述双向访问链表的头部,将所述当前实体的地址插入所述目标线性表的地址中,并将所述目标线性表的地址存储至所述目标节点中。
作为本发明进一步的改进,所述缓存容器从所述内存中查询待查询数据,得到查询结果,包括:
S31,将所述待查询数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待查询数据的键所在的目标分段;
S32,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S33,确定所述目标线性表的地址是否为空,如果为空,则返回空并结束流程,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S34,确定所述待查询数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则执行S35,反之返回空并结束流程;
S35,确定所述待查询数据的键对应的当前实体在所述双向访问链表中是否过期,如果过期,则将所述当前实体从所述双向访问链表中删除,并将所述当前实体的地址从所述目标线性表的地址中删除,并将所述当前实体的数据从所述本地存储库中删除,反之执行S36;
S36,调整所述当前实体的地址引用关系,将所述当前实体插入所述双向访问链表的头部,并返回查询结果。
作为本发明进一步的改进,所述缓存容器从所述本地存储库中删除所述待删除数据,并从所述内存中删除所述待删除数据,包括:
S41,删除所述本地存储库中存储的待删除数据,如果在所述本地存储库中删除失败,直接返回失败状态并结束流程,反之执行S42;
S42,将所述待删除数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待删除数据的键所在的目标分段;
S43,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S44,确定所述目标线性表的地址是否为空,如果为空,则返回空并结束流程,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S45,确定所述待删除数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则将所述当前实体从所述双向访问链表中删除,反之返回调用方并结束流程;
S46,将所述当前实体的地址从所述目标线性表的地址中删除。
作为本发明进一步的改进,在所述缓存容器初始化完成之后,
所述方法还包括:所述缓存容器定期清理所述内存中的过期数据,包括:
S51,从双向访问链表的尾部至头部方向遍历所述双向访问链表,依次确定所述双向访问链表中的各个实体是否过期,如果遍历过程中有当前实体过期,则执行S52,反之继续执行S51直至遍历完所述双向访问链表中的所有实体;
S52,调整所述双向访问链表中实体的地址引用关系,将所述当前实体从所述双向访问链表中删除;
S53,对所述当前实体的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述当前实体的键所在的目标分段,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S54,将所述当前实体的地址从所述目标线性表的地址中删除。
本发明实施例还提供了一种电子设备,包括存储器和处理器,所述存储器用于存储一条或多条计算机指令,其中,所述一条或多条计算机指令被处理器执行以实现所述的方法。
本发明实施例还提供了一种计算机可读存储介质,其上存储有计算机程序,所述计算机程序被处理器执行以实现所述的方法。
本发明的有益效果为:
能够高效的对缓存数据进行读写操作以及持久化存储,解决了缓存重启数据丢失的问题,以及高并发访问大体量缓存时频繁回收JVM垃圾,导致业务应用抖动的问题。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
需要说明,若本发明实施例中有涉及方向性指示(诸如上、下、左、右、前、后……),则该方向性指示仅用于解释在某一特定姿态(如附图所示)下各部件之间的相对位置关系、运动情况等,如果该特定姿态发生改变时,则该方向性指示也相应地随之改变。
另外,在本发明的描述中,所用术语仅用于说明目的,并非旨在限制本发明的范围。术语“包括”和/或“包含”用于指定所述元件、步骤、操作和/或组件的存在,但并不排除存在或添加一个或多个其他元件、步骤、操作和/或组件的情况。术语“第一”、“第二”等可能用于描述各种元件,不代表顺序,且不对这些元件起限定作用。此外,在本发明的描述中,除非另有说明,“多个”的含义是两个及两个以上。这些术语仅用于区分一个元素和另一个元素。结合以下附图,这些和/或其他方面变得显而易见,并且,本领域普通技术人员更容易理解关于本发明所述实施例的说明。附图仅出于说明的目的用来描绘本发明所述实施例。本领域技术人员将很容易地从以下说明中认识到,在不背离本发明所述原理的情况下,可以采用本发明所示结构和方法的替代实施例。
本发明实施例所述的一种可持久化的Java堆外缓存系统,所述系统包括:
缓存容器,用于提供调用方的缓存访问接口,根据接收到的请求类型,分别在本地存储库和内存中对待处理数据进行与所述请求类型对应的处理,以使所述本地存储库中存储的数据与所述内存中缓存的数据保持一致;
本地存储库,用于持久化存储缓存于所述内存中的数据,以在所述缓存容器宕机或重启后,为所述缓存容器提供初始化数据;
其中,缓存于所述内存中的数据和存储于所述本地存储库中的数据均以键值对方式存储,
所述内存中缓存的数据按照预设数据存储结构缓存,以使所述缓存容器在所述内存中对所述待处理数据进行处理时,根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理。
本发明提出一种缓存系统,有两个主要模块,分别是缓存容器和本地存储库。所述系统为一种支持Java堆外内存的缓存系统,通过缓存容器能高效的对内存中的缓存数据进行高效的读写操作,在高并发情况下,缓存容器的线程能安全访问,将内存数据存储至堆外内存,不影响JVM垃圾回收,解决了高并发访问大体量缓存时频繁回收垃圾,导致业务应用抖动的问题,同时本地存储库能持久化存储内存中的缓存数据,将数据持久化存储至磁盘,并支持快速重启,以在缓存容器的进程宕机或者重启后,为缓存容器提供初始化数据,解决了缓存重启数据丢失的问题。
本发明所述缓存容器提供缓存访问接口,即调用方可以根据该缓存访问接口来调用缓存容器的线程,读写性能高,微秒级的延迟。调用方的请求可以是插入请求,即插入数据至内存和本地存储库,此时待处理数据为待缓存数据;调用方的请求可以是查询请求,即查询内存中已有的缓存数据,此时待处理数据为待查询数据;调用方的请求可以是删除请求,即删除本地存储库和内存中的数据,此时待处理数据是待删除数据。由此可见,缓存容器可以维护内存中所有的缓存数据。调用方对缓存数据的增加和删除,本地存储库会同时进行相应的操作,以保持本地存储库和内存数据的严格一致性。
本发明所述内存中的数据是按照预设数据存储结构(即内存中数据的组织结构)进行存储的,在对待处理数据进行处理时,由于内存中的数据都是以键值对方式存储的,因此需要先根据该预设数据存储结构在内存中确定待处理数据的键对应的当前实体所在的目标位置,在确定出目标位置后,即可在该目标位置处执行相应的处理,例如是插入数据、查询数据或是删除数据。
一种可选的实施方式中,所述预设数据存储结构包括:
多个分段,每个分段有多个节点组成的节点数组,所述节点数组中的每个节点存储一个线性表的地址,第一键哈希值相同的数据存储于一个分段中;
线性表,一个分段内第二键哈希值相同的数据存储于同一个线性表中,所述线性表的数据结构包括实体个数和按顺序排列的多个实体地址,实体的数据结构包括过期时间、上一实体地址、下一实体地址、键长度、键内容、值长度和值内容;
双向访问链表,一个线性表的地址对应的所有实体组成一个双向访问链表,所述双向访问链表记录访问的实体顺序,并采用头插法将最新访问的实体插入至所述双向访问链表的头部。
下面将结合附图对本发明所述预设数据存储结构进行说明。
(1)分段
如图1所示,包括多个分段,例如Segment-1(分段1)、Segment-2(分段2)、Segment-3(分段3)、……、Segment-n(分段n),分段的数量n不做具体限制,每个分段中存储key hash值相同的数据,该key hash值作为第一键哈希值,是对数据的key计算hash值得到的。
每个分段内部有个节点数组,节点数组包括多个节点,例如Segment-1中包括Node-1(节点1)、Node-2(节点2)、……、Node-k(节点k)组成的节点数组,Segment-n中包括Node-1(节点1)、Node-2(节点2)、……、Node-k(节点k)组成的节点数组,本发明对节点的数量k不做具体限定。节点的数量k根据如下公式计算:k=argmin(max{2^k,capacity/factor}),k为大于或等于1的整数,其中,capacity是分段存储容量,根据内存的总容量处理分段个数得到,例如可以将分段个数默认设置为16,根据实际的业务应用需求进行调整,factor是预设的负载因子。
一个节点中存储一个线性表的地址,例如Segment-1的Node-1中存储一个Table(线性表)的地址,该线性表的地址包括entry add-1(实体1的地址)、entry add-2(实体2的地址)、……、entry add-i(实体i的地址),Segment-n的Node-k中存储一个Table(线性表)的地址,该线性表的地址包括entry add-1(实体1的地址)、entry add-2(实体2的地址)、……、entry add-j(实体j的地址)。每一类数据对象的个体被作为一个实体。
(2)线性表
如前述,分段内的数据做了第一次哈希运算,节点是将分段的数据按照key进一步计算hash值,得到第二键哈希值,两次哈希计算可以降低key的冲突。一个分段内key hash值相同的数据存储在一个线性表中。
线性表的数据结构包括实体个数(4个字节)和按顺序排列的多个实体地址(例如:实体1地址(8个字节)、实体2地址(8个字节)、……、实体i地址(8个字节)),占用内存大小为:4+8*i字节,i为实体个数,实体个数不做具体限制。
实体的数据结构包括过期时间(4个字节)、prev实体地址(8个字节)、next实体地址(8个字节)、key长度(4个字节)、key内容、value长度(4个字节)和value内容。
由此可见,本发明所述缓存容器在缓存数据时,支持key的过期时间设置,使得在初始化缓存容器后,所述缓存容器还可以定期清理内存中的过期数据。所述缓存容器支持LRU逐出策略,定期对缓存数据进行清理,可以节约内存,快速释放掉不必要的内存占用,同时能较好的支持用户更多的应用场景,提高应用系统的速度。
(3)双向访问链表
双向访问链表是记录访问实体顺序的链表,一个线性表中实体的数据结构存储了前后实体的地址,将一个线性表中的所有实体组成一个双向访问链表。如图2所示,双向访问链表的header(头部)和tail(尾部),头部和尾部之间记录有entry data-1(实体1)、entry data-2(实体2、……、entry data-m(实体m)的访问顺序。当有最新访问的实体时,利用头插法将最新访问的实体插入双向访问链表的最前端即头部。例如,在初始化缓存容器构造实体时,缓存待缓存数据插入实体时,将实体插入双向访问链表的头部。
本发明对缓存容器缓存的数据结构和双向访问链表的结构进行了设计,节省了数据存储的内存空间,分段的数据结构设计,可以进一步提高在高并发访问时的性能。
一种可选的实施方式,所述根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理,包括:
根据第一键哈希值确定所述待处理数据的键所在的目标分段,其中,所述第一键哈希值根据所述待处理数据的键求哈希值得到;
根据第二键哈希值确定所述目标分段的目标节点中目标线性表的地址,其中,所述第二键哈希值根据所述第一键哈希值求哈希值得到;
根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
确定所述双向访问链表中是否存在所述待处理数据的键对应的当前实体,并在存在所述当前实体时,所述当前实体进行与所述请求类型对应的处理。
由于所述内存中数据按照预设数据存储结构进行缓存,在确定目标位置时,先根据待处理数据(待缓存数据/待查询数据/待删除数据)的键的哈希值(即第一键哈希值),从多个分段中确定出目标分段;再根据第二键哈希值,从目标分段中确定出目标节点(该目标节点中存储有目标线性表的地址);确定出目标节点后,即可根据目标线性表的地址(该目标线性表的地址包括多个实体地址)获取对应的多个实体;获取多个实体后,即可在双向访问链表中确定待处理数据的键对应的当前实体,双向访问链表中确定出的当前实体对应的位置即为目标位置,此后即可对当前实体执行对应的操作,例如缓存待缓存数据的键对应的当前实体,或者是查询待查询数据的键对应的当前实体,或者是删除待删除数据的键对应的当前实体。
一种可选的实施方式中,所述请求类型包括插入请求、查询请求和删除请求,所述待处理数据包括待缓存数据、待查询数据和待删除数据,
调用方的插入请求发送的插入数据包括基本类型和对象类型,当所述插入数据的类型是对象类型时,将所述插入数据序列化成字节数组得到所述待缓存数据,当所述待查询数据的类型是基本类型时,将所述待查询数据直接进行反变换后返回;
所述待查询数据的类型包括基本类型和对象类型,当所述待查询数据的类型是基本类型时,将所述待查询数据直接进行反变换后返回,当所述待查询数据的类型是对象类型时,将所述待查询数据反序列化后返回。
本发明所述缓存容器将缓存数据以键值对方式缓存,对待缓存数据的键(key)和值(value)支持基本类型和自定义对象类型,内存内部会将键(key)和值(value)变换或序列化成字节数组后存储于内存中,并在调用方读取内存中的缓存数据时,根据数据类型进行反变换或反序列化成对象。所述缓存容器支持Key和Value的序列化和反序列化。其中,基本类型是指Java语言中的基本数据类型,例如:byte(位)、short(短整数)、int(整数)、long(长整数)、float(单精度)、double(双精度)、char(字符)和boolean(布尔值)等数据类型。对象类型是指Java语言中自定义类的类型,也是一种数据结构类型,例如,class Person{
private String name;
private int age;
private long id;
}
所述本地存储库负责持久化缓存数据,本地存储库中的数据以键值对方式存储,并且键(key)和值(value)都支持对象的序列化和反序列化。也就是说,对于调用方的插入数据:key的数据类型是基本类型时,直接转换成字节数组,key的数据类型是对象类型时,序列化成字节数组;value的数据类型基本类型时,直接转换成字节数组,value的数据类型是对象类型时,序列化成字节数组。相应的,对于待查询数据:key的数据类型是基本类型时,直接对字节数组进行反变换,key的数据类型是对象类型时,对字节数组进行反序列化;value的数据类型是基本类型时,直接对字节数组进行反变换,value的数据类型是对象类型时,对字节数组进行反序列化。可以理解的是,所述本地存储库与所述缓存容器的序列化、反序列化机制一样。
上述直接变换是指,将上述基本类型的数据用对应的字节来表示,例如将byte、boolean类型用1个字节表示,short 、char类型用2个字节表示,int、float类型用4个字节表示,double、long 用8个字节 表示等,相应的,反变换将字节表示的数据转换成相应基本类型的数据。上述序列化是指,将上述对象类型的数据转化成字节流,相应的,反序列化表示将字节流还原成对象。
一种可选的实施方式中,缓存于所述内存中的数据和存储于所述本地存储库中的数据均以键值对方式存储,
其中,键的数据结构包括键长度和键内容,值的数据结构包括过期时间、值长度和值内容。
key的数据结构:包括key长度和key内容;
value的数据结构:过期时间(4个字节),value长度(4个字节)和value内容。
由此可见,本发明所述内存和所述本地存储库在存储数据时,支持value的过期时间设置,使得本地存储库可定期对存储的过期数据进行清理。
一种可选的实施方式中,所述本地存储库采用KV存储引擎对数据进行存储。
本发明所述本地存储库采用KV存储引擎作为缓存数据的持久化存储引擎,例如,开源的rocksdb等。采用KV存储引擎对缓存数据进行持久化,能够防止因系统重启导致内存缓存数据丢失。KV存储引擎和缓存容器数据结构一致,能够快速的数据写入以及对丢失数据进行回放,读写效率都比较高。
一种可选的实施方式中,所述缓存容器还用于定期清理所述内存中的过期数据。
本发明对过期数据的清理机制以及双向访问链表的设置,可以进一步节省存储空间,同时还提升了过期数据清理的性能。
本发明实施例所述的一种可持久化的Java堆外缓存方法,采用前述实施方式所述的系统,缓存于内存中的数据和存储于本地存储库中的数据均以键值对方式存储,所述方法包括:
缓存容器根据缓存访问接口接收到的调用方的请求类型,分别在本地存储库和内存中对待处理数据进行与所述请求类型对应的处理,以使所述本地存储库中存储的数据与所述内存中缓存的数据保持一致,其中,所述内存中缓存的数据按照预设数据存储结构缓存,以使所述缓存容器在所述内存中对所述待处理数据进行处理时,根据所述待处理数据的键,在所述内存中确定所述待处理数据的键对应的当前实体所在的目标位置,并在所述目标位置对所述当前实体进行与所述请求类型对应的处理;
所述本地存储库持久化存储缓存于所述内存中的数据,以在所述缓存容器宕机或重启后,为所述缓存容器提供初始化数据。
一种可选的实施方式中,所述请求类型包括插入请求、查询请求和删除请求,所述待处理数据包括待缓存数据、待查询数据和待删除数据,
当所述缓存容器接收到所述插入请求时,初始化所述缓存容器,在初始化成功后,所述缓存容器将所述待缓存数据存储于所述本地存储库中,并将所述待缓存数据缓存于所述内存中,所述待缓存数据由所述调用方发送的插入数据直接变换或序列化成字节数组得到;
当所述缓存容器接收到所述查询请求时,所述缓存容器从所述内存中查询所述待查询数据,得到查询结果,并将所述待查询数据直接反变换或反序列化后返回调用方;
当所述缓存容器接收到所述删除请求时,所述缓存容器从所述本地存储库中删除所述待删除数据,并从所述内存中删除所述待删除数据。
一种可选的实施方式中,初始化所述缓存容器,包括:
S11,在所述缓存容器中创建实例;
S12,检查所述本地存储库是否存在数据,如果不存在,则结束流程,反之检查所述本地存储库中存储的数据是否过期,如果存在过期数据,则从所述本地存储库中删除过期数据,反之遍历所述本地存储库中存储的数据并将所述本地存储库中存储的数据依次填充至所述缓存容器;
S13,构造实体数据,调整双向访问链表中地址的引用关系,并采用头插法将构造的实体数据插入双向访问链表的头部,并将所述实体数据插入所述缓存容器中;
S14,重复S12-S13直至所述本地存储库中存储的数据遍历完毕。
一种可选的实施方式中,所述缓存容器将所述待缓存数据存储于所述本地存储库中,并将所述待缓存数据缓存于所述内存中,包括:
S21,将所述待缓存数据存储在所述本地存储库中,如果在所述本地存储库中存储失败,直接返回失败状态并结束流程,反之执行S22;
S22,将所述待缓存数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待缓存数据的键所在的目标分段;
S23,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S24,确定所述目标线性表的地址是否为空,如果为空,则执行S26,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S25,确定所述待缓存数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则调整所述双向访问链表中地址的引用关系,将所述当前实体插入所述双向访问链表的头部,反之执行S26;
S26,在所述双向访问链表中构建所述当前实体,调整所述当前实体的地址引用关系使所述当前实体插入所述双向访问链表的头部,将所述当前实体的地址插入所述目标线性表的地址中,并将所述目标线性表的地址存储至所述目标节点中。
一种可选的实施方式中,所述缓存容器从所述内存中查询待查询数据,得到查询结果,包括:
S31,将所述待查询数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待查询数据的键所在的目标分段;
S32,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S33,确定所述目标线性表的地址是否为空,如果为空,则返回空并结束流程,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S34,确定所述待查询数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则执行S35,反之返回空并结束流程;
S35,确定所述待查询数据的键对应的当前实体在所述双向访问链表中是否过期,如果过期,则将所述当前实体从所述双向访问链表中删除,并将所述当前实体的地址从所述目标线性表的地址中删除,并将所述当前实体的数据从所述本地存储库中删除,反之执行S36;
S36,调整所述当前实体的地址引用关系,将所述当前实体插入所述双向访问链表的头部,并返回查询结果。
一种可选的实施方式中,所述缓存容器从所述本地存储库中删除所述待删除数据,并从所述内存中删除所述待删除数据,包括:
S41,删除所述本地存储库中存储的待删除数据,如果在所述本地存储库中删除失败,直接返回失败状态并结束流程,反之执行S42;
S42,将所述待删除数据的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述待删除数据的键所在的目标分段;
S43,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S44,确定所述目标线性表的地址是否为空,如果为空,则返回空并结束流程,反之遍历所述目标线性表的地址,根据所述目标线性表的地址中存储的多个实体地址,获取所述多个实体地址对应的实体;
S45,确定所述待删除数据的键对应的当前实体在双向访问链表中是否存在,如果存在,则将所述当前实体从所述双向访问链表中删除,反之返回调用方并结束流程;
S46,将所述当前实体的地址从所述目标线性表的地址中删除。
一种可选的实施方式中,在所述缓存容器初始化完成之后,
所述方法还包括:所述缓存容器定期清理所述内存中的过期数据,包括:
S51,从双向访问链表的尾部至头部方向遍历所述双向访问链表,依次确定所述双向访问链表中的各个实体是否过期,如果遍历过程中有当前实体过期,则执行S52,反之继续执行S51直至遍历完所述双向访问链表中的所有实体;
S52,调整所述双向访问链表中实体的地址引用关系,将所述当前实体从所述双向访问链表中删除;
S53,对所述当前实体的键求哈希值得到第一键哈希值,并根据所述第一键哈希值确定所述当前实体的键所在的目标分段,将所述第一键哈希值求哈希值得到第二键哈希值,并根据所述第二键哈希值确定所述目标分段的目标节点中目标线性表的地址;
S54,将所述当前实体的地址从所述目标线性表的地址中删除。
本公开还涉及一种电子设备,包括服务器、终端等。该电子设备包括:至少一个处理器;与至少一个处理器通信连接的存储器;以及与存储介质通信连接的通信组件,所述通信组件在处理器的控制下接收和发送数据;其中,存储器存储有可被至少一个处理器执行的指令,指令被至少一个处理器执行以实现上述实施例中的方法。
在一种可选的实施方式中,存储器作为一种非易失性计算机可读存储介质,可用于存储非易失性软件程序、非易失性计算机可执行程序以及模块。处理器通过运行存储在存储器中的非易失性软件程序、指令以及模块,从而执行设备的各种功能应用以及数据处理,即实现方法。
存储器可以包括存储程序区和存储数据区,其中,存储程序区可存储操作系统、至少一个功能所需要的应用程序;存储数据区可存储选项列表等。此外,存储器可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他非易失性固态存储器件。在一些实施例中,存储器可选包括相对于处理器远程设置的存储器,这些远程存储器可以通过网络连接至外接设备。上述网络的实例包括但不限于互联网、企业内部网、局域网、移动通信网及其组合。
一个或者多个模块存储在存储器中,当被一个或者多个处理器执行时,执行上述任意方法实施例中的方法。
上述产品可执行本申请实施例所提供的方法,具备执行方法相应的功能模块和有益效果,未在本实施例中详尽描述的技术细节,可参见本申请实施例所提供的方法。
本公开还涉及一种计算机可读存储介质,用于存储计算机可读程序,所述计算机可读程序用于供计算机执行上述部分或全部的方法实施例。
即,本领域技术人员可以理解,实现上述实施例方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,该程序存储在一个存储介质中,包括若干指令用以使得一个设备(可以是单片机,芯片等)或处理器(processor)执行本申请各实施例所述方法的全部或部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(ROM,Read-OnlyMemory)、随机存取存储器(RAM,Random Access Memory)、磁碟或者光盘等各种可以存储程序代码的介质。
在此处所提供的说明书中,说明了大量具体细节。然而,能够理解,本发明的实施例可以在没有这些具体细节的情况下实践。在一些实例中,并未详细示出公知的方法、结构和技术,以便不模糊对本说明书的理解。
此外,本领域普通技术人员能够理解,尽管在此所述的一些实施例包括其它实施例中所包括的某些特征而不是其它特征,但是不同实施例的特征的组合意味着处于本发明的范围之内并且形成不同的实施例。所要求保护的实施例的任意之一都可以以任意的组合方式来使用。
本领域技术人员应理解,尽管已经参考示例性实施例描述了本发明,但是在不脱离本发明的范围的情况下,可进行各种改变并可用等同物替换其元件。另外,在不脱离本发明的实质范围的情况下,可进行许多修改以使特定情况或材料适应本发明的教导。因此,本发明不限于所公开的特定实施例,而是本发明将包括落入所附权利要求范围内的所有实施例。