缓存数据的方法、设备及存储介质
技术领域
本申请涉及内存管理技术领域,尤其涉及一种缓存数据的方法、设备及存储介质。
背景技术
目前,主流的终端应用程序的服务器部署在数据中心,每台服务器主机处理高达数万QPS(Queries-per-second,每秒查询率)的数据请求,并且需要在尽量短的时间内返回结果。为了优化服务性能,避免频繁访问外部存储设备(如数据库、缓存集群等),服务端应用程序将频繁被访问的访问对象数据缓存到内存,以便从内存中查询该访问对象数据。服务器内存空间有限,当有新的访问对象出现时,需要按照预定的策略选择内存中的访问对象数据进行替换。
ARC(Adaptive replacement cache,自适应替换缓存)逐出算法应用场景一般是单机的文件系统或者数据库系统,其缓存的每个对象大小相同,当需要写入一个新对象时,挑选一个旧对象逐出时即可。
但是,ARC算法将申请的大片内存切割成等大小的分页,每个分页用来写入一个缓存对象,但这样需要将分页设置的尽量大以容纳最大的缓存项,这会造成内存空间浪费。
发明内容
本申请实施例提供一种缓存数据的方法、设备及存储介质,以减小写入缓存数据所造成的空间资源浪费问题。
第一方面,本申请实施例提供一种缓存数据的方法,该方法包括:
针对需要在设备内存中写入应用程序的访问对象数据,确定所述访问对象数据所需占用的缓存空间的分页数量,所述缓存空间为所述设备内存的部分存储空间,所述缓存空间被划分为多个大小相等的分页;
根据所述访问对象数据所需占用的缓存空间的分页数量,从所述缓存空间未被占用的分页中确定分配给所述访问对象数据的可用分页;
将所述访问对象数据写入所述可用分页。
第二方面,本申请实施例提供一种缓存数据的方法,该方法包括:
确定需要修改设备内存中缓存的应用程序的访问记录;
根据缓存在所述设备内存中的访问对象数据的被访问状态修改所述应用程序的访问记录,所述访问记录的数据结构包括访问记录数组、元素索引集合和映射关系集合:
所述访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,所述特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
所述元素索引集合保存有所述访问记录数组中未被占用的元素的索引;
所述映射关系集合中关联保存访问对象数据的特定关键字和所述访问对象数据的特定关键字在访问记录数组中的元素索引。
第三方面,本申请实施例提供一种电子设备,所述电子设备包括:
所需缓存空间确定模块,用于针对需要在设备内存中写入应用程序的访问对象数据,确定所述访问对象数据所需占用的缓存空间的分页数量,所述缓存空间为所述设备内存的部分存储空间,所述缓存空间被划分为多个大小相等的分页;
可用分页确定模块,用于根据所述访问对象数据所需占用的缓存空间的分页数量,从所述缓存空间未被占用的分页中确定分配给所述访问对象数据的可用分页;
访问对象数据写入模块,用于将所述访问对象数据写入所述可用分页。
第四方面,本申请实施例提供一种电子设备,所述电子设备包括:
访问记录修改确定模块,用于确定需要修改设备内存中缓存的应用程序的访问记录;
访问记录修改执行模块,用于根据缓存在所述设备内存中的访问对象数据的被访问状态修改所述应用程序的访问记录,所述访问记录的数据结构包括:
访问记录数组,所述访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,所述特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
元素索引集合,所述元素索引集合保存有所述访问记录数组中未被占用的元素的索引;
映射关系集合,所述映射关系集合中关联保存访问对象数据的特定关键字和所述访问对象数据的特定关键字在访问记录数组中的元素索引。
第五方面,本申请实施例提供一种电子设备,包括处理器和存储器;
所述存储器用于存储执行上述缓存数据的方法的程序;
所述处理器被配置为执行所述存储器中存储的程序。
第六方面,本申请实施例提供一种计算机可读存储介质,存储有执行上述缓存数据的方法的程序。
本发明实施例提供的一种缓存数据的方法、设备及存储介质,与传统的每个分页用来写入一个缓存对象不同,本实施例在获取到访问对象数据之后,根据访问对象数据的大小确定所需占用的分页数量,然后为访问对象数据分配对应数量的分页,以使得访问对象数据可以写入到缓存空间中,即本实施例缓存空间被划分为多个分页,写入访问对象数据时,可以根据访问对象数据的数据量分配不同数量的分页,以满足不同大小的访问数据的缓存需求,从而减少了写入缓存数据所造成的空间资源浪费。
附图说明
图1为本申请一个实施例提供的缓存数据的方法流程图;
图2为本申请一个实施例提供的缓存空间级联分页示意图;
图3为申请另一个实施例提供的缓存数据的方法流程图;
图4为本申请一个实施例提供的电子设备的框图;
图5为本申请另一个实施例提供的电子设备的框图;
图6为本申请一个实施例提供的电子设备结构示意图。
具体实施方式
为了更好的理解上述技术方案,下面通过附图以及具体实施例对本申请实施例的技术方案做详细的说明,应当理解本申请实施例以及实施例中的具体特征是对本申请实施例技术方案的详细的说明,而不是对本申请技术方案的限定,在不冲突的情况下,本申请实施例以及实施例中的技术特征可以相互组合。
本申请实施例提供的方法应用在服务器的服务端应用程序上,也可以应用在终端设备上的应用程序。如图1所示,本申请实施例提供的缓存数据的方法包括如下操作:
步骤101、针对需要在设备内存中写入应用程序的访问对象数据,确定该访问对象数据所需占用的缓存空间的分页数量。
其中,缓存空间为设备内存的部分存储空间,用于缓存应用程序的多个访问对象数据,缓存空间被划分为多个大小相等的分页。具体的,根据访问对象数据的大小和分页大小确定所需占用的缓存空间的分页数量。例如,访问对象数据所需要的存储空间为100M,每个分页的大小为50M,则访问对象数据需要占用的缓存空间的分页数量为2。
其中,应用程序的访问对象可以但不仅限于包括:网页、视频、图片、文本。应用程序的访问对象数据可以但不仅限于包括访问对象的关键字(访问对象关键字,KEY)和关键字取值(VALUE)。
若本方法应用在服务端应用程序,设备内存即服务器内存,若本方法应用在客户端应用程序,设备内存即终端设备内存。
本申请不对写入访问对象数据的判断条件进行限定,实际应用中可以根据需要配置。例如,当在一定时间内对该访问对象数据的访问次数达到设定次数,则需要将其写入设备内存。实际应用中,应用程序可以通过主动检测的方式确定是否需要写入访问对象数据,进而执行步骤101,也可以响应写入请求而执行步骤101。
步骤102、根据上述访问对象数据所需占用的缓存空间的分页数量,从缓存空间未被占用的分页中确定分配给该访问对象数据的可用分页。
其中,可用分页的数量不少于访问对象数据所需占用的缓存空间的分页数量。
步骤103、将上述访问对象数据写入上述可用分页。
本发明实施例提供的一种缓存数据的方法,与传统的每个分页用来写入一个缓存对象不同,本实施例在获取到访问对象数据之后,根据访问对象数据的大小确定所需占用的分页数量,然后为访问对象数据分配对应数量的分页,以使得访问对象数据可以写入到缓存空间中,即本实施例缓存空间被划分为多个分页,写入访问对象数据时,可以根据访问对象数据的数据量分配不同数量的分页,以满足不同大小的访问数据的缓存需求,从而减少了写入缓存数据所造成的空间资源浪费。
本申请实施例不对申请缓存空间的时机进行限定,作为举例而非限定,可以在应用程序启动时申请缓存空间,也可以在应用程序运行过程中首次写入访问对象数据时申请。具体的,可以根据配置的分页大小(Page Size)和分页数量(Page Num)计算缓存空间大小(Page Size*Page Num),其中,分页大小和分页数量根据需要以及内存空间大小等来确定;调用make函数申请缓存空间(cacheMem)。
可选的,还可以创建页标识集合来保存缓存空间中未被占用的分页。本申请实施例不对页标识集合的具体实现形式进行限定,作为举例而非限定,页标识集合可以采用数组来实现。那么,在上述步骤102中,具体可以根据上述访问对象数据所需占用的缓存空间的分页数量,从页标识集合中确定分配给该访问对象数据的可用分页的页标识。相应的,上述步骤103中,根据可用分页的页标识在缓存空间中查找可用分页,并将上述访问对象数据写入可用分页。其中,分页的页标识可以但不仅限于包括页编号(pageIndex)。
上述处理过程中,若缓存空间中未被占用的分页数量小于待写入的访问对象数据所需占用的分页数量,那么可以按照预定的策略从缓存空间中删除已写入的访问对象数据,从而释放缓存空间的分页,直至未被占用的分页数量满足待写入的访问对象所需占用的分页数量要求。实际应用中,可以采用不同的逐出算法,每个逐出算法均有自己的逐出策略。作为举例而非限定,本申请实施例提供的方法可以借鉴ARC(Adaptive ReplacementCache,自适应替换缓存)算法,以提高缓存命中率。
上述处理过程中,将访问对象数据写入可用分页的实现方式有多种,例如,按照分页大小对访问对象数据进行切分,切分得到的每部分数据分配一个可用分页,按照数据的顺序保存可用分页的页标识,具体的,将访问对象数据的KEY(或者其散列运算值)与顺序保存的分页的页标识关联保存。又例如,将该访问对象数据按照指定顺序级联保存到可用分页。通过级联保存的方式,一方面可以高效利用内存资源,避免内存资源的浪费,另一方面便于快速查询读取数据,有助于提高数据读取效率。
作为举例而非限定,在一种级联保存的实现方式中,每个分页被划分为至少两部分,其中一部分(例如头部字节)用于保存下一个分页的页标识,最后一个可用分页的这部分(例如头部字节)用于保存终结符,另一部分用于保存访问对象数据。
若在可用分页中通过级联的方式保存访问对象数据,本申请实施例提供的方法还可以关联保存上述访问对象数据的特定关键字和该访问对象数据对应的目标信息集合,以便查询该访问对象数据。其中,特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;目标信息集合包括上述可用分页中的首个分页的页标识和访问对象数据的元信息。
作为举例而非限定,可以通过字典(MAP)结构来关联保存上述访问对象数据的特定关键字和该访问对象数据对应的目标信息集合,相应的,特定关键字作为字典的关键字,目标信息集合作为字典的关键字取值。其中,访问对象关键字的散列运算值可以但不仅限于是哈希(HASH)值,例如MD5值等等。其中,保存到目标信息集合中的元信息可以但不仅限于包括访问对象关键字的长度、缓存对象关键字取值的长度。其中,目标信息集合可以但不仅限于由不超过设定长度的结构体(struct)实现。
假设设备内存中缓存有3个访问对象数据,其中一个访问对象数据占用缓存空间中的页标识为0、2、5的分页,另一个访问对象数据占用缓存空间中的页标识为1、7的分页,最后一个访问对象数据占用缓存空间中的页标识为6、8的分页。那么,如下表1所示,在对应的字典中,一个访问对象的特定关键字1关联于缓存空间中的分页0,另一个访问对象数据的特定关键字2关联于缓存空间中的分页1,最后一个访问对象数据的特定关键字3关联于缓存空间中的分页6。
特定关键字1 |
0 |
特定关键字2 |
1 |
特定关键字3 |
6 |
…… |
…… |
表1
这三个访问对象数据在缓存空间中的级联存储方式如图2所示,其中,
在分页0、2、5中保存有第一个访问对象数据,且在分页0的头部字节保存有分页2的页标识,在分页2的头部字节保存有分页5的页标识,在分页5的头部字节保存有截止符;在分页1和7中保存有第二个访问对象数据,且在分页1的头部字节保存有分页7的页标识,在分页7的头部字节保存有截止符;在分页6和8中保存有第三个访问对象数据,且在分页6的头部字节保存有分页8的页标识,在分页8的头部字节保存有截止符。
图2所示的缓存空间中,分页3和4未被占用,因此在表2所示的页标识集合中保存有分页3和分页4的页标识:
表2
现有技术中,为便于查询访问对象数据,将访问对象数据中的关键字和关键字取值关联保存,而访问对象数据中的关键字和关键字取值中都引入了指针。在对缓存数据执行垃圾回收操作时,会对包含指针的数据进行扫描。那么,当关联保存的关键字和关键字取值数量增加,垃圾回收的耗时也会增加,内存性能下降。本申请实施例提供的方法将访问对象数据的关键字的散列运算值和可用分页的首个分页的页标识以及访问对象数据的元信息关联保存,既可以用于查询该访问对象数据,又没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。另外,由于访问对象数据通过级联的方式保存到可用分页中,因此,仅需要将可用分页中的首个分页的页标识关联保存,即可查找到完整的访问对象数据。
除了对访问对象数据进行写入操作,还可以对访问对象数据进行读取、删除、更新等操作。
在上述任意方法实施例的基础上,当需要读取已写入上述可用分页的上述访问对象数据,本申请实施例提供的方法还可以将该访问对象数据从该可用分页复制到复制存储空间,其中,复制存储空间为预先申请的设备内存的部分存储空间,供多个被读取的访问对象数据复用。
具体实现中,给调用方提供一个参数来传入空的byte slice(字节分片,即复制存储空间),当其大小够存放访问对象数据时,将访问对象数据复制到其中返回给调用者。调用者在读取多个缓存项时,仅需要在第一次读取时调用Make函数创建byte slice,后续调用者复用这个byte slice降低耗时。
在现有的从内存读取数据的过程中,需要首先申请内存空间,以用于复制需要读取的数据,其中,申请内存空间的耗时较长。本申请实施例提供的方法,预先申请复制存储空间,当需要读取访问对象数据时,在读取过程中不需要再申请内存空间,而是复用预先申请的复制存储空间,可降低读取过程的耗时。在高并发场景下,采用本申请实施例提供的方法,可有效降低从内存读取数据过程的耗时,从而降低响应时延、提高内存读写性能。
若关联保存有上述访问对象数据的特定关键字和该访问对象数据对应的目标信息集合,相应的,当需要读取已写入上述可用分页的上述访问对象数据,根据该关联关系查找到保存访问对象数据的首个分页的页标识,在缓存空间中查找该页标识对应的分页,根据分页中保存的下一个分页的页标记,依次读取每个分页中的数据,直至读取到截止符。
将上述访问对象数据从可用分页复制到复制存储空间后,从所述复制存储空间读取所述访问对象数据之后,归还所述复制存储空间;判断空闲的所述复制存储空间的数量是否超出阈值;如果超出所述阈值,则释放所述复制存储空间。在本实施例中,预先申请一些复制存储空间,读取缓存时取得一个复制存储空间将内容复制进去,然后调用者处理里面的数据,然后归还这片空间,然后接着调用,如此读取完100个缓存项,只用同一块空间,实现了空间复用。并且在没有待读取的访问对象数据的情况下释放复制存储空间,可以有效避免内存资源的浪费,提高内存使用效率。
若关联保存有上述访问对象数据的特定关键字和该访问对象数据对应的目标信息集合,相应的,当需要删除已写入上述可用分页的上述访问对象数据,根据该关联关系查找到保存访问对象数据的首个分页的页标识,在缓存空间中查找该页标识对应的分页,根据分页中保存的下一个分页的页标记,依次删除每个分页中的数据,直至读取到截止符;将删除的访问对象数据占用的分页的页标识添加到页标识集合中,完成分页回收。
在上述任意方法实施例的基础上,本申请实施例提供的方法还可以确定外部设备保存的上述访问对象数据已更新,则从该外部设备获取该访问对象数据的更新数据;利用该更新数据更新已写入可用分页的该访问对象数据。
一个实施例中,可以接收来自消息队列的数据更新消息,如果数据更新消息指示的访问对象数据已经缓存在设备内存中,则从外部设备获取更新数据对写入设备内存的访问对象数据进行更新。另一个实施例中,可以主动检测外部设备存储的访问对象数据是否发生更新,若更新,从外部设备获取更新数据对写入设备内存的访问对象数据进行更新。
本申请实施例中,外部设备可以但不仅限于是缓存集群、数据库等。
目前的应用程序往往以集群的形式运行,不同设备上的应用程序共享一个更底层的外部设备(比如数据库或外部缓存集群),当设备内存缓存的访问对象数据在外部设备被更新时,需要让设备内存中缓存的访问对象数据及时更新。本申请实施例提供的方法可以通过主动检测或根据接收到的更新消息来确定外部设备保存的上述访问对象数据已更新,进而对设备内存中缓存的该访问对象数据进行更新,保持访问对象数据的同步。
在上述任意方法实施例的基础上,当需要对上述访问对象数据进行目标操作,还可以按照预定的映射规则查找与该访问对象数据所包含的关键字对应的内存分片(shard),其中,设备内存被划分为多个内存分片,每个内存分片分别绑定有读写锁;对查找到的内存分片的读写锁进行加锁处理以便对该访问对象数据进行上述目标操作,其中,目标操作可以包括以下任意一种:写入操作、读取操作、删除操作、更新操作。
当完成目标操作,释放读写锁。
每次内存读写操作需要拿锁,高并发场景下,锁竞争导致多线程不能很好地并行执行,内存缓存反而可能会成为性能瓶颈。本申请实施例提供的方法通过将锁粒度从内存级别降低到分片级别,拿锁时成功的概率大大增加,可有效降低锁竞争的时间成本,降低锁竞争导致的内存读写性能下降问题。
实际应用中,预先将设备内存划分为2n个分片(shard),对于待进行目标操作的访问对象数据,对其访问对象关键字进行散列运算(例如哈希运算)得到散列运算值,将散列运算值与2n-1做按位与运算,即可确定对应的内存分片。
应当指出的是,除了上述基于散列运算的映射规则,实际应用中,还可以配置其他映射规则来建立访问对象数据与内存分片的映射关系,本申请对此不作限定。
在上述任意方法实施例的基础上,本申请实施例提供的方法还可以根据上述访问对象数据的被访问状态修改应用程序的访问记录,该访问记录缓存在设备内存中,其数据结构包括:
访问记录数组,该访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,其中,特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
元素索引集合,该元素索引集合保存有访问记录数组中未被占用的元素的索引;
映射关系集合,该映射关系集合中关联保存访问对象数据的特定关键字和该访问对象数据的特定关键字在访问记录数组中的元素索引。
其中,元素索引集合可以但不仅限于由数组实现。其中,映射关系集合可以但不仅限于由字典(map)实现,相应的,字典的关键字为访问对象数据的特定关键字,字典的关键字取值为访问对象数据的特定关键字在访问记录数组中的元素索引。
其中,被访问状态可以但不仅限于:当前被访问、被访问的频率状态、最后一次被访问的时间状态等等。本申请实施例对此不作限定,实际应用中,可以根据不同的逐出算法确定被访问状态。
以ARC算法为例,访问记录通过LRU(Least Recently Used,最近最少使用)链表维护,现有的LRU由字典和双向链表来实现。本申请实施例提供的数据结构中,由访问记录数组来模拟实现双向链表,访问记录数组的元素可以但不仅限于由结构体实现,该结构体包括prev、next、value三个字段,其中,第一索引字段(prev)保存该元素的前一个节点元素(该元素中的特定关键字的前序访问对象数据的特定关键字所在元素)在访问记录数组中的索引,第二索引字段(next)保存该元素的下一个节点元素(该元素中的特定关键字的后序访问对象数据的特定关键字所在元素)在访问记录数组中的索引,关键值字段(value)保存访问对象数据的特定关键字。
如表3所示,假设字典(map)中保存有两个访问对象数据的特定关键字和对应的元素索引:
表3
其中,访问对象数据A的特定关键字为5,在访问记录数组中的元素索引为2,访问对象数据B的特定关键字为8,在访问记录数组中的元素索引为5。
访问记录数组由7个元素组成,基于表3所示的字典,访问记录数组如表4所示:
|
头 |
尾 |
|
|
|
|
|
Prev |
- |
5 |
0 |
|
|
2 |
|
Value |
|
|
5 |
未占用 |
未占用 |
8 |
未占用 |
Next |
2 |
- |
5 |
|
|
1 |
|
表4
其中,序号为3、4、6的元素未被占用,那么,元素索引集合如表5所示:
表5
现有技术中,应用程序的访问记录的数据结构通过字典和双向链表实现,其中,字典中的关键字为访问对象数据中的访问对象关键字,字典中的关键字取值是该访问对象关键字在双向链表中的节点指针。在对缓存数据执行垃圾回收操作时,会对包含指针的数据进行扫描。那么,双向链表中保存的访问对象关键字数量增加,指针数量也会增加,垃圾回收的耗时也会增加,内存性能下降。本申请实施例提供的方法提供一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
若采用本申请实施例提供的方法结合ARC算法进行缓存数据管理,在命中率方面,发明人使用生产环境真实访问序列测试表明,较之LRU算法可提高大约两倍,较之FIFO算法可提高大约四倍;在性能方面,通过6核心16G的系统上的基准测试表明,当pageSize=1kb,pageNum=800000,访问对象数据平均大小6kb时,读写操作的平均耗时约400ns,完全满足常见的高并发应用;另外,理论分析和测试结果同时表明,本申请实施例提供的方法即使在较大的访问对象数据缓存数量(数十万量级)下,对GC的影响也微乎其微。
应当指出的是,上述“当需要在设备内存中写入应用程序的访问对象数据”所表达的是“需要在设备内存中写入应用程序的访问对象数据”这样一种状态,而不应理解为对“确定所述访问对象数据所需占用的缓存空间分页数量”的执行时机的严格限定,即不应理解为“当确定需要在设备内存中写入应用程序的访问对象数据时,必须立即确定所述访问对象数据所需占用的缓存空间分页数量”。
应当指出的是,上述“当需要对已写入所述可用分页的所述访问对象数据进行目标操作”所表达的是“需要对已写入所述可用分页的所述访问对象数据进行目标操作”这样一种状态,而不应理解为对“按照预定的映射规则查找与该访问对象数据所包含的关键字对应的内存分片”的执行时机的严格限定,即不应理解为“当需要对已写入所述可用分页的所述访问对象数据进行目标操作时,必须立即按照预定的映射规则查找与该访问对象数据所包含的关键字对应的内存分片”。
应当指出的是,上述“当需要读取已写入上述可用分页的上述访问对象数据”所表达的是“需要读取已写入上述可用分页的上述访问对象数据”这样一种状态,而不应理解为对“将该访问对象数据从该可用分页复制到复制存储空间”的执行时机的严格限定,即不应理解为“当需要读取已写入上述可用分页的上述访问对象数据时,必须立即将该访问对象数据从该可用分页复制到复制存储空间”。
应当指出的是,上述“当需要删除已写入上述可用分页的上述访问对象数据”所表达的是“需要删除已写入上述可用分页的上述访问对象数据”这样一种状态,而不应理解为对“根据该关联关系查找到保存访问对象数据的首个分页的页标识”及后续操作的执行时机的严格限定,即不应理解为“当需要删除已写入上述可用分页的上述访问对象数据时,必须立即根据该关联关系查找到保存访问对象数据的首个分页的页标识”。
为了降低垃圾回收的耗时的目的,本申请实施例提供一种缓存数据的方法,应用在服务端应用程序上,也可以应用在客户端应用程序上,用于维护应用程序访问记录,如图3所示,该方法包括如下操作:
步骤301、确定需要修改设备内存中缓存的应用程序的访问记录。
对于不同的逐出算法,步骤301的实现方式不同,本申请实施例对此不作限定。
步骤302、根据缓存在设备内存中的访问对象数据的被访问状态修改应用程序的访问记录。其中,访问记录的数据结构包括:
访问记录数组,该访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
元素索引集合,该元素索引集合保存有访问记录数组中未被占用的元素的索引;
映射关系集合,该映射关系集合中关联保存访问对象数据的特定关键字和该访问对象数据的特定关键字在访问记录数组中的元素索引。
本实施例中,访问记录数组的第0个元素和第1个元素分别记为头(Head)和尾(Tail),为保留元素。真正的数据从第2个元素开始写入。
本申请实施例提供的方法提供一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
当需要在访问记录数组中添加访问对象数据的特定关键字,可以从元素索引集合中获取未被占用的元素的索引,并将该索引从元素索引集合中删除;将获取到的索引和待添加的特定关键字关联保存到映射关系集合;将待添加的特定关键字保存到访问记录数组中该索引对应的元素中,并将该元素的prev字段的取值设置为指定元素的索引,将该指定元素的next字段的当前取值设置为该元素的next字段的取值,将该当前取值对应的元素的prev字段的取值设置为该元素的索引,将该指定元素的next字段的取值修改为该元素的索引。
仍以基于表3至表5构成的ARC算法中的LRU链表为例。LRU链表需要支持头部插入新元素、将某个元素移到头部、查询某个元素是否存在、删除尾部元素这四个常用操作,需要以O(1)时间复杂度完成。下面演示本申请提供的数据结构如何完成上述操作:
假设需要将访问对象数据C的特定关键字9添加至访问记录数组中,那么,从表5的元素索引集合中读取索引6,并在元素索引集合中删除索引6;将特定关键字9和索引6关联保存到表3所示的字典中;在访问记录数组中查找索引6对应的元素,将特定关键字保存到访问记录数组中索引6的元素的Value字段,并在索引6的元素的prev字段保存索引0,在索引6的元素的next字段保存索引2;将索引2的元素的prev字段中的索引修改为索引6;将Head元素的next字段修改为索引6。添加完特定关键字9之后的字典、访问记录数组和元素索引集合分别如下表6、表7和表8所示。
表6
|
头 |
尾 |
|
|
|
|
|
Prev |
- |
5 |
6 |
|
|
2 |
0 |
Value |
|
|
5 |
未占用 |
未占用 |
8 |
9 |
Next |
6 |
- |
5 |
|
|
1 |
2 |
表7
表8
当需要将某个访问对象数据的特定关键字移到队首时,首先从映射关系集合中查找到该指定访问对象的特定关键字关联的索引Index,然后根据索引在访问记录数组中定位到元素A;修改元素A逻辑上相邻的元素的Prev值和Next值:将元素A的Prev字段A.Prev的当前值记作OPrev,将元素A的Next字段A.Next的当前值记为ONext,将A.Prev对应元素的Next值设为ONext,将A.Next对应元素的Prev值设为OPrev;修改元素A的Next和Prev值:将A.Prev设为0(Head元素的索引),将A.Next设为Head.Next(Head元素的Next字段当前取值);最后找到数组第0个元素Head(头),将Head.Next对应元素的Prev值设为元素A的索引Index,将Head.Next值设为元素A的索引Index。
当需要删除尾部元素时,根据访问记录数组的第1个(从0开始计数)元素Tail的Prev值定位真正的尾部元素的索引BIndex,尾部元素记为B,删除过程是:将B.Prev对应的元素的Next设为B.Next,将Tail.Prev设为B.Prev;从映射关系集合中删除B.Value;将BIndex加入到元素索引集合中。
当需要查找指定访问对象数据的特定关键字是否存在时,只需要从映射关系集合中查找该指定访问对象的特定关键字是否存在即可。
其中,对于“当需要在访问记录数组中添加访问对象数据的特定关键字”、“当需要在访问记录数组中移动指定访问对象数据的特定关键字”,“当需要在访问记录数组中移动指定访问对象数据的特定关键字”,“当需要在访问记录数组中删除指定访问对象数据的特定关键字”的理解可以参照上述说明,此处不再赘述。
采用本申请实施例提供的数据结构,头部插入新元素、将某个元素移到头部、查询某个元素是否存在、删除尾部元素这四个常用操作复杂度仍然是O(1)。
基于与图1所示的方法同样的发明构思,本申请实施例提供一种电子设备,如图4所示,该电子设备可以包括所需缓存空间确定模块401、可用分页确定模块402和访问对象数据写入模块403,所述各个模块可分别执行上文中结合图1描述的缓存数据的方法的各个步骤/功能。以下仅对该电子设备的各模块的主要功能进行描述,而省略以上已经描述过的细节内容。
所需缓存空间确定模块401,用于针对需要在设备内存中写入应用程序的访问对象数据,确定该访问对象数据所需占用的缓存空间的分页数量,缓存空间为预先申请的设备内存的部分存储空间,缓存空间被划分为多个大小相等的分页;
可用分页确定模块402,用于根据访问对象数据所需占用的缓存空间的分页数量,从缓存空间未被占用的分页中确定分配给访问对象数据的可用分页;
访问对象数据写入模块403,用于将访问对象数据写入可用分页。
在现有的数据写入内存过程中,需要首先申请内存空间,然后将数据写入申请到的内存空间中,其中,申请内存空间的耗时较长。本申请实施例提供的电子设备,预先申请用于存储应用程序的多个访问对象数据的缓存空间,当有访问对象数据需要写入设备内存时,在写入过程中不需要再申请内存空间,可降低写入过程的耗时。在高并发场景下,采用本申请实施例提供的电子设备,可有效降低数据写入内存过程的耗时,从而降低响应时延、提高内存读写性能。另外,与传统的固定大小的访问对象不同,近年来的应用程序的访问对象类型多样,访问对象大小也不再固定,为适应这一情况,缓存空间被划分为多个分页,写入访问对象数据时,可以根据访问对象数据的数据量分配不同数量的分页,以满足不同大小的访问数据的缓存需求。
当需要读取已写入上述可用分页的上述访问对象数据,本申请实施例提供的电子设备还包括访问对象数据读取模块,用于将该访问对象数据从该可用分页复制到复制存储空间时,其中,复制存储空间为预先申请的设备内存的部分存储空间,供多个被读取的访问对象数据复用。
在现有的从内存读取数据的过程中,需要首先申请内存空间,以用于复制需要读取的数据,其中,申请内存空间的耗时较长。本申请实施例提供的电子设备,预先申请复制存储空间,当需要读取访问对象数据时,在读取过程中不需要再申请内存空间,而是复用预先申请的复制存储空间,可降低读取过程的耗时。在高并发场景下,采用本申请实施例提供的电子设备,可有效降低从内存读取数据过程的耗时,从而降低响应时延、提高内存读写性能。
在此基础上,本申请实施例提供的电子设备还可以包括内存空间释放模块,将上述访问对象数据从可用分页复制到复制存储空间后,从所述复制存储空间读取所述访问对象数据之后,归还所述复制存储空间;判断空闲的所述复制存储空间的数量是否超出阈值;如果超出所述阈值,则释放所述复制存储空间。
在没有待读取的访问对象数据的情况下释放复制存储空间,可以有效避免内存资源的浪费,提高内存使用效率。
在上述任意电子设备实施例的基础上,上述访问对象数据写入模块将该访问对象数据按照指定顺序级联保存到可用分页。
通过级联保存的方式,一方面可以高效利用内存资源,避免内存资源的浪费,另一方面便于快速查询读取数据,有助于提高数据读取效率。
在此基础上,本申请实施例提供的电子设备还包括字典管理模块,用于关联保存上述访问对象数据的特定关键字和该访问对象数据对应的目标信息集合,以便查询该访问对象数据。其中,特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;其中,目标信息集合包括上述可用分页中的首个分页的页标识和访问对象数据的元信息。
现有技术中,为便于查询访问对象数据,将访问对象数据中的关键字和关键字取值关联保存,而访问对象数据中的关键字和关键字取值中都引入了指针。在对缓存数据执行垃圾回收操作时,会对包含指针的数据进行扫描。那么,当关联保存的关键字和关键字取值数量增加,垃圾回收的耗时也会增加,内存性能下降。本申请实施例提供的电子设备将访问对象数据的关键字的散列运算值和可用分页的首个分页的页标识以及访问对象数据的元信息关联保存,既可以用于查询该访问对象数据,又没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。另外,由于访问对象数据通过级联的方式保存到可用分页中,因此,仅需要将可用分页中的首个分页的页标识关联保存,即可查找到完整的访问对象数据。
在上述任意电子设备实施例的基础上,本申请实施例提供的电子设备还可以包括拿锁控制模块,当需要对上述访问对象数据进行目标操作,拿锁控制用于按照预定的映射规则查找与该访问对象数据所包含的关键字对应的内存分片,其中,设备内存被划分为多个内存分片,每个内存分片分别绑定有读写锁;对查找到的内存分片的读写锁进行加锁处理以便对该访问对象数据进行上述目标操作,其中,目标操作可以包括以下任意一种:写入操作、读取操作、删除操作、更新操作。
本申请实施例提供的电子设备通过将锁粒度从内存级别降低到分片级别,可有效降低锁竞争导致的内存读写性能下降问题。
在上述任意电子设备实施例的基础上,本申请实施例提供的电子设备还可以包括访问记录管理模块,用于根据上述访问对象数据的被访问状态修改应用程序的访问记录,该访问记录缓存在设备内存中,其数据结构包括:
访问记录数组,该访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,其中,特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
元素索引集合,该元素索引集合保存有访问记录数组中未被占用的元素的索引;
映射关系集合,该映射关系集合中关联保存访问对象数据的特定关键字和该访问对象数据的特定关键字在访问记录数组中的元素索引。
现有技术中,应用程序的访问记录的数据结构通过字典和双向链表实现,其中,字典中的关键字为访问对象数据中的访问对象关键字,字典中的关键字取值是该访问对象关键字在双向链表中的节点指针。在对缓存数据执行垃圾回收操作时,会对包含指针的数据进行扫描。那么,双向链表中保存的访问对象关键字数量增加,指针数量也会增加,垃圾回收的耗时也会增加,内存性能下降。本申请实施例提供的电子设备提供一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
在上述任意电子设备实施例的基础上,本申请实施例提供的电子设备还包括访问对象数据更新模块,用于确定外部设备保存的上述访问对象数据已更新,则从该外部设备获取该访问对象数据的更新数据;利用该更新数据写入可用分页的该访问对象数据。
本申请实施例提供的电子设备可以通过主动检测或根据接收到的更新消息来确定外部设备保存的上述访问对象数据已更新,进而对设备内存中缓存的该访问对象数据进行更新,保持访问对象数据的同步。
基于与图3所示的方法同样的发明构思,本申请实施例提供一种电子设备,如图5所示,该电子设备可以包括访问记录修改确定模块501和访问记录修改执行模块502,所述各个模块可分别执行上文中结合图3描述的缓存数据的方法的各个步骤/功能。以下仅对该电子设备的各模块的主要功能进行描述,而省略以上已经描述过的细节内容。
访问记录修改确定模块501,用于确定需要修改设备内存中缓存的应用程序的访问记录;
访问记录修改执行模块502,用于根据缓存在所述设备内存中的访问对象数据的被访问状态修改所述应用程序的访问记录,所述访问记录的数据结构包括:
访问记录数组,所述访问记录数组中每个被占用的元素保存有访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引和后序访问对象数据的特定关键字所在元素的索引,访问对象数据的顺序根据被访问状态确定,所述特定关键字包括访问对象关键字的散列运算值,访问对象数据包括访问对象关键字;
元素索引集合,所述元素索引集合保存有所述访问记录数组中未被占用的元素的索引;
映射关系集合,所述映射关系集合中关联保存访问对象数据的特定关键字和所述访问对象数据的特定关键字在访问记录数组中的元素索引。
本申请实施例提供的电子设备提供一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
本申请实施例提供的电子设备还包括元素添加模块,用于当需要在访问记录数组中添加访问对象数据的特定关键字,可以从元素索引集合中获取未被占用的元素的索引,并将该索引从元素索引集合中删除;将获取到的索引和待添加的特定关键字关联保存到映射关系集合;将待添加的特定关键字保存到访问记录数组中该索引对应的元素中,并将该元素的prev字段的取值设置为指定元素的索引,将该指定元素的next字段的当前取值设置为该元素的next字段的取值,将该当前取值对应的元素的prev字段的取值设置为该元素的索引,将该指定元素的next字段的取值修改为该元素的索引。
其中,若需要在访问记录数组的头部添加访问对象数据,且该访问记录数组的第0个元素(头部元素)和第1个元素(尾部元素)为保留元素,那么,上述指定元素为头部元素。
本申请实施例提供的电子设备还包括元素移动模块,用于当需要在访问记录数组中移动指定访问对象数据的特定关键字,可以从映射关系集合中查找到该指定访问对象的特定关键字关联的索引(目标索引);在访问记录数组中查找到该目标索引对应的元素(目标元素);查找目标元素的prev字段取值对应的元素,将该元素的next字段的取值设置为目标元素的next字段的当前取值,查找目标元素的next字段取值对应的元素,将该元素的prev字段的取值是设置为目标元素的prev字段的当前取值;将目标元素的prev字段的取值修改为指定元素的索引,将目标元素的next字段的取值修改为指定元素的next字段的当前取值;将该当前取值对应元素的prev字段的取值修改为目标元素的索引,将指定元素的next字段的取值修改为目标元素的索引。
其中,若需要将某个访问对象数据移动到访问记录数组的头部,且该访问记录数组的第0个元素(头部元素)和第1个元素(尾部元素)为保留元素,那么,上述指定元素为头部元素。
本申请实施例提供的电子设备还包括元素删除模块,用于当需要在访问记录数组中删除指定访问对象数据的特定关键字,可以从映射关系集合中查找到该指定访问对象的特定关键字关联的索引;在访问记录数组中查找到该索引对应的元素;查找该元素的prev字段的取值对应元素(记作prev元素),将prev元素的next字段的取值设置为该元素的next字段的取值,查找该元素的next字段的取值对应元素(记作next元素),将next元素的prev字段的取值设置为该元素的prev字段的取值,删除该元素中的数据,从映射关系集合中删除该元素的索引,并将该元素的索引添加到元素索引集合中。
其中,若需要删除访问记录数组的尾部元素,且该访问记录数组的第0个元素(头部元素)和第1个元素(尾部元素)为保留元素,那么,元素删除模块根据访问记录数组的尾部元素的prev字段的取值定位尾部元素。
本申请实施例提供的电子设备还包括元素查找模块,用于当需要查找指定访问对象数据是否存在,可以从映射关系集合中查找该指定访问对象的特定关键字是否存在。
上述各实施例中的电子设备可以包括数据中心服务器、智能手机、掌上电脑、平板电脑、带显示屏的可穿戴设备、车载电脑、智能音箱、个人计算机等等。
所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的电子设备的模块的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
基于与方法同样的发明构思,本申请实施例还提供一种电子设备,包括处理器和存储器;
存储器用于存储执行上述各个方法实施例所述方法的程序;处理器被配置为执行存储器中存储的程序。当存储器中存储的程序指令被处理器运行时,所述处理器执行上述各个方法实施例所述方法,并且还用于实现根据本发明实施例的电子设备中的相应模块。处理器可以是包括中央处理单元(CPU)或者具有数据处理能力和/或指令执行能力的其它形式的处理单元,并且可以控制电子设备中的其它组件以执行期望的功能。存储器可以包括一个或多个计算机程序产品,所述计算机程序产品可以包括各种形式的计算机可读存储介质,例如易失性存储器和/或非易失性存储器。所述易失性存储器例如可以包括随机存取存储器(RAM)和/或高速缓冲存储器(cache)等。所述非易失性存储器例如可以包括只读存储器(ROM)、硬盘、闪存等。在所述计算机可读存储介质上可以存储一个或多个计算机程序指令,处理器可以运行所述程序指令,以实现上文所述的本公开的实施例的功能以及/或者其它期望的功能。
若本申请实施例提供的电子设备实现图1所示的方法,则预先申请用于存储应用程序的多个访问对象数据的缓存空间,当有访问对象数据需要写入设备内存时,在写入过程中不需要再申请内存空间,可降低写入过程的耗时。在高并发场景下,采用本申请实施例提供的电子设备,可有效降低数据写入内存过程的耗时,从而降低响应时延、提高内存读写性能。另外,与传统的固定大小的访问对象不同,近年来的应用程序的访问对象类型多样,访问对象大小也不再固定,为适应这一情况,缓存空间被划分为多个分页,写入访问对象数据时,可以根据访问对象数据的数据量分配不同数量的分页,以满足不同大小的访问数据的缓存需求。
若本申请实施例提供的电子设备实现图3所示的方法,则基于一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
本申请实施例提供的电子设备可以包括服务器,如图6所示,服务器不仅包括处理器和存储器,I/O接口(输入输出接口)和总线。
其中,处理器(如中央处理器)可以根据存储在只读存储器(ROM)中的程序或者从存储装置加载到随机访问存储器(RAM)中的程序而执行各种适当的动作和处理。在RAM中,还存储有服务器工作所需的各种程序和数据。ROM、RAM以及存储装置统称为存储器,处理器、ROM、RAM以及存储装置通过总线彼此相连。I/O接口也连接至总线。通常,以下装置可以连接至I/O接口:包括例如触摸屏、触摸板、键盘、鼠标、摄像头、麦克风等的输入装置;包括例如液晶显示器(LCD)、扬声器等的输出装置;包括例如磁带、硬盘等的存储装置;以及通信装置。通信装置可以允许服务器与其他设备进行无线或有线通信以交换数据。虽然图6示出了具有各种装置的服务器,但是应理解的是,并不要求实施或具备所有示出的装置。可以替代地实施或具备更多或更少的装置。
基于与方法同样的发明构思,本申请实施例还提供一种计算机可读存储介质,存储有执行上述各个实施例所述方法的程序。
若本申请实施例提供的计算机可读存储介质中所保存的程序实现图1所示的方法,则预先申请用于存储应用程序的多个访问对象数据的缓存空间,当有访问对象数据需要写入设备内存时,在写入过程中不需要再申请内存空间,可降低写入过程的耗时。在高并发场景下,可有效降低数据写入内存过程的耗时,从而降低响应时延、提高内存读写性能。另外,与传统的固定大小的访问对象不同,近年来的应用程序的访问对象类型多样,访问对象大小也不再固定,为适应这一情况,缓存空间被划分为多个分页,写入访问对象数据时,可以根据访问对象数据的数据量分配不同数量的分页,以满足不同大小的访问数据的缓存需求。
若本申请实施例提供的计算机可读存储介质中所保存的程序实现图3所示的方法,则基于一种新的访问记录的数据结构,其中的访问记录数组代替了现有的双向链表,该访问记录数字中的每个元素包括三个字段:访问对象数据的特定关键字、前序访问对象数据的特定关键字所在元素的索引,后序访问对象数据的特定关键字所在元素的索引;相应的,数据结构中的映射关系集合中关联保存访问对象数据的特定关键字和其在访问记录数组中的元素索引,起到字典的作用,数据结构中的元素索引集合保存访问记录数组中未被占用的元素的索引。上述数据结构没有引入指针,不会增加垃圾回收的耗时,内存性能也不会因为垃圾回收耗时而下降。
本说明书是参照根据本说明书实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的设备。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令设备的制造品,该指令设备实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本说明书的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例作出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本说明书范围的所有变更和修改。
显然,本领域的技术人员可以对本说明书进行各种改动和变型而不脱离本说明书的精神和范围。这样,倘若本说明书的这些修改和变型属于本说明书权利要求及其等同技术的范围之内,则本说明书也意图包含这些改动和变型在内。