具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
为了对本发明实施例进行清楚详细的介绍,先介绍一下分布式文件系统。
分布式文件系统一般是由客户端、元数据节点和对象存储节点组成,其物理结构如图1所示。其中,客户端是用户访问分布式文件系统的入口,用户的请求首先提交给客户端,由客户端发给分布式文件系统进行处理;元数据节点是分布式文件系统中的负责文件系统的元数据处理的节点,包括元数据的创建、修改、文件布局等;对象存储节点是实际存放数据的节点。最终,用户首先通过客户端访问元数据节点,然后将数据存放在对象存储节点上。
在分布式文件系统的逻辑结构中,以命名空间为单位进行划分。在每个命名空间下面是目录和文件,每个命令空间及其目录和文件构成一个目录子树,如图2所示。应用中,对文件系统中目录或文件的任意操作均将导致对日志系统的操作,比如添加事务。另外,日志系统还定期发起事务提交,将日志系统的事务中记录的信息刷到文件系统,在提交后还需要定期删除已提交的事务。在对分布式文件系统进行一致性校验时,需要根据日志系统中的事务对文件系统中的数据进行校验。现有技术中集中式架构的日志系统使得对日志系统的操作速度非常慢,举例来说,若同时发生了对不同目录子树中的不同文件的操作,基于集中式架构的日志系统,需要将这些操作对应的事务依次添加到日志系统中,日志操作速度非常慢,随着系统的增大、事务的增多,这严重影响了整个系统的性能。
本发明实施例根据分布式文件系统中的目录结构,将日志系统设计为日志树根(Journal Root)和日志子树(Journal Sub-tree)的结构,使得可以并行地对日志子树进行操作,提高了日志操作的速度。具体地,本发明实施例可以通过图3所示方法实现。
图3为本发明实施例提供的一种文件系统实施例的结构示意图。如图3所示,该系统包括:日志系统32和至少两个目录子树31;
日志系统32,包括日志树根321和与日志树根321连接的至少两个日志子树322,至少两个日志子树322与所述至少两个目录子树31对应;
日志树根321,用于存储至少两个目录子树31的日志和寻址信息;
至少两个日志子树322,分别用于存储对应的目录子树31中目录和文件的日志。
这里的日志树根321存储的是整个分布式文件系统的目录子树31的操作,包括目录子树31的创建、修改、删除等。日志树根321由文件系统的日志系统创建,存放在某个元数据节点上。这里的寻址信息是所述日志子树存放位置的地址信息。日志子树之间彼此之间没有直接联系,是通过日志树根联系的。日志树根321中还存储了目录子树的地址信息,以及目录子树与日志子树的对应关系。
这里的每个日志子树对应一个目录子树,每个日志子树均由文件系统的日志系统根据其对应的目录子树创建,存储该目录子树的日志操作,包括目录和文件的创建、修改、删除、写操作等。日志子树之间彼此之间没有直接联系,是通过日志树根联系的。日志子树存放在某个元数据节点上,较优地存放在负责该目录子树的元数据节点上。
日志子树由至少一个事务组成。这里的事务是对文件系统的一个原子操作,例如写文件、删除目录等。每个事务都有一个唯一的事务号,该事务号有先后顺序,较优地,根据事务发生的时间进行排序。如图4所示,日志子树3221存放有事务T00,T01,T02,...,等。日志子树3222中存放有事务T00,T01,T02,...,等。日志子树3223中存放事务T00,T01,T02,...,等。日志子树之间彼此之间没有直接联系,是通过日志树根联系的,所以日志子树3221、3222、3223之间的事务也没有关系,日志子树内的事务以事务号排序。所有日志子树的事务通常先保存在内存中,并定期刷新到硬盘上。
在日志子树中,日志的内部结构定义如下。日志由一个日志头(JournalHeader)、至少一个事务(Transaction)组成,如表1所示。
表1
日志头的结构包含日志子树中事务的总数和上次提交的事务的事务号,较优地,还可以包括下一个需要提交的事务的块编号,如表2所示。应用中,若该日志子树未提交过事务,则上次提交的事务的事务号可以为空,若该日志子树中的事务已全部提交,则下一个需要提交的事务的块编号可以为空,本实施例对此不作限定。
表2
事务的总数 |
上次提交的事务的事务号 |
下一个需要提交的事务的块编号 |
事务的结构包含事务号(Transaction ID)、事务时间戳(TransactionTimestamp)、至少一个块(Block),较优地,还可以包括块总数(Block number)如表3所示。其中,事务时间戳记录该事务发生的时间,块总数描述总共有多少块用于记录该事务,至少一个块用于记录该事务的具体操作信息,比如对哪个路径下的哪个文件进行和何种操作等。
表3
事务号 |
事务时间戳 |
块总数 |
块0 |
..... |
块M |
在本发明的一个可选的实施例中,当一个日志子树中的事务总数超过一个预设的阈值或该日志子树的数据量超过一个预设的阈值,或是日志操作的请求数超过预设的阈值时,可以对该日志子树进行拆分,具体地可以拆分成至少两个事务表(Transaction Table),如图5所示。所述阈值可以根据CPU和文件系统的处理能力来设定,可以给定一个初始值,例如1万个事务,或10万个事务。每个事务表包含表日志头和至少一个事务,所述表日志头包含所述事务表中的事务的总数和上次提交的事务的事务号。事务表内部依旧保持事务号的顺序关系。由于事务表之间是并行的,系统可以同时对多个事务表进行并行操作,从而大大提高日志操作的并行处理能力。
本发明实施例采用了将文件系统中的日志系统划分成日志树根和至少两个日志子树,所述至少两个日志子树与文件系统中的至少两个目录子树对应的技术手段,提高了日志的分布性和日志操作的独立性,使得可以并行地对所述至少两个日志子树进行操作,进而提高了日志操作的速度。进一步地,还可以将日志子树拆分成至少两个事务表,使得可以对至少两个事务表并行进行操作,进一步提高了日志操作的速度。
图6为本发明实施例提供的一种日志操作方法实施例的流程示意图。如图6所示,该方法包括:
步骤601、获取与日志树根连接的至少两个日志子树的寻址信息,所述至少两个日志子树与文件系统的至少两个目录子树对应;
这里的文件系统为如本发明实施例提供的一种文件系统实施例所述的系统。
步骤602、根据所述寻址信息查找到所述至少两个日志子树;
步骤603、对所述至少两个日志子树进行操作。
这里对日志子树的操作包括添加事务、删除事务或提交事务等,本实施例对此不作限定。
若在步骤603之前,所述至少两个日志子树中的第一日志子树被拆分成了至少两个事务表,则步骤603中对所述第一日志子树进行操作时还可以对所述至少两个事务表进行操作。需要说明的是,这里的第一日志子树可以是任意一个日志子树,并且本实施例中不仅可以将第一日志子树拆分成至少两个事务表,还可以将出第一日志子树之外的至少一个日志子树拆分成至少两个事务表。
在本发明的一个可选的实施例中,可以在对日志子树进行操作时将日志子树拆分成至少两个事务表,以并行地对至少两个事务表进行操作,进一步提高日志操作的速度。在这种场景下,步骤603具体可以包括:
将所述至少两个日志子树中的第一日志子树拆分成至少两个事务表;
对所述至少两个事务表进行操作。
为了便于对拆分的事务表进行并行操作,可以根据事务的相关性来进行拆分,也就是说,将相关的事务,比如记录对同一路径下文件的操作的事务存储到同一事务表中,不相关的事务可以存储到不同的事务表中。需要说明的是,何时对某个日志子树进行拆分,不是本发明的重点,举例来说,可以在操作时直接拆分,也可以在操作前或其他任何时刻,根据该日志子树的事务总数、数据量或是日志操作的请求数来确定是否拆分,本实施例对此不作限定
图7为上述将第一日志子树拆分成至少两个事务表的一种流程示意图。如图7所示,包括:
步骤701、遍历所述第一日志子树中的事务;
所述事务的个数为至少两个。
步骤702、解析所述事务,获取所述事务对应的目标路径;
这里事务对应的目标路径指的是该事务的具体操作信息中记录的路径,即为了说明该事务是对哪个路径下的数据进行了一次原子操作。应用中,还可以解析得到该事务对应的操作命令,本发明不限于按照事务的路径进行日志子树的拆分,也可以根据事务的相关性进行日志子树的拆分,例如将写、修改、删除等需要改变数据的操作等按照事务号的先后顺序拆分到同一个事务表,而将读等不需要改变数据的操作拆分到其他事务表中,本实施例对此不作限定。
步骤703、确定至少两个最短目标路径;
步骤704、将所述事务按照对应的目标路径与所述至少两个最短目标路径的关系,存储到与所述至少两个最短目标路径对应的至少两个事务表中的一个。
举例来说,若所述事务对应的目标路径包含所述至少两个最短目标路径中的第一最短目标路径,则将所述第一事务存储到与所述第一最短目标路径对应的第一事务表中。需要说明的是,这里的第一最短目标路径可以是所述至少两个最短目标路径中的任意一个最短目标路径。
若多个目标路径包含有同一个公共路径,则可以将该公共路径作为一个最短目标路径,若某个目标路径跟其他所有目标路径都不存在公共路径,则可以将该目标路径自身作为一个最短目标路径。举例来说,事务1的目标路径1为/user/home/A/B/,事务2的目标路径2为/user/home/A/,事务3的目标路径3为/user/home/A/C/D/,则可以将/user/home/A/作为一个最短目标路径;若事务4的目标路径4为/client/A/,与其他目标路径不存在公共路径,即其他目标路径都不包含/client/A,则将/client/A/也作为一个最短目标路径。这种情况下,将事务1、2、3存储到最短目标路径/user/home/A/对应的事务表中,将事务4存储到另一最短目标路径/client/A/对应的另一事务表中。当然,最短目标路径的长度可以根据经验值选定,以避免一个事务表包含的事务太多或是事务表的个数太多,影响对事务表并行操作以提交日志操作速度的效果,本实施例对此不作限定。
图8为上述将所述第一日志子树拆分成至少两个事务表的又一种流程示意图。如图8所示,包括:
步骤801、从所述第一日志子树中获取第i个事务;
假设所述日志子树中事务的总数为N,N为正整数,这里的i为不大于N的正整数,初始化i=1。
步骤802、解析所述第i个事务,获取所述第i个事务对应的目标路径i;
步骤803、判断所述目标路径i是否包含已有的k个最短目标路径中的一个,若是则执行步骤804,若否则执行步骤807;
这里的k为不大于i的自然数。已有的k个最短目标路径是指在遍历第i个事务之前,通过遍历前i-1个事务已经得到的最短目标路径,初始化k=0.
步骤804、所述目标路径i包含最短目标路径j,将所述第i个事务存储到所述最短目标路径j对应的事务表j中;
其中,j为不大于k的正整数。
步骤805,判断i是否小于N,若是则执行806,若否则结束步骤;
步骤806、令i=i+1,执行步骤801;
步骤807、判断所述目标路径i是否被已有的k个最短目标路径中的一个包含,若是则执行步骤808,若否则执行步骤809;
步骤808、所述目标路径i被最短目标路径j包含,将第i个事务存储到所述事务表j中,执行步骤805;
若所述目标路径i被多个最短目标路径包含,可以将所述第i个事务存储到所述多个最短目标路径对应的多个事务表中的一个。应用中,由于最短目标路径越短,目标路径包含该最短目标路径的事务就越多,该最短目标路径对应的事务表就越大,因此将第i个事务存储到所述事务表j中后,可以根据最短目标路径j的长度确定是否将事务表j对应的最短目标路径更新为目标路径i,本实施例对此不作限定。
步骤809、将所述目标路径i作为最短目标路径k+1,建立与所述最短目标路径k+1对应的事务表k+1,将所述第i个事务存储到所述事务表k+1中,令k=k+1,执行步骤805。
在本发明的又一可选的实施例中,为了在一致性校验时可以对多个事务表并行进行操作,在步骤704或步骤801~808结束之后还可以包括:
为所述至少两个事务表分别建立一个表日志头,所述表日志头包含所述事务表中的事务的总数和上次提交的事务的事务号。可选地,还可以根据所述至少两个事务表中每个事务表表日志头中的上次提交的事务的事务号,对所述每个事务表中进行事务提交。举例来说,日志子树中共有10个事务,上次提交的事务的事务号为事务5,下一个需提交的事务为事务6;进行事务表的拆分后,事务表1中有事务1、2、4、6、7,事务表2中有事务3、8、9,事务表3中有事务5、10,这样事务表1、2、3的表日志头中事务总数分别为5、3、2,上次提交的事务的事务号均为5,这样各事务表下一个需提交的事务分别为事务6、8、10,在各事务表均经过一次事务提交后,事务表1、2、3的上次提交的事务的事务号变为7、9和空。应用中,日志系统还可以定期地将已提交的事务从日志子树/事务表中删除,并修改对应的日志头/表日志头中事务的总数。
在本发明的又一可选的实施例中,所述将所述第一日志子树拆分成至少两个事务表之后若有新事务加入所述第一日志子树,则还可以包括:
若有新事务加入所述日志子树,且所述新事务对应的目标路径包含所述至少两个最短目标路径中的第二最短目标路径,则将所述新事务存储到与所述第二最短目标路径对应的第二事务表中;或是
若有新事务加入所述日志子树,且所述新事务对应的目标路径不包含所述至少两个最短目标路径,则建立新的第三事务表,所述第三事务表对应的最短目标路径为所述新事务对应的目标路径,将所述新事务存储到所述第三事务表中;或是
若有新事务加入所述日志子树,且所述至少两个最短目标路径中的第三最短目标路径包含所述新事务对应的目标路径,则将所述新事务存储到与所述第三最短目标路径对应的第三事务表中。
需要说明的是,第二最短目标路径、第三最短目标路径可以是所述至少两个最短目标路径中的任意最短目标路径,与第一最短目标路径可以相同,也可以不同。
在本发明的又一可选的实施例中,为了平衡各日志子树的事务总数、数据量或日志操作请求,还可以某个日志子树拆分出的事务表转到其他日志子树中,这种场景下,所述将所述第一日志子树拆分成至少两个事务表之后还可以包括:
将所述至少两个事务表中的至少一个事务表转移到其他日志子树中。
这里的其他日志子树与该日志子树同属于一个日志树根。具体转移到哪个其他日志子树,可以根据其他日志子树自身的事务总数、数据量或日志操作请求来确定,本实施例对此不作限定。
日志系统是用来进行文件系统的一致性校验的重要工具。当文件系统意外崩溃、或系统意外断电后,文件系统的部分操作没有进行,内存中的数据和硬盘上的数据不一致。当文件系统再次启动后,首先需要根据日志系统进行文件系统中数据的一致性校验,将崩溃前的操作进行完,将系统中不一致的数据校验完毕。
基于本发明实施例提供的日志系统和日志操作方法进行一致性校验时,可以先用日志树根对文件系统进行一致性校验,从硬盘日志区读取日志树根,看看有没有未提交的事务,如果有就进行事务提交,并在日志中记录提交结果;然后用日志子树对文件系统进行一致性校验,从硬盘日志区读取日志子树,检查各个日志子树中的事务提交情况,如果有未提交的事务,根据事务号逐一进行提交,并在日志中记录提交结果。通过上述一致性校验,保证因断电而没有及时刷到硬盘的数据能保存到硬盘上,并且可以提高系统意外掉电后数据一致性检验的性能,降低数据丢失的风险。这里的日志树根存储了各日志子树的寻址信息。文件系统可以从硬盘上读取日志树根的全部日志,也就获取了各日志子树的寻址信息。这种场景下,文件系统可以同时将所有的日志子树的全部日志从硬盘中读到内存,然后根据所有日志子树的日志可以并行地对文件系统的数据进行一致性校验。对应地,步骤603具体可以包括:
根据所述至少两个日志子树,对所述至少两个目录子树进行一致性校验。
进一步地,在第一日志子树被拆分成了至少两个事务表的场景下,对所述至少两个事务表进行操作具体可以包括:
根据所述至少两个事务表,对所述至少两个最短目标路径下的文件进行一致性校验。
本发明实施例采用了将日志系统划分成日志树根和至少两个日志子树,所述至少两个日志子树与文件系统中的至少两个目录子树对应的技术手段,使得可以并行地对所述至少两个日志子树进行操作,比如根据所述至少两个日志子树并行地对至少两个目录子树进行校验,提高了文件系统一致性校验的性能,降低了数据丢失的风险。进一步地,还可以将日志子树拆分成至少两个事务表,使得可以对至少两个事务表并行进行操作,可以进一步提高日志操作的速度。
图9为本发明实施例提供的一种日志操作装置实施例的结构示意图。如图9所示,该装置与如本发明实施例提供的一种文件系统实施例所述的文件系统连接,包括:
获取模块91,用于获取与日志树根连接的至少两个日志子树的寻址信息,所述至少两个日志子树与文件系统的至少两个目录子树对应;
查找模块92,用于根据所述寻址信息查找到所述至少两个日志子树;
操作模块93,用于对所述至少两个日志子树进行操作。
在本发明的一个可选的实施例中,该装置还包括:
拆分模块94,用于将所述至少两个日志子树中的第一日志子树拆分成至少两个事务表;
操作模块93具体用于,对所述至少两个事务表进行操作。
在本发明的又一可选的实施例中,拆分模块94具体包括:
遍历单元941,用于遍历所述第一日志子树中的事务,所述事务的个数为至少两个;
解析单元942,用于解析所述事务,获取所述事务对应的目标路径;
确定单元943,用于确定至少两个最短目标路径;
划分单元944,用于将所述事务按照对应的目标路径与所述至少两个最短目标路径的关系,存储到与所述至少两个最短目标路径对应的至少两个事务表中的一个。
在本发明的又一可选的实施例中,操作模块93具体用于,
根据所述至少两个事务表,对所述至少两个最短目标路径下的文件进行一致性校验。
应用中,本实施例的日志操作装置可以内嵌在文件系统中,或是独立于文件系统设置,本实施例对此不作限定。
本发明实施例采用了将日志系统划分成日志树根和至少两个日志子树,所述至少两个日志子树与文件系统中的至少两个目录子树对应的技术手段,使得可以并行地对所述至少两个日志子树进行操作,比如根据所述至少两个日志子树并行地对至少两个目录子树进行校验,提高了文件系统一致性校验的速度。进一步地,还可以将日志子树拆分成至少两个事务表,使得可以对至少两个事务表并行进行操作,可以进一步提高日志操作的速度。
本领域普通技术人员可以理解:实现上述方法实施例的全部或部分步骤可以通过程序指令相关的硬件来完成,前述的程序可以存储于一计算机可读取存储介质中,该程序在执行时,执行包括上述方法实施例的步骤;而前述的存储介质包括:ROM、RAM、磁碟或者光盘等各种可以存储程序代码的介质。
最后应说明的是:以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。