元数据

元数据是 Manufacturing Data Engine (MDE) 中的一个关键概念。它表示有关事实的上下文数据。例如,传感器读数或事件。元数据有助于回答以下问题:

  • 哪个代码发出了数值读数?
  • 在获取数字读数时,正在处理什么产品?
  • 传感器属于哪个设备?
  • 事件发生时,哪个班次正在进行?
  • 在进行读数时,哪个配方处于有效状态?

MDE 根据元数据的变化速度区分两种类型的元数据:

  1. 缓慢变化的云元数据
  2. 快速变化的嵌入式元数据

云元数据

缓慢变化的元数据是指在较长时间内保持不变的情境数据,例如描述给定传感器所处机器、单元、生产线和工厂的资产情境。借助 MDE,您可以对缓慢变化的元数据进行建模、管理和探索,并将其与记录相关联。将元数据与记录相关联后,您可以使用关联的上下文探索记录。

MDE 中缓慢变化的元数据称为云元数据。云元数据在解决方案中发挥着两项作用:

  1. 对记录进行情境化和分类。
  2. 用作有关制造实体(例如传感器、设备和生产线)的版本化主数据的来源。

通过 MDE,可以从边缘获取云元数据,也可以使用 MDE 网页界面手动创建云元数据,还可以使用 API 以编程方式创建云元数据。后者可让您从现有的企业资产管理 (EAM) 或主数据管理 (MDM) 系统中获取元数据。

元数据存储分区

云元数据存储分区(也称为“存储分区”或“元数据存储分区”)是一种配置实体,用于对一组相关的缓慢变化的情境数据进行建模。例如,一个桶可以模拟标记或配方的属性。在数据分析领域,您可以将分桶视为数据维度。

元数据存储桶的关键属性是其架构。该架构(以 JSON 架构对象表示)定义并限制了其中包含的元数据实例的结构。您可以创建新的元数据存储桶版本,但新版本必须遵守云元数据存储桶版本控制规则

存储分区是全局性的,这意味着它们可以被任何类型引用。

元数据实例

元数据实例表示云元数据存储分区的“内容”。每个实例都描述了某个实体,例如正在捕获的记录的资产、流程或方面。实例有两种类型的标识符:

  1. 系统生成的 UUID(通用唯一标识符),用于标识 MDE 中的实例。
  2. 在 MDE 之外标识实体的自然键(例如,传感器的序列号)。

元数据实例按自然键进行版本控制。这意味着,对于给定的自然键,MDE 会跟踪属性的演变。例如,一个自然键为“tag-123”的标记最初可能位于单元格“X”中,但后来移到了单元格“Y”中。MDE 会存储每个实例并为其添加时间戳,还会为其提供唯一的 UUID。借助此唯一 UUID,您可以检索自然键的实例历史记录,在提取时使用正确的实例将记录情境化,以及在查询时追溯性地将实例应用于过去的记录。

从 v1.5.0 开始,元数据实例会进行版本控制,并根据 event-time(而非 processing time)进行处理。当您发送包含历史记录的元数据实例时,MDE 会根据消息的 eventTimestamp 对这些元数据实例进行版本控制,这样一来,历史元数据和最新元数据就可以共存,而无需更改最新实例。如需了解详情,请参阅为元数据存储分区添加版本信息

MDE 只允许将实例添加到符合相应存储桶特定版本架构的存储桶中。

元数据存储桶架构

每个元数据存储桶版本都包含一个架构,并且元数据实例只能添加到存储桶的特定版本。架构进一步限制了可添加到存储桶版本的元数据实例的结构。

元数据存储桶架构以 JSON 架构对象的形式表示,符合 JSON 架构规范的 2019-09 版本

例如,如果后来将架构添加到某个存储桶版本,则该架构会声明每个实例对象都必须具有一个名为 deviceName 的属性,其值为 string,并且此属性是必需的。请参阅以下示例:

{
  "$schema": "https://json-schema.org/draft/2019-09/schema#",
  "type": "object",
  "properties": {
    "deviceName": {
      "type": "string"
    }
  },
  "required": ["deviceName"]
}

元数据实例验证

元数据实例必须符合为特定元数据存储桶版本定义的架构,才能插入。

存储分区类型

MDE 定义了三种类型的存储分区:

  1. 标记存储分区
  2. 记录存储分区
  3. 查找存储分区

存储桶的类型是在创建时定义的,之后无法更改。

为存储分区添加标记

标记桶表示可提供标记上下文的桶。这意味着,存储桶中包含的实例的自然键必须是标记名称。

记录存储分区

记录桶表示可以根据共享的通用自然键将任何一组记录置于特定情境中的桶。记录桶实例的自然键可以是任何值。

查找存储分区

查找桶是指不直接将记录置于上下文中的桶,而是提供可在解析器中使用的参考数据。查找桶实例的自然键可以是任何值。

记录存储桶实例绝不会与记录相关联。不过,您可以在 Whistle 脚本中调用 mde::lookupByKey 函数,从查找存储桶中检索实例。该函数以查找 bucketNamebucketVersionnaturalKey 作为实参,并返回所提供自然键的最新元数据实例。您可以使用该实例来填充解析器中 proto 记录的字段。

版本控制元数据存储分区

元数据桶的架构可以不断发展,但您必须创建桶的新版本才能修改架构。现有存储桶版本以及引用存储桶之前版本的任何现有配置实体不受此操作的影响。为确保元数据存储桶在整个生命周期内的数据一致性,新的元数据存储桶架构版本会受到以下限制:

新版本可能

  • 添加了新的选填字段。
  • 将必填字段标记为可选字段。

新版本可能无法

  • 移除字段。
  • 更改现有字段的数据类型。
  • 将可选属性标记为必需属性。

从 v1.5.0 开始,元数据实例的解析也基于事件时间戳。这意味着,MDE 会解析相对于记录的事件时间而言最新的元数据实例。这概括了 MDE 关联元数据的概念,使其能够跨不同时间工作,而时间由源消息控制。为了提高元数据实例的查询可读性,MDE v1.5.0 引入了一个名为 validFrom 的新字段,用于指定特定元数据实例的生效时间。MDE 使用此字段根据源消息事件时间检查要选择哪个元数据实例。

例如,对于自然键 sensor-a,假设您今天向 MDE 发送了一个具有以下值的元数据实例:


{
    "naturalKey": "sensor-a",
    "instance": {
        "site": "ONE",
        "factory": "ONE",
        "floor": "ONE",
        "line": "ONE",
        "cell": "ONE"
    }
}

MDE 会根据传入消息的 eventTimestamp 值(此元数据实例的发送位置)为此实例设置版本,并且由于时间戳设置为今天,因此 MDE 会将此实例视为相应自然键迄今为止收到的绝对最新版本。此新版本元数据实例的 validFrom 值将是传入消息的 eventTimestamp 值。

现在,假设您针对同一自然键 sensor-a 发送了历史元数据实例(例如,去年的数据),其值为:


{
    "naturalKey": "sensor-a",
    "instance": {
        "site": "OLD",
        "factory": "OLD",
        "floor": "OLD",
        "line": "OLD",
        "cell": "OLD"
    }
}

在此示例中,MDE 通过将此实例与在收到 eventTimestamp(例如去年)时或之前可用的最新元数据实例进行比较来确定此实例的版本,并将其插入时间轴中的正确位置,这是 v.1.4.x 和 1.5.0 之间的根本区别。当 MDE 收到历史记录事件时,它将解析在事件时间点最新的历史元数据条目。下图展示了处理和关联逻辑的运作方式:

版本控制元数据逻辑

将云元数据实例与记录相关联

为记录添加上下文涉及将记录关联到元数据实例。 这是通过在记录中存储对元数据实例 UUID 的引用来实现的。MDE 提供了两种在解析器中创建此链接的方式:

  1. 通过提供实例的自然键。
  2. 通过提供 proto 元数据实例。

例如,BigQuery 数据接收器会在名为 cloud_metadata_ref 的字段中存储每个存储桶的元数据实例引用。以下示例展示了元数据实例引用在 BigQuery 记录中的显示方式:

{
  "id": "e4b66cb9-7c60-4473-b1a1-1954eca92405",
  "tag_name": "primepaintingrobot-01-airpressure",
  "type_version": "1",
  "event_timestamp": "2023-06-20 07:11:59.757000 UTC",
  "value": "762.53",
  "embedded_metadata": {},
  "materialized_cloud_metadata": {
    "device-metadata": {
      "deviceName": "example-device"
    }
  },
  "cloud_metadata_ref": {
    "device-metadata": {
      "bucket_number": 143,
      "bucket_version": 1,
      "instance_id": "50e156a0-dbd9-4f9b-bdc8-1e77574bc4b1"
    }
  },
  "ingest_timestamp": "2023-06-20 07:12:06.335000 UTC",
  "source_message_id": "8434396321424812"
}

使用自然键将记录关联到云元数据实例

您可以在解析器中提供对云元数据存储桶版本和 proto 记录中实例的自然键的引用,从而将记录关联到元数据实例。如果存在实例的 UUID,MDE 会自动将自然键替换为该 UUID,并将链接存储在记录中。如果所提供的自然键有多个实例,MDE 会选择最新的实例(具有最新 created_timestamp 的实例)。

如果引用的存储桶是 TAG 存储桶,则提供自然键是可选的。 如果省略了自然键,MDE 会默认使用 tagName 字段的值。

如需了解如何使用自然键将记录关联到元数据实例,请参阅通过自然键解析元数据 instance_id

使用 proto 元数据实例将记录关联到云元数据实例

您可以在解析器中提供对云元数据存储桶版本的引用,并提供 Proto 元数据实例和(可选)Proto 记录中的自然键,从而将记录关联到元数据实例。如果源消息已包含用于构建有效 proto 实例的上下文信息,则此元数据实例关联方法特别有用。

使用 proto 元数据实例将记录关联到云元数据实例时,请考虑以下事项:

  • 如果您省略自然键,MDE 会根据桶类型自动为您选择一个。
  • 如果您在 TAG 存储桶的上下文中省略了 proto 实例中的自然键,MDE 会自动选择 tagName 作为自然键。
  • 如果您在 RECORD 存储桶的上下文中省略了 proto 实例中的自然键,MDE 会自动生成消息对象的哈希值并将其用作自然键。
  • 如果所提供的 proto 实例与所提供自然键的最新元数据实例相匹配,MDE 会将所提供的 proto 实例替换为匹配实例的 UUID,并将该 UUID 存储在记录中。
  • 如果提供的 proto 实例与所提供自然键的最多元数据实例不匹配,MDE 会为所提供的自然键创建一个新的元数据实例,并将新创建的实例的 UUID 存储在记录中。系统的这种行为可让您使用从源消息生成的实例动态填充元数据桶。

如需了解如何使用 proto 元数据实例将记录关联到元数据实例,请参阅按实例值解析元数据实例 ID

实例具体化

记录可以选择性地包含整个元数据实例,而不仅仅是存储元数据实例的 UUID。这称为“物化”。您可以在类型级为每个接收器配置此行为,只需将接收器的 materializeCloudMetadata 字段的值设置为 true 即可。

例如,为 BigQuery 接收器启用元数据实体化后,对于包含元数据实例引用的记录,将生成如下所示的行:

{
  "id": "e4b66cb9-7c60-4473-b1a1-1954eca92405",
  "tag_name": "primepaintingrobot-01-airpressure",
  "type_version": "1",
  "event_timestamp": "2023-06-20 07:11:59.757000 UTC",
  "value": "762.53",
  "embedded_metadata": {},
  "materialized_cloud_metadata": {
     "tag":{
       "bucket_number":143,
       "bucket_version":1,
       "instance":{
         "datatype":"float",
         "deviceID":"ppr-01",
         "deviceName":"primepaintingrobot-01",
         "vendor":"KUKA"
       }
     }
  },
  "cloud_metadata_ref": {
    "device-metadata": {
      "bucket_number": 143,
      "bucket_version": 1,
      "instance_id": "50e156a0-dbd9-4f9b-bdc8-1e77574bc4b1"
    }
  },
  "ingest_timestamp": "2023-06-20 07:12:06.335000 UTC",
  "source_message_id": "8434396321424812"
}

嵌入式元数据

快速变化的元数据表示快速变化的上下文数据。快速变化的元数据的典型示例包括自动递增的计数器和 ID,例如序列号或交易 ID。

借助 MDE,您可以使用 Whistle 快速构建、协调和转换快速变化的元数据,并通过在 解析器的 proto 记录中填充名为 embeddedMetadata 的字段,将元数据直接嵌入记录中。

所有受支持的 MDE 数据接收器都会提供嵌入式元数据。例如,在解析器中填充 proto 记录中的 embeddedMetadata 字段会在 BigQuery 中生成如下所示的结果记录行:

{
  "id": "e4b66cb9-7c60-4473-b1a1-1954eca92405",
  "tag_name": "primepaintingrobot-01-airpressure",
  "type_version": "1",
  "event_timestamp": "2023-06-20 07:11:59.757000 UTC",
  "value": "762.53",
  "embedded_metadata": {
    "transactionNumber": "1234"
  },
  "materialized_cloud_metadata": {},
  "cloud_metadata_ref": {},
  "ingest_timestamp": "2023-06-20 07:12:06.335000 UTC",
  "source_message_id": "8434396321424812"
}

元数据自动删除

对于记录元数据和标记元数据,MDE 会通过将每个新实例与旧实例进行比较,来跟踪每个自然键中发生的更改。当任何实例属性发生更改时,MDE 都会创建一个新版本,并将其标记为最新有效实例。根据设计,标记和记录元数据的粒度应为数千和不到十万。这些限制允许 MDE 对来自边缘或 API 的元数据实例进行索引,而不会影响处理吞吐量。

有时,由于配置错误,解析器会在元数据实例中注入高基数字段(例如时间戳),这会导致每个自然键的版本快速增加。超过一定阈值后,这会对提取性能产生负面影响。在某些情况下,在解决方案管理员扩展底层云基础架构服务之前,这可能会导致处理完全停止。

自 v1.4.0 起,MDE 会强制执行每个自然键的最大实例数,以确保性能一致。当自然键的数量接近此阈值(默认值为 200)时,MDE 会向新的通知 API 发送警告,告知用户哪些自然键具有大量元数据实例版本。当自然键实例大小超出阈值时,MDE 会自动从内部存储区中删除旧实例。它还会向 Notifications API 发送另一条通知,告知用户已删除的自然键。

警告和删除活动都会在日志中报告,您可以使用这些日志在项目 Cloud Monitoring 中创建提醒政策。

元数据存储分区的命名限制

元数据存储分区名称可包含以下内容:

  • 字母(大写和小写)、数字以及特殊字符 -_
  • 最长不得超过 255 个字符。

您可以使用以下正则表达式进行验证:^[a-z][a-z0-9\\-_]{1,255}$

如果您尝试创建违反命名限制的实体,则会收到 400 error