首页> 中国专利> 存储数据项并且标识存储的数据项

存储数据项并且标识存储的数据项

摘要

在一个方面,将数据项写入流片段的数据块。流片段包括流片段报头和多个数据块。将数据项的第一标识符写入流片段的流片段报头。将数据项的第二标识符写入流片段的数据块的报头。在另一个方面,以查询标识符来查询流片段的流片段报头。该查询操作识别流片段的数据块中是否有任何数据项具有该查询标识符。如果流片段的数据块中有任何数据项具有该查询标识符,则使用该查询标识符查询流片段的数据块,以识别流片段的哪些数据块具有该查询标识符。

著录项

  • 公开/公告号CN112262379A

    专利类型发明专利

  • 公开/公告日2021-01-22

    原文格式PDF

  • 申请/专利权人 微软技术许可有限责任公司;

    申请/专利号CN201980038910.X

  • 申请日2019-05-31

  • 分类号G06F16/29(20060101);G06F16/22(20060101);G06F16/13(20060101);

  • 代理机构72002 永新专利商标代理有限公司;

  • 代理人赵腾飞

  • 地址 美国华盛顿州

  • 入库时间 2023-06-19 09:36:59

说明书

技术领域

本公开内容涉及用于存储数据项以及用于标识存储的数据项的方法、计算机系统和计算机程序。

背景技术

存储数据的情形很多,通常用于以后使用或访问等等。在一些情况下,存在大量的数据项需要随时进行存储。这些数据项本身通常都很小。然而,数据项的数量大这一事实提出了与以下一项或多项有关的问题:高效地将数据项写入存储设备、以及高效地搜索和检索所存储的数据项。

发明内容

根据本文公开的第一方面,提供了一种计算机程序,该计算机程序包括一组计算机可读指令,当该组计算机可读指令由计算机系统执行时,使计算机系统执行存储数据项的方法,该方法包括:

在所述计算机系统的计算机存储器中,接收要存储的数据项;

将所述数据项写入流片段的数据块中,所述流片段包括流片段报头和多个数据块;

从所述数据项中获得第一标识符;

将所述数据项的所述第一标识符写入所述数据项所写入的所述流片段的所述流片段报头中;

从所述数据项中获得第二标识符,所述第二标识符与所述第一标识符不同;以及

将所述数据项的所述第二标识符写入所述数据项所写入的所述流片段的所述数据块的报头中;

由此,能够使用所述流片段报头中的所述第一标识符来识别所述流片段的所述数据块中的任何数据块中的任何数据项是否包括所述第一标识符,并且由此,能够使用所述流片段的所述数据块的所述报头中的所述第二标识符来识别所述数据块中的任何数据项是否包括所述第二标识符。

可以提供一种存储如上所述的计算机程序的非临时计算机可读存储介质。

本文描述的一些例子提供了对计算机技术的改进,其中技术优势在于:所述改进的计算机技术使得能够快速搜索和检索数据项,并且还使得能够快速删除数据项。可以在合理和实际的时间范围内,快速地搜索和检索数据项。具体而言,本文描述的示例解决的技术问题在于,由于通常必须依次地检查每个数据项,因此搜索存储在计算机系统中的大量数据项以识别特定的数据项可能很慢。

可以以不同的顺序执行以上列出的操作。例如,在至少一些例子中,该方法可以在将数据项写入数据块之前,获得第一标识符和第二标识符中的一个或两个等等。

一旦如上所述已经组装了数据块,并且可能一旦满足一个或多个其它标准(例如,已经达到该块的最大大小),就可以将数据块写入持久性存储设备中。

在一个例子中,所述第一标识符是适用于所述流片段的所述数据块中的第一数量的数据项的粗略标识符,并且其中,所述第二标识符是适用于所述流片段的所述数据块中的第二较少数量的数据项的精细标识符。

根据本文公开的第二方面,提供了一种存储数据项的方法,所述方法包括:

在计算机存储器中接收要存储的数据项;

将所述数据项写入流片段的数据块中,所述流片段包括流片段报头和多个数据块;

从所述数据项中获得第一标识符;

将所述数据项的所述第一标识符写入所述数据项所写入的所述流片段的所述流片段报头中;

从所述数据项中获得第二标识符,所述第二标识符与所述第一标识符不同;以及

将所述数据项的所述第二标识符写入所述数据项所写入的所述流片段的所述数据块的报头中;

由此,能够使用所述流片段报头中的所述第一标识符来识别所述流片段的所述数据块中的任何数据块中的任何数据项是否包括所述第一标识符,并且由此,能够使用所述流片段的所述数据块的所述报头中的所述第二标识符来识别所述数据块中的任何数据项是否包括所述第二标识符。

在一个例子中,所述第一标识符是适用于所述流片段的所述数据块中的第一数量的数据项的粗略标识符,并且其中,所述第二标识符是适用于所述流片段的所述数据块中的第二较少数量的数据项的精细标识符。

在任何特定时间点,在所述第二标识符所适用的所述流片段的所述数据块中,通常可能有零个、或一个、或多个数据项。通常,所述第二标识符所适用的所述数据项的数量将小于所述第一标识符所适用的数据项的数量。适用于所述第二标识符的所述数据项通常将是适用于所述第一标识符的所述数据项的一个子集。

在一个例子中,所述第一标识符是标识组织的租户(tenant)标识符,并且所述第二标识符是用户标识符,所述用户标识符标识作为所述组织成员的个人用户。

在一个例子中,将所述数据项的所述第一标识符写入到概率数据结构中,其中所述概率数据结构被包含在所述数据项所写入的所述流片段的所述流片段报头中。

在一个例子中,将所述数据项的所述第二标识符写入到概率数据结构中,其中所述概率数据结构被包含在所述数据项所写入的所述流片段的所述数据块的所述报头中。

在一个例子中,所述方法包括:

对从所述数据项获得的所述第一标识符执行一致的散列运算;以及

基于对从所述数据项获得的所述第一标识符的所述一致散列运算的结果,识别所述数据项要写入到的所述流片段。

在一个例子中,所述流片段是日志流的一部分,存在多个日志流,每个日志流包含一个或多个不同的流片段,并且,基于所述一致散列运算的所述结果来识别所述数据项要写入到的所述流片段,包括:基于所述一致散列运算的所述结果,识别具有所述流片段的所述日志流。

使用多个日志流可以允许并行处理数据项,这提供了所述数据项的高吞吐量。

在一个例子中,将所述数据项写入流片段的数据块中包括:将所述数据项作为行条目写入所述数据块中,所述行条目包括行头部,并且所述方法包括:

将模式ID写入所述行头部中,所述模式ID标识如何从所述数据项中提取所述第一标识符和所述第二标识符中的至少一个。

在稍后出于检索和/或删除目的而搜索数据时,能够使用存储在行头部中的模式ID。将模式ID存储在行头部中意味着,以后可以提取标识符,而不必考虑标识符在数据项中保存的格式。它还允许具有不同模式的数据项存在于同一块中,从而改善了该处理的功能性,使其更加通用。此外,如果使用其它(第三或另外的)标识符,则可以存储这些标识符的模式ID。

在一个例子中,该方法包括:

将与所述数据项有关的数据写入流分区,以使得所述流分区对所述数据项所写入的所述流片段进行索引。

与所述数据项有关的所述数据可以是以下中的一个或多个:所述数据项写入的所述流片段的文件名、与所述数据项有关的时间、以及所述数据项的所述第一标识符。这使得对数据项的后续搜索能够更快、更高效地进行。

在另一个例子中,提供了一种计算机系统,其包括:

至少一个处理器;

和至少一个存储器,所述至少一个存储器包括计算机程序指令;

所述至少一个存储器和所述计算机程序指令被配置为与所述至少一个处理器一起使所述计算机系统执行如上所述的存储数据项的方法。

根据本文公开的第三方面,提供了包括一组计算机可读指令的计算机程序,当所述一组计算机可读指令由计算机系统执行时,使所述计算机系统执行基于数据项的查询标识符来识别存储在所述计算机系统中的所述数据项的方法,所述方法包括:

利用查询标识符来查询流片段的流片段报头,其中,所述流片段包括流片段报头和一个或多个数据块,其中每个数据块包括数据项,并且所述流片段报头包括所述数据块中的所述数据项的标识符,其中,对所述流片段报头的所述查询用于识别:所述流片段的所述数据块中的所述数据项中是否有任何数据项具有所述查询标识符;以及

如果所述流片段的所述数据块中的所述数据项中有任何数据项具有所述查询标识符,则利用所述查询标识符来查询所述流片段的所述数据块,以识别所述流片段的哪些数据块具有所述查询标识符;以及

执行以下中的至少一项:检索所述流片段的所述数据块中的至少一个数据块中的所述数据项中的具有所述查询标识符的至少一个数据项;以及删除所述流片段的所述数据块中的至少一个数据块中的所述数据项中的具有所述查询标识符的至少一个数据项。

提供了存储如上所述的计算机程序的非临时性计算机可读存储介质。

在一个例子中,所述方法包括:针对所述流片段中具有所述查询标识符的所有数据块,查询所述数据块中的所述数据项,以识别所述数据块中的哪些数据项具有所述查询标识符;以及

执行以下中的至少一项:检索所述流片段的所述数据块中的所有数据块中的所述数据项中具有所述查询标识符的所有数据项;以及删除所述流片段的所述数据块中的所有数据块中的所述数据项中具有所述查询标识符的所有数据项。

在一个例子中,所述流片段报头中的所述数据项的所述标识符包含在概率数据结构中。

在一个例子中,所述数据项的所述标识符是第一标识符,每个数据块均具有报头,所述报头包括所述数据块中的所述数据项的第二标识符,所述第二标识符不同于所述第一标识符,并且所述方法包括:

对于具有所述第一查询标识符的所述流片段的每个数据块,利用第二查询标识符来查询每个所述数据块的所述报头,以识别所述数据块中是否有任何数据项具有所述第二查询标识符。

在一个例子中,所述方法包括:对于被识别为包含有具有所述第二查询标识符的数据项的数据块,查询所述数据块中的所述数据项以识别所述数据块中的哪些数据项具有所述第二查询标识符。

在一个例子中,所述第一标识符是适用于所述流片段的所述数据块中的第一数量的数据项的粗略标识符,并且其中,所述第二标识符是适用于所述流片段的所述数据块中的第二较少数量的数据项的精细标识符。

在一个例子中,所述第一标识符是标识组织的租户标识符,并且所述第二标识符是用户标识符,所述用户标识符标识作为所述组织成员的个人用户。

在一个例子中,所述数据项的所述第二标识符包含在所述数据块的所述报头中的概率数据结构中。

在一个例子中,所述数据项是所述数据块中的行条目,每个行条目包括行头部,每个行头部包括标识如何从所述数据项中提取标识符的模式ID,并且,查询数据块中的所述数据项以识别所述数据块中的哪些数据项具有所述查询标识符包括:从行条目的所述行头部中检查所述模式ID,并且使用所识别的模式从所述行条目中提取所述标识符。

在另一个例子中,提供了一种计算机系统,其包括:

至少一个处理器;

和至少一个存储器,所述至少一个存储器包括计算机程序指令;

所述至少一个存储器和所述计算机程序指令被配置为与所述至少一个处理器一起使所述计算机系统执行如上所述的识别存储在所述计算机系统中的数据项的方法。

在另一个例子中,提供了一种如上所述的识别存储在计算机系统中的数据项的方法。

提供本概括部分以便用简化的形式介绍将在以下的详细描述中进一步描述的概念选择。本概括部分并不是旨在标识本发明的关键特征或本质特征,也不是使用该概括部分来限制本发明的保护范围。此外,本发明并不限于解决本文所陈述的任何或所有缺点。

附图说明

为了帮助理解本公开内容并示出实施例如何生效,仅通过示例的方式来参考附图,其中:

图1示意性地示出了根据本文所述的一些例子的计算机系统、以及用户与计算机系统进行交互的的示例;

图2示意性地示出了本公开内容的例子的操作和数据结构的概述;

图3示意性地示出了本公开内容的例子的块的示例的结构;

图4示意性地示出了本公开内容的例子的流片段的示例;

图5示意性地示出了在计算机系统中存储数据项的方法的例子;以及

图6示意性地示出了识别存储在计算机系统中的数据项的方法的例子。

具体实施方式

如前所述,存储数据的情形很多,通常用于以后使用或访问等等。通常情况下,存在大量的数据项需要随时进行存储。这些数据项本身通常都很小。然而,数据项的数量大这一事实(在一些情况下确实可能非常大)提出了与以下一项或多项有关的问题:高效地将数据项写入存储设备、以及高效地搜索和检索所存储的数据项。

在计算机系统中,数据项通常可以由(人类)用户、设备和软件应用程序生成。这些数据项的例子包括系统日志、用于训练机器学习模型的数据集、遇到错误或其它问题的服务和系统的日志、分析生成的数据(结果)、以及分析所需的其它数据。这种类型的数据项通常以高速率生成,并且常常是不可预测的。然而,经常需要能够基于一种或多种标准来搜索这样的数据项,以识别满足一种或多种标准的数据项。对于大量的数据,这可能很难在短时间内实现。

日益重要的特定当前问题是用户隐私以及组织对用户数据的使用和保留。许多国家已经出台或正在出台立法,除其它事项外,这些立法还要求组织向用户披露该组织持有的与用户有关的数据。这通常称为“访问权”。另外,许多国家已经出台或正在出台立法,除其它事项外,这些立法还要求组织根据用户的要求来删除该组织持有的与用户有关的数据。这通常称为“被遗忘权利”。作为在撰写本文时的一个具体示例,欧盟通过了《通用数据保护条例》(GDPR),其主要目的是让用户对其个人数据进行控制,并为组织制定了严格的时间表,以遵守对他们所使用的数据进行披露的要求,并根据要求删除这些数据。(例如,当前为了符合GDPR,组织必须在30天内完成用户的删除要求。)

然而,根据请求读取全部的数据量,并在给定的期限内返回结果可能成本很大,并且在一些情况下是不可能的或者至少实际上是不可能的。为了避免这些问题,许多组织已将其数据保留策略更改为小于允许的最大处理时间(例如,删除请求)。尽管这种方法在某些情况下令人满意,但在一些情况下,必须将数据(其包括系统日志或者与用户有关的其它信息)存储更长的时间。所需要的是针对该问题的技术解决方案。

本文所描述的一些例子提供了改进的计算机系统,该计算机系统能够根据需要实现对数据的快速搜索和检索,并能够对数据进行快速删除。数据可能与客户和(人类)用户有关。通过提高这些操作的效率,可以避免高影响数据的缺省的较短保留时间,并且可以增加可保留的数据量。

下面将详细描述本公开内容的一些具体示例。应该注意的是,并非在所有情况下或者在所有实现中,都需要下面描述的所有组件。

将根据实时软件系统或服务的示例来给出本文讨论的特定示例,在该实时软件系统或服务中,作为系统操作的一部分来生成数据。存储数据的一个例子是系统日志(特别是使用日志),该日志记录用户与系统交互的详细信息。这种使用日志可以提供有关这些交互如何影响系统性能和行为的信息。例如,当基于Web的文档编辑套件的用户对文档进行更改时,此类日志将包含关于以下方面的信息:用户何时登录、登录发生的IP(互联网协议)地址、更改的文档、更改的时间、更改了多少字节、这些操作的代价怎样等等。然而,本公开内容也可以应用于其它类型的数据,其包括例如用于训练机器学习模型的数据集、遇到错误或其它问题的服务和系统的日志、由分析产生的数据(结果)、以及为了进行分析所需的其它数据(例如,其包括有关系统警报、电子邮件、社交媒体帐户上的帖子等等的数据)。可以应用的数据分析的一个特定示例是学习数据的来源(例如,特定用户、设备、软件功能等等)。

如上面所提到的,尤其是随着出台了关于如何处理与用户有关的数据的法律的立法,希望确保可以将与给定用户有关的所有数据追溯到该用户,并对其进行定位、检索和删除(如果需要或者要求的话)。此外,服务提供商必须经常保证可以在严格的响应时间内完成该操作。在企业软件系统的上下文中,客户群或组织(例如,企业(公司))(本文称为“租户”)也可以请求删除与其个人用户有关的所有数据。为了促进用户和租户两者的数据检索,本文所描述的例子有效地将两个标识符与正在存储的每条数据相关联,即将租户和用户标识符(ID)进行关联。这些ID可以是唯一的,或者至少是有效的或实际上是唯一的。例如,租户ID可以是通用唯一标识符(UUID),其也称为全局唯一标识符(GUID)。UUID或GUID是用于标识计算机系统中的信息的128位数字。应当注意的是,使用情况日志在大多数情况下已经包含这些标识符,这是因为通常它们对于高效地调试问题以及进行使用情况分析是必需的。

当用户与软件系统交互时,以ad-hoc方式来生成使用日志。用户与系统的每次交互都可以生成一个或多个记录,它们详细地记录各种软件组件的行为。当发生用户交互时,通常按时间顺序在一行之后添加一行来构造日志。

由于日志是在已知系统中生成和写入的,因此全面搜索与特定用户有关的所有数据将需要对整个日志量进行线性扫描。尽管可以根据例如用户和租户ID来对日志进行分类,但是由于很难与日志的生成方式保持一致,因此传统上不会这样做。也就是说,建立这样的索引或分类流将需要:a)长时间在存储器中保留大量的数据;b)读取先前写入的日志,并以批处理的方式重新处理它们(包括存储器和输入/输出密集型);和c)两者的组合。这些方法中的每一种方法的成本使得难以高效地支持对大量系统日志(以及以类似方式生成的其它类型的数据)的客户数据的检索和删除。

总的来说,在一个方面,本公开内容提供了一种将数据项存储到持久性存储设备中的方法。计算机存储器中接收要存储的数据项。该数据项写入到流片段的数据块中,该流片段包括流片段报头和多个数据块。从数据项获得第一标识符。数据项的第一标识符写入到数据项写入的流片段的流片段报头中。从数据项获得第二标识符,第二标识符不同于第一标识符。数据项的第二标识符写入到该数据项所写入的流片段的数据块的报头中。能够使用流片段报头中的第一标识符,来识别流片段的任何数据块中的任何数据项是否包括第一标识符。能够使用流片段的数据块的报头中的第二标识符,来识别数据块中的任何数据项是否包括第二标识符。

在本文所描述的特定示例中,第一标识符可以是标识组织(例如,企业/公司)的租户ID。在该特定例子中,第二标识符可以是用户ID,其标识系统的(人类)用户。这些用户可以与一个或多个租户相关联。例如,每个用户可以是租户的雇员。如本文所描述地获得、存储和使用的第一标识符和第二标识符的使用,为数据的快速搜索、检索和删除中的一个或多个操作提供了分层或层次化方法。第一标识符可以用作相对粗糙的过滤器,第二标识符可以用作相对精细的过滤器。在一些例子中,可以存在多于两层的标识符/过滤器,它们提供逐渐精细的过滤器和/或替代的过滤器。仅作为一个示例,可以用作过滤器的另一个标识符是(地理)区域。例如,在多个地区存在一些租户。在这种情况下,便有可能使用<租户ID、区域、用户ID>形式的三元组。例如,可能存在一个三元组<租户ID、欧洲、用户ID>和另一个三元组<租户ID、亚洲、用户ID>等等。这些标识符的顺序(即,层次结构)可以根据期望实现的结果进行更改。

分层标识符的另一个例子是针对特定的设备,其中粗略ID可以是该设备的IP地址,精细ID可以是该设备的MAC地址。还存在用于识别移动设备的不同类型的标识符,可以在数据表示使用日志的情况下使用这些标识符。使用日志中可能感兴趣的标识符的另一个例子是操作系统和浏览器的组合(例如,);在这些情况下,粗略键值和精细键值分别取决于特定的使用日志。也可以将移动业务绑定到蜂窝塔:例如,粗略ID标识该蜂窝塔,而精细ID标识移动设备。再举一个例子,如果数据流经作为处理的一部分的一组功能,则指定这些功能的标识符可能是感兴趣的。如果发现某个功能发生故障,则可以将数据与该功能相关联。然后,粗略ID可以与处理多于给定数量的数据项的功能相关联,而精细ID可以与处理少于给定阈值的功能相对应。这也开辟了多层解决方案的可能性。

现在参照图1,该图根据本公开内容的例子,示意性地示出了用户20可以经由用户计算机22与之交互的计算机系统10的例子。计算机系统10具有一个或多个处理器12、工作存储器或RAM(随机存取存储器)14(通常是易失性存储器)和永久性(非易失性)存储设备16。持久性存储设备16可以是例如一个或多个硬盘、非易失性半导体存储器(例如,固态驱动器或SSD)等等。计算机系统10可以由一个单独的计算机或者多个单独的计算机提供。用户计算机22同样具有通常的一个或多个处理器24、RAM 26和持久性存储设备28。用户计算机22可以通过网络30与计算机系统10进行交互,该网络30可以是局域网和互联网中的一个或多个,并且可能涉及有线和/或无线连接。

计算机系统10可以为用户提供软件服务,上面讨论了其一些特定示例。在此处考虑的特定示例中,至少一些用户20与组织(例如,企业等)相关联,并且可以例如是组织的雇员。这样的组织在本文中被称为“租户”(因为该组织可以视作为“租赁”计算机系统10提供的服务)。计算机系统10可以例如提供计算机系统10远离用户20并存储、管理和处理用户20的数据的“云计算”服务,其中用户20与计算机系统之间的连接包括互联网,而不是由本地服务器或个人计算机来执行。

现在参考图2,图2示意性地示出了本公开内容的例子的操作的概述。如上所述,并不是在所有情况下或者在所有实现中都需要图2所示和下面详细描述的所有项目。可以将图2视作为示意性地示出了将数据项存储到计算机系统10的持久性存储设备16的示例方法的流程。应当注意,可以以与此处描述的特定示例和图2中示意性指示的顺序不同的顺序,来执行该方法中的某些操作。图2还示意性显示了该例子中使用的数据结构。

接下来将给出图2中所示的主要项目的简要概述。然后,将对每个主要项目及其用法进行更详细的讨论。

在200处,数据进入计算机系统10或者由计算机系统10生成。在该特定例子中,数据是作为计算机系统10的操作或使用的一部分而生成的系统日志。数据的特定示例是使用情况日志,其记录了用户与计算机系统10交互的详细信息。

在该特定例子中,将在200处输入的数据总量(此处为生成的日志)分为多个“日志流”202,在图2中分别表示为202#1、202#2、...、202#N。这允许对日志进行并行处理,同时保持内存占用量和其它系统资源使用的可管理性。这提供了高数据吞吐量,还可以更好地利用多核(和多计算机)配置。但是,在其它例子中,例如,每单位时间要处理的数据总量较小时,则不必将数据拆分为多个日志流。

每个日志流202包含至少一个流分区204。流分区204可以视作为一种数据结构。通常,每个日志流202包含多个流分区204。在一个例子中,根据可定义的策略来创建流分区204,可定义的策略可以是基于例如时间、数据大小或两者。下面将进一步讨论其具体示例。流分区204索引或者引用保存实际数据的文件(例如,在下面讨论的例子中的流片段206)。流分区204能够使用例如元数据来注释,这可以使数据搜索更快和更高效。注释还可以更高效地直接搜索给定的数据。同样,下面将进一步讨论其特定示例。

每个流分区204索引(例如,引用)一组流片段206。在该例子中,流片段206是计算机系统10中用于存储数据的单元(例如,计算机系统10中管理数据的单元)。流片段206可以视作为一种数据结构。如图4中示意性示出的,每个流片段206包含一个片段头208。在一个例子中,片段头208包含片段过滤器,在一个例子中,其是允许快速判断是否必须更彻底地检查流片段206内的数据的概率数据结构。使用数据的第一标识符来填充该片段过滤器。在一个例子中,第一标识符是相对粗糙的较高阶标识符。在数据是用户日志并且用户20与租户相关联的特定例子中,该第一标识符可以是租户ID(也就是说,与用户20相关联的企业或其它组织的标识符)。通常,将存在多个租户,每个租户都有自己的租户ID,每个都有自己的关联用户集20。在示例性片段过滤器的操作中,第一标识符用作概率片段过滤器中的关键字,以便识别包含有与第一标识符有关的数据的流片段206,如下面将进一步讨论的。片段头208还可以包含其它信息,例如片段长度和其它可选的元数据(例如,在多个不同的进程/计算机系统/机器分别向计算机系统10提供输入的情况下,其包括标识各个进程/计算机系统/机器的信息)等等。

除了具有片段过滤器的片段头208之外,每个流片段206还包含一组“块”210。可以再次将块210视作为数据结构。每个块210包含多个数据项(例如,在该特定的例子中,用于用户日志的日志条目)。每个块210还包含块过滤器212(也参见下面进一步讨论的图3)。该块过滤器212是概率数据结构,其类似于片段过滤器。然而,使用数据的第二标识符来填充块过滤器212。在一个例子中,第二标识符是相对精细的低阶标识符。在数据是用户日志的特定例子中,第二标识符可以直接绑定到与特定数据项的生成相关联的终端用户,并且可以是例如该用户的唯一用户标识符或用户ID。在块过滤器212的示例的操作中,第二标识符用作概率块过滤器212中的关键字,以便标识包含与该第二标识符有关的数据的块210,如下面将进一步讨论的。

现在将更详细地描述以上概述的每个组件,从具有块210的最低级开始。

将到达计算机系统10的诸如用户日志或上面所讨论的其它类型的数据之类的数据写入块210中。块210的大小可以是可配置的。块210的大小可能受到以下的约束:计算机系统10的存储器消耗的约束、以及关于在将数据持久化到诸如一个或多个硬盘16之前应当在存储器14中停留多长时间的期望上限。因此,计算机系统10的RAM 14的容量更大,意味着块210可能更大,反之亦然。以分块方式写入数据的优点是效率:与对持久性存储16进行较小且更频繁的随机写入相比,对持久性存储16进行较大的顺序写入更高效,并提供更高的吞吐量。这在持久性存储16由硬盘提供的情况下尤其相关,鉴于硬盘提供的每单位数据存储(例如,每千兆字节)的成本相对较低,这一点目前仍然很常见。另一个优点是,这还允许在块数据之前添加块过滤器212。如上所述,在一个例子中,块过滤器212是一种概率数据结构,其中包含有关存储在块212中的数据的信息。块过滤器212能够快速地确定在块210中是否存在与给定用户有关的数据。

块过滤器212(以及片段头208中的片段过滤器)可以使用多种不同类型的概率过滤器。在该例子中使用的概率过滤器的特性是它们可能给出误报率,但是没有漏警率。这意味着当扫描日志时(例如,搜索与某个特定用户相对应的数据时),可以在检查实际日志数据本身之前使用该特定用户的用户ID来查询块过滤器212。如果在查询特定用户的用户ID时,块过滤器212返回否定响应,则可以完全跳过该块210,这是因为这意味着:存储在该块210中的数据均不包含该用户ID。通过调整块过滤器212以使误报率很小,可以实现相当大的加速,这是因为必须读取和搜索的数据量可以大大减少。(为了进一步解释起见,在创建这些过滤器时,在过滤器的大小(以位为单位)、所使用的散列函数的数量(如果过滤器足够大且没有“填满”,则更多函数可降低误报概率,但代价更高)和误报率之间进行权衡。通过使过滤器足够大并具有足够的散列函数,可以实现极低的误报率。但是,这是以增加插入/查询时间以及存储空间成本为代价的。应当将过滤器调整为“足够好”,例如,提供较低的误报率,但不会引起不必要的计算和存储开销。根据情况,可以在此处进行不同的权衡。)

在构建块210的同时,从数据中提取第二更细的标识符(在示例中,将在随后的数据搜索中使用),并将其添加到块过滤器212。在数据是在用户日志的特定例子中,从日志行中提取用户的唯一ID,并将其添加到块过滤器212。基于唯一标识符和期望的误报率的预期分布,来创建块过滤器212。这里,在误报的数量、块过滤器212中插入键值的成本、以及块过滤器212的大小之间进行权衡。当块210达到某个期望大小时,其以块过滤器212为前缀,然后将其写入持久性存储设备16(例如,一个或多个硬盘16)中。

图3示意性地显示了完整块210的示例的结构。在一个例子中,块210是将数据提交到持久性存储16的单元。块210包含块头214加块数据216。块头214包含块过滤器212(其包含对其进行重构所需的信息)。可以对块过滤器212进行序列化。即,以能够重构的形式来表示块过滤器212。块头214还可以包含标识块长度218的数据。块头214还可以包含其它可选的元数据220。这种其它元数据220可以包括例如以下中的一个或多个:时间(例如,其可以是用户20创建块210中的日志数据216或者计算机系统10接收块210中的日志数据216的时间或时间范围)等等;原始文本,其反映了块210中的日志数据216中存在的某些文本项;在多个不同的进程/计算机系统/机器分别向计算机系统10提供输入的情况下,标识各个进程/计算机系统/机器的信息;等等。

块数据216包含一组数据线222。在数据为用户日志的特定例子中,块数据216包含一组日志行222。每个日志行222转而包含在查询时对其进行重构所必需的数据。每个日志行222还包含必要的信息,以促进特定示例中的租户ID和用户ID以及可选的其它ID的提取。具体而言,在一个例子中,每个日志行222包含小报头224和实际日志条目226。在所示的例子中,报头224包含与日志行222的总长度有关的信息228。在所示的例子中,报头224还包含模式标识符230。当确定如何从各个日志条目226中包含的原始数据中提取各种标识符时,使用该模式标识符230,这允许提取各种标识符,而不管它们在原始数据中存储时所采用的格式。通过将用于提取标识符的一组方法或功能与模式标识符230相关联,可以以通用方式来支持不同的日志模式。它还允许具有不同模式的日志条目226出现在同一块210中,从而提高了该过程的功能性,因为它使得更通用。(在图3中,块长度218、有关日志行222的总长度的信息228和模式标识符230以“单元”开头)。这是“无符号整数”,即,该整数仅是正数。)

尽管块210是将数据提交到持久性存储16的单元,但是转而将块210一起存储在流片段206中。在图4中示意性地示出了流片段206的例子。流片段206包含多个块210,并作为单个文件存储在持久性存储16(例如,一个或多个硬盘16)、共享/分布式网络连接系统(例如,Hadoop文件系统(HDFS))等等中。因此,流片段206用作在计算机系统10中管理数据的单元。

类似于块210,并且如上所述,还为流片段206维护过滤器结构。但是,片段过滤器未填充与块过滤器212中存在的标识符相同的标识符。替代地,在片段过滤器中使用第一标识符,其中在一个例子中提供比块210本身使用的第二标识符“更粗”的过滤器。该第一标识符的粗略度很重要:如果不够粗略,则所有流片段206将包含它,并且片段过滤器的值减小。在数据是用户日志的特定例子中,第一标识符是租户ID,如上所述。实际上,租户ID是一个合理的选择,这是因为它可以捕获使用的时间性。具体而言,常见的情况是,属于单个租户的大多数(如果不是全部)用户在每天大致相同的时间段内处于活动状态。如果片段过滤器的误报率保持较低,则可以有效地排除与属于该租户的用户的不活动时间段相对应的流片段206。

如果在片段过滤器中使用了租户ID,则这允许快速地判断在流片段206中是否存在源自给定租户的任何用户的任何日志,这是因为仅需要为此使用片段过滤器:在该阶段不需要检查流片段206本身中的每个块210。如果答案是肯定的,则然后检查流片段206内的各个块210(或更准确地说是其过滤器212),以查找源自一个或多个特定用户的数据。

由于流片段206包含多个块210,并且每个块210本身潜在地包含大量数据(在上面的例子中的日志行222中),因此,将流片段206全部保存在计算机系统10的存储器14中通常是不可行的。在这种情况下,可以选择如何生成和存储片段过滤器。这三种可能的选项包括:

(1)将片段过滤器附加在流片段206的末尾。当要搜索流片段206的块210时,这会导致其它查找操作。

(2)通过提前确定片段过滤器的大小,可以在流片段206的开始处保留必要的空间。然后,当流片段206完成时,可以将片段过滤器写入该空间。这需要在写入时进行额外的查找操作。

(3)片段过滤器不存储在流片段文件206自身中,而是存储在索引流片段206的各个流分区204中。这使得可以避免必须读取流片段206(在至少最初用于初始搜索),但意味着必须在查询时使用这些流分区204。

尽管这些方法中的每一种都有其优点,但是在一些例子中,选项(2)可能具有特别的优势。这是因为在写入日志数据时,吞吐量比延迟更重要,而在读取时进行额外的查找操作通常会减慢数据的读取速度(例如,当必须迅速定位涉及特定租户和/或用户的数据时,通常要避免发生这种情形)。

在该特定例子中,数据结构的层次结构是流分区204。流分区204可以视作为流片段206的集合。流分区204不存储任何原始日志条目数据,而是保留对属于分区204的流片段文件206进行定位所需的信息。因此,流分区204用作引用或索引结构,并在计算机系统10正在服务数据检索和删除请求时,用于指导流片段文件206的搜索。

为了支持高效的搜索,能够使用元数据对每个流分区204进行丰富的注释。支配如何创建流分区204的规则或流策略,可以用于生成很好地映射到预期查询模式的流分区204。例如,一个用于生成流分区204的策略是关于时间:可以创建与1小时、1天、1周等等内记录的数据相对应的流分区。另一种策略是基于大小,对流分区204进行封顶。也可以使用混合方法,例如最多将流分区204覆盖一天,但大小永远不能超过N GB。

为了避免依赖于必须保留在存储器中或者以特定方式解析的复杂索引结构,流分区204可以实现为平面文本文件,该平面文本文件包含由流分区204索引的对应流片段文件206的报头和文件名。该报头可以包含对于以下判断有用的元数据:判断对计算机系统10的查询是否需要评估流分区204。这样的元数据的一个例子是流分区204覆盖的时间间隔。数据是用户日志的特定示例的另一个例子,是在流分区204中具有数据的租户(租户ID)列表。这使查询能够确定性地确定流分区204包含特定租户的数据(例如,用于审核目的)。为了完整性,需要注意的是,如果需要非常有限的元数据集,则流分区204不需要具有报头。相反,可以将必要的元数据并入流分区204文件本身的文件名中。这种元数据可以例如是流分区204的开始时间。计算机系统10也可以自动添加一些元数据。

如上所述,在该特定例子中,将进入200的数据总量(此处为生成的日志)分成多个“日志流”202,在图2中分别表示为202#1、202#2、…、202#N。这允许高数据吞吐量和更好地利用多核(和多计算机)配置。

在该例子中,每个日志流202经由各自的队列232接收进入200计算机系统10的数据。进一步将日志流202分成上面所描述的流分区204。当某条数据进入200计算机系统10中时,将数据一致地散列234到日志流202中的一个,并放到其相应的队列232中。(持续性散列是一种特殊的散列,因此当调整散列表的大小时,平均只需要重新映射K/n个键,其中K是键的数量,n是槽的数量)。相比而言,在大多数传统的散列表中,数组槽数量的变化几乎导致所有键重新映射,这是因为键和槽之间的映射是由模块化操作定义的。用于这种散列的键与上面讨论的片段过滤器中使用的“粗键”相同。这有效地限制了在处理后续数据检索或删除请求时必须评估的文件数量。例如,如果租户ID用于该散列键值,则与该租户相对应或有关的所有数据都将驻留在同一日志流202中。也可以使用双重散列技术,以适应存储在不同日志流202中的数据量的不平衡。例如,如果在散列之后确定目标日志流202将包含太多数据,则可以将第二散列函数应用于关键字以确定该数据的替代日志流202。在查询时,可以将相同的散列函数应用于应当检索或删除数据的租户的ID。通过这样做,可以快速地排除属于不同日志流202的所有文件。在图2示意性示出的例子中,这是通过将单个文件夹236与每个日志流202相关联来实现的。然后,将属于该日志流202的所有流片段文件206存储在该文件夹236中,并且只有该文件夹236中的流片段文件206是在查询时进行评估的候选对象。

如上面所提及的,许多不同类型的概率过滤器可以用于块过滤器212和片段过滤器。具体的例子包括所谓的Bloom过滤器和Cuckoo过滤器。这些(至少与其它一些概率过滤器相同)都具有可以产生误报率的特征,但不会产生漏警。由于它们的实现方式,在插入新键值时,Bloom过滤器提供了更好的性能。但是,Bloom过滤器不支持删除。相反,需要通过插入所有剩余的标识符来重新计算过滤器。另一方面,Cuckoo过滤器本身支持删除操作,并且在删除键时不必重新计算过滤器。如果希望使过滤器与块210和/或流片段206的内容完全一致,则要使用的过滤器结构很大程度上取决于操作混合。如果预计有很多删除,则可以使用Cuckoo过滤器。在删除很少的情况下,Bloom过滤器提供了代价更少的解决方案。通过暂时存储要删除的键值,然后以批处理方式删除或者从过滤器中删除/重新计算键值,也可以推迟过滤器的清理/重新计算。

当从块210(因此从流片段206)删除数据条目时,可以以“急切”或“懒惰”的方式从已删除的条目中回收数据。一种急切的回收策略的示例是,通过迭代所有条目(仅保留不应删除的条目),从块210中删除该条目,然后重写块210。这将导致修改后的块210的尾部和流片段206中的下一个块210之间存在未使用的空间,该空间可以通过移动随后的块210进行回收。另一种方法是延迟回收:不是在删除时回收未使用的空间,而是将块210(和流片段206)标记为“脏的”(这可以通过在块头214和流片段报头208中设置“脏位”来实现),并且将保存被删除项的字节归零。然后,将日志条目本身标记为已删除(例如,通过在行的标题中设置特定的模式ID)。对计算机系统10的稍后查询,能够使用条目的长度加上被标记为已删除来跳过记录。然后,在以后的某个时间点(例如,按既定时间表或者在满足某些特定条件时)执行回收例程。如果使用基于非周期性或基于策略的延迟压缩/回收方案,这也可以处理过滤器结构的延迟删除/重新计算。为了避免对计算机系统10的查询性能(数据的检索和删除)产生负面影响,回收未使用空间的作业可以安排在计算机系统10轻微加载时运行。

现在参考图5,其示意性地示出了在计算机系统中存储数据项的方法的示例。

在500处,接收到要存储的数据项。在510处,将数据项写入流片段的数据块。在图5的示例方法中,流片段包括流片段报头和多个数据块。

在520处,从数据项获得第一标识符。在一些例子中,可以认为第一标识符是粗略的标识符。根据本文所描述的一些例子,第一标识符是租户ID,其标识“租户”,该“租户”可以是例如组织(例如,企业/公司)。在不同应用中使用的其它例子中,第一标识符可以是一些其它标识符。

在530处,将数据项的第一标识符写入数据项所写入的流片段的流片段报头中。

在540处,从数据项获得第二标识符。第二标识符不同于第一标识符。在一些例子中,可以认为第二标识符是不太粗略或精细的标识符。根据本文描述的一些例子,第二标识符是用户ID,其标识系统的(人类)用户。在第一标识符是租户ID的情况下,可以将用户与一个或多个租户相关联。例如,每个用户可以是租户的雇员。在不同应用中使用的其它例子中,第二标识符可以是一些其它标识符。

在550处,将数据项的第二标识符写入到数据项所写入的流片段的数据块的报头中。

结果,流片段报头中的第一标识符可以用于识别流片段的任何数据块中的任何数据项是否包括第一标识符,流片段的数据块报头中的第二标识符可以用于识别数据块中的任何数据项是否包括第二标识符。

然后,操作流程可以返回到500,在步骤500中,接收要存储的新的或另外的数据项,并且如上所述继续进行操作。

现在参考图6,其示意性地示出了识别存储在计算机系统中的数据项的方法的例子。在实践中,计算机系统中可能存储了大量的数据项。

在600处,使用查询标识符来查询流片段的流片段报头。在图6的示例方法中,流片段包括流片段报头和一个或多个数据块。每个数据块包括数据项,并且流片段报头包括数据块中的数据项的标识符。对流片段报头的查询用于识别:该流片段的数据块中的任何数据项是否可以具有查询标识符。

在610处,如果流片段的数据块中的所有数据项都不具有查询标识符,则流程返回到600。然后,可以使用查询标识符来查询另一个流片段(例如,下一个流片段)的流片段报头。否则,在610处,如果流片段的数据块中有任何数据项具有查询标识符,则流程移至620。

在620处,使用查询标识符来查询流片段的数据块,以识别流片段的哪些数据块具有查询标识符。

在630处,对具有查询标识的流片段中的至少一个数据块:获取数据块中的数据项的至少一个;或者删除数据块中的数据项的至少一个;或者检索并删除数据块中的数据项的至少一个。然后,流程可以返回到600,准备用另一个查询标识符来查询流片段的流片段报头。

现在,下面是如何执行以下操作的一些具体示例的描述:如何将数据插入或登录到计算机系统10中、如何从计算机系统10中检索数据以及如何从计算机系统10中删除数据。这些例子是根据上面讨论的特定示例给出的,其中数据表示用户日志,并且在其中,将租户ID用作粗略的第一标识符或键值,以用于对片段过滤器进行一致的散列运算和填充,并且块过滤器212内的精细的第二标识符或键值是唯一的用户ID。应当理解的是,对于不同类型的数据和使用不同的标识符,可以在其它应用中应用相同的原理。还应当理解,并非在所有实施方式中都需要这里描述的所有操作。

在一个例子中,可以通过以下来概括计算机系统10中的数据记录:

1.由于用户和计算机系统之间的某些交互而创建了日志条目。

a.日志行头部224填充与日志行222匹配的模式ID 230以及日志条目数据226和报头224的组合总长度(大小)228。

2.通过以下方式将日志条目一致地散列234到流202之一:

a.为了提取要用作散列键的租户ID,使用行头部224中的模式ID 230来查找可以执行该操作的方法或功能。

b.来自a的方法或函数应用于条目,以提取要用作散列键的租户ID。

c.将键值传递给散列函数234。

d.将该条目放在与散列结果相对应的队列232上。

3.从流队列232中,对该条目进行出队,并通过以下方式进行处理:

a.评估流分区策略,并在必要时,通过以下方式来创建新的流分区204:

i.将当前块210写入当前流片段文件206。

ii.通过添加当前片段文件206的片段过滤器,并将其存储到持久性存储16中,来完成当前片段文件206。

iii.将片段文件名以及任何元数据添加到当前流分区204。

iv.更新当前流分区文件204的报头中的任何字段,并将当前流分区204写入到持久性存储16中。

V.创建新的流分区文件204。

b.提取日志条目的租户ID,并将其插入到当前流片段206的过滤器中。

c.提取日志条目的用户ID,并将其插入到当前流片段206的当前块210的块过滤器212中。

d.将日志条目附加到当前块数据216中。

i.如果块210中的结果变满:

1.将块210附加到流片段文件206,并持久化到磁盘16。

2.如果这导致流片段206已满,则用于:

a.将片段过滤器写入到流片段206中。

b.将片段文件名添加到当前流分区文件204中。

c.创建新的流片段206。

3.创建新的块210。

在一个例子中,可以通过以下方式,对识别和/或检索来自特定租户的与给定用户相对应的所有数据进行概括:

1.对租户的租户ID进行一致散列234,以确定哪个日志流202包含该租户的数据。

2.通过以下方式,确定必须进行评估的流分区文件204集合:

a.在流文件夹236中获取全部的流分区文件204集。

b.使用任何提供的元数据(例如,租户的客户关系的开始日期)来减少需要评估的流分区204集合。

3.对于必须评估的每个流分区文件204:

a.读取流分区204中的流片段文件206的列表

b.对于每个流片段文件206:

i.查询具有租户ID的片段过滤器

1.如果过滤器返回“假”,则继续下一个流片段文件206。(这反映出,流片段206通常可能具有多个租户的数据/日志条目。)

2.如果过滤器返回“真”,则通过如下评估流片段文件206的每个块210,来扫描流片段文件206:

a.利用用户ID来查询块过滤器212。

b.如果块过滤器212返回“假”,则继续下一个块210。

c.如果块过滤器212返回“真”,则通过以下方式来逐行扫描块210:

i.从行头部224中提取模式ID 230

ii.查找使用模式ID 230提取租户ID的方法

iii.从日志行条目222中提取租户ID

iv.如果日志行条目222的租户ID与查询中的租户ID不匹配,则继续下一行222

v.否则,使用模式ID 230来查找用于提取用户ID的方法

vi.从日志行条目222中提取用户ID

vii.将日志行条目222中的用户ID与查询中的用户ID进行比较

viii.如果用户ID匹配,则将日志行条目222添加到结果集中。

4.返回结果集。

在一个例子中,可以通过以下方式,对识别和/或检索与给定租户相对应的所有数据(而不是如上例中那样,与特定租户的给定用户相对应的所有数据)进行概括:

l.对租户的租户ID进行一致散列234,以确定哪个日志流202包含该租户的数据。

2.通过以下方式,确定必须进行评估的流分区文件204集合:

a.在流文件夹236中获取全部的流分区文件204集。

b.使用任何提供的元数据(例如,租户的客户关系的开始日期)来减少需要评估的流分区204集合。

3.对于必须评估的每个流分区文件204:

a.读取流分区204中的流片段文件206的列表

b.对于每个流片段文件206:

i.查询具有租户ID的片段过滤器

1.如果过滤器返回“假”,则继续下一个流片段文件206。(这反映出,流片段206通常可能具有多个租户的数据/日志条目。)

2.如果过滤器返回“真”,则通过如下评估流片段文件206的每个块210,来扫描流片段文件206:

a.通过以下方式来逐行扫描块210:

i.从行头部224中提取模式ID 230

ii.查找使用模式ID 230提取租户ID的方法

iii.从日志行条目222中提取租户ID

iv.如果日志行条目222的租户ID与查询中的租户ID

不匹配,则继续下一行222

v.否则,则将日志行条目222添加到结果集中。

4.返回结果集。

最后,在回收被删除的日志行条目所使用的空间的例子中,可以执行以下操作:

1.对于每个流片段文件206:

a.如果流片段206未标记为脏,则继续下一个流片段文件206

b.否则,通过以下方式来回收流片段文件206中的空间:

i.将针对流片段206的初始偏移设置为零(该偏移是从文件中的当前点到文件中的下一个点的(逻辑)距离)

ii.对于流片段206中的每个块210:

1.如果未将块210标记为脏,则继续下一个块210

2.迭代块210中的每个日志行条目222

a.如果行222未被标记为已删除,则将其添加到行222集合中以进行保留

b.从日志行条目222中提取用户ID

c.将用户ID添加到新的块过滤器212

3.以当前片段偏移量,将新块210(及其过滤器222)写入流片段文件206

4.通过添加压缩块210的大小,来更新当前片段偏移。

应当注意到,本文所描述的一些例子并不排除例如数据压缩或加密的使用,从而进一步实现数据的紧凑存储。具体而言,从数据中获得数据的第一标识符和第二标识符,并将它们分别存储(针对第一标识符,存储在写入数据项的流片段的流片段报头中,而针对第二标识符,存储在写入数据项的流片段的数据块的报头中),数据本身可以是压缩和/或加密的,这是因为在搜索与第一和/或第二标识符有关的数据时不必检查数据本身。

关于数据是用户日志并且用户与诸如公司之类的组织相关联的特定示例,已经给出了上面的许多具体描述。在这种情况下,第一标识符是租户ID(例如,组织的ID),第二标识符是用户ID(例如,与该(或另一个)组织相关联的用户的ID)。作为标识符的分层或分层结构的类型的另一个例子,第一标识符可以是父母的ID,而用户ID可以是该父母的孩子的ID。

本文参考用于存储数据的数据存储。可以通过单个设备或多个设备来提供数据存储。适当的设备包括例如硬盘和非易失性半导体存储器(例如,固态驱动器或SSD)、共享/分布式网络连接系统(例如,Hadoop文件系统(HDFS)等)。

虽然本文参考附图描述的实施例的至少一些方面包括在处理系统或处理器中执行的计算机过程,但是本发明还可以扩展到适于将本发明付诸实践的计算机程序,特别是载体上或载体中的计算机程序。该程序可以采用非临时性源代码、目标代码、中间源代码和目标代码之间的代码形式(例如,部分编译的形式),也可以采用适用于根据本发明来实现过程的任何其它非临时性形式。载体可以是能够承载程序的任何实体或设备。例如,载体可以包括存储介质(例如,固态驱动器(SSD)或其它基于半导体的RAM、ROM(例如,CD ROM或半导体ROM)、磁记录介质(例如,软盘或硬盘);一般的光学存储设备等等。

应当理解的是,本文所指的处理器或处理系统或电路实际上可以由单个芯片或集成电路或多个芯片或集成电路来提供(可选地提供为芯片组、专用集成电路(ASIC)、现场可编程门阵列(FPGA)、数字信号处理器(DSP)、图形处理单元(GPU)等)。一个或多个芯片可以包括用于体现以下中的至少一个或多个的电路(以及可能的固件):一个或多个数据处理器、一个或多个数字信号处理器、基带电路和射频电路,它们是可配置的,以便根据示例性实施例进行操作。在该方面,可以至少部分地由存储在(非临时性)存储器中并且可以由处理器执行的计算机软件来实现,或者由硬件来实现,或者通过有形存储的软件和硬件(以及有形存储的固件)的组合来实现。

应当将本文所描述的例子理解为本发明的实施例的说明性示例。设想进一步的实施例和示例。关于任何示例或实施例描述的任何特征可以单独地使用,或者与其它特征组合地使用。另外,关于任何示例或实施例描述的任何特征也可以与任何其它示例或实施例的一个或多个特征结合使用,或者是这些示例或实施例中的任何其它示例或实施例的任意组合。此外,在权利要求书所限定的本发明的范围内,也可以采用本文未记载的等同物和修改。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号