这里写目录标题
一个通用种源库
论文背景
大多数来源捕获都发生在特定的工具中–工作流引擎、数据库、操作系统或应用程序。然而,大多数用户都有一个现有的工具集–一组能够很好地满足他们的需求并让他们感到舒适的不同工具的集合。目前,这类用户在不中断工作和改变环境的情况下收集来源的能力有限,而大多数用户对此犹豫不决。即使是愿意采用新工具的用户,如果不与其整个环境(可能包括多种语言和框架)集成,也可能会意识到这些工具的出处带来的好处有限。我们介绍了核心种源库(CPL),这是一个便携的、多语种的库,应用程序程序员可以很容易地将其集成到各种工具中,以收集和整合种源。虽然手动检测增加了应用程序编程人员的额外工作,但我们表明,在大多数情况下,工作量很小,由此产生的系统解决了困扰更多受限来源收集系统的几个问题。
当前的溯源工作集
计算科学家对起源的采纳率很低,因为大多数现有的系统要求用户采用特定的工具集。例如,Pass[9]和Story Book[10]要求用户运行修改版本的操作系统,StarFlow[4]需要使用Python、Kepler[2]、VisTrails[5],以及许多其他工作流引擎需要使用特定的引擎-但用户通常不愿更改他们的工作环境。此外,许多来源系统要求用户在单一编程语言或环境中进行所有数据分析,而在现实中,异构性是常态。例如,使用Perl脚本处理用C或Java编写的模拟生成的数据,然后再对其进行处理的情况并不少见。或者使用外壳脚本或分析程序的组合。考虑到这些和其他几个以前确定的经验教训[3]**,我们开发了核心起源库(CPL),它可以很容易地集成到现有的脚本和应用程序中。CPL可以跨操作系统移植,具有多种语言绑定,**并且可以使用各种数据库后端中的任何一种。应用程序可以使用该库的API通过创建起源对象并描述它们之间的数据和控制流来揭示起源。现有的来源和工作流系统可以使用相同的API向CPL披露来源,从而最终将系统中不同工具的来源整合在一起。除了提供API以编程方式访问收集的来源之外,该库还负责持久存储、周期检测和解析、查询和可视化。即使手动检测增加了额外的工作,我们发现这样的工作只需要很少的工作,并且由此产生的系统解决了困扰其他系统的几个问题[3],例如版本断开和出处集成。它使应用程序能够以对它们最合乎逻辑的任何粒度导出来源。例如,自动收集出处的出处系统可能不知道与其观点没有直接关系的两个对象实际上是同一对象的较旧版本和较新版本。我们将在2.1节中进一步讨论这一点。
溯源
种源库的主要设计考虑因素是简单性和跨多个应用程序轻松集成种源的能力。使用库的应用程序调用CPL_ATTACH来为当前进程初始化库,并将其附加到适当的存储后端。然后,应用程序使用库来获取对应于以下各项的唯一ID:
对于新对象使用cpl_create_object,对于现有对象使用cpl_lookup_object将其逻辑对象(如工作流引擎中的参与者或数据库中的表)。然后,每当一个对象使用另一个对象中的数据时(例如,当工作流中的执行元读取文件内容或将计算值传输到工作流中的另一个执行元时),它都会调用cpl_data_flow。应用程序使用cpl_control指示对象在不传递任何数据的情况下影响任务的执行;例如,工作流引擎中的循环操作数影响循环内的执行。应用程序可以使用cpl_add_property将任意键/值对附加到对象。最后,应用程序在cpl_Detach值存在之前调用它(如viaatexit)。不需要清理任何其他状态,例如关闭或以其他方式处置起源对象;库自动执行此操作。这种自动清理是一个明确的设计决策,旨在简化库与现有应用程序的集成。附录A更详细地介绍了API。CPL在内部为每个对象分配一个全局唯一ID。在外部,它使用三个字段的组合来标识对象:
**命名空间:**对象所属的应用程序或系统组件的名称。例如,工作流引擎中的参与者应该在引擎的私有命名空间中定义,而文件应该在文件系统的命名空间中定义。此字段对于防止无关应用程序之间的名称冲突以及促进协作应用程序共享对象非常重要。
**·名称:**对象的本地名称。·
类型:对象的类型,比如是文件还是进程。这可以是标准的(CPL定义的)类型,也可以是用户定义的类型。
如果有多个对象具有相同的名称空间、名称和类型,则默认情况下,查找操作将返回最近创建的对象;其他对象可以使用cpl_lookup_object_ext进行检索。该库为共享定义了几个特殊的命名空间对象使用循环避免算法[9],以避免在起源中创建循环,以便应用程序可以适当地引用对象的较旧版本。该库用出处注释每个出处记录,以便每个出处可以归因于在特定计算机上运行的应用程序的特定实例。它记录用户名、时间、二进制映像的名称、命令行参数和机器的MAC地址。例如,这对回答“这块出处是从哪里来的?”很有用。问题,要列出由应用程序的特定实例产生的起源对象,
优点
这种方法的一个关键特征是,应用程序可以以最符合逻辑和最适合它们的方式向CPL揭示出处,消除了困扰其他系统的几个问题[3]。系统经常遇到的第一个问题是版本断开:例如,大多数文本编辑器保存文件的方式是先创建一个临时文件,然后将其移动到适当位置,替换文件的较旧版本。像PASS[9]这样通过观察系统调用来收集来源的系统经常错过这种连接,并将文档的旧版本和新版本视为不同的对象,即使版本连接对用户来说是显而易见的。使用CPL的编辑器可以选择是将文档的新版本视为旧文档的新版本,还是将其视为通过数据依赖关系连接的单独对象,这取决于对应用程序最具逻辑性的是什么。CPL解决的第二个问题是起源集成:协作应用程序可以共享和引用其对象的GUID,从而消除了W3C起源标准[8]中替代关系的许多用法。如果对象是文件系统上的文件(或不同类型的共享对象),则即使是不协作的应用程序也可以轻松地统一引用它。另一个经常出现的问题是不同来源概念之间的脱节:例如,StarFlow[4]静态分析Python程序以确定其调用图和它读写的文件,而不是在运行时捕获动态信息。它可以将其输出到CPL,而根据我们的经验,将其输出到PASS则更加困难。
缺点
虽然使用CPL需要部分应用程序编程人员的努力,但我们发现这方面的努力相当小;我们在第5节提供了一些轶事证据。
第二个缺点是,图书馆不能保证来源是完整的,甚至是正确的。程序员可能会忘记透露相关信息,可能会无意中泄露错误信息,或者可能会滥用标准类型,从而在以后对出处的推断中引入错误。我们需要获得更多与各种用户打交道的经验,以评估这些可能性的重要性。
查询出处
CPL包括用于以编程方式访问所收集的出处的API。它包括cpl_get_object_ancestry等函数,用于列出对象的祖先和后代,或cpl_get_object_info,用于检索有关对象的信息,如名称空间、名称、类型、创建时间、当前版本和出处。附录A包含更多详细信息。CPL发行版还包括一个命令行工具,用于对文件发出简单的来源查询,它还与Orbiter[7]集成以实现可视化
实现
我们用C++实现了这个库,目前支持C、Java和Perl绑定,外加一个命令行工具,用于检测shell脚本和手动揭示出处。事实证明,我们自己使用该工具是必不可少的,因为它使我们能够揭示我们从命令行执行的简单操作(如复制文件)的起源。CPL可以在Linux、OS X上运行,但在Windows上有一些限制。使用CPL的每个应用程序都将其作为共享库加载,并如上所述调用CPL_ATTACH,进而打开其数据库连接。因此,在每个启用起源的进程中都嵌入了CPL的一个运行实例,而不是每个应用程序与单个服务通信。CPL的各个实例依赖于数据库进行缓存,并且在少数情况下需要时依靠共享信号量来执行同步。从用户的角度来看,这种方法的优点是简单,因为不需要担心运行单独的服务。缺点是这给数据库带来了更大的压力,因为它限制了图书馆可以缓存的信息类型。另一方面,我们的经验表明数据库缓存是有效的,并且我们节省了如果CPL作为单独的进程运行时的IPC开销。CPL旨在与多个数据库引擎(包括关系数据库和图形数据库)协同工作。我们实现了ODBC和SPARQL/RDF[6]驱动程序,它们我们在MySQL、PostgreSQL和4store[1]上进行了测试。该库使用高级接口与驱动程序通信,在该接口中,各个API函数被设计为具有足够的表现力,以便数据库驱动程序可以利用数据库的特定功能高效地实现它们。同时,动作被设计得足够简单,如果需要,可以将它们简单地分解成更小的动作。实际上,几乎所有的任务都可以使用单个SQL或SPARQL查询来执行。CPL要求每个数据库操作都是原子的和持久的,并保持数据库一致性。CPL不需要跨多个操作的原子保证。源代码附带的文档包含更多详细信息(请参阅附录B)。
GraphDB BENCH
是一个对图形数据库进行基准测试的工具–既可以比较不同的数据库,也可以更好地了解单个数据库系统的性能。基准测试被组织为一系列操作符(例如摄取GraphML文件、添加顶点、获取节点的k跳邻域),这些操作符作用于图形数据库的实例。该程序将每个已完成操作的结果、运行时间和内存使用情况写入一个.csv文件。我们利用基准测试来揭示从数据库到访问它的每个操作员的数据流,以及从每个操作员到.csv文件的数据流和结果。基准测试还揭示了从修改数据库的操作员(如摄取)到数据库实例的数据流。我们用它的参数来注释每个算子,如k跳微标中的k值或随机图生成器中的模型参数值。检测涉及添加或修改大约270行源代码(不包括注释),其中大部分是复制和粘贴。结果是我们可以很容易地跟踪每个.csv是如何生成的–比如使用了什么运算符,它们在数据库的哪个实例上操作,以及我们用什么参数来配置运算符和基准测试工具。我们还可以通过检查起源来了解有关基准的其他信息,其中包括传递给运行基准的Java虚拟机的命令行参数,例如Java堆的最大大小。收集的出处还使我们能够查询数据库的祖先,以便了解哪些运算符修改了它,数据库最初是从哪个GraphML文件构建的。这很有用,例如,如果我们发现数据库在最初摄取之后没有被修改,我们就可以安全地将其重用于后续基准测试。否则,我们可能需要将其恢复到原始状态。
Kepler
Kepler[2]是一个工作流引擎,可以自动将来源收集到几个存储后端中的一个,比如SQL数据库、OPM文件或文本文件。我们只用了不到一个小时就实现了基本的CPL支持。我们的实现基于开普勒的OPM模块的源代码,工作相对简单。该模块就像OPM模块一样,公开参与者和构件之间的数据依赖关系,只是它将参与者参数存储为属性,而不是存储为与其各自的参与者具有数据依赖关系的构件。这显著地清理了起源图,并使我们的可视化工具能够在一个简单、简洁的表格中显示参与者的属性。我们进一步扩展了CPL模块,通过在执行之前公开从输入文件到文件读取参与者的数据流,以及在执行之后从文件写入参与者到其输出文件的数据流,将其起源与文件系统集成在一起。对于每个执行文件I/O的执行文件I/O的参与者,这在起源模块中平均需要1-2行特定于参与者的代码来从其参数中检索文件名。这使我们能够在工作流引擎之外的多个工作流和数据处理阶段轻松跟踪来源。
结论
我们将CPL设计为通用起源库,并演示了它在应用程序和数据分析管道中的使用。CPL为在不同环境中收集种源提供了一个简单、可行的解决方案。它解决了困扰现有种源系统的几个问题,跨多个程序和环境集成种源,并提供API来访问种源并促进其与种源分析工具的集成。