一种数据处理方法和装置与流程

文档序号:16855553发布日期:2019-02-12 23:14阅读:187来源:国知局
一种数据处理方法和装置与流程

本申请涉及存储技术领域,尤其是涉及一种数据处理方法和装置。



背景技术:

key-value(键-值)数据库是目前使用最广泛的数据库,可以通过唯一标识来对数据进行存储、读取和管理,存储结构可以为树结构或者哈希结构,且可以包括lmdb(lightingmemory-mappeddatabase,内存映射数据库)等。

key-value数据库使用cow(copy-on-write,写时拷贝)技术来提供并发保护,提高数据存储的并发性,数据读写性能较高。cow技术是指:针对每次修改操作,将修改涉及的内存页拷贝一份,对原内存页不修改,修改操作集中在拷贝的新内存页。由于原内存页未修改,因此读事务可以不间断的进行访问。

但是,针对每次的修改操作,cow技术均需要拷贝大量内存页,造成大量的拷贝操作,占用大量的cpu(centralprocessingunit,中央处理器)资源。为了解决cow技术的大量拷贝问题,目前引入了mvbt(multi-versionb+tree,多版本b+树)技术,mvbt技术通过对每个key(键)增加一个生存周期(lifespan),从而可以大幅降低内存页的拷贝次数,可以节省cpu资源。

在mvbt技术中,每个内存页包括大量内存元素,为了从大量内存元素中读取到目标内存元素,需要从第一个内存元素开始进行遍历,一直到遍历出目标内存元素,上述方式需要遍历大量内存元素,会耗费大量时间,影响页内访问速度。例如,内存页包括400个内存元素,若目标内存元素是第300个内存元素,则从第一个内存元素开始进行遍历,在执行300次遍历操作后,才能够遍历到目标内存元素,耗费大量时间来执行遍历操作,影响页内访问速度。



技术实现要素:

本申请提供一种数据处理方法和装置,以减少遍历次数,提高访问速度。

第一方面,本申请提供一种数据处理方法,应用于采用mvbt存储数据的网络设备,所述网络设备的内存包括多个内存页,每个内存页包括至少一个内存元素,每个内存页均配置对应的排序数组,所述排序数组中的每个数组元素用于表征内存元素在所述内存页中的位置偏移量,所述方法包括:

在接收到读操作命令后,确定所述读操作命令携带的第一key对应的第一内存页;

从与所述第一内存页对应的第一排序数组中,获取第一数组元素表征的第一位置偏移量,并确定所述第一位置偏移量对应的所述第一内存页中的第一内存元素;

判断所述第一key和所述第一key对应的生存周期,与所述第一内存元素中记录的第二key和生存周期是否匹配;如果是,从所述第一内存元素中读取与所述第一key对应的数据部分。

第二方面,本申请提供一种数据处理装置,应用于采用mvbt存储数据的网络设备,所述网络设备的内存包括多个内存页,每个内存页包括至少一个内存元素,每个内存页均配置对应的排序数组,所述排序数组中的每个数组元素用于表征内存元素在所述内存页中的位置偏移量,所述装置包括:

确定模块,用于在接收到读操作命令后,确定所述读操作命令携带的第一key对应的第一内存页;

获取模块,用于从与所述第一内存页对应的第一排序数组中,获取第一数组元素表征的第一位置偏移量,并确定所述第一位置偏移量对应的所述第一内存页中的第一内存元素;

判断模块,用于判断所述第一key和所述第一key对应的生存周期,与所述第一内存元素中记录的第二key和生存周期是否匹配;

读取模块,用于当判断结果为是时,从所述第一内存元素中读取与所述第一key对应的数据部分。

第三方面,本申请提供一种网络设备,包括处理器和机器可读存储介质,所述机器可读存储介质存储有能够被所述处理器执行的机器可执行指令;所述处理器用于执行机器可执行指令,以实现上述的数据处理方法步骤。

第四方面,本申请提供一种机器可读存储介质,所述机器可读存储介质存储有机器可执行指令,所述机器可执行指令在被处理器调用和执行时,所述机器可执行指令可以促使所述处理器实现上述的数据处理方法步骤。

基于上述技术方案,本申请实施例中,在采用mvbt存储数据的网络设备,若网络设备的内存包括多个内存页,且每个内存页包括大量内存元素,不需要从内存页的第一个内存元素开始进行遍历,而是从与内存页关联的排序数组中选择数组元素,并从该数组元素表征的位置偏移量对应的内存元素进行遍历,从而减少遍历次数,可以快速从大量内存元素中读取到目标内存元素,节省大量时间,提高页内访问速度,使得查找效率大幅度提高,加强了读写性能。

附图说明

为了更加清楚地说明本申请实施例或者现有技术中的技术方案,下面将对本申请实施例或者现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请中记载的一些实施例,对于本领域普通技术人员来讲,还可以根据本申请实施例的这些附图获得其他的附图。

图1a-图1e是本申请一种实施方式中的采用cow存储数据的示意图;

图2a-图2i是本申请一种实施方式中的采用mvbt存储数据的示意图;

图3a和图3b是本申请一种实施方式中的数据处理方法的流程图;

图4a和图4b是本申请一种实施方式中的排序数组的示意图;

图5a-图5c是本申请一种实施方式中的堆栈数组的处理示意图;

图6是本申请一种实施方式中的数据处理装置的结构图;

图7是本申请一种实施方式中的网络设备的硬件结构图。

具体实施方式

在本申请实施例使用的术语仅仅是出于描述特定实施例的目的,而非限制本申请。本申请和权利要求书中所使用的单数形式的“一种”、“所述”和“该”也旨在包括多数形式,除非上下文清楚地表示其它含义。还应当理解,本文中使用的术语“和/或”是指包含一个或多个相关联的列出项目的任何或所有可能组合。

应当理解,尽管在本申请实施例可能采用术语第一、第二、第三等来描述各种信息,但这些信息不应限于这些术语。这些术语仅用来将同一类型的信息彼此区分开。例如,在不脱离本申请范围的情况下,第一信息也可以被称为第二信息,类似地,第二信息也可以被称为第一信息。取决于语境,此外,所使用的词语“如果”可以被解释成为“在……时”或“当……时”或“响应于确定”。

本申请实施例中提出一种数据处理方法,可以应用于采用key-value数据库存储数据的网络设备(如路由器、交换机等),key-value数据库可以包括但不限于lmdb等,后续以lmdb为例进行说明。lmdb一般存储在内存中,lmdb的存储结构可以为树结构或者哈希结构,可以使用cow技术实现数据更新。

在一个例子中,lmdb在网络设备上具有广泛使用,例如,可以将接口名称作为key,并将该接口名称的属性作为value进行查找。又例如,可以将ip地址作为key,并将该ip地址对应的acl(accesscontrollist,访问控制列表)规则作为value进行查找。当然,上述应用只是两个示例,对此不做限制。

在一个例子中,lmdb通常使用b+tree(b+树)作为存储结构,b+tree是一种按照内存页(page)分层的数据结构,b+tree可以由页节点(leafpage)和非页节点(branchpage)组成,最下层的是页节点,用于存储数据,其余层均是非页节点,用于组织key方便查找。参见图1a所示,为lmdb采用b+tree存储数据的示例,内存页5-内存页12是页节点,内存页1-内存页4是非页节点。此外,内存页5包括3个内存元素,第一个内存元素存储key5与数据的对应关系,第二个内存元素存储key8与数据的对应关系,第三个内存元素存储key9与数据的对应关系,对于其它内存页的内存元素,与内存页5类似,不再赘述。

其中,b+tree可以是一种平衡树,即任意页节点到根节点(如内存页1)的路径长度一致,为了保证b+tree的效率和平衡,则插入操作与删除操作可以满足如下约束条件:

1、对于插入操作,如果新插入数据没有超过内存元素上限(表示内存页最多容纳的内存元素数量),则直接插入数据即可。

2、对于插入操作,如果新插入数据超过内存元素上限,则对插入的内存页进行分裂;例如,新申请一个内存页,将分裂内存页的数据进行平分,并将新内存页的索引插入到分裂内存页的父节点中。

3、对于删除操作,如果删除数据后,内存页的容量(即内存元素数量)仍然大于等于总容量的1/2,则不进行任何操作。

4、对于删除操作,如果删除数据后,内存页的容量小于总容量的1/2,则根据兄弟内存页的情况进行调整;具体的,若兄弟内存页的容量小于等于总容量的1/2,则将两个内存页的数据进行合并,并更新父节点的索引;若兄弟内存页的容量大于总容量的1/2,则将两个内存页的数据进行合并后,在对这些数据进行平分。

其中,b+tree的查找方式是自顶向下,依次进入到更小的区间内,直到最底层的页节点确定查找结果。参见图1a所示,在lmdb最后一行的内存页,存储key与数据的对应关系,例如,key5的数据存储在内存页5,key8的数据存储在内存页5,以此类推,key83的数据存储在内存页12。在lmdb第二行的内存页,存储key与页指针的对应关系,如key5与内存页5的页指针存储在内存页2,key10与内存页6的页指针存储在内存页2,以此类推,key80与内存页12的页指针存储在内存页4。在lmdb第一行的内存页,可以存储key与页指针的对应关系,如key5与内存页2的页指针存储在内存页1,key28与内存页3的页指针存储在内存页1,key65与内存页4的页指针存储在内存页1。

假设需要查询key15的数据,则先查询根节点的内存页1,由于key15位于key5与key28之间,因此key15处于key5的页指针指向的内存页2,并查询内存页2。由于key15位于key10与key20之间,因此key15处于key10的页指针指向的内存页6,并查询内存页6。然后从内存页6查询到key15的数据。

在一个例子中,lmdb通常使用cow技术实现数据更新,例如,假设需要删除key83的数据,则可以采用cow技术实现数据的删除。具体的,可以对内存页12进行拷贝操作,得到一个新的内存页13,在得到内存页13后,还可以删除key83的数据,即内存页13只包括key80的数据,参见图1b所示。

然后,由于内存页4的页指针指向内存页11和内存页12,因此,在对内存页12进行拷贝操作之后,还可以对内存页11进行拷贝操作,并将拷贝操作后的内容与内存页13进行平分,得到内存页13和内存页14,参见图1c所示。然后,可以对内存页4进行拷贝操作,得到内存页15,对内存页15进行修改,得到修改后的内存页15,参见图1d所示,内存页15可以包括key65与内存页14的页指针的对应关系,key77与内存页13的页指针的对应关系。然后,可以对内存页1(即根节点)进行拷贝操作,得到内存页16,并对内存页16进行修改,得到修改后的内存页16,参见图1e所示,内存页16可以包括:key5与内存页2的页指针的对应关系,key28与内存页3的页指针的对应关系,key65与内存页15的页指针(与内存页1进行相比,针对内存页16,这里是内存页15的页指针,而不再是内存页4的页指针)的对应关系。

经过上述处理,参见图1e所示,假设需要查询key68的数据,则可以先查询根节点的内存页16(此时根节点不再是内存页1),由于key68大于key65,因此,key68处于key65的页指针指向的内存页15,并查询内存页15。由于key68位于key65与key77之间,因此,key68处于key65的页指针指向的内存页14,并查询内存页14。然后,可以从内存页14中查询到key68的数据。

综上所述,cow技术是将修改涉及的内存页拷贝一份,对原内存页不修改,修改集中在拷贝的内存页上。针对每次的修改操作,cow技术均需要拷贝大量内存页,造成大量的拷贝操作,占用大量的cpu资源。例如,针对key83的删除操作,就需要进行4次内存页的拷贝操作,从而造成大量的拷贝操作。

针对上述发现,为了解决cow技术的大量拷贝问题,可以引入mvbt技术,mvbt技术可以对b+tree进行改造,mvbt技术通过对每个key增加一个生存周期,从而可以大幅降低内存页的拷贝次数,节省cpu资源。其中,该生存周期可以记做[a,b),表示从版本a开始到版本b-1的读事务能够查询到该数据。如果b为+∞,则表示从版本a开始的所有读事务都可以查询到该数据。

以下介绍与mvbt相关的术语和符号。版本号(version):写事务可以分配版本号(相当于时间戳),本次写事务内的创建、删除会以版本号赋值,且版本号是单调递增。活key(livekey):一个key的生存周期是[a,+∞),则称该key为活key。死key(deadkey):非活key之外的其它key均为死key。活页(livepage):包含至少一个活key的内存页。死页(deadpage),即不包含活key的内存页。b:一个内存页可以容纳key的数量(即内存元素上限),每个内存页的容量是固定。m:lmdb中活key的个数。m(p):内存页p中活key的个数。k(p):内存页p中key的范围。v(p):内存页p中version的范围。kv(p):内存页p的key-version组成的矩形。min:内存页中活key个数的下限。mins:新内存页p中最小的活key个数。maxs:新内存页p中最大的活key个数。s:最小的操作个数,使得该内存页需要进行下一次分裂/合并操作。

生存周期[a,b)中的a和b是两个版本,也是写事务的事务标识和读事务的事务标识。写事务是指一次完整的数据库操作,一次写事务从开始到结束,可以包含多个针对数据库的操作(如增加、删除、修改等操作),每个写事务具有唯一的事务标识,且事务标识是递增的。例如,第一次写事务的事务标识为1,得到的是版本1的数据。第二次写事务的事务标识为2,得到的是版本2的数据,以此类推。读事务是指一次完整的数据库操作,一次读事务从开始到结束,可以包含多个针对数据库的读操作,每个读事务的事务标识是最后一次写事务的事务标识。例如,在第一次写事务后,在第二次写事务之前产生的所有读事务,则事务标识可以为第一次写事务的事务标识1,即读取版本1的数据;在第二次写事务后,在第三次写事务之前产生的所有读事务,则事务标识为第二次写事务的事务标识2,即读取版本2的数据,以此类推。

参见图2a所示,为lmdb采用mvbt存储数据的示例,内存页2和内存页3是页节点,内存页1是非页节点。在内存页2包括5个内存元素,第一个内存元素内存储key10、生存周期[1,+∞)与数据的对应关系,生存周期[1,+∞)表示第一个内存元素中的数据是第一次写事务(事务标识1)写入的,且事务标识大于等于1的所有读事务均可以读取第一个内存元素中的数据;此外,第二个内存元素内存储key15、生存周期[1,+∞)与数据的对应关系,以此类推。

为了保证mvbt的查找效率,则mvbt的内存页可以满足如下约束条件的一种:内存页的活key数量大于等于min;内存页的活key数量为0;内存页的活key数量等于m;内存页的活key数量大于等于2,且该内存页可以是根节点。此外,在mvbt的split(分裂)操作中,对于分裂后的新内存页,可以满足如下约束条件的一种或多种:m(p)小于等于maxs,m(p)大于等于mins。在mvbt中,相关参数和限制的意义在于:min用于保证整棵树的高度不会超过上限,使得mvbt树不会退化成二叉树;s、maxs、mins用于控制多少个操作后才能引起节点的分裂合并,可以保证mvbt不会频繁的进行分裂。

maxs可以大于等于2倍的mins,从而保证内存页有maxs时总能分裂成包含2个mins的内存页。例如,以b=100,min=20,s=20为例,为了使新内存页至少20次操作才继续分裂,可知mins>=min+s=40,maxs>=2*mins>=80,又由于b=100,且maxs<=b-s=80,因此可以得出,mins=40,maxs=80。基于b、min、s、mins和maxs可知,在一个内存页分裂后,新内存页的条目数在40到80之间,且至少20个插入或删除操作后才导致下一次分裂,合理设定b、min、s、mins和maxs的取值,可以保证mvbt性能。

以下结合具体应用场景,对mvbt的插入操作和删除操作进行说明。参见图2b所示,在初始状态下,lmdb为空,第一次写事务用于插入key5的数据,且第一次写事务的版本为1,则在内存页的第一个内存元素写入key5、生存周期[1,+∞)与数据的对应关系。参见图2c所示,第二次写事务用于插入key8的数据,且第二次写事务的版本为2,则在内存页的第二个内存元素写入key8、生存周期[2,+∞)与数据的对应关系;与cow技术不同的是,在插入key8的数据时,不是拷贝原内存页,在拷贝后的新内存页插入key8的数据,而是直接在原内存页插入key8的数据,避免一次拷贝操作。参见图2d所示,第三次写事务用于插入key9的数据,且第三次写事务的版本为3,则可以在内存页的第三个内存元素写入key9、生存周期[3,+∞)与数据的对应关系;与cow技术不同的是,在插入key9的数据时,不是拷贝原内存页,在拷贝后的新内存页插入key9的数据,而是直接在原内存页插入key9的数据,避免一次拷贝操作。

以下结合图2a所示的应用场景,对mvbt的插入操作和删除操作进行进一步说明。在本应用场景中,是以b=6,min=2,mins=3,maxs=5为例,即一次分裂后最少包含3个活key,最多包含5个活key。在第一次写事务结束后,lmdb中已经插入了11个key,参见图2a所示。在此基础上,假设第二次写事务用于插入key40的数据,且第二次写事务的版本为2,则在内存页2的第六个内存元素写入key40、生存周期[2,+∞)与数据的对应关系,参见图2e所示。

然后,假设第三次写事务用于删除key65的数据,且第三次写事务的版本为3,则将内存页3的第三个内存元素的生存周期修改为[1,3),参见图2f所示。在删除key65的数据时,并不是从内存页3的第三个内存元素中删除key65、生存周期与数据的对应关系,而是将生存周期修改为[1,3)。这样,基于生存周期[1,3),对于事务标识为1或2的读事务,可以读取第三个内存元素中的数据,而对于事务标识大于等于3的读事务,将无法读取第三个内存元素中的数据。然后,假设第四次写事务用于删除key35的数据,第五次写事务用于删除key15的数据,第六次写事务用于删除key30的数据,第七次写事务用于删除key25的数据,则处理后的lmdb参见图2g所示,对此处理过程不再赘述。

假设第八次写事务用于插入key5的数据,由于内存页2已经被写满6个内存元素,无法容纳key5的数据,因此进行分裂操作,将内存页2的所有活key拷贝到新的内存页4,修改内存页2中key10的生存周期和key40的生存周期,并在根节点的第三个内存元素写入key5、生存周期[8,+∞)与内存页4的页指针的对应关系,将第一个内存元素的生存周期修改为[1,8),参见图2h示。

在图2g的基础上,假设第八次写事务用于删除key40的数据,由于删除操作会导致内存页2不满足约束条件min,因此将内存页2和内存页3进行合并,才能满足mvbt的约束条件。由于合并后的内存页包括6个活key,不满足约束条件mins和maxs,因此进行均摊操作,得到内存页4和内存页5。此外,还可以更新根节点的数据,对上述操作不再赘述,最终得到图2i的示意图。

在图2g的基础上,假设某个读事务用于读取key25的数据,且读事务的事务标识为5,即读事务的版本为5,在此情况下,为精确查找key25的数据,则:

先查询根节点的内存页1,由于key25位于key10与key45之间,且版本5处于key10对应的生存周期[1,+∞),因此,key25处于key10的页指针指向的内存页2,并查询内存页2。在内存页2中,先遍历内存页2的第一个内存元素,发现第一个内存元素为key10,与待查询的key25不匹配,因此遍历内存页2的第二个内存元素,发现第二个内存元素为key15,与待查询的key25不匹配,因此遍历内存页2的第三个内存元素,发现第三个内存元素为key25,与待查询的key25匹配。然后,还可以判断待查询的版本5是否处于第三个内存元素的生存周期[1,7);如果不处于,则继续遍历内存页2的第四个内存元素,以此类推;如果处于,则说明当前查询操作命中第三个内存元素,可以从第三个内存元素中读取到与key25和版本5对应的数据,完成数据的查询操作。

综上所述,可以使用mvbt技术实现数据的写入和读取,在使用mvbt技术时,需要使用key和生存周期进行数据的写入和读取,只有key和生存周期均匹配,才能够查询到与key和生存周期对应的数据。在生存周期[a,b)中,a和b是两个版本,a表示写事务在版本a中写入数据,b表示写事务在版本b中删除数据,这样,只有从版本a开始到版本b-1的读事务能够查询到该数据。

而且,只要不违背mvbt的约束条件,无论写入操作是增加、删除还是修改,需要拷贝的内存页很少,与采用cow技术的实现方式相比,mvbt技术通过对每个key增加一个生存周期,从而降低内存页拷贝次数,节省cpu资源。

在传统方式中,是采用遍历方式获取目标内存元素,即从第1个内存元素开始依次遍历,一直到遍历到目标内存元素,需要耗费大量时间来执行遍历操作,影响页内访问速度。参见图2g所示,假设某个读事务用于读取key25的数据,则内存页1的第1个内存元素是目标内存元素,内存页2的第3个内存元素是目标内存元素。在图2g中,是以6个内存元素为例,在实际应用中,内存元素数量(即b的取值)远远大于6个,如400个等。若需要从大量内存元素中遍历出目标内存元素,显然需要执行多次遍历操作,耗费大量时间来执行遍历操作,影响页内访问速度。例如,若目标内存元素是第300个内存元素,则从第1个内存元素开始进行遍历,在执行300次遍历操作后,才能够遍历到目标内存元素。若目标内存元素是第400个内存元素,则从第1个内存元素开始进行遍历,在执行400次遍历操作后,才能够遍历到目标内存元素,以此类推。

针对上述发现,本申请实施例中,可以为每个内存页设置排序数组,该排序数组中的每个数组元素用于表征该内存页的内存元素的位置偏移量。基于此,若内存页包括大量内存元素,则不需要从第一个内存元素开始进行遍历,而是从与内存页关联的排序数组中选择数组元素,并从该数组元素表征的位置偏移量对应的内存元素进行遍历,从而减少遍历次数,快速从大量内存元素中读取到目标内存元素,节省大量时间,提高页内访问速度,使查找效率大幅度提高,加强读写性能。

本实施例中的数据处理方法,可以应用于采用mvbt存储数据的网络设备(如路由器、交换机等),该网络设备的内存包括多个内存页,每个内存页包括至少一个内存元素。参见图2g所示,以3个内存页为例,即内存页1、内存页2和内存页3。在每个内存页中,均可以包括多个内存元素,如在内存页1中,key10、生存周期[1,+∞)、内存页2的指针的对应关系,存储在第一个内存元素,且该内存元素在内存页1中的位置偏移量是1,key45、生存周期[1,+∞)、内存页3的指针的对应关系,存储在第二个内存元素,且该内存元素在内存页1中的位置偏移量是2,其它内存页的内存元素类似,在此不再重复赘述。

在一个例子中,每个内存页均配置对应的排序数组,该排序数组中的每个数组元素用于表征内存元素在内存页中的位置偏移量。例如,参见图2g所示,内存页1配置对应的排序数组a,排序数组a中记录两个数组元素,第一个数组元素用于表征内存页1的第一个内存元素在内存页1中的位置偏移量1,第二个数组元素用于表征内存页1的第二个内存元素在内存页1中的位置偏移量2。

又例如,内存页2配置对应的排序数组b,排序数组b中记录六个数组元素,第一个数组元素用于表征内存页2的第一个内存元素在内存页2中的位置偏移量1,第二个数组元素用于表征内存页2的第二个内存元素在内存页2中的位置偏移量2,以此类推。对于排序数组的相关内容,在后续实施例介绍。

在上述应用场景下,参见图3a所示,为数据处理方法的流程示意图,该数据处理方法可以用于实现数据的写入过程,该方法可以包括以下步骤:

步骤311,在接收到写操作命令后,确定该写操作命令携带的第三key对应的第二内存页。

步骤312,将该第三key、该第三key对应的生存周期和该第三key对应的数据部分,存储到该第二内存页中的第三内存元素。

其中,在第二内存页是页节点时,则第三key对应的数据部分是需要写入的数据,在第二内存页是非页节点时,则第三key对应的数据部分是下一级内存页的指针。

例如,参见图2e所示,假设接收到写操作命令后执行第二次写事务,且写操作命令携带key40和待写入的数据a,则第二次写事务的版本为2;然后,确定第三key是key40,且key40对应的生存周期是[2,+∞),key40对应的数据部分是数据a。此外,还可以确定第二内存页是内存页2,且第三内存元素是内存页2的第六个内存元素,对此确定过程不做限制。基于此,可以在内存页2的第六个内存元素中存储key40、生存周期[2,+∞)与数据a的对应关系。

参见图2h所示,假设接收到写操作命令后执行第八次写事务,且写操作命令携带key5和待写入的数据b,则第八次写事务用于插入key5的数据b,且第八次写事务的版本为8;然后,确定第三key是key5,且key5对应的生存周期是[8,+∞),key5对应的数据部分是数据b。此外,还可以确定第二内存页是内存页4,且第三内存元素是内存页4的第三个内存元素。基于此,可以在内存页4的第三个内存元素中存储key5、生存周期[8,+∞)与数据b的对应关系。

其中,可以先进行内存页的分裂操作,将内存页2的所有活key拷贝到新的内存页4,然后确定第二内存页是内存页4,第三内存元素是内存页4的第三个内存元素。此外,还可以修改内存页2中key10的生存周期和key40的生存周期,在根节点的第三个内存元素写入key5、生存周期[8,+∞)与内存页4的页指针的对应关系,将第一个内存元素的生存周期修改为[1,8),对此不再赘述。

其中,在根节点的第三个内存元素写入key5、生存周期[8,+∞)与内存页4的页指针的对应关系时,可以确定第三key是key5,且key5对应的生存周期是[8,+∞),key5对应的数据部分是内存页4的页指针,确定第二内存页是内存页1,第三内存元素是内存页1的第三个内存元素。基于此,在内存页1的第三个内存元素中存储key5、生存周期[8,+∞)与内存页4的页指针的对应关系。

当然,上述过程只是数据写入的示例,对此不做限制。在数据写入过程中,还可以涉及数据增加、删除、内存页分裂、内存页均摊、更新根节点的数据等操作,这些操作均需要满足mvbt的约束条件,对这些操作不再赘述。

步骤313,对该第二内存页中的每个内存元素的位置重新排序。

在一个例子中,对第二内存页中的每个内存元素的位置重新排序,可以包括但不限于:获取该第二内存页中的每个内存元素记录的key。然后,可以按照每个key的值从小到大的顺序,依次对每个key进行排序,得到每个内存元素的位置排序结果;或者,可以按照每个key的值从大到小的顺序,依次对每个key进行排序,得到每个内存元素的位置排序结果。

步骤314,根据第三内存元素的位置排序结果,在第二内存页对应的第三排序数组中插入数组元素,并将第三内存元素在第二内存页中的位置偏移量记录到插入的该数组元素中。

其中,根据第三内存元素的位置排序结果,在第二内存页对应的第三排序数组中插入数组元素,可以包括但不限于:拷贝与第二内存页对应的第三排序数组,得到拷贝后的第三排序数组,并保留拷贝前的第三排序数组(即不删除第三排序数组);然后,根据该位置排序结果,确定第三内存元素在该位置排序结果中的位置,并根据该位置在拷贝后的第三排序数组中的对应位置插入一个数组元素。

参见图4a所示,为lmdb的一个示例,图4a中只是示出了内存页12,还可以包括其它内存页,图4a中并未示出。在内存页12的第一个内存元素,包括key40、生存周期[25,+∞)与数据的对应关系;在内存页12的第二个内存元素,包括key55、生存周期[25,+∞)与数据的对应关系;在内存页12的第三个内存元素,包括key70、生存周期[25,+∞)与数据的对应关系;在内存页12的第四个内存元素,包括key10、生存周期[32,+∞)与数据的对应关系。

参见图4a,在内存页12对应的排序数组中,第一个数组元素用于记录内存页12的第四个内存元素在内存页12中的位置偏移量4,第二个数组元素用于记录内存页12的第一个内存元素在内存页12中的位置偏移量1,第三个数组元素用于记录内存页12的第二个内存元素在内存页12中的位置偏移量2,第四个数组元素用于记录内存页12的第三个内存元素在内存页12中的位置偏移量3。

在图4a的基础上,假设收到写操作命令后执行第33次写事务,写操作命令携带key60和待写入数据c,则第33次写事务用于插入key60的数据c,第33次写事务的版本为33。确定第三key是key60,key60对应的生存周期是[33,+∞),key60对应的数据部分是数据c。确定第二内存页是内存页12,第三内存元素是内存页12的第五个内存元素,基于此,在内存页12的第五个内存元素中存储key60、生存周期[33,+∞)与数据c的对应关系,参见图4b所示。

然后,获取内存页12中的每个内存元素记录的key,并按照每个key的值从小到大的顺序,依次对每个key进行排序,得到的排序结果是key10、key40、key55、key60、key70。由于key10对应第四个内存元素、key40对应第一个内存元素、key55对应第二个内存元素、key60对应第五个内存元素、key70对应第三个内存元素,因此,每个内存元素的位置排序结果是第四个内存元素、第一个内存元素、第二个内存元素、第五个内存元素、第三个内存元素。

然后,拷贝与内存页12关联的排序数组1,得到排序数组2,在排序数组2中,第一个数组元素用于记录位置偏移量4,第二个数组元素用于记录位置偏移量1,第三个数组元素用于记录位置偏移量2,第四个数组元素用于记录位置偏移量3。针对写操作命令携带的key60,由于key60写入到内存页12的第五个内存元素,且第五个内存元素在位置排序结果中的位置是第4个位置,因此在排序数组2的第4个位置插入一个数组元素,并将插入的数组元素分配给第五个内存元素,即在该数组元素中记录第五个内存元素的位置偏移量5,得到图4b所示的排序数组2。在排序数组2中,第一个数组元素用于记录位置偏移量4,第二个数组元素用于记录位置偏移量1,第三个数组元素用于记录位置偏移量2,第四个数组元素用于记录位置偏移量5,第五个数组元素用于记录位置偏移量3。

当然,上述方式只是一个示例,对此不做限制。例如,可以按照key的值从大到小的顺序,依次对内存页12的每个内存元素记录的key进行排序。

在上述应用场景下,参见图3b所示,为数据处理方法的流程示意图,该数据处理方法可以用于实现数据的读取过程,该方法可以包括以下步骤:

步骤321,在接收到读操作命令后,确定该读操作命令携带的第一key对应的第一内存页。

其中,第一内存页可以是页节点或者非页节点,页节点的数据部分是待读取的数据,而非页节点的数据部分是下一级内存页的指针。

例如,参见图2g所示,假设读操作命令中携带的第一key是key55,则先确定key55对应的第一内存页是根节点,也就是内存页1,然后,采用图3b所示的流程,从内存页1中读取到与key55对应的数据部分,具体读取过程参见后续实施例,从内存页1中读取到的数据部分是内存页3的指针。

然后,可以确定key55对应的第一内存页是该指针指向的内存页,也就是内存页3,然后,采用图3b所示的流程,从内存页3中读取到与key55对应的数据部分,具体读取过程参见后续实施例,从内存页3中读取到的数据部分是与key55对应的数据。当然,若从内存页3中读取到的数据部分是下一级内存页的指针,则继续确定key55对应的第一内存页,以此类推,一直到从内存页中读取到的数据部分是与key55对应的数据,结束读取过程。

为了方面描述,本实施例中,以图4b为例进行说明,假设读操作命令中携带的第一key是key55,则确定与key55对应的第一内存页是内存页12。

步骤322,从与第一内存页对应的第一排序数组中,获取第一数组元素表征的第一位置偏移量,并确定该第一位置偏移量对应的第一内存页中的第一内存元素。

其中,该第一数组元素可以为第一排序数组中中间位置的数组元素。

参见图4b所示,假设第一内存页是内存页12,则内存页12对应的第一排序数组为排序数组2,排序数组2的第一个数组元素记录位置偏移量4,第二个数组元素记录位置偏移量1,第三个数组元素记录位置偏移量2,第四个数组元素记录位置偏移量5,第五个数组元素记录位置偏移量3。然后,从排序数组2中选取中间位置的数组元素作为第一数组元素,也就是第三个数组元素。

因此,第一数组元素表征的第一位置偏移量是第三个数组元素记录的位置偏移量2,且位置偏移量2对应内存页12中的第二个内存元素,也就是说,第一位置偏移量对应的第一内存元素是内存页12中的第二个内存元素。

步骤323,判断第一key和该第一key对应的生存周期,与第一内存元素中记录的第二key和生存周期是否匹配;如果是,则可以执行步骤324。

步骤324,从该第一内存元素中读取与第一key对应的数据部分。

在一个例子中,针对步骤323,判断第一key和该第一key对应的生存周期,与第一内存元素中记录的第二key和生存周期是否匹配是否匹配,可以包括:对于页节点,若第二key与第一key相同,则确定key匹配,若第二key与第一key不同,则确定key不匹配。若第一key对应的生存周期处于第二key对应的生存周期的范围内,则确定生存周期匹配,若第一key对应的生存周期不处于第二key对应的生存周期的范围内,则确定生存周期不匹配。若key匹配且生存周期匹配,则步骤323的判断结果为匹配;若key不匹配和/或生存周期不匹配,则步骤323的判断结果为不匹配。

例如,参见图2g所示,假设读操作命令中携带的第一key是key55,第二key是内存页3中记录的key55,则第一key与第二key相同,即key匹配。假设第一key对应的生存周期是2,由于生存周期2处于第二key对应的生存周期[1,+∞)的范围内,即生存周期匹配。又例如,假设第一key是key55,第二key是内存页3中记录的key65,则第一key与第二key不同,即key不匹配。假设第一key对应的生存周期是4,由于生存周期4不处于第二keykey65对应的生存周期[1,3)的范围内,即生存周期不匹配。

对于非页节点,若第二key与第一key相同,或,第二key与第一key最接近且小于第一key,则key匹配,否则key不匹配。若第一key对应的生存周期处于第二key对应的生存周期的范围内,则生存周期匹配,若第一key对应的生存周期不处于第二key对应的生存周期的范围内,则生存周期不匹配。若key匹配且生存周期匹配,步骤323的判断结果为匹配;若key不匹配和/或生存周期不匹配,步骤323的判断结果为不匹配。例如,参见图2g所示,假设读操作命令中携带的第一key是key45,第二key是内存页1中记录的key45,则第一key与第二key相同,即key匹配。假设读操作命令中携带的第一key是key20,第二key是内存页1中记录的key10,由于第二key与第一key最接近且小于第一key,因此key匹配。假设读操作命令中携带的第一key是key50,第二key是内存页1中记录的key10,虽然第二key小于第一key,但是第二keykey10不是与第一keykey50最接近的(内存页1存在与第一keykey50更接近的key45),因此key不匹配。假设第一key对应的生存周期是2,由于生存周期2处于第二key对应的生存周期[1,+∞)的范围内,即生存周期匹配。

以下结合图4b对步骤323和步骤324进行说明。假设接收到读操作命令后执行第34次读事务,且读操作命令携带key55,则第34次读事务用于读取key55的数据,且第34次读事务的版本为34。然后,可以确定第二key是key55,且key55对应的生存周期是[1,34)。在步骤322中,已经确定第一内存元素是内存页12中的第二个内存元素,即,第二个内存元素中记录的第二key是key55,第二个内存元素中记录的生存周期生存周期[25,+∞)。

由于内存元素中的关第二键字key55与key55相同,且key55对应的生存周期是[1,34)处于生存周期[25,+∞)的范围内,因此,步骤323的判断结果为匹配,从第二个内存元素中读取与key55对应的数据部分,即,可以从内存页12中读取到与key55对应的数据。

在另一个例子中,步骤323之后,如果判断结果为否,则从与第一内存页对应的第一排序数组中,获取第二数组元素表征的第二位置偏移量,并确定该第二位置偏移量对应的第一内存页中的第二内存元素;然后,重复执行步骤323,直至第一key和第一key对应的生存周期,与内存元素中记录的第二key和生存周期匹配,并从该内存元素中读取与第一key对应的数据部分结束。

例如,在确定第二内存元素之后,可以判断第二内存元素中记录的key和生存周期,与第一key和该第一key对应的生存周期是否匹配;如果是,则可以从该第二内存元素中读取与第一key对应的数据部分。如果否,则进一步从与第一内存页对应的第一排序数组中,获取第三数组元素表征的第三位置偏移量,并确定该第三位置偏移量对应的第一内存页中的第三内存元素,并判断该第三内存元素中记录的key和生存周期,与第一key和该第一key对应的生存周期是否匹配,以此类推,对于后续过程不再重复赘述。

其中,在判断结果为否时,则可以采用二分查找策略从第一排序数组中选取第二数组元素,并获取第二数组元素表征的第二位置偏移量。例如,第一排序数组中存在5个数组元素,第一次选取的第一数组元素是第3个数组元素(处于1-5的中间位置),第二次选取的第二数组元素是第4个数组元素(处于3-5的中间位置),或者第2个数组元素(处于1-3的中间位置),以此类推。

具体的,为了采用二分查找策略从第一排序数组中选取第二数组元素,则从与第一内存页对应的第一排序数组中,获取第二数组元素表征的第二位置偏移量之前,还可以包括:若第二key大于第一key,则可以将该第一排序数组中起始位置数组元素与中间位置数组元素之间的所有数组元素,确定为第一内存页对应的第二排序数组,并从第二排序数组中,获取数组元素表征的位置偏移量;也就是说,可以将第二排序数组中的中间位置的数组元素作为第二数组元素。若第二key小于第一key,则可以将该第一排序数组中中间位置数组元素与结束位置数组元素之间的所有数组元素,确定为第一内存页对应的第二排序数组,并从第二排序数组中,获取数组元素表征的位置偏移量;也就是说,可以将第二排序数组中的中间位置的数组元素作为第二数组元素。

参见图4b所示,假设接收到读操作命令后执行第35次读事务,且读操作命令携带key60,则第35次读事务用于读取key60的数据,且第35次读事务的版本为35。确定第一key是key60,第一key对应的生存周期是[1,35)。假设第一内存页是内存页12,则内存页12对应的第一排序数组为排序数组2。

然后,从排序数组2中选取中间位置的数组元素,即第三个数组元素,该数组元素记录位置偏移量2,且位置偏移量2对应内存页12中的第二个内存元素,由于第二个内存元素中记录的第二key是key55,且key55与key60不同,因此,步骤323的判断结果可以为不匹配。

由于第二key小于第一key,因此,可以将排序数组2中中间位置数组元素(即第三个数组元素)与结束位置数组元素(即第五个数组元素)之间的所有数组元素,确定为内存页12对应的排序数组3,也就是说,该排序数组3的第一个数组元素(即上述排序数组2中的第三个数组元素)记录位置偏移量2,第二个数组元素记录位置偏移量5,第三个数组元素记录位置偏移量3。

然后,从排序数组3中选取中间位置的数组元素,即第二个数组元素,该数组元素记录位置偏移量5,且位置偏移量5对应内存页12中的第五个内存元素,由于第五个内存元素中记录的第二key是key60,第五个内存元素中记录的生存周期是生存周期[33,+∞),且第二key与第一key相同,第一key对应的生存周期是[1,35)处于生存周期[33,+∞),因此,步骤323的判断结果可以为匹配,并可以从第五个内存元素中读取数据c。

在上述实施例中,若排序数组存在偶数个数组元素,如存在4个数组元素,则中间位置的数组元素,可以是第2个数组元素,也可以是第3个数组元素。

在上述实施例中,每个内存页还可以包括排序数组的指针,该指针用于指向与该内存页关联的排序数组,即通过该指针可以查询到该排序数组。

在上述实施例中,涉及key的比较和生存周期的比较,以下对这一比较过程进行说明。其中,可以将key和生存周期的组合称为比较参数,后续以{a,[b,c)}的形式表示,a是比较参数的key,[b,c)是比较参数的生存周期。

在一个例子中,针对写入操作的比较过程,可以先比较key,key大的则比较参数大,key小的则比较参数小。如果key相同,则比较生存周期,生存周期晚的则比较参数大,生存周期早的则比较参数小。

例如,比较参数1为{3,[1,+∞)},比较参数2为{4,[5,6)},由于key4大于key3,因此,比较参数2大于比较参数1。又例如,比较参数1为{3,[1,4)},比较参数2为{3,[6,+∞)},由于key相同,且生存周期[6,+∞)的起始版本6比生存周期[1,4)的起始版本1晚,因此,比较参数2大于比较参数1。

在一个例子中,针对查询操作的比较过程,可以将待查询的比较参数称为比较参数1(如search比较参数),并将内存元素中记录的比较参数称为比较参数2(如compare比较参数)。针对比较参数1中的生存周期,可以将其转换为一个唯一值,而不是区间值,如上述生存周期[1,35)对应的唯一版本是35。

可以先比较key,key大的则比较参数大,key小的则比较参数小。如果key相同,则比较生存周期;如果比较参数1的版本大于等于比较参数2的生存周期的结束版本,则比较参数1大于比较参数2;如果比较参数1的版本小于比较参数2的生存周期的开始版本,则比较参数1小于比较参数2;如果比较参数1的版本大于等于比较参数2的生存周期的开始版本,且比较参数1的版本小于比较参数2的生存周期的结束版本,则比较参数1等于比较参数2。

例如,基于上述的比较策略,若比较参数1为{3,8},且比较参数2为{3,[10,+∞)},则比较参数1可以小于比较参数2;若比较参数1为{3,8},且比较参数2为{3,[2,6)},则比较参数1可以大于比较参数2;若比较参数1为{3,8},而比较参数2为{3,[8,9)},则比较参数1可以等于比较参数2;若比较参数1为{3,8},而比较参数2为{3,[6,8)},则比较参数1可以大于比较参数2。

基于上述技术方案,本申请实施例中,若内存页包括大量内存元素,不需要从第一个内存元素开始进行遍历,而是从与内存页关联的排序数组中选择数组元素,并从该数组元素表征的位置偏移量对应的内存元素进行遍历,在保证读事务并发访问的情况下,可以减少遍历次数,并可以快速从大量内存元素中读取到目标内存元素,节省大量时间,提高页内访问速度,达到页内访问速度和整体访问速度的平衡,使得查找效率大幅度提高,加强了mvbt的读写性能。

在一个例子中,若读操作命令携带多个key,针对当前选取的待查询key,可以判断是否已经存在与该读操作命令对应的堆栈数组。若不存在,则可以创建与该读操作命令对应的堆栈数组,并在该堆栈数组中添加该待查询key对应的访问路径信息;其中,该访问路径信息可以包括:待查询key对应的内存页的页标识、内存元素中记录的key和生存周期。若存在,则可以根据该堆栈数组中记录的访问路径信息,确定与该待查询key对应的内存页;在查询到该待查询key对应的数据部分后,在该堆栈数组中添加该待查询key对应的访问路径信息。

其中,堆栈数组是一个stack(堆栈)结构,用于记录一次查询操作的所有访问路径信息,堆栈数组的每个路径条目包括一个访问路径信息,如内存页的页标识、内存元素记录的key和生存周期等。例如,堆栈数组的第1个路径条目用于记录第一层内存页的访问路径信息,堆栈数组的第2个路径条目用于记录第二层内存页的访问路径信息,依次类推,直到最后一层内存页。通过堆栈数组可以回溯访问路径上的所有内存页,继而完成添加和删除等操作。此外,堆栈数组还可以包括一个depth变量,表示堆栈数组中的路径条目数量。

参见图5a所示,假设接收到读操作命令后执行第1次读事务,且该读操作命令中携带有key5和key6,则该第1次读事务用于读取key5的数据,且该第1次读事务也用于读取key6的数据,而且,第1次读事务的版本可以为1。然后,从读操作命令中选取key5,并读取key5的数据。为了读取key5的数据,先判断是否已经存在与该读操作命令对应的堆栈数组。若不存在,则创建与该读操作命令对应的堆栈数组,在初始状态下,该堆栈数组可以为空。然后,可以采用步骤321-步骤324的流程读取key5的数据。

其中,先确定key5对应的第一内存页是根节点(即内存页1),然后,参见图5b所示,确定内存页1的第二个内存元素与key5和生存周期1匹配,因此,可以在堆栈数组中添加一个路径条目,该路径条目用于记录内存页1的页标识、第二个内存元素记录的key4和生存周期[1,2),并将depth变量设置为1,表示当前存在一个内存页的路径信息,参见如下所示的堆栈数组。

stack.depth=1;

stack.path[1]=内存页1、key4、生存周期[1,2)。

基于内存页1的第二个内存元素记录的指针,确定key5对应的第一内存页是内存页6,参见图5c所示,确定内存页6的第二个内存元素与key5和生存周期1匹配,因此,可以在堆栈数组中添加一个路径条目,该路径条目用于记录内存页6的页标识、第二个内存元素记录的key5和生存周期[1,2),并将depth变量设置为2,表示当前存在两个内存页的路径信息,如下所示的堆栈数组。

stack.depth=2;

stack.path[1]=内存页1、key4、生存周期[1,2);

stack.path[2]=内存页6、key5、生存周期[1,2)。

进一步的,内存页6的第二个内存元素记录的数据,也就是与key5对应的数据,即查询到与key5对应的数据。然后,可以从读操作命令中选取key6,并读取key6的数据。为了读取key6的数据,先判断是否已经存在与该读操作命令对应的堆栈数组。若存在,则根据该堆栈数组中记录的访问路径信息,确定与key6对应的第一内存页,也就是说,不用从根节点开始依次遍历到第一内存页,从而减少遍历次数,例如,若mvbt树中共存在五级节点,可以直接确定到第五级的第一内存页,不用再确定第一级至第四级的第一内存页。

例如,由于堆栈数组的访问路径信息中,key5与读操作命令中的key6最接近,因此,将key5对应的内存页6确定为key6对应的第一内存页。然后,确定内存页6的第三个内存元素与key6和生存周期1匹配,即内存页6的第三个内存元素记录的数据,也就是与key6对应的数据,此外,可以在堆栈数组中添加一个路径条目,该路径条目用于记录内存页6的页标识、第三个内存元素记录的key6和生存周期[1,2),并将depth变量设置为3,表示当前存在三个内存页的路径信息,参见如下所示的堆栈数组。

stack.depth=2;

stack.path[1]=内存页1、key4、生存周期[1,2);

stack.path[2]=内存页6、key5、生存周期[1,2);

stack.path[3]=内存页6、key6、生存周期[1,2)。

在上述实施例的基础上,还可以涉及“终结”等操作,具体的,当需要对内存页(page,可以称为第一目标内存页)插入内存元素(包括key、value和生存周期,可以称为第一内存元素)时,若第一目标内存页中内存元素的数量等于预设内存元素数量上限(预设第一数量阈值),则创建新的内存页(可以称为第一内存页),将第一目标内存页中包含活key的内存元素和第一内存元素插入第一内存页,并将第一目标内存页中的活key标注为死key(即对第一目标内存页进行终结)。

其中,若第一目标内存页中包含活key的内存元素和第一内存元素的数量之和大于预设第一数量阈值,则创建两个第一内存页,并将第一目标内存页中包含活key的内存元素和第一内存元素平分插入至每一个第一内存页(终结并均摊);若第一目标内存页中包含活key的内存元素和第一内存元素的数量之和小于等于预设第一数量阈值,则创建一个第一内存页,并将第一目标内存页中包含活key的内存元素和第一内存元素插入至第一内存页(终结并插入)。

当需要对内存页(称为第二目标内存页)中的内存元素进行删除(将内存元素中包括的活key设置为死key)时,若第二目标内存页不是根结点页,且第二目标内存页中内存元素的数量小于预设内存元素数量下限(预设第二数量阈值),则创建新的内存页(可以称为第二内存页),将第二目标内存页与第二目标内存页的兄弟页(与第二目标内存页同层,且同父结点)中包含活key的内存元素插入第二内存页,并将第二目标内存页和第二目标内存页的兄弟页中的活key标注为死key(即对第二目标内存页和第二目标内存页的兄弟页进行终结)。

其中,若第二目标内存页和第二目标内存页的兄弟页中包含活key的内存元素的数量之和大于预设第一数量阈值,则创建两个第二内存页,并将第二目标内存页和第二目标内存页的兄弟页中包含活key的内存元素平分插入至每一个第二内存页(终结并分裂);若第二目标内存页和第二目标内存页的兄弟页中包含活key的内存元素的数量之和小于等于预设第一数量阈值,则创建一个第二内存页,并将第二目标内存页和第二目标内存页的兄弟页中包含活key的内存元素插入至第二内存页(终结并合并)。

基于与上述方法同样的构思,本申请实施例中还提出一种数据处理装置,应用于采用mvbt存储数据的网络设备,所述网络设备的内存包括多个内存页,每个内存页包括至少一个内存元素,每个内存页均配置对应的排序数组,所述排序数组中的每个数组元素用于表征内存元素在所述内存页中的位置偏移量,如图6所示,为本申请提出的数据处理装置的结构图,所述装置包括:

确定模块601,用于在接收到读操作命令后,确定读操作命令携带的第一键key对应的第一内存页;

获取模块602,用于从与所述第一内存页对应的第一排序数组中,获取第一数组元素表征的第一位置偏移量,并确定所述第一位置偏移量对应的所述第一内存页中的第一内存元素;

判断模块603,用于判断所述第一key和所述第一key对应的生存周期,与所述第一内存元素中记录的第二key和生存周期是否匹配;

读取模块604,用于当判断结果为是时,从所述第一内存元素中读取与所述第一key对应的数据部分。

所述获取模块602,还用于当判断结果为否时,从与所述第一内存页对应的第一排序数组中,获取第二数组元素表征的第二位置偏移量,确定所述第二位置偏移量对应的所述第一内存页中的第二内存元素;

所述判断模块603,还用于重复执行判断所述第一key和所述第一key对应的生存周期,与内存元素中记录的key和生存周期是否匹配的步骤,直至所述第一key和所述第一key对应的生存周期,与内存元素中记录的key和生存周期匹配,由读取模块604从内存元素中读取与所述第一key对应的数据部分。

所述获取模块602,还用于在从与所述第一内存页对应的第一排序数组中,获取第二数组元素表征的第二位置偏移量之前,若所述第二key大于所述第一key,将所述第一排序数组中起始位置数组元素与中间位置数组元素之间的所有数组元素,确定为所述第一内存页对应的第二排序数组,并从所述第二排序数组中,获取数组元素表征的位置偏移量;若所述第二key小于所述第一key,将所述第一排序数组中中间位置数组元素与结束位置数组元素之间的所有数组元素,确定为所述第一内存页对应的第二排序数组,并从所述第二排序数组中,获取数组元素表征的位置偏移量。

在一个例子中,所述确定模块601,还用于在接收到写操作命令后,确定所述写操作命令携带的第三key对应的第二内存页;

所述装置还包括(在图中未示出):存储模块,用于将所述第三key、所述第三key对应的生存周期和所述第三key对应的数据部分存储到所述第二内存页中的第三内存元素;

排序模块,用于对所述第二内存页中的每个内存元素的位置重新排序;

所述存储模块,还用于根据第三内存元素的位置排序结果,在所述第二内存页对应的第三排序数组中插入数组元素,并将所述第三内存元素在所述第二内存页中的位置偏移量记录到插入的所述数组元素中。

所述排序模块对所述第二内存页中的每个内存元素的位置重新排序时具体用于:获取所述第二内存页中的每个内存元素记录的key;按照每个key的值从小到大的顺序,依次对每个key进行排序,得到每个内存元素的位置排序结果;或者,按照每个key的值从大到小的顺序,依次对每个key进行排序,得到每个内存元素的位置排序结果。

所述存储模块根据第三内存元素的位置排序结果,在所述第二内存页对应的第三排序数组中插入数组元素时具体用于:拷贝与所述第二内存页对应的第三排序数组,得到拷贝后的第三排序数组,并保留拷贝前的第三排序数组;根据位置排序结果,确定所述第三内存元素在所述位置排序结果中的位置,并根据所述位置在所述拷贝后的第三排序数组中的对应位置插入一个数组元素。

在一个例子中,内存页还包括指针,所述指针用于指向与所述内存页关联的排序数组。

在一个例子中,若所述读操作命令携带多个key,针对当前选取的待查询key:

所述判断模块603还用于判断是否已经存在与所述读操作命令对应的堆栈数组;

所述存储模块还用于当判断结果为不存在时,则创建与所述读操作命令对应的堆栈数组,并在所述堆栈数组中添加所述待查询key对应的访问路径信息;其中,所述访问路径信息包括:所述待查询key对应的内存页的页标识、内存元素中记录的key和生存周期。

所述存储模块还用于当判断结果为存在时,根据所述堆栈数组中记录的访问路径信息,确定与所述待查询key对应的内存页;在查询到待查询key对应的数据部分后,在所述堆栈数组中添加所述待查询key对应的访问路径信息。

基于上述技术方案,本申请实施例中,若内存页包括大量内存元素,不需要从第一个内存元素开始进行遍历,而是从与内存页关联的排序数组中选择数组元素,并从该数组元素表征的位置偏移量对应的内存元素进行遍历,在保证读事务并发访问的情况下,可以减少遍历次数,并可以快速从大量内存元素中读取到目标内存元素,节省大量时间,提高页内访问速度,达到页内访问速度和整体访问速度的平衡,使得查找效率大幅度提高,加强了mvbt的读写性能。

本申请实施例提供的网络设备,从硬件层面而言,硬件架构示意图具体可以参见图7所示,可以包括:机器可读存储介质和处理器,其中:

机器可读存储介质:存储指令代码。

处理器:与机器可读存储介质通信,读取和执行机器可读存储介质中存储的所述指令代码,实现本申请上述示例公开的数据处理操作。

这里,机器可读存储介质可以是任何电子、磁性、光学或其它物理存储装置,可以包含或存储信息,如可执行指令、数据,等等。例如,机器可读存储介质可以是:ram(radomaccessmemory,随机存取存储器)、易失存储器、非易失性存储器、闪存、存储驱动器(如硬盘驱动器)、固态硬盘、任何类型的存储盘(如光盘、dvd等),或者类似的存储介质,或者它们的组合。

上述实施例阐明的系统、装置、模块或单元,具体可以由计算机芯片或实体实现,或者由具有某种功能的产品来实现。一种典型的实现设备为计算机,计算机的具体形式可以是个人计算机、膝上型计算机、蜂窝电话、相机电话、智能电话、个人数字助理、媒体播放器、导航设备、电子邮件收发设备、游戏控制台、平板计算机、可穿戴设备或者这些设备中的任意几种设备的组合。

为了描述的方便,描述以上装置时以功能分为各种单元分别描述。当然,在实施本申请时可以把各单元的功能在同一个或多个软件和/或硬件中实现。

本领域内的技术人员应明白,本申请的实施例可提供为方法、系统、或计算机程序产品。因此,本申请可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、cd-rom、光学存储器等)上实施的计算机程序产品的形式。

本申请是参照根据本申请实施例的方法、设备(系统)、和计算机程序产品的流程图和/或方框图来描述的。应理解可以由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其它可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其它可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。

而且,这些计算机程序指令也可以存储在能引导计算机或其它可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或者多个流程和/或方框图一个方框或者多个方框中指定的功能。

这些计算机程序指令也可装载到计算机或其它可编程数据处理设备上,使得在计算机或者其它可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其它可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。

以上所述仅为本申请的实施例而已,并不用于限制本申请。对于本领域技术人员来说,本申请可以有各种更改和变化。凡在本申请的精神和原理之内所作的任何修改、等同替换、改进等,均应包含在本申请的权利要求范围之内。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1