具体实施方式
这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本申请相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本申请的一些方面相一致的装置和方法的例子。
图1示例了一种涉及到数据的存储和读取的场景,如图1所示,业务系统11在业务执行过程中,将产生多个业务数据,这些业务数据都将发送至后台处理系统12。当业务执行结束时,后台处理系统12可以接收到该业务过程中生成的所有业务数据,再根据这些数据进行一定的处理,可以称为“将这些数据进行合并处理”,即该处理需要所有这些数据的参与。
后台处理系统12可以是一个集群部署方式,其中可以包括多个子系统,例如Core1、Core2和Core3,上述业务系统11发送的业务数据可以随机到达其中一个子系统,并由该子系统负责对所接收到的数据进行存储;当业务执行结束时,再由某个子系统获取所有接收到的数据进行合并处理。
请继续参见图1,由于后台处理系统12本身的内存容量有限,可以使用一个存储系统来存储上述接收到的业务数据,比如,该存储系统可以是高性能分布式的缓存系统(例如,tair、leveldb等)。如图1所示,Core1、Core2和Core3可以均将接收到的业务数据存储至缓存系统13,待最后业务执行结束时再从该缓存系统13读取到所有的数据,在后台处理系统12进行处理。
为了提高后台处理系统12与缓存系统13之间,在数据的存储或读取时的网络传输速度,本申请实施例提供了一种数据存储方法,该方法在向缓存系统13存储数据时,就采用了一种与传统方式不同的存储方法,如下先对该存储方法进行说明,再描述存储之后如何基于该存储结构读取数据的方式。
结合图2所示,在缓存系统13中,设计如下存储结构:
例如,假设该缓存系统13中已经存储了一个数据集的数据,该数据集可以是某一个业务执行过程中产生的业务数据,可以包括业务数据21、业务数据22、业务数据23和业务数据24,这些业务数据中可以包括相同的用于表示从属该数据集的数据主键,比如是sofa系统中的tracerID,以标识一个业务的处理路径,这个业务的执行路径上产生的数据都携带该tracerID,就可以识别这些数据都是同一个业务产生的,以方便后续合并处理。上述例子中的各个业务数据,可以是后台处理系统12的各个子系统分别接收到并存储至该缓存系统13,比如,业务数据21是业务系统11发送给后台处理系统12中的Core1,由Core1存储至缓存系统13,业务数据22、业务数据23都是由Core2接收存储。
对于上述的数据集中数据的存储,可以是以key-value形式存储,即给定一个key,就可以查找对应的value,该value即为所存储的业务数据,而对应业务数据的key,本实施例可以称为数据索引。请继续参见图2,缓存系统13在存储数据时,包括两种类型的对应关系的存储,一种对应是“数据主键与存储标识数值的对应”,如图2所示,该数据主键是这个数据集中的各个数据中包括的一个相同的信息,可以是上述例子中提到的tracerID,后台处理系统在接收到业务系统的数据时,就可以获取到数据中携带的数据主键。而存储标识数值,可以暂时用B来表示,该数值的特点是,每次存储一个新的业务数据时,该存储标识数值都会更新。该B的作用将在另一种对应关系介绍时进行说明。
如图2所示,还有一种对应关系是“数据索引与存储数据的对应”,其中,数据索引的作用是,提供该数据索引就可以对应找到存储数据,存储数据即为上述的业务数据21、业务数据22等数据集的各个数据。数据索引的得到,就使用到了上述提到的存储标识数值B,在每次存储一个新的业务数据时,都可以根据更新后的存储标识数值B,计算得到一个数据索引。那么可以得到,不同的业务数据,存储标识数值B不同,会更新,而对应得到的数据索引也不同。比如图2中,数据索引暂时使用KB表示,KB1对应业务数据21,作为业务数据21的数据索引,KB2对应业务数据22,等。其中的KB1、KB2等都是根据B计算得到。
上述例子中,存储标识数值B的更新,可以根据预设的标识更新规则来处理,后续例子中将举一个例子进行说明,但不限于这些例子;其中的根据存储标识数值B计算数据索引KB的方法,可以根据预设的索引生成规则来计算,同样不限于后续例子中的示例。
基于上述说明的存储结构设计,图3描述了数据存储方法,该方法可以由后台处理系统执行,比如,当后台处理系统12中的其中一个子系统Core1接收到业务系统发送的数据时,就可以执行该方法,将数据存储至缓存系统13。如图3所示,该方法可以包括:
在步骤301中,根据待存储的目标数据包含的数据主键,由存储系统中获取对应数据主键的存储标识数值,按照预设的标识更新规则,更新存储标识数值。
例如,假设后台处理系统12中的其中一个子系统Core1接收到了业务系统11发送的业务数据,要将该业务数据先存储至缓存系统13,本实施例可以将该待存储的数据称为目标数据。
Core1可以由业务数据中获取携带的数据主键,比如tracerID,并根据该数据主键查询缓存系统13中的“Key-B”的对应关系,Key即为数据主键,得到对应的存储标识数值B。并且,根据预设的标识更新规则,在每次存储新的目标数据时,都要更新B,完成对B的更新。
在步骤302,将更新后的存储标识数值与数据主键对应存储至存储系统。
例如,Core1在步骤301中由缓存系统13获取到B,并更新B之后,在本步骤中,Core1还要将更新后的B与数据主键Key,存储至缓存系统13,其实就相当于是更新了缓存系统13中的存储标识数值,Key是不变的。
此外,可以由图1中看到,后台处理系统是分布式的,包括core1、core2、core3等多个core,在本步骤中,假设在某一个时刻出现多个core(例如,core1和core2)同时向缓存系统13中获取并更新B,那么这种情况下,该多个core由缓存系统13获取的B可能是相同的,按照预定规则更新后的B也是相同的,就出现向缓存系统13存储更新后的B的存储冲突,可能会导致其中部分core在向缓存系统13存储更新后的B时失败。
如果core向缓存系统13存储B失败,则该core可以重新执行一次步骤301和步骤302,直至存储成功;如果core向缓存系统13存储B成功,则可以继续执行步骤303。
在步骤303中,根据更新后的存储标识数值以及预设的索引生成规则,计算对应本次数据存储的数据索引,并将所述数据索引与待存储的目标数据,对应存储至所述存储系统。
例如,在更新了B后,Core1还可以根据预设的索引生成规则,根据更新后的存储标识数值B,计算数据索引,得到一个KB,比如,可以计算得到KB5,并将KB5与步骤301中所述的Core1接收到的业务系统的数据,对应存储至缓存系统13,以备后续根据该KB5直接获取对应的业务数据。
由上述图3所示的数据存储过程可以看到,在该过程中,后台处理系统在存储数据时,有两个阶段,一个阶段是更新缓存系统中的Key对应的存储标识数值,这个阶段需要在后台处理系统与缓存系统之间传输存储标识数值(包括获取旧的B,放回更新后的B);另一个阶段是将业务数据与数据索引对应存储至缓存系统,这个阶段需要在后台处理系统与缓存系统之间主要传输业务数据。
将这个过程与传统方式比较来看,传统方式中,缓存系统中是将包括各个业务数据的整个数据集与一个数据主键Key建立对应存储,Core需要根据Key将整个数据集取出来进行更新(即将本次待存储的数据放入数据集中),再将数据集存储回缓存系统。经过比较可以看到,采用本实施例的数据存储方法后,后台处理系统与缓存系统之间传输的数据量大幅减少,比如,随着后台处理系统接收到的业务数据越来越多,数据集的规模越来越大,系统之间的传输数据量也越来越多,才造成数据传输速度缓慢,而本实施例的方法中,后台处理系统只需要将本次待存储的数据传输至缓存系统即可,并不是整个数据集,即使涉及到存储标识数值的更新,但该数值相对于数据集来说,数据量非常小。因此,数据传输速度显著提高,而且,后台处理系统也不会有过大的内存占用,即使在存储标识数值的更新过程中出现版本冲突,也只需要重新获取和更新存储标识数值即可,数据量很小。
如下结合图4来说明,对于按照图2所示的存储结构存储后的业务数据,如何读取的过程。假设一个业务执行结束,整个数据集的业务数据都已经存储入缓存系统13中;并且假设此时后台处理系统12中的Core3收到了业务结束的信号,该Core3需要负责将缓存系统13中该业务的所有数据取出来,在后台处理系统进行处理。那么该Core3可以执行图4的流程,来读取数据集中的数据,同样,本实施例的数据集中包括的各个业务数据也可以称为目标数据。如图4所示,该方法可以包括:
在步骤401中,根据所述数据主键,由存储系统中获取对应所述数据主键的存储标识数值。
例如,当Core3要读取一个业务对应的数据集时,该业务的业务数据具有的数据主键,Core3是可以获知的,相当于该业务的一个标识。本步骤中,Core3可以由缓存系统中查找到对应数据主键Key的存储标识数值B。
需要说明的是,缓存系统中可以存储有多种业务的数据,每一种业务的数据可以具有不同的数据主键Key,而其中的每一种业务的数据,都可以按照图2所示的结构来存储。只要后台处理系统获得所要读取的数据集中数据的数据主键,就可以得到缓存系统中与该主键对应的存储标识数值B。
在步骤402中,根据所述存储标识数值、标识更新规则和索引生成规则,计算得到所述数据集中的各个目标数据分别对应的数据索引。
本实施例中,当Core3获得存储标识数值时,这个数值是经过数据集中多个业务数据的多次存储的过程,更新后的最新的存储标识数值,每一次存储数据都会更新一次。并且,只要Core3知道标识更新规则,就可以计算得到存储标识数值的历次数值,比如,假设当前的存储标识数值是5,并且已知标识更新规则是每次存储时加一,且初始值是1,就可以得到历次的存储标识数值的数值是1、2、3、4、5。该每一个数值都对应着一次存储数据。
如果Core3知道索引生成规则,就可以根据历次的存储标识数值,计算得到每次存储的数据的数据索引。比如,图2中的KB2即为由B根据索引生成规则计算得到,Core3也可以根据规则计算,得到各个目标数据分别对应的数据索引,比如可以计算得到KB1、KB2、KB3等。
在步骤403中,根据所述各目标数据分别对应的数据索引,由存储系统中获取对应所述数据索引的各个目标数据。
本步骤中,当Core3已经计算出来待读取的数据集中的各个数据的数据索引时,就可以根据索引读取数据集中的各个目标数据了。比如,可以分别根据各个数据的数据索引,逐个数据进行读取,或者也可以并发读取。
如下通过一个具体的实现应用例,来再次描述一下采用本申请的数据存储方法,向存储系统存储和读取数据的过程。
在本例子中,假设后台处理系统12中的Core1、Core2、Core3都会向缓存系统13存储一次数据,并且Core2先存储,然后依次是Core3、Core1存储,并假设最后由Core3执行数据集的读取。可以按照如下的流程执行:
第一步:Core2系统根据key查询,向缓存系统发送获取key对应的存储标识数值B的指令get(key)。如果缓存系统返回null,则表示此时存储系统中还没有存储该数据集的数据,该数据集即具有Key的数据组成的集合,目前该集合为空。
本实施例中,key对应的存储标识数值B可以是一个计数器的计数值,用counter表示;并且,假设预设的标识更新规则为,将counter的初始值设定为1,且每次存储一个新的目标数据时,将所述计数器counter的计数值累积加一。那么,上述Core2根据Key查询得到的结果是null,则可以接着初始化counter为1,并将更新后的counter存储入缓存系统,使用指令put(key,1)。
接着,Core2可以根据更新后的counter1,生成数据索引。本例子中,假设索引生成规则可以是,将数据主键Key和计数器的计数值counter进行组合,得到所述数据索引。这里列举一种组合的方式,即将Key和counter组合成组合计数器Ckey,该Ckey的形式可以为key_counter。根据该方法,Core2得到的Ckey是key_1,这就是Core2要存储的数据对象object1的数据索引。
在计算出数据索引后,Core2使用指令put(key_1,object1),将数据索引及对应的数据存储入缓存系统。可以看到,本次Core2在存储数据object1时,使用了一次get(获取key对应的counter),两次put(一次是存储更新后的counter,一次是存储Ckey对应的数据,索引的计算可以在后台处理系统执行)。后面的Core3和Core1存储数据,方法与Core2相同,不再详述。
第二步:Core3系统根据key查询,得到计数器counter为1,累积加1后,counter数值更新为2,执行put(key,2),将更新后的counter存储入缓存系统。执行成功后,Core3根据counter数值2和key,计算得到本次数据的数据索引即组合计数器Ckey为key_2,并执行put(key_2,object2),其中,object2为本次Core3存储的数据。
第三步:Core1系统根据key查询,得到计数器counter为2,累积加1后,counter数值更新为3,执行put(key,3),将更新后的counter存储入缓存系统。执行成功后,Core1根据counter数值3和key,计算得到本次数据的数据索引即组合计数器Ckey为key_3,并执行put(key_3,object3),其中,object3为本次Core1存储的数据。
第四步:收到业务结束信号的系统,假如是Core3,它首先get(key),得到counter为3,然后,根据counter的初始值是1,且更新规则是每次存储就加一,可以得到counter的历次变更值为1、2、3。接着,根据数据索引的生成规则,是将key与counter的数值按照“key_counter”的形式组合,则可以计算出数据索引Ckey有(key_1,key_2,key_3)。Core3可以执行命令mget(key_1,key_2,key_3),得到object List,该List中包括object1、object2、object3,则Core3已经读取到整个数据集,可以开始处理数据。
为了实现上述方法,本申请还提供了一种数据存储装置,该装置例如可以应用于图2中的后台处理系统,使得后台处理系统可以执行本申请实施例的方法,以由缓存系统存储和读取数据。如图5所示,该装置可以包括:标识更新模块51、标识存储模块52和数据存储模块53。
标识更新模块51,用于根据待存储的所述目标数据包含的数据主键,由存储系统中获取对应所述数据主键的存储标识数值;按照预设的标识更新规则,更新所述存储标识数值;
标识存储模块52,用于将更新后的所述存储标识数值与数据主键对应存储至所述存储系统;
数据存储模块53,用于当所述存储标识数值与数据主键存储成功时,根据更新后的存储标识数值以及预设的索引生成规则,计算对应本次数据存储的数据索引,并将所述数据索引与待存储的目标数据,对应存储至所述存储系统。
参见图6,该装置还可以包括:标识获取模块54、索引计算模块55和数据读取模块56。
标识获取模块54,用于当要读取所述数据集中包括的各个目标数据时,根据所述数据主键,由存储系统中获取对应所述数据主键的存储标识数值;
索引计算模块55,用于根据所述存储标识数值、标识更新规则和索引生成规则,计算得到所述数据集中的各个目标数据分别对应的数据索引;
数据读取模块56,用于根据所述各目标数据分别对应的数据索引,由存储系统中获取对应所述数据索引的各个目标数据。
在一个例子中,存储标识数值是一个计数器的计数值;所述标识更新模块51,用于按照预设的标识更新规则,将所述计数器的计数值累积加一。
在一个例子中,所述索引生成规则,包括:将所述数据主键和计数器的计数值组合,得到所述数据索引。
在一个例子中,所述存储系统为分布式缓存系统。
以上所述仅为本申请的较佳实施例而已,并不用以限制本申请,凡在本申请的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本申请保护的范围之内。