数据存储方法、装置、计算机设备及存储介质与流程

文档序号:32206899发布日期:2022-11-16 04:55阅读:61来源:国知局
数据存储方法、装置、计算机设备及存储介质与流程

1.本技术实施例属于区块链技术领域,特别是涉及数据存储方法、装置、计算机设备及存储介质。


背景技术:

2.区块链的状态数据,也称为账户数据,是指区块链上所有账户状态的集合,用于记录区块链系统中事务关联的账户信息,如账户私钥、账户公钥、账户资产、数字证书等。状态数据常被储存在账户拥有者处。由于区块链技术在应用中常面临大量状态数据写入的场景,因此区块链的存储数据库需要拥有高效的写入性能和随机读取性能,同时能够进行回滚等操作。在现有技术中,区块链状态数据常以键值对形式进行存储,因此传统的区块链系统常使用键对型数据库对状态数据库进行存储,例如leveldb数据库。但直接使用leveldb数据库对状态数据进行存储难以满足实际应用时区块链系统对数据的高效写入需求。


技术实现要素:

3.有鉴于此,本技术实施例提供了一种数据存储方法、装置、计算机设备及存储介质,可以解决现有技术中数据存储时,将数据写入数据库时效率较低的问题。
4.第一方面,本技术实施例提供了一种数据存储方法,应用于区块链,所述方法包括:
5.构建包括多个节点的双向链表每个所述节点包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量;
6.将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据;
7.将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述链表的内存临时数据库中。
8.本技术实施例的第二方面提供了一种数据存储的装置,应用于区块链,所述装置包括:
9.链表构建模块,用于构建包括多个节点的链表,每个所述节点包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量;
10.区块数据缓存模块,用于将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据;
11.区块数据写入模块,用于将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述链表的内存临时数据库中。
12.本技术实施例的第三方面提供了一种计算机设备,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时实现如上述第一方面所述的数据存储方法。
13.本技术实施例的第四方面提供了一种计算机可读存储介质,所述计算机可读存储
介质存储有计算机程序,所述计算机程序被处理器执行时实现如上述第一方面所述的数据存储方法。
14.本技术实施例的第五方面提供了一种计算机程序产品,当所述计算机程序产品在计算机上运行时,使得所述计算机执行上述第一方面所述的数据存储方法。
15.与现有技术相比,本技术实施例具有以下优点:
16.在本技术实施例中,存储数据时,可以首先构建包括多个节点的链表,每个节点可以包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量。这样,对于待存储的数据,可以按区块将其存储至新建的批处理单元中,使得每个批处理单元存储一个区块中的数据。然后,可以将批处理单元中的数据以并行的方式写入硬盘上的预写日志和链表的内存临时数据库中。由于在数据写入预写日志时,主要进行的是io操作,而数据写入内存临时数据库内主要进行的是cpu和内存的操作,二者相互独立。因此,本技术实施例将二者并行执行,能够提高数据写入的效率。此外,本技术实施例通过链表存储数据,可以控制每个内存临时数据库的容量大小,将检查点交给链表进行管理,可以解决传统区块链数据存储方案中,由于区块包含的数据总体积不可控而导致的持久化过程中过多的io操作和过慢的合并操作的问题。
附图说明
17.为了更清楚地说明本技术实施例中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单的介绍。显而易见地,下面描述中的附图仅仅是本技术的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
18.图1是本技术实施例提供的一种数据存储方法的示意图;
19.图2是本技术实施例提供的一种链表的示意图;
20.图3是本技术实施例提供的另一种数据存储方法的示意图;
21.图4是本技术实施例提供的一种双向链表的示意图;
22.图5是本技术实施例提供的一种数据存储方法中s303的一种实现方式的示意图;
23.图6是本技术实施例提供的一种数据回滚操作的示意图;
24.图7是本技术实施例提供的一种数据存储装置的示意图;
25.图8是本技术实施例提供的一种计算机设备的示意图。
具体实施方式
26.以下描述中,为了说明而不是为了限定,提出了诸如特定系统结构、技术之类的具体细节,以便透彻理解本技术实施例。然而,本领域技术人员应当清楚,在没有这些具体细节的其他实施例中也可以实现本技术。在其他情况中,省略对众所周知的系统、装置、电路以及方法的详细说明,以免不必要的细节妨碍本技术的描述。
27.下面通过具体实施例来说明本技术的技术方案。
28.参照图1,示出了本技术实施例提供的一种数据存储方法的示意图,具体可以包括如下步骤:
29.s101、构建包括多个节点的链表,每个所述节点包括内存临时数据库、起始序列
号、结束序列号,并配置有相应的最大存储容量。
30.需要说明的是,本方法可以应用于区块链中,本技术实施例的执行主体可以是计算机设备,上述计算机设备可以是台式计算机、云端服务器等设备,本技术实施例对计算机设备的具体类型不作限定。
31.参见图2,是本技术实施例提供的一种链表的示意图,该链表可以包括多个节点,例如图2中所示的链表包括3个节点。其中,链表的第一个节点称为头节点,链表的最后一个节点被称为尾节点,每个节点之间通过两个指针连接。每个节点内均包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量。例如,在一些场景中,链表每个节点的最大存储容量可以设置为4.5m(兆字节),上述数值可以表示链表的每个节点最多存储4.5m大小的数据。
32.因此,在实现本技术实施例提供的数据存储方法时,可以首先构建一链表。在本技术实施例中,链表可以在软件初始化时通过代码层面建立。同时,在建立链表的数据结构时,可以在软件层面对双向链表进行上锁,从而实现链表的并发安全。具体的,当涉及新增节点或删除节点等改变链表结构的操作时,可以对链表上写锁;当涉及读取链表节点上的数据时,可以对链表上读锁。
33.在本技术实施例中,链表各个节点的起始序列号可以为写入该节点的区块数据的序列号的最小值。相应地,链表中各个节点的结束序列号可以为写入该节点的区块数据的序列号的最大值。链表中各个节点可以按照节点对应的起始序列号的大小排列。具体的,起始序列号小的节点排在起始序列号大的节点的前面。例如,在某一链表中,节点1存储了区块序列号为1、2、3、4的状态数据,则该节点的起始序列号为1,结束序列号为4;节点2存储了区块序列号为5、6、7、8的状态数据,则该节点的起始序列号为5,结束序列号为8,且节点1排在节点2的前面。
34.s102、将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据。
35.需要说明的是,待存储的数据可以是任意类型的数据。例如,待存储的数据可以是任意类型的键值型数据,在实际应用中,区块链的状态数据便是一种键值型数据,因此为了更直观地描述本技术的技术方案,下述实施例中均以区块链中的状态数据这一键值型数据为例,来进行说明。即,将状态数据作为待存储数据,来介绍如何利用构建的链表存储状态数据。
36.在本技术实施例中,状态数据的写入可以以批处理单元(batch)为单位,批处理单元可以是以数组形式存在。每个区块的状态数据可以首先存储至一个由数组实现的batch中,针对状态数据所有的添加、删除等操作都以追加(append)的形式加入到数组中。因此,在获取到状态数据后,可以首先将每个区块的状态数据按区块分别存储在批处理单元中,一个区块的状态数据对应一个批处理单元。在后续过程中,当需要对状态数据进行添加、删除等操作时,都可以将同一区块内的数据当作一个整体的对象对其进行操作,以保证对状态数据有序且高效的存储。
37.例如,当有10个区块的状态数据需要写入链表的内存临时数据库时,可以首先依次新建10个批处理单元,然后将10个区块的状态数据依次写入新建的批处理单元中,一个批处理单元存储一个区块的状态数据。通过新建的批处理单元,将10个区块的状态数据写
入链表的内存临时数据库。
38.s103、将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述链表的内存临时数据库中。
39.需要说明的是,为了保证待存储的状态数据不会因为系统宕机而导致数据丢失,本技术实施例中,会在将待存储的状态数据写入内存临时数据库的同时,以并行的方式将待存储的状态数据写入到硬盘上的预写日志中。在区块链状态数据的存储过程中,在待存储的状态数据写入到磁盘后,可以先将数据写入内存临时数据库以等待区块链网络进行共识,因此链表中每个节点的内存临时数据库都是一个跳表。
40.在本技术实施例的写入操作中,每次将待存储的区块状态数据写入批处理单元的同时,以批处理单元为单位对各个批处理单元内存储的数据调用写入方法,将批处理单元中存储的数据以并行的方式同时写入硬盘上的预写日志中和链表上的内存临时数据库中。
41.在现有的区块链状态数据存储技术中,常以串行的方式将待存储的状态数据写入预写日志和内存临时数据库,即先将待存储的状态数据写入硬盘上的预写日志中再将其写入内存临时数据库中。但是将待存储的状态数据写入硬盘上的预写日志中主要进行的是io操作,而将待存储的数据写入内存临时数据库中则主要是对cpu和内存进行操作,二者相互独立。因此本技术所述技术方案将批处理单元中存储的数据以并行的方式同时写入硬盘上的预写日志中和链表上的内存临时数据库中,能提高数据存储的总体效率,尤其是在io速度较慢的机械硬盘上,数据存储速度提升的效果尤为明显。
42.在本技术实施例中,存储数据时,可以首先构建包括多个节点的链表,每个节点可以包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量。这样,对于待存储的数据,可以按区块将其存储至新建的批处理单元中,使得每个批处理单元存储一个区块中的数据。然后,可以将批处理单元中的数据以并行的方式写入硬盘上的预写日志和链表的内存临时数据库中。由于在数据写入预写日志时,主要进行的是io操作,而数据写入内存临时数据库内主要进行的是cpu和内存的操作,二者相互独立。因此,本技术实施例将二者并行执行,能提高数据写入的效率。此外,本技术实施例通过链表存储数据,可以控制每个内存临时数据库的容量大小,将检查点交给链表进行管理,可以解决传统区块链数据存储方案中,由于区块包含的数据总体积不可控而导致的持久化过程中过多的io操作和过慢的合并操作的问题。
43.参照图3,示出了本技术实施例提供的另一种数据存储方法的示意图,具体可以包括如下步骤:
44.s301、构建双向链表,所述双向链表包括多个节点,每个所述节点包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量。
45.在本技术实施例中,可以采用链表来存储数据并实现后续的数据读取及持久化等操作。通常,在从链表中读取数据时,由于读取数据常常需要读取最新的数据,而链表后面节点存储的数据的键有可能与链表前面节点存储的数据的键相同,因此在读取链表数据时,可以从后往前遍历链表。同样地,在对链表中的数据进行持久化时,持久化后需要保证存储在数据库最后的数据为最新写入的数据,而链表后面节点存储的数据的键有可能与链表前面节点存储的数据的键相同,如果持久化时先写入后面的节点的数据,则前面节点的老数据会覆盖具有相同键的新数据。因此在持久化过程中,通常从前往后遍历链表。为了控
制读取链表数据和将链表数据持久化的操作时间复杂度,因此可以将链表设计为双向链表。在具体实现中,如图4所示,是本技术实施例提供的一种双向链表的示意图,可以通过在链表的每个节点均设置两个指针,一个指针指向指针所在节点的上一个节点,另一个指针指向所在节点的下一个节点,如此便可实现双向链表。
46.s302、将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据。
47.由于本实施中s301-s302与前一实施例中s101-s102类似,可以相互参阅,本实施例对此不再赘述。
48.s303、将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述双向链表的内存临时数据库中。
49.在本技术实施例的一种可能的实现方式中,如图5所示,s303中,将批处理单元中的数据以并行的方式写入硬盘上的预写日志和双向链表的内存临时数据库中,具体可以包括如下步骤s3031-s3034:
50.s3031、判断将待写入的所述批处理单元中的数据写入所述双向链表的尾节点后,所述尾节点的大小是否大于配置的每个所述节点的最大存储容量。
51.在本技术实施例的写入操作中,将批处理单元中存储的状态数据写入双向链表中的内存临时数据库时,可以首先判断写入待存储的状态数据后当前尾节点的大小是否大于尾节点能存储的最大数据容量,即判断待写入的状态数据能否写入当前尾节点的内存临时数据库中。
52.若尾节点的大小大于配置的每个节点的最大存储容量,则可以执行s3032;若尾节点的大小小于或等于配置的每个节点的最大存储容量,则可以执行s3033。
53.s3032、在所述双向链表中新建尾节点,并将待写入的所述批处理单元中的数据写入新建的所述尾节点中,更新新建的所述尾节点的起始序列号、结束序列号为新写入的所述批处理单元中第一个区块和最后一个区块的序列号。
54.在本技术实施例的写入操作中,若判断写入待存储的状态数据后当前尾节点的大小大于双向链表中节点的最大存储容量,可以新建尾节点来写入待存储的状态数据,并在写入待存储的状态数据的同时,可以更新新建尾节点的起始序列号为第一个写入的状态数据的区块序列号,更新新建尾节点的结束序列号最后一个写入的状态数据的区块序列号。
55.例如,若有10个批处理单元的状态数据需要写入双向链表时,假设每个批处理单元的大小都为1m,双向链表配置的最大存储容量为4.5m。那么在写入第1~4个批处理单元时,可以判断第1~4个批处理单元写入当前双向链表第一节点后,该节点的大小为4m,小于配置的节点最大存储容量4.5m,因此第1~4个批处理单元会被写入双向链表的第一节点。当写入到第5个批处理单元时,可以判断第5个批处理单元写入双向链表的第一节点后,第一节点的大小为5m大于配置的节点最大存储容量4.5m,则会判断第一节点已经满了,因此可以在双向链表上新建第二节点,将第5个批处理单元写入双向链表的第二节点中。同理可得,第5~8个批处理单元会被写入到双向链表的第二节点中,第9~10个批处理单元会被写入双向链表的第三节点中。在将批处理单元的状态数据写入新建尾节点的同时,更新尾节点的起始序列号和结束序列号。具体到本示例中,将第5个批处理单元写入双向链表新建的第二个节点时,可以更新第二个节点的起始序列号为5、结束序列号为5。将第9个批处理单
元写入双向链表新建的第三个节点的内存临时数据库时,可以更新第三个节点的起始序列号为9、结束序列号为9。
56.s3033、将待写入的所述批处理单元中的数据写入所述尾节点,并更新所述尾节点的结束序列号为新写入的最后一个区块的序列号。
57.在本技术实施例的写入操作中,若判断写入待存储的状态数据后当前尾节点的大小小于或等于双向链表中节点的最大存储容量,则待存储的状态数据可以写入当前尾节点的内存临时数据中,可以不新建尾节点。在将待存储的状态数据写入当前尾节点的内存临时数据的同时,可以更新当前尾节点的结束序列号为写入的状态数据的区块序列号。
58.例如,若有10个批处理单元的状态数据需要写入双向链表时,假设每个批处理单元的大小都为1m,双向链表配置的最大存储容量为4.5m。那么在写入第1~4个批处理单元时,可以判断第1~4批处理单元写入当前双向链表第一个节点后,该节点的大小为4m,小于配置的节点最大存储容量4.5m,因此第1~4个批处理单元会被写入双向链表的第一个节点。在判断待存储的状态数据能够写入当前尾节点后,每次写入一个批处理单元的同时,会更新当前数据写入的尾节点结束序列号为写入的状态数据的区块序列号,具体到本示例中,当第1个批处理单元写入双向链表第一节点的内存临时数据时,第一节点的结束序列号更新为1;当第4个批处理单元写入双向链表第一节点的内存临时数据库时,第一节点的结束序列号更新为4。
59.s3034、更新所述双向链表中每个节点的大小。
60.在本技术实施例中,完成数据写入操作后,还可以更新写入状态数据后各个节点的大小。
61.例如,若有10个批处理单元的状态数据需要写入双向链表,假设每个批处理单元的大小都为1m,双向链表节点配置的最大存储容量为4.5m。那么在写入第1~4个批处理单元时,可以判断第1~4批处理单元写入当前双向链表第一节点后,第一节点的大小为4m,小于配置的节点最大存储容量4.5m,因此第1~4个批处理单元会被写入双向链表的第一节点,并更新双向链表第一节点的大小为4m。
62.在本技术实施例中,双向链表的每个节点都配置有最大存储容量,并在写入过程中每写入一个批处理单元之前,可以判断将待写入的批处理单元中的数据写入双向链表当前的尾节点后,当前尾节点的大小是否大于配置的每个节点的最大存储容量。若当前尾节点容量已满,可以新建尾节点对待存储的状态数据进行存储。通过这种方式,能够确保双向链表中的每个节点存储的状态数据大小是恒定的,从而确保每次写入数据库的状态数据大小是恒定的。本技术实施例通过构建双向链表,将多个批处理单元写入双向链表的一个节点中,再将批处理单元中的状态数据以节点为单位写入数据库中,能够控制状态数据每次写入数据库时的大小,从而能减少数据库的合并操作,以达到提高数据存储速度的效果。
63.在本技术实施例的一种可能的实现方式中,将批处理单元中的数据以并行的方式写入硬盘上的预写日志和双向链表的内存临时数据库中之后,还包括:
64.若系统宕机导致存储在双向链表的内存临时数据库中的数据丢失,可以根据硬盘上的预写日志中存储的状态数据重建双向链表的内存临时数据库。
65.为了保证待存储的状态数据不会因为系统宕机而导致数据丢失,本技术实施例中,会在将待存储的状态数据写入内存临时数据库的同时,以并行的方式将待存储的状态
数据写入到硬盘上的预写日志中。当系统宕机时,存储在双向链表节点的内存临时数据库上的状态数据会丢失,但是写入硬盘上的状态数据并不会因为系统宕机而丢失。因此,系统宕机时可以根据硬盘上的预写日志存储的状态数据来对双向链表的内存临时数据库进行数据恢复。
66.s304、确定所述双向链表中待持久化的内存临时数据库。
67.在本技术实施例的一次持久化操作中,并非所有区块序列号小于等于最新写入数据的区块序列号的状态数据都会进行持久化操作。因此,可以先确定出双向链表中需要进行持久化操作的内存临时数据库。
68.进一步地,s304中,确定双向链表中待持久化的内存临时数据库具体可以包括:
69.从后往前遍历双向链表,获得双向链表中各个节点的大小及结束序列号。
70.将所在节点的大小达到配置的最大存储容量且所在节点的结束序列号小于或等于尾节点的结束序列号的内存临时数据库确定为待持久化的内存临时数据库。
71.需要说明的是,在传统的区块链数据存储方案中,数据的持久化操作常发生在数据的稳定检查点(checkoutpoint),若某段区间内的数据通过了稳定检查点,则代表这段区间内的状态数据是一致的没有异常的,再对通过稳定检查点的数据通过保存(commit)指令调用数据库,将区块序列号在两个检查点序号之间的固定数量的状态数据持久化到数据库中。在本技术实施例的持久化操作过程中,调用保存指令后不是立即将区块序列号在两个检查点序号之间的固定数量的状态数据持久化到数据库中,而是可以先更新最后一次保存的数据区块序列号为调用保存指令时传入的状态数据区块序列号,即先更新最近一次保存的值(lastcommit值)为最新写入双向链表的批处理单元的区块序列号。然后从后往前遍历双向链表中所有内存临时数据库,挑选出双向链表中节点大小已经达到配置的最大存储容量且结束序列号小于或等于最后一次保存的数据的区块序列号的节点。在本技术的实施例中,按照上述方法挑选出的符合条件的节点对应的内存临时数据库即为待持久化的内存临时数据库。
72.s305、将待持久化的所述内存临时数据库中的数据写入leveldb数据库的l0层中。
73.可以将s304中挑选出来的待持久化的内存临时数据库内保存的状态数据写入leveldb数据库的l0层中进行持久化操作。
74.需要说明的是,在本技术实施例的一种可能的实现方式中,双向链表中并非所有节点都会被写入leveldb数据库的l0层中进行持久化操作,而是只有满足节点大小已经达到配置的最大存储容量且结束序列号小于或等于最后一次保存的数据的区块序列号这两个条件的节点的内存临时数据库才会被写入leveldb数据库的l0层中进行持久化操作。由于在构建双向链表时给链表的每个节点配置了固定的最大存储容量,因此通过筛选得到的待持久化的内存临时数据库的数据大小可以是固定的。将固定大小的待持久化的内存临时数据库写入leveldb数据库的l0层时,可以避免因为写入leveldb数据库l0层的文件过小而导致的leveldb数据库大量的io操作和合并(compaction)操作,同时能避免因为写入leveldb数据库l0层中的文件过大而导致的过慢的合并操作。
75.在传统的区块链状态数据存储方案中,leveldb数据库会将待存储的状态数据先写入数据库的内存临时数据库中,内存临时数据库中的状态数据达到阈值后再将待存储的状态数据写入硬盘进行持久化储存。为了防止数据存储过程中因为系统宕机导致待存储的
状态数据丢失,leveldb数据库将待存储的状态数据写入内存临时数据库的同时,会以串行的方式将待存储的状态数据通过预写日志写入硬盘中。而在本技术实施例中,由于在数据持久化操作之前已经通过双向链表将数据写入了内存临时数据库和硬盘上的预写日志中,所以leveldb数据库将数据写入内存临时数据库和硬盘上的预写日志中的操作是冗余的。因此,在本技术实施例的一种可能实现方式中,挑选出待持久化的内存临时数据库后,可以直接将待持久化的内存临时数据库写入leveldb数据库的l0层中,从而减少了不必要的硬盘写入操作,节省了存储空间,使得数据存储的整体写入效率得到了提高。
76.在本技术实施例中,数据持久化操作之前增加了一个独立于leveldb数据库的上层操作,即先将数据存储到双向链表的内存临时数据库中,在双向链表中筛选出节点大小已经达到配置的最大存储容量的内存临时数据库,使得写入leveldb数据库的文件大小恒定,从而能避免大量的io操作或过慢的合并操作,因此能从整体上提高数据存储的效率,并且优化数据库的数据写入性能。
77.s306、删除已持久化的所述内存临时数据库的对应跳表和所述硬盘上对应的预写日志。
78.在本技术实施例中,由于已持久化的数据已经被存储进leveldb数据库的l0层,因此可以删除双向链表中对应节点的内存临时数据库内缓存的状态数据和硬盘上缓存的对应的预写日志。
79.图6为本技术实施例提供的一种数据回滚操作的示意图,具体可以包括如下步骤:
80.s601、确定待回滚区块;
81.需要说明的是,本技术实施例介绍的数据回滚操作可以是基于前述实施例介绍的方法,将数据存储至链表的内存临时数据库。数据回滚(rollback)指的是程序或数据处理错误,将程序或数据恢复到上一次正确状态的行为。
82.在本技术实施例的回滚操作中,可以首先通过恢复指令(revert)调入恢复序列号,根据恢复序列号可以确定链表中需要进行回滚操作的数据区块。
83.例如,链表已经通过图1的数据存储方法写入了10个区块的状态数据,数据的区块序列号为1~10,若需要回滚的区块的区块序列号为5,则系统在调用恢复指令时会传入5作为恢复序列号,那么待回滚的区块则为区块序列号为5~10的区块。
84.s602、删除所述链表中包含所述待回滚区块的节点以及位于所述待回滚区块的节点之后的各个节点的内存临时数据库中的数据;
85.在确定了待回滚的状态数据的区块序列号后,获取待回滚的状态数据所在的节点,并删除所在节点的内存临时数据库。
86.例如,链表已经通过图1的数据存储方法写入了10个区块的状态数据,被写入的状态数据的区块序列号为1~10,这10个区块的状态数据被写入到链表的各个节点中后,形成了如下结构[1,2,3]-[4,5,6]-[7,8,9]-[10]。在上述结构中,区块序列号为1、2、3的状态数据所在的节点为头节点,区块序列号为10的状态数据所在的节点为尾节点。若需要回滚的状态数据的区块序列号为5,则删除链表的第二节点、第三节点和尾节点的内存临时数据库中的数据,删除后链表的剩余结构为[1,2,3]。
[0087]
s603、若已删除数据的内存临时数据中包含序列号小于所述待回滚区块的序列号的目标区块,则对所述目标区块中的数据进行恢复。
[0088]
在本技术实施例中,由于回滚操作中需要对待回滚状态数据所在节点的内存临时数据库进行整体的删除,所以可能会误删内存临时数据库内存储的其他不需要进行回滚操作的状态数据。可以对误删的状态数据进行数据恢复。
[0089]
例如,链表已经通过图1的数据存储方法写入了10个区块的状态数据,被写入的状态数据的区块序列号为1~10,这10个区块的状态数据被写入到链表的各个节点中后,形成了如下结构[1,2,3]-[4,5,6]-[7,8,9]-[10]。在上述结构中,区块序列号为1、2、3的状态数据所在的节点为头节点,区块序列号为10的状态数据所在的节点为尾节点。若需要回滚的状态数据的区块序列号为5,则可以删除链表的第二节点、第三节点和尾节点的内存临时数据库中的数据,删除后链表的剩余结构为[1,2,3]。但是原链表的第二节点中包含了区块序列号为4的状态数据,由于该状态数据并非待回滚的状态数据,因此需要从硬盘上的预写日志中获得区块序列号为4的状态数据,在链表中新建节点,将区块序列号为4的状态数据重新写入到链表的新建节点中。因此,数据恢复完成后,该链表的结构为[1,2,3]-[4]。
[0090]
为了对本技术实施例做进一步的说明,下面将对s603做进一步的细化,其中对所述目标区块中的数据进行恢复具体可以包括:
[0091]
确定数据已删除的各个内存临时数据库所在节点的起始序列号的最小值;
[0092]
若最小值小于待回滚区块的序列号,则根据硬盘上的预写日志恢复序列号介于最小值与待回滚区块的序列号减一之间的各个区块上的数据;
[0093]
删除序列号大于或等于待回滚区块的序列号的各个区块对应的预写日志。
[0094]
例如,链表已经通过图1的数据存储方法写入了10个区块的状态数据,被写入的状态数据的区块序列号为1~10,这10个区块的状态数据被写入到链表的各个节点中后,形成了如下结构[1,2,3]-[4,5,6]-[7,8,9]-[10]。在上述结构中,区块序列号为1、2、3的状态数据所在的节点为头节点,区块序列号为10的状态数据所在的节点为尾节点。若此时,需要回滚的状态数据的区块序列号为6,则删除链表的第二节点、第三节点和尾节点的内存临时数据库,删除后链表的剩余结构为[1,2,3]。由于已删除内存临时数据的各个节点是起始序列号分别是4、7、10,因此,已删除内存临时数据库的节点起始序列号的最小值为4,小于待回滚区块的序列号6,可以根据硬盘上的预写日志恢复序列号为4和5的状态数据并将其写入链表的内存临时数据库中。将序列号为4和5的状态数据重新写入链表的内存临时数据库后,便可删除预写日志中序列号大于等于待回滚区块序列号的状态数据,具体到本示例中,可以删除预写日志中序列号为5~10的状态数据。若此时,需要回滚的状态数据的区块序列号为4。则删除链表的第二节点、第三节点和尾节点的内存临时数据库中的数据,删除后链表的剩余结构为[1,2,3]。由于已删除内存临时数据的各个节点是起始序列号分别是4、7、10,因此,已删除内存临时数据库的节点起始序列号的最小值为4,等于需要回滚的状态数据的区块序列号4。因此回滚过程中没有误删无需回滚的状态数据,可以直接删除预写日志中区块序列号为4~10的状态数据。
[0095]
参见图7,示出了本技术实施例提供的一种数据存储装置的示意图,该装置可以应用于区块链,该装置具体可以包括链表构建模块701、区块数据缓存模块702和区块数据写入模块703,其中:
[0096]
链表构建模块701,用于构建多个节点的链表,每个所述节点包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量;
[0097]
区块数据缓存模块702,用于将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据;
[0098]
区块数据写入模块703,用于将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述链表的内存临时数据库中。
[0099]
在本技术实施例的一种可能实现方式中,区块数据写入模块703具体可以用于:判断将待写入的批处理单元中的数据写入链表的尾节点后,尾节点的大小是否大于配置的每个节点的最大存储容量;若尾节点的大小大于配置的每个节点的最大存储容量,则在链表中新建尾节点,并将待写入的批处理单元中的数据写入新建的尾节点中,更新新建的尾节点的起始序列号、结束序列号为新写入的批处理单元中第一个区块和最后一个区块的序列号;若尾节点的大小小于或等于配置的每个节点的最大存储容量,则将待写入的批处理单元中的数据写入尾节点,并更新所述尾节点的结束序列号为新写入的最后一个区块的序列号;更新链表中每个节点的大小。
[0100]
在本技术实施例的另一种可能实现方式中,所述装置还可以包括持久化模块,持久化模块具体可以用于:确定双向链表中待持久化的内存临时数据库;将待持久化的内存临时数据库中的数据写入leveldb数据库的l0层中;删除已持久化的内存临时数据库的对应跳表和所述硬盘上对应的预写日志。
[0101]
在本技术实施例的再一种可能实现方式中,所述持久化模块还可以用于:从后往前遍历双向链表,获得双向链表中各个节点的大小及结束序列号;将所在节点的大小达到配置的最大存储容量且所在节点的结束序列号小于或等于尾节点的结束序列号的内存临时数据库确定为待持久化的内存临时数据库。
[0102]
在本技术实施例的又一种可能实现方式中,所述装置还包括数据恢复模块,具体可以用于:若区块链节点宕机导致内存临时数据库中的数据丢失,则根据预写日志重建链表的内存临时数据库。
[0103]
在本技术实施例的又一种可能实现方式中,所述装置还可以包括数据回滚模块,数据回滚模块具体可以用于:确定待回滚区块;删除链表中包含待回滚区块的节点以及位于所回滚区块的节点之后的各个节点的内存临时数据库中的数据;若已删除数据的内存临时数据中包含序列号小于待回滚区块的序列号的目标区块,则对目标区块中的数据进行恢复。
[0104]
在本技术实施例的又一种可能实现方式中,所述数据回滚模块还可以用于:确定数据已删除的各个内存临时数据库所在节点的起始序列号的最小值;若最小值小于待回滚区块的序列号,则根据硬盘上的预写日志恢复序列号介于最小值与待回滚区块的序列号减一之间的各个区块上的数据;删除序列号大于或等于待回滚区块的序列号的各个区块对应的预写日志。
[0105]
参照图8,示出了本技术实施例提供的一种计算机设备的示意图。如图8所示,本技术实施例中的计算机设备800包括:处理器810、存储器820以及存储在所述存储器820中并可在所述处理器810上运行的计算机程序821。所述处理器810执行所述计算机程序821时实现上述数据存储方法各个实施例中的步骤,例如图1所示的步骤s101至s103。或者,所述处理器810执行所述计算机程序821时实现上述各装置实施例中各模块的功能,例如图7所示模块701至703的功能。
[0106]
示例性的,所述计算机程序821可以被分割成一个或多个模块/单元,所述一个或者多个模块/单元被存储在所述存储器820中,并由所述处理器810执行,以完成本技术。所述一个或多个模块可以是能够完成特定功能的一系列计算机程序指令段,该指令段可以用于描述所述计算机程序821在所述计算机设备800中的执行过程。例如,所述计算机程序821可以被分割成双向链表构建模块、区块数据缓存模块和区块数据写入模块,各模块具体功能如下:
[0107]
双向链表构建模块,用于构建双向链表,所述双向链表包括多个节点,每个所述节点包括内存临时数据库、起始序列号、结束序列号,并配置有相应的最大存储容量;
[0108]
区块数据缓存模块,用于将待存储的数据按区块存储至新建的批处理单元中,每个所述批处理单元用于存储一个所述区块中的数据;
[0109]
区块数据写入模块,用于将所述批处理单元中的数据以并行的方式写入硬盘上的预写日志和所述双向链表的内存临时数据库中。
[0110]
所述计算机设备800可以是用于实现前述各个方法实施例的计算机设备,该该计算机设备800可以是桌上型计算机、云端服务器等计算设备。所述计算机设备800可包括,但不仅限于,处理器810、存储器820。本领域技术人员可以理解,图8仅仅是计算机设备800的一种示例,并不构成对计算机设备800的限定,可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件,例如所述计算机设备800还可以包括输入输出设备、网络接入设备、总线等。
[0111]
所述处理器810可以是中央处理单元(central processing unit,cpu),还可以是其他通用处理器、数字信号处理器(digital signal processor,dsp)、专用集成电路(application specific integrated circuit,asic)、现成可编程门阵列(field-programmable gate array,fpga)或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等。通用处理器可以是微处理器或者该处理器也可以是任何常规的处理器等。
[0112]
所述存储器820可以是所述计算机设备800的内部存储单元,例如计算机设备800的硬盘或内存。所述存储器820也可以是所述计算机设备800的外部存储设备,例如所述计算机设备700上配备的插接式硬盘,智能存储卡(smart media card,smc),安全数字(secure digital,sd)卡,闪存卡(flash card)等等。进一步地,所述存储器820还可以既包括所述计算机设备800的内部存储单元也包括外部存储设备。所述存储器820用于存储所述计算机程序821以及所述计算机设备800所需的其他程序和数据。所述存储器820还可以用于暂时地存储已经输出或者将要输出的数据。
[0113]
本技术实施例还公开了一种计算机设备,包括存储器、处理器以及存储在所述存储器中并可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时实现如前述各个实施例所述的数据存储方法。
[0114]
本技术实施例还公开了一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现如前述各个实施例所述的数据存储方法。
[0115]
本技术实施例还公开了一种计算机程序产品,当所述计算机程序产品在计算机上运行时,使得所述计算机执行前述各个实施例所述的数据存储方法。
[0116]
以上所述实施例仅用以说明本技术的技术方案,而非对其限制。尽管参照前述实施例对本技术进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本技术各实施例技术方案的精神和范围,均应包含在本技术的保护范围之内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1