一种数据处理方法、装置、电子设备及存储介质
文献发布时间:2023-06-19 11:35:49
技术领域
本申请涉及云存储领域,尤其涉及一种数据处理方法、装置、电子设备及存储介质。
背景技术
随着业务发展数据规模越来越大,目前本地(服务进程内)全量数据加载的方式使服务越来越庞大,为使服务向着云原生方向发展,需要将后端服务轻量化,因此将全量数据由本地迁移到分布式远程数据库中,同时为了减少远程调用的开销,本地缓存小部分热门数据,形成本地缓存+远程数据中心的存储方案。
目前,分布式远程数据存储业界已经有非常成熟的产品,例如Redis等,但目前的本地缓存实现方式在使用过程中,发明人发现在一些高访问量、高并发场景下本地缓存存在下述问题:服务进程重启后,本地内存中缓存的数据全部丢失,本地缓存处于失效状态。
发明内容
为了解决上述技术问题或者至少部分地解决上述技术问题,本申请提供了一种数据处理方法、装置、电子设备及存储介质。
第一方面,本申请提供了一种数据处理方法,包括:
在服务启动时,将本地存储系统中存储的数据写入本地缓存,所述数据为所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
获取服务离线期间未处理的数据处理消息;
根据所述数据处理消息对所述本地缓存中存储的数据进行处理。
作为一种可能的实施方式,将所述本地存储系统中存储的数据写入本地缓存,包括:
对所述本地存储系统中存储的数据进行遍历,以读取所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
将所述数据和所述数据的数据主键写入缓存插入内部队列;
调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键;
将所述数据的数据主键插入缓存策略链表的表头;
将所述数据插入所述本地缓存中。
作为一种可能的实施方式,据所述数据处理消息对所述本地缓存中存储的数据进行处理,包括:
对所述数据处理消息进行解析,以获取所述数据处理消息中包含的数据处理类型和目标数据主键;
若确定所述本地缓存中存储有与所述目标数据主键对应的数据,则根据所述数据处理类型和所述目标数据主键对所述本地缓存中存储的数据进行处理。
作为一种可能的实施方式,根据所述数据处理类型和所述目标数据主键对所述本地缓存中存储的数据进行处理,包括:
若所述数据处理类型为数据更新,则从远程数据库中获取与所述目标数据主键对应的数据,将所述数据和所述数据的数据主键写入缓存插入内部队列,调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键,将所述数据的数据主键插入缓存策略链表的表头,将所述数据插入所述本地缓存中;
若所述数据处理类型为数据删除,则将所述目标数据主键写入缓存删除内部队列,调用第二独立线程读取所述缓存删除内部队列中存储的所述目标数据主键,将所述本地缓存中与所述目标数据主键对应的数据删除。
作为一种可能的实施方式,所述方法还包括:
接收数据查询请求,所述数据查询请求中携带有目标数据主键;
若确定所述本地缓存中存储有与所述目标数据主键对应的目标数据,则将所述目标数据主键写入缓存策略更新内部队列,并将所述目标数据返回至所述数据查询请求的调用端;
调用第二独立线程读取所述缓存策略更新内部队列中存储的所述目标数据主键;
将所述目标数据主键在缓存策略链表中的位置调整至所述缓存策略链表的表头,所述缓存策略链表用于存储所述本地缓存中缓存的数据的数据主键。
作为一种可能的实施方式,所述方法还包括:
若确定所述本地缓存中未存储与所述目标数据主键对应的目标数据,则从远程数据库中获取与所述目标数据主键对应的数据;
将从远程数据库中获取的所述数据的格式转换为所述本地缓存支持的格式;
将格式转换后的所述数据和所述数据的数据主键写入缓存插入内部队列,并将格式转换后的所述数据返回至所述数据查询请求的调用端;
调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键;
将所述数据的数据主键插入缓存策略链表的表头;
在确定所述数据的数据主键插入所述缓存策略链表后,将所述数据插入所述本地缓存中。
作为一种可能的实施方式,所述将所述数据插入所述本地缓存中包括:
所述本地缓存以哈希表的数据结构进行数据存储,计算所述数据的数据主键对应的哈希值;
通过所述哈希值对所述本地缓存中哈希表的桶的数量进行取模,得到对应的模值;
根据所述模值确定所述数据对应的目标桶;
对所述目标桶添加排他锁,并将所述数据插入所述目标桶。
第二方面,本申请实施例还提供了一种数据处理装置,包括:
写入模块,用于在服务启动时,将本地存储系统中存储的数据写入本地缓存,所述数据为所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
获取模块,用于获取服务离线期间未处理的数据处理消息;
处理模块,用于根据所述数据处理消息对所述本地缓存中存储的数据进行处理。
第三方面,本申请实施例还提供了一种计算机设备,包括:处理器和存储器,所述处理器用于执行所述存储器中存储的数据处理程序,以实现第一方面所述的数据处理方法。
第四方面,本申请实施例还提供了一种存储介质,所述存储介质存储有一个或者多个程序,所述一个或者多个程序可被一个或者多个处理器执行,以实现第一方面所述的数据处理方法。
本申请实施例提供的上述技术方案与现有技术相比具有如下优点:
本申请实施例提供的一种数据处理方法,在服务启动时,先将服务前次运行过程中从本地缓存写入本地存储系统中的数据重新写回到本地缓存,再获取服务离线期间未处理的数据处理消息,根据数据处理消息对本地缓存中的数据进行更新。本方案通过在服务运行过程中将本地缓存中的数据写入本地存储系统,实现了缓存数据的持久化,在服务启动时将数据由本地存储系统还原至本地缓存中,避免了服务重启后本地缓存数据的丢失。进一步的,在将本地存储系统中的数据重新写回到本地缓存中后,根据服务离线期间未处理的数据处理消息对本地缓存中的数据进行更新,实现了缓存数据的及时更新。
附图说明
此处的附图被并入说明书中并构成本说明书的一部分,示出了符合本申请的实施例,并与说明书一起用于解释本申请的原理。
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1为本申请实施例提供的一种数据处理方法的流程图;
图2为本申请实施例提供的一种步骤S11实现方法的流程图;
图3为本申请实施例提供的一种基于数据处理消息对本地缓存中存储的数据进行处理的实现流程图;
图4为本申请实施例提供的另一种数据处理方法的流程图;
图5为本申请实施例提供的一种数据处理系统的框图;
图6为本申请实施例提供的流程1的示意图;
图7为本申请实施例提供的流程2的示意图;
图8为本申请实施例提供的流程3的示意图;
图9为本申请实施例提供的流程4的示意图;
图10为本申请实施例提供的流程5的示意图;
图11为本申请实施例提供的流程6的示意图;
图12为本申请实施例提供的一种数据处理装置的框图;
图13为本申请实施例提供的一种电子设备的示意图。
具体实施方式
为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请的一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本申请保护的范围。
为了实现服务轻量化,通常会将服务的全量数据迁移到分布式远程数据库中,例如云数据库中,为了减少远程调用的开销,同时会在本地缓存中存储小部分热门数据,进而形成了本地缓存+远程数据库的存储方案。
目前,分布式远程数据存储已经有非常成熟的产品,例如Redis等,而本地缓存目前主流实现方式在一些高访问量、高并发场景下存在一些技术问题,主要体现在:
服务进程重启后,本地缓存的数据全部丢失,本地缓存处于失效状态,由于缺少缓存状态还原机制,这使得在一些高访问量、高并发场景下,在服务重启后,会造成大规模缓存穿透,导致大量请求访问远程数据库,从而引发远程数据库性能下降的问题。缓存穿透是查询数据时出现的一种情况,该情况需同时满足下述两个条件:查询的数据未在本地缓存,需要从远程数据库查询;这种情况大量出现。
为了解决服务重启时,本地缓存数据丢失无法还原的问题,本发明实施例提供了一种数据处理方法。
参见图1,为本发明实施例提供的一种数据处理方法的实现流程图,该方法应用于高并发场景下的数据处理系统,如图1所示,该方法可以包括如下步骤:
S11.在服务启动时,将本地存储系统中存储的数据写入本地缓存,所述数据为所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据。
在本发明实施例中,在服务前次运行过程中会将本地缓存中的数据写入到本地存储系统中,并且会根据对本地缓存中存储的数据的处理(插入/更新/删除),对本地存储系统中的数据进行相应的处理(插入/更新/删除),实现了本地缓存的数据的持久化。基于此,在服务启动时,可以从本地存储系统中获取该服务前次运行过程中本地缓存的数据,实现了本地缓存数据的恢复,从而解决了服务重启时,本地缓存数据丢失的问题。
示例性的,本地存储系统可以为具有插入、删除、遍历等操作方法的嵌入式数据库,其中,嵌入式数据库可以是Rocksdb,在实际应用时也可以根据实际需要对嵌入式数据库进行替换,本实施例不做具体限定。
进一步的,由于嵌入式数据库的内存通常是有限的,所以为了保证本地缓存中的数据可以顺利的写入到本地存储系统中,以实现持久化,当嵌入式数据库所用内存达到设定阈值时,可以将嵌入式数据库中存储的数据顺序写入本地磁盘,其中设定阈值可以根据实际需求设定。
S12.获取服务离线期间未处理的数据处理消息。
在本发明实施例中,为了保证本地缓存数据的及时更新,采用了基于消息队列的更新事件通知策略,数据更新上游模块在将某个变化的数据更新到远程数据库的同时,会将对应的更新通知(下称数据处理消息)写入消息队列,通过消费消息队列中的数据处理消息,来对本地缓存中的数据进行处理。
在实际应用中,在消费消息队列中的数据处理消息后,会将已经被消费的消息的消费信息,比如订阅的Topic(即主题)、分区号以及每个分区对应的最新时间戳等消费信息,写入到本地磁盘的检查点文件中。基于此,本步骤S12可以根据检查点文件中存储的数据确定服务离线期间未处理的数据处理消息,具体的,可以包括:获取本地磁盘中的检查点文件,确定所述检查点文件中存储的最新时间戳作为目标时间戳,获取消息队列中,对应的时间戳在所述目标时间戳之后的数据处理消息,作为服务离线期间未处理的数据处理消息。检查点文件中存储的最新时间戳即为最新消费的消息对应的时间戳,对应的时间戳在该时间戳之后的消息即为未被消费的消息,因此将这类信息作为服务离线期间未处理的数据处理消息。
S13.根据所述数据处理消息对所述本地缓存中存储的数据进行处理。
作为一个实施例,可以通过解析数据处理消息,获取数据处理消息中包含的数据主键和数据处理类型(数据更新或数据删除)等信息,然后基于解析得到的上述信息对本地缓存中的数据进行更新或删除。
本实施例提供的一种数据处理方法,在服务启动时,先将服务前次运行过程中从本地缓存写入本地存储系统中的数据重新写回到本地缓存,再获取服务离线期间未处理的数据处理消息,根据数据处理消息对本地缓存中的数据进行更新。本方案通过在服务运行过程中,将本地缓存中的数据写入本地磁盘,实现了缓存数据的持久化,在服务启动时将数据由本地存储系统还原至本地缓存中,避免了服务重启后本地缓存数据的丢失。进一步的,在将本地存储系统中的数据重新写回到本地缓存中后根据服务离线期间未处理的数据处理消息对本地缓存中的数据进行处理,实现了缓存数据的及时更新。
基于上述内容,参见图2,为本发明的另一实施例中S11的实现流程,如图2所示,可以包括以下步骤:
S111.服务启动时,对所述本地存储系统中存储的数据进行遍历,以读取所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据。
在本发明实施例中,可以按照本地缓存系统中存储的数据的写入顺序进行遍历。
作为一个实施例,本地存储系统为嵌入式数据库,在服务启动时,可以将嵌入式数据库中的全量数据均写入到本地缓存中。
S112.将所述数据和所述数据的数据主键写入缓存插入内部队列。
其中,缓存插入内部队列为预先创建的用于对待插入本地缓存中的数据和对应的数据主键进行存储的内部队列。
在本发明实施例中,因为通常本地缓存与本地存储系统支持的数据格式不同,所以,在将读取的数据写入缓存插入内部队列中之前,先对读取的数据进行格式转换,转换为本地缓存支持的格式,再将格式转换后的数据插入到缓存插入内部队列中。
在实际应用中,可以预先设置并存储数据转换回调函数,通过调用数据转换回调函数将读取的数据的数据格式转换为本地缓存支持的格式。
S113.调用第二独立线程读取缓存插入内部队列中存储的所述数据和所述数据的数据主键。
在本发明实施例中,采用一写多读的模式进行数据处理,即所有对本地缓存的写操作均由同一个写入线程完成,其他读取操作(比如查找数据、拉取远程数据等)都由读取线程完成。
在实际应用中,预先创建一个独立运行的线程(下称第二独立线程)作为写入线程,在通过S112将格式转换后的数据和数据的数据主键写入缓存插入内部队列后,通过调用第二独立线程将缓存插入内部队列中的数据插入本地缓存中。
S114.将所述数据的数据主键插入缓存策略链表的表头。
其中,缓存策略链表是与本地缓存使用的缓存策略对应的链表。
在本实施例中,本地缓存使用的缓存策略为LRU,即最近最少使用策略,在本地缓存已满的情况下,选择最近最久未使用的数据予以淘汰。
进一步的,缓存策略链表中存储的是数据主键而不是存储数据本身,所以对缓存策略链表中所属元素的增加、删除、调整均操作的是键值,因为数据的主键往往比较小,所以保存数据主键会比较轻量。
S115.将所述数据插入所述本地缓存中。
在本发明实施例中,在将数据插入本地缓存中时,先将数据的数据主键插入到缓存策略链表中,在确定数据主键成功插入到缓存策略链表后,再将数据写入到本地缓存中,避免由于缓存策略链表插入失败导致的数据插入失败。
作为一个实施例,数据主键成功插入到缓存策略链表中后会生成一个表示插入成功的信息,基于此,在将数据主键插入到缓存策略链表中时,可以启动一个定时器,若在定时器超时之前检测到表示插入成功的信息,则确定数据主键插入成功,从而将数据插入本地缓存,若在定时器超时之间未检测到表示插入成功的信息,或检测到表示数据主键插入失败的消息,则确定数据主键未插入成功,从而不将数据插入本地缓存。
在本实施例中,采用一写多读的模式对本地缓存中的数据进行处理,可以实现读、写的异步处理,避免高并发情况下的大规模的锁竞争。
在实际应用中,除了在服务启动时需要根据数据处理消息对本地缓存中存储的数据进行处理,在服务运行过程中,也需要基于消息队列中的数据处理消息对本地缓存中存储的数据进行处理。
参见图3,本发明另一实施例提供的一种基于数据处理消息对本地缓存中存储的数据进行处理的实现流程图,如图3所示,可以包括如下步骤:
S31.对数据处理消息进行解析,以获取数据处理消息中包含的数据处理类型和目标数据主键。
S32.查找本地缓存中是否存储有与目标数据主键对应的数据,若是,则执行S33,若否,则不执行数据处理操作。
因为数据处理消息通常用于对本地缓存中已存储的数据进行处理,所以若本地缓存中没有存储与目标数据主键对应的数据,也就说明没有需要处理的数据,则不需要执行数据处理操作。
S33.确定所述数据处理类型,若数据处理类型为数据更新,则执行S34,若所述数据处理类型为数据删除,则执行S39。
S34.从远程数据库中获取与所述目标数据主键对应的数据,并执行S35。
S35.将所述数据和所述数据的数据主键写入缓存插入内部队列。
在本发明实施例中,由于远程数据库支持的数据格式和本地缓存支持的数据格式通常不同,因此在将从远程数据库中获取的数据写入缓存插入内部队列之前,先将获取的数据的格式转换为本地缓存支持的格式,在将格式转换后的数据插入到缓存插入内部队列中。
在实际应用中,可以预先设置并存储数据转换回调函数,通过调用数据转换回调函数将读取的数据的数据格式转换为本地缓存支持的格式。
S36.调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据主键。
S37.将所述数据主键插入缓存策略链表的表头。
S38.将所述数据插入所述本地缓存中。
在本发明实施例中,在确定数据主键成功插入缓存策略链表后,在将数据插入到本地缓存中,避免由于缓存策略链表插入失败导致的数据插入失败。
下面对S34-S38进行统一说明:
本发明实施例,采用一写多读的模式进行数据处理,在确定数据处理类型为更新时,读取线程只需采用S34-S35从远程数据库中获取到数据,并对数据进行格式转换之后,将格式转换后的数据和对应的数据主键写入到缓存插入内部队列中即可,然后可以选取合适的时机(比如在系统空闲或系统可用资源足够多时),再通过调用第二独立线程,使第二独立线程利用S36-S38基于缓存插入内部队列中存储的数据和数据主键,将数据写入到本地缓存中。由于读取和写入采用的是不同的线程,因此可以异步处理,避免了高并发场景下同步对数据进行写入造成大规模锁竞争和系统并发度和吞吐力受限。
进一步的,在将数据插入到本地缓存中时,若本地缓存中存储有与待插入数据的数据主键对应的原始数据,则将待插入的数据插入到本地缓存中时,会将原始数据覆盖。
S39.将所述目标数据主键写入缓存删除内部队列。
其中,缓存删除内部队列是预先创建的用于存储本地缓存中待删除的数据的主键的内部队列。
S310.调用第二独立线程读取所述缓存删除内部队列中存储的所述目标数据主键。
S311.将所述本地缓存中与所述目标数据主键对应的数据删除。
下面对S39-S311进行统一说明:
本发明实施例,采用一写多读的模式进行数据处理,在确定数据处理类型为删除时,读取线程只需采用S39将待删除数据的数据主键(即数据处理消息中的目标数据主键)写入到缓存删除内部队列中即可。然后可以根据需求选取合适的时间(例如在系统空闲或可用资源充足时),再通过调用第二独立线程采用S310-S311基于缓存删除内部队列对本地缓存进行数据删除。由于读取和写入采用的是不同的线程,因此可以异步处理,避免了高并发场景下同步对数据进行写入造成大规模锁竞争和系统并发度和吞吐力受限。
目前的本地缓存实现方式除了数据易丢失外,在一些高访问量、高并发场景下由于基于缓存淘汰策略和缓存数据的同步更新机制,导致在对本地缓存进行数据查询时需要对缓存数据查找和缓存策略更新进行多线程同步,这在高并发场景下会造成大规模锁竞争,使得系统并发度和吞吐力受限。
为了解决上述问题,为本申请实施例提供的另一种数据处理方法。
参见图4为本申请实施例提供的另一种数据处理方法的实现流程图,该方法应用于高并发场景下的数据处理系统。如图4所示,该方法可以包括以下步骤:
S41.接收数据查询请求。
在本实施例中,所述数据查询请求中携带有目标数据主键,目标数据主键为待查询的数据的数据主键。
在一实施例中,可以在数据处理系统的调用端(例如业务层)提供用于查询本地缓存中存储的数据的API接口,使调用端可以通过调用该API接口来获取缓存数据,因此,数据查询请求可以为该API接口的调用请求。
进一步的,为了提高查询效率该API接口可以支持批量数据查询。
S42.检测所述本地缓存中是否存储有与所述目标数据主键对应的目标数据,若是,则执行S43,若否,则执行S47。
S43.将所述目标数据主键写入缓存策略更新内部队列。
S44.将所述目标数据返回至所述数据查询请求的调用端。
其中,数据查询请求的调用端即为发起该数据查询请求的一端。
进一步的,如图4所示,基于缓存策略更新内部队列对缓存策略链表进行更新,可以包括:
S45.调用第二独立线程读取所述缓存策略更新内部队列中存储的所述目标数据主键。
其中第二独立线程为预先创建的用于对缓存策略更新内部队列进行读取的线程。
S46.将所述目标数据主键在缓存策略链表中的位置调整至所述缓存策略链表的表头。
下面对S43-S46进行统一说明:
在本发明实施例中,采用一写多读的模式进行数据处理,在确定查询命中本地缓存时,读取线程只需采用S43将命中的数据的数据主键写入缓存策略更新内部队列策略,然后在采用S44将命中数据发送至调用端即可无需对缓存策略链表进行同步更新。可以选取合适的时间(比如在系统空闲或系统可用资源足够多时),再通过调用第二独立线程采用S45-S46的方式对缓存策略进行异步更新。实现了数据查找与缓存策略链表更新的异步执行,解决了目前由于采用缓存策略更新和缓存数据查找的同步更新机制导致的系统并发度和吞吐力受限的问题。
S47.从远程数据库中获取与所述目标数据主键对应的数据。
S48.将从远程数据库中获取的所述数据的格式转换为所述本地缓存支持的格式。
在一个实施例中,可以通过调用预先设置并存储的数据转换回调函数进行数据格式转换,然后再将格式转换后的数据写入到本地缓存中。
S49.将格式转换后的所述数据和所述数据的数据主键写入缓存插入内部队列。
S410.将格式转换后的所述数据返回至所述数据查询请求的调用端。
因为从远程数据库中获取的数据通常为字符串格式,不符合调用端的业务需求,因此此处先将从远程数据库中获取的数据进行数据格式转换后写入缓存插入内部队列,然后再从缓存插入内部队列中获取格式转换后的数据并返回至调用端,从而保证了返回至调用端的数据符合调用端的业务需求。
S411.调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据主键。
S412.将所述数据主键插入缓存策略链表的表头。
S413.将所述数据插入所述本地缓存中。
在本发明实施例中,在确定数据主键成功插入缓存策略链表后,再将对应的数据插入到本地缓存中。
下面对S47-S413进行统一说明:
在本发明实施例中,采用一写多读的模式进行数据处理,在确定未命中本地缓存时,只需通过调用读取线程利用S47-S410在从远程数据库中获取到数据,并将格式转换后的数据和数据的数据主键写入到缓存插入内部队列中,然后将格式转换后的数据直接发送至调用端即可,无需同步将从远程数据库中获取的数据写入到本地缓存中,可以根据需求选取合适的时将(比如在系统空闲或系统可用资源足够多时),再通过调用第二独立线程,采用S411-S413的方式将格式转换后的数据写入到本地缓存中。避免高并发情况下对远程数据库读取与数据写入本地缓存同步执行导致的系统并发度和吞吐力受限。
进一步的,因为对缓存策略进行异步更新的话,会存在缓存策略更新滞后的问题,所以为了尽量减少这一问题,在本发明的又一个实施例中,在非高并发场景下,若接收到数据查询请求,在确定本地缓存中存储有与数据查询请求中携带的目标数据主键对应的目标数据时,基于缓存策略和缓存数据的同步更新机制,将目标数据的数据主键在缓存策略链表中的位置调整至缓存策略链表的表头,并将目标数据返回至数据查询请求的调用端。
在非高并发场景下,通过采用同步更新机制减少异步更新缓存策略带来的缓存策略更新滞后的问题。
在实际应用中,可以通过检测数据处理系统的当前访问量是否超过设定阈值来确定是否处于高并发场景,若当前访问量超过设定阈值,则确定当前处于高并发场景,若当前访问量不超过设定阈值,则确定当前未处于高并发场景下,也就是处于非高并发场景下,其中设定阈值可以根据实际需求设定。
基于上述内容可知,在本发明实施例中,所有的写入操作均需要通过调用第二独立线程来实现。
因此,作为一个实施例,可以设置缓存插入内部队列、缓存删除内部队列和缓存策略更新内部队列的读取顺序,然后第二独立线程可以基于该顺序对缓存插入内部队列、缓存删除内部队列和缓存策略更新内部队列进行循环读取,例如读取顺序为“缓存插入内部队列-缓存删除内部队列-缓存策略更新内部队列”,则第二独立线程依据上述读取顺序,先读取缓存插入内部队列并进行数据插入,再读取缓存删除内部队列,并进行数据删除,再读取缓存策略更新内部队列,并进行缓存策略链表更新,依次循环,通过此种方式可以只需调用一次第二独立线程即可执行多个写入操作,更加方便。
目前缓存策略链表的缓存容量通常是有限的,当缓存策略链表中数据主键的数量大于缓存容量时,缓存策略链表中将无法再插入新的数据主键,进而导致数据写入时数据主键插入失败的问题。
因此,基于上述内容,针对任一实施例,在将所述数据插入本地缓存中之后,进一步的还可以包括:
判断当前缓存策略链表中数据主键的数量是否大于预设的缓存容量,若是,将当前缓存策略链表中位于表尾的数据主键删除,并将该删除的数据主键以及该删除的数据主键对应的缓存数据从本地缓存中删除。若否,则数据写入流程结束。
在本实施例中,使用的缓存策略为LRU,所以位于表尾的数据主键为最近最少使用的数据的数据主键,在数据主键数量大于缓存容量时,通过将位于表尾的数据主键删除,解决了由于缓存策略链表中数据主键数量过多导致的数据主键插入失败的问题,进而提高了数据写入成功率。
目前,本地缓存通常以哈希表的数据结构进行数据存储。为了保证多线程高并发这一场景下数据的安全访问和更新,在对本地缓存进行数据写入时,现有技术通常是对整个哈希表加锁,例如,当有线程需要更新本地缓存中的数据时,则会对整个哈希表加一把写锁,这会导致此时其他所有读取该哈希表的业务线程全部被阻塞,导致业务流程耗时过长。
为了解决现有技术存在的业务流程耗时过长的问题,基于上述内容,针对任一实施例,在将数据写入到本地缓存中时,可以采用下述方式:
计算该数据的数据主键对应的哈希值,通过所述哈希值对所述本地缓存中哈希表的桶的数量进行取模,得到对应的模值,根据所述模值确定所述数据对应的目标桶,对所述目标桶添加排他锁,并将该数据插入所述目标桶。具体的,可以利用预设的哈希算法(例如MurmurHash算法)根据数据主键计算对应的哈希值。通过此种方式,在将数据写入到本地缓存中时,只需要对该数据对应的哈希桶添加排他锁(又称写锁),这样只有同时读取该哈希桶的业务线程会阻塞,读取其他哈希桶的业务线程不会阻塞,减少了因本地缓存数据更新引起的业务线程阻塞情况,使得在高并发场景下,大大提升系统CPU利用率和减少业务流程的耗时。
如果按照现有的在访问本地缓存数据时同步更新缓存策略的机制,则为了保证缓存数据的安全就必须采用互斥锁,而在本发明实施例中,将在多线程下保证本地缓存数据安全的手段由互斥锁改成读写锁,通过异步化更新缓存策略,在本地缓存查询时,只需用读锁保证本地缓存中数据的安全读取,保证了多个读取线程之间不互斥,提升了系统并发度和处理性能。
在本发明实施例中,本地缓存中的数据变化需要及时同步到本地存储系统中,这样才能保证本地存储系统中的数据与本地缓存保持一致。
因此,基于上述内容,本发明的另一实施例,还包括:
在对本地缓存进行数据更新时,将待更新的数据和对应的操作类型写入缓存转储内部队列,所述操作类型为插入,然后后续可以在合适的时机下,通过调用第一独立线程来读取缓存转储内部队列中存储的所述目标数据和对应的操作类型,并根据操作类型将目标数据写入本地存储系统。
在对本地缓存进行数据删除,则可以将待删除的数据的数据主键和对应的操作类型写入缓存转储内部队列,所述操作类型为删除,然后后续可以在合适的时机下,通过调用第一独立线程来读取缓存转储内部队列中存储的所述目标数据主键和对应的操作类型,根据操作类型将本地存储系统中与目标数据主键对应的数据删除。
其中,缓存转储内部队列为预先创建的用于存储本地存储系统中待处理的数据和/或对应的数据主键的内部队列。
第一独立线程为预先创建的用于基于缓存转储内部队列中存储内容对本地存储系统进行处理的独立线程。
在本实施例中,对本地存储系统的写操作也采用独立的线程,从而可以先通过将本地存储系统中待处理的数据和/或对应的数据主键写入到缓存转储内部队列中,然后再根据需求选取合适的时机,基于缓存转储内部队列中的内容对本地存储系统中的数据进行处理,无需同步对本地存储系统进行数据处理,实现本地缓存系统的异步转储。
本实施例,通过对本地存储系统进行数据处理,可以保证本地存储系统中存储的数据与本地缓存中的数据一致,保证了后续服务启动时,本地缓存中恢复的数据的准确性。
本发明实施例还提供了一种数据处理系统,用于实现上述任一实施例所述的数据处理方法,下面结合附图对本发明实施例提供的系统进行说明。
参见图5,为本申请实施例示出的一种数据处理系统架构示意图,该数据处理系统可以应用于本地缓存,用于对本地缓存的数据进行处理。
如图5所示,数据处理系统可以包括:初始化模块501、本地缓存管理模块502、本地缓存转储模块503、远程数据拉取模块504和消息队列消费模块505。需要说明的是,这里所说的模块是广义的,可以是类、函数、线程、进程等。
其中,初始化模块501,主要负责进行一些初始化工作,在服务启动时由调用端(例如业务层)调用,该模块接收调用端调用时传入的缓存策略链表缓存容量大小、数据转换回调函数等参数,并将这些参数保存,以便后续流程使用,其中数据转换回调函数是一种回调函数,负责将字符串数据转换成缓存格式数据,由于该转换过程是个性化实现,所以转换逻辑由调用端提供。
本地缓存管理模块502,主要负责对本地缓存中存储的缓存策略链表和数据进行管理。可包含本地缓存策略子模块和本地缓存数据存储子模块,其中本地缓存策略子模块负责管理缓存策略链表,本地缓存数据存储子模块用于对缓存的数据进行存储。本地缓存管理模块还包括三种实现方法,分别为本地缓存策略实现方法、本地缓存数据存储方法以及本地缓存管理方法。下面分别针对这三种实现方法进行说明:
本地缓存策略实现方法:在本实施例中,缓存策略链表中存储的是本地缓存中存储的数据的主键,而不是数据本身,因为数据的主键往往比较小,所以保存数据主键会比较轻量。在对缓存策略链表中所属元素的增加、删除或调整等均操作的是键值。本地缓存策略实现方法主要为采用LRU本地缓存淘汰策略对缓存策略链表中的主键进行调整。LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。
本地缓存数据存储实现方法:本地缓存中缓存的数据以哈希表的数据结构存储,由于在多线程并发访问环境下,需要保证缓存数据的安全更新和访问,本实施例采用了分而治之的存储机制。
本地缓存管理实现方法:主要用于实现本地缓存数据的查询、缓存策略调整、缓存数据插入、缓存数据删除等操作,具体实现如下:
1)缓存数据查询:直接查找本地缓存的数据并进行数据返回,而缓存策略链表不进行同步更新,而是采用本地缓存淘汰策略异步化更新机制对缓存策略链表进行异步更新。
2)缓存策略更新:直接调用本地缓存策略子模块,根据LRU本地缓存淘汰策略将要本地缓存中调整的数据的主键调整到缓存策略链表的表头。
3)缓存数据插入:先调用本地缓存策略子模块,将要插入的数据的主键插入缓存策略链表的表头,若本地缓存策略子模块返回插入成功,则将要插入的数据插入到缓存数据存储子模块。
4)缓存数据删除:先调用本地缓存策略子模块将要删除的数据的主键从缓存策略链表中删除,再调用缓存数据存储子模块将要删除的数据从本地缓存中删除。
本地缓存转储模块503,主要负责将本地缓存管理模块中缓存的数据转储到本地存储系统中。
远程数据拉取模块504,主要负责将本地缓存中不存在的数据从远程数据库拉取到本地。该模块实现封装了远程数据库对应的客户端访问程序,可以访问和拉取远程数据库中的数据,支持批量数据拉取,以及分库访问机制。
消息队列消费模块505,主要负责消费消息队列中的数据更新或者数据删除等数据处理消息,该模块支持断点消费。在应用本地缓存+远程数据库这一存储方案时,当远程数据中的数据发生了更新或删除等时,本地缓存中对应的数据也需要进行更新或删除。在本实施例中,为保证本地缓存中数据的及时更新,采用了基于消息队列的更新事件的通知策略,数据更新上游模块(例如客户端)在将某个变化的数据更新到远程数据库的同时,将该更新通知(下称数据处理消息)写入消息队列,消息队列消费模块505消费消息队列中的数据处理消息,进行本地缓存更新。
消息队列消费模块505实现的功能主要包括:
a.封装消息队列的客户端访问程序。在本实施例中消息队列选型可以是Kafka,在实际应用中,也可以使用其他消息队列进行替换。
b.消费消息队列中的消息,对消息进行解析,确定数据处理类型(更新或删除)和对应的数据主键。
c.保存消费信息,包括订阅的Topic(即主题)、分区号以及每个分区对应的最新时间戳。
d.实现IO线程,负责定时将保存的消费信息刷到本地磁盘中的检查点文件。
e.服务启动或者模块初始化时加载检查点文件并根据检查点文件中保存的消费消息的时间戳对消息队列中的消息进行消费。
本发明实施例提供的数据处理系统500在运行时,主要可以实现下述6个流程:
流程1,即缓存数据的查询流程,该流程负责对业务层提供缓存数据查询的API接口传入的数据查询请求进行处理,使业务层获取缓存数据,该流程支持对批量数据进行查询。参见图6,该流程可以包括如下步骤:
a.基于数据查询请求,调用本地缓存管理模块502,根据数据查询请求中携带的数据主键在本地缓存中查找对应的数据,判断是否命中本地缓存,如果命中本地缓存,则执行b步骤,否则,执行c步骤。
b.将数据主键写入缓存策略更新内部队列,由流程4异步进行缓存策略更新,并返回命中的数据。
由于在查询本地缓存时只查找了数据,没有对应更新缓存策略,而是把缓存策略的更新操作写入内部队列,从而实现本地缓存策略异步化更新机制。
c.执行流程3,最后将数据返回。
流程2,即缓存数据的更新和删除流程,该流程由消息队列消费模块505触发,从消息队列消费模块505获取待更新的数据主键和待删除的数据主键,然后进行本地缓存的更新和删除。如图7所示,实现步骤如下:
a.遍历待更新的数据主键,执行b步骤。
b.调用本地缓存管理模块502在本地缓存中查找与待更新的数据主键对应的数据,根据是否命中本地缓存进行如下处理:
若命中,执行流程3。
若未命中,则不做任何处理。
c.遍历待删除的数据主键,执行d步骤
d.调用本地缓存管理模块502在本地缓存中查找与待删除的数据主键对应的数据,根据是否命中本地缓存进行如下处理:
若命中本地缓存,则将数据主键插入缓存删除内部队列,由流程4异步进行缓存删除处理。
若未命中,则不做任何处理。
流程3,即远程数据拉取流程,该流程负责将某条数据从远程数据库同步到本地,并缓存,如图8所示,实现如下:
a.调用远程数据拉取模块504将数据从远程拉取到本地。
b.调用数据转换回调函数进行数据格式转换。
c.将数据写入缓存插入内部队列,异步实现本地缓存的插入,该写入会触发流程4。
流程4,即本地缓存更新调度流程,该流程负责本地缓存的更新调度,如图9所示,实现如下:
a.该流程作为一个独立运行单元运行,即一写多读中的‘一写’,重复执行b步骤。
b.读取缓存插入内部队列,取出要插入本地缓存的数据信息,调用本地缓存管理模块502执行本地缓存的插入操作,将缓存数据以及插入操作类型写入缓存转储内部队列,由流程5进行异步化缓存转储。
c.读取缓存更新内部队列,取出要更新缓存策略的数据信息,调用本地缓存管理模块502执行本地缓存的策略更新操作。
d.读取缓存删除内部队列,取出要删除的本地缓存中的数据的数据信息,调用本地缓存管理模块502执行本地缓存的删除操作,将缓存数据以及删除操作类型写入缓存转储内部队列,由流程5进行异步化缓存转储。
流程5,即本地缓存转储流程,该流程负责将本地缓存中缓存数据转储到本地存储系统中,以达到持久化目的,如图10所示,实现如下:
a.该流程作为一个独立运行单元运行,重复执行b步骤。
b.从缓存转储内部队列读取要转储的字符串形式的缓存数据,判断其操作类型,若操作类型为插入,则执行c步骤;若操作类型为删除,则执行d步骤。
c.调用本地缓存转储模块503的数据插入方法。
d.调用本地缓存转储模块503的数据删除方法。
流程6,即本地缓存还原流程,该流程负责在服务启动时将本地存储系统中转储的缓存数据还原到服务启动前的内存状态,如图11所示,实现方法如下:
a.服务启动时调用该流程进行本地存储系统加载,按照写入的顺序进行遍历,循环执行b、c步骤。
b.调用数据转换回调函数将本地存储系统中字符串格式的数据转换成业务实际需要的数据格式。
c.调用本地缓存管理模块502将格式转换后的数据插入本地缓存。
d.待a步骤中本地存储系统加载完毕之后,调用消息队列消费模块505,消费服务离线期间没有处理的数据处理消息,以进行缓存更新,通过执行流程2来完成。
本申请另一实施例还提供了一种数据处理装置,如图12所示,该装置可以包括:
写入模块1201,用于在服务启动时,将本地存储系统中存储的数据写入本地缓存,所述数据为所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
获取模块1202,用于获取服务离线期间未处理的数据处理消息;
处理模块1203,用于根据所述数据处理消息对所述本地缓存中存储的数据进行处理。
作为一个实施例,所述写入模块1201具体用于:
对所述本地存储系统中存储的数据进行遍历,以读取所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
将所述数据和所述数据的数据主键写入缓存插入内部队列;
调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键;
将所述数据的数据主键插入缓存策略链表的表头;
将所述数据插入所述本地缓存中。
作为一个实施例,所述获取模块1202具体用于:
获取本地磁盘中的检查点文件;
确定所述检查点文件中存储的最新时间戳作为目标时间戳;
获取消息队列中,对应的时间戳在所述目标时间戳之后的数据处理消息,作为服务离线期间未处理的数据处理消息。
作为一个实施例,所述处理模块1203具体用于:
对所述数据处理消息进行解析,以获取所述数据处理消息中包含的数据处理类型和目标数据主键;
若确定所述本地缓存中存储有与所述目标数据主键对应的数据,则根据所述数据处理类型和所述目标数据主键对所述本地缓存中存储的数据进行处理。
作为一个实施例,根据所述数据处理类型和所述目标数据主键对所述本地缓存中存储的数据进行处理,包括:
若所述数据处理类型为数据更新,则从远程数据库中获取与所述目标数据主键对应的数据,将所述数据和所述数据的数据主键写入缓存插入内部队列,调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键,将所述数据的数据主键插入缓存策略链表的表头,将所述数据插入所述本地缓存中。
若所述数据处理类型为数据删除,则将所述目标数据主键写入缓存删除内部队列,调用第二独立线程读取所述缓存删除内部队列中存储的所述目标数据主键,将所述本地缓存中与所述目标数据主键对应的数据删除。
作为一个实施例,所述装置还包括(图12中未示出):
查询模块,用于接收数据查询请求,所述数据查询请求中携带有目标数据主键,若确定所述本地缓存中存储有与所述目标数据主键对应的目标数据,则将所述目标数据主键写入缓存策略更新内部队列,并将所述目标数据返回至所述数据查询请求的调用端;
调用第二独立线程读取所述缓存策略更新内部队列中存储的所述目标数据主键;
将所述目标数据主键在缓存策略链表中的位置调整至所述缓存策略链表的表头,所述缓存策略链表用于存储所述本地缓存中缓存的数据的数据主键。
作为一个实施例,所述查询模块还可以用于:
若确定所述本地缓存中未存储与所述目标数据主键对应的目标数据,则从远程数据库中获取与所述目标数据主键对应的数据;
将从远程数据库中获取的所述数据的格式转换为所述本地缓存支持的格式;
将格式转换后的所述数据和所述数据的数据主键写入缓存插入内部队列,并将格式转换后的所述数据返回至所述数据查询请求的调用端;
调用第二独立线程读取所述缓存插入内部队列中存储的所述数据和所述数据的数据主键;
将所述数据的数据主键插入缓存策略链表的表头;
在确定所述数据的数据主键插入所述缓存策略链表后,将所述数据插入所述本地缓存中。
作为一个实施例,所述装置还包括(图12中未示出):
链表更新模块,用于在将所述数据插入所述本地缓存中之后,若确定当前缓存策略链表中数据主键的个数大于预设的缓存容量,则将当前缓存策略链表中位于表尾的数据主键删除,并将该删除的数据主键以及该删除的数据主键对应的缓存数据从本地缓存中删除。
作为一个实施例,所述将所述数据插入到所述本地缓存中包括:
所述本地缓存以哈希表的数据结构进行数据存储,计算所述数据的数据主键对应的哈希值;
通过所述哈希值对所述本地缓存中哈希表的桶的数量进行取模,得到对应的模值;
根据所述模值确定所述数据对应的目标桶;
对所述目标桶添加排他锁,并将所述数据插入所述目标桶。
在本申请另一实施例中,还提供了一种电子设备,如图13所示,包括处理器1301、通信接口1302、存储器1303和通信总线1304,其中,处理器1301,通信接口1302,存储器1303通过通信总线1304完成相互间的通信;
存储器1303,用于存放计算机程序;
处理器1301,用于执行存储器1303上所存放的程序时,实现如下步骤:
在服务启动时,将本地存储系统中存储的数据写入本地缓存,所述数据为所述服务在前次运行过程中从所述本地缓存写入所述本地存储系统中的数据;
获取服务离线期间未处理的数据处理消息;
根据所述数据处理消息对所述本地缓存中存储的数据进行处理。
上述电子设备提到的通信总线1304可以是外设部件互连标准(PeripheralComponent Interconnect,简称PCI)总线或扩展工业标准结构(Extended IndustryStandard Architecture,简称EISA)总线等。该通信总线1304可以分为地址总线、数据总线、控制总线等。为便于表示,图13中仅用一条粗线表示,但并不表示仅有一根总线或一种类型的总线。
通信接口1302用于上述电子设备与其他设备之间的通信。
存储器1303可以包括随机存取存储器(Random Access Memory,简称RAM),也可以包括非易失性存储器(non-volatile memory),例如至少一个磁盘存储器。可选的,存储器还可以是至少一个位于远离前述处理器的存储装置。
上述的处理器1301可以是通用处理器,包括中央处理器(Central ProcessingUnit,简称CPU)、网络处理器(Network Processor,简称NP)等;还可以是数字信号处理器(Digital Signal Processing,简称DSP)、专用集成电路(Application SpecificIntegrated Circuit,简称ASIC)、现场可编程门阵列(Field-Programmable Gate Array,简称FPGA)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件。
在本申请另一实施例中,还提供了一种计算机可读存储介质,其特征在于,所述计算机可读存储介质上存储有数据处理方法程序,所述数据处理方法程序被处理器执行时实现上述任一所述的数据处理方法的步骤。
本申请实施例在具体实现时,可以参阅上述各个实施例,具有相应的技术效果。
需要说明的是,在本文中,诸如“第一”和“第二”等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。
以上所述仅是本申请的具体实施方式,使本领域技术人员能够理解或实现本申请。对这些实施例的多种修改对本领域的技术人员来说将是显而易见的,本文中所定义的一般原理可以在不脱离本申请的精神或范围的情况下,在其它实施例中实现。因此,本申请将不会被限制于本文所示的这些实施例,而是要符合与本文所申请的原理和新颖特点相一致的最宽的范围。
- 一种数据处理方法、装置、电子设备和存储介质
- 一种图像数据处理方法、装置、电子设备及其存储介质