一、字段抽取与读时建模
1、Why 读时建模?
在处理传统业务数据时,一般使用传统的关系型数据库或者数据仓库来解决问题。在当前云原生大数据时代,日志分析愈加重要。日志分析的痛点主要有如下三点:
- 海量机器数据的产生,会消耗大量存储空间,同时要求较高的写入速度;
- 微服务架构流行,整体业务迭代迅速,数据(日志)格式变化频繁,数据格式统一工作需要耗费较高的时间和物理成本;
- 格式不统一的数据写入关系型数据库,需要维护额外的 ETL 任务(如数据清理、转换等),一方面增加系统维护成本,另一方面额外的性能开销可能导致数据写入速度降低。
鸿鹄系统在设计之初决定采用读时建模来有效地解决以上几个问题。如下图所示,左侧为读时建模系统,右侧为写时建模系统。
写时建模系统中,通常需要预先定义好若干张表格,并定义好表中列名和属性等。将来自不同系统的 Access Log 日志写入到预定义好的关系型数据库表格中,需要额外维护三个 ETL 任务,并将数据格式统一。
鸿鹄系统(读时建模)中,数据写入时不需要对数据格式做转换,无需额外的 ETL 任务开销,写入速度相比写时系统较快。数据写入只需存储数据的原始信息以及对后续查询有益的元信息(目标数据集、数据导入时间等),写入磁盘的内容相比写时建模系统较少,节约整体磁盘空间。当用户进行查询,使用目标数据时,会通过预定义的计算规则,动态生成一张包括新富化字段的表格,也即在查询时完成数据的建模。
2、字段抽取的定义
针对读时建模系统,字段抽取是指原始数据在被查询时,通过预先定义的字段提取规则,对数据进行字段规整、字段富化的过程。字段抽取的作用是在查询时,通过消耗 CPU 的算力,来换取查询的灵活性,可以节省大量的存储空间。
鸿鹄数据平台中,字段抽取功能实现了在查询过程中将异构数据动态结构化,为数据分析提供了很大的灵活性,这是鸿鹄系统读时建模的最大特性。
二、字段抽取功能实现原理
字段抽取需要预定义一系列抽取规则,规则是否复杂,是否需要额外的编程学习呢?带着这些问题,下面来看一下字段抽取功能的实现原理。
在鸿鹄系统中,字段抽取功能是通过定义字段抽取规则应用来实现的,每一个字段抽取规则应用由若干个字段抽取规则组合而成。每个规则应用,根据内部字段抽取规则定义先后顺序,依次执行字段抽取规则,实现数据字段的归整和富化功能。
通过将规则应用与数据源类型相互绑定,可以明确字段抽取应用的目标数据,当目标数据被使用(查询)时,根据该数据所属数据源类型,执行绑定的字段抽取规则应用。
1、字段抽取规则
在鸿鹄系统中,一条字段抽取规则是由来源字段和抽取规则类型组成的。
(1)来源字段
来源字段即需要应用字段抽取规则的原始字段名。通过选择来源字段,即可知道抽取规则需要应用到原始数据的哪一部分内容中。
举例说明,一条日志信息可能包含日志的时间、日志的 log、level 以及一些用户的具体请求信息。
- 通常针对某一个字段抽取规则并不需要将其应用到原始数据的整体;
- 只需要指定来源字段,如数据的时间信息进行详细抽取,或对日志的用户行为做分析。一方面可以降低字段抽取规则应用时所消耗的系统资源;另一方面,限定了字段抽取应用的原始文本内容,可以有效避免误抽取。
(2)来源字段类型
- 原始数据本身(即 _message 字段)——鸿鹄系统内置
- 任意通过字段抽取规则富化出的新字段。(该抽取规则必须在生成来源字段的抽取规则之后定义)
(3)抽取规则类型
当前鸿鹄系统内置四种抽取规则类型,下面介绍这些规则的具体适用场景及其作用。
正则抽取
正则抽取,利用正则表达式从原始事件中提取出匹配的内容作为字段,是处理非结构化事件中最常用的一种抽取方式。在鸿鹄系统中,通过定义若干个命名捕获组(捕获组的名称为新抽取或新富化出的字段名称),捕获组所匹配的内容为字段值。
以如下日志数据为例,包含多个子信息,每个子信息是固定的 pattern:
- 绿色部分:日志产生的时间信息
- 红色部分:日志对应的模块信息
- 蓝色部分:日志对应的详细信息
上述情况非常适用于正则抽取,对原始数据进行内容的切分。上述三个信息可以对应三个命名捕获组,当对原始日志数据应用了该条正则抽取规则后,可在查询时动态生成三个新的字段(time 字段、module 字段、message 字段)以及它们对应的字段值。
正则抽取的方式:
- 用户手工撰写正则表达式
- 通过 UI 界面,划词自动生成正则表达式
JSON 抽取
JSON 抽取主要针对原始数据中包含有类似 JSON 的文本数据,通过内置的 JSON 字段解析,将原始的 JSON 对象中对应的属性值和属性名提取为新的字段。
针对如下包含 json 格式的文本内容的日志数据,应用内置的 JSON 抽取后,可以非常方便地将原始的半结构化数据自动转换成一个动态的表格,表格中每一列是JSON 对象中的属性名,属性值会自动匹配到对应的属性列。
键值对抽取
键值对抽取,主要针对原始数据中包含有类似 key=value 的文本数据,通过内置的键值对抽取的方式,抽取出新的字段,等号左侧的 key 提取为新字段,等号右侧的 value 提取为新字段值。
以如下包含 key-value 的日志数据为例,应用了鸿鹄系统内置的键值对抽取,可将半结构化的键值对自动转换成一个动态的表格。所有的 key 值被提取成了字段名,value 值会动态地应用到相应字段值。
IP 地址抽取
IP 地址抽取,主要针对原始数据中包含有 IP 地址信息的内容,通过内置的方法可快速提取出 IP 地址对应的国家、城市、省市、运营商等信息。
2、数据源类型绑定
在鸿鹄系统中,针对每一个定义好的具体规则应用,需按照抽取规则定义的先后顺序依次执行。使用某个规则应用时,必须将规则应用与特定的数据源类型做绑定,才能在查询时动态地将该规则应用到读时建模的目标数据。
从外部导入数据到鸿鹄系统,无论是文件导入、HTTP 采集还是采集 CS log 数据,除了需指定数据集,另一个必填项为数据源类型。
鸿鹄系统是 NoSQL 范畴,将数据集比喻为数据库或 Namespace,则数据源类型是一张表格,字段抽取规则应用,可类比为表格所对应的表格定义。
通过数据源类型,可区分一个数据集当中的不同类型数据,针对不同类型的数据,需采用不同的抽取规则进行后续查询时的读时建模。举例说明,IT 运维人员在采集设备的数据集中同时接收交换机数据、防火墙数据,路由器数据。由于三种设备的数据格式各不相同,在数据导入时,需新建三种不同的数据源类型。
3、规则应用界面
在规则应用页面中,可点开“字段加工”选择“字段抽取”标签页,支持展示如下内容:
- 内置或自定义的若干个规则应用。
- 每个规则应用绑定到哪些数据源类型。
- 可点击左侧加号按钮,对规则应用下的某一抽取规则进行展开。
- 可以查看抽取规则的执行顺序。
- 抽取规则的元素组成。
三、字段抽取示例
以常用的日志数据为例,通过鸿鹄系统提供的开箱即用的 UI 界面,建立读时建模中抽取规则应用的过程如下图所示。
- 确定查询结果,即确定对哪些目标数据进行字段抽取。
- 选择具体样例事件,用于预览字段抽取规则的部分结果进行分析。
- 抽取规则编辑、变形、修改,预览读时建模的整体效果,保存抽取规则。
- 在查询页面,查询原始目标数据,自动应用定义的抽取规则来动态富化出分析所需的额外字段。
1、检索原始数据
- 通过查询检索原始数据,即字段抽取的目标数据。输入类似于 select * from xxx event set 的查询,为后台系统提供字段抽取所需的数据源字段及其对应的数据源类型。
- 确保查询结果包含自定义的数据源类型字段,否则无法应用到原有的数据中。最佳实践:使用自定义的数据源类型。
- 点击抽取新字段进入字段抽取页面。
2、选取样例事件
在下面的选取样例事件的字段抽取页面,用户可选择一条简单的样例事件,进行后续的字段抽取规则的修改、预览和调整。
- 选定进行字段抽取的目标数据源类型,后续系统会自动将新建的规则应用与数据源类型进行绑定。
- 通过过滤条件对原始事件进行筛选,如筛选脏数据等。
- 基于查询结果表格中选取任意一个具体的样例事件,进到字段抽取规则设置页面。对用户选择的样例事件及样例事件字段抽取结果进行预览。中间的用户编辑区域(新增、删除或者编辑抽取规则),可选择来源字段,也可选择抽取规则。
3、抽取规则设置
字段抽取规则设置页面:
- 用户选择的样例事件及中间的用户编辑区域(新增、删除或者编辑抽取规则),可选择来源字段,也可选择抽取规则。
- 完成字段抽取规则的编辑后,下方是样例事件字段抽取结果的预览,如富化出的字段。
下面以一个常见的日志数据为例,该数据包含日志产生的 IP 地址、日志时间信息以及日志对应的详细信息三部分。这个日志数据每部分信息可通过固定 pattern 分割,选取正则抽取,对原始数据做富化。
下面展示在鸿鹄系统中如何便捷地在 UI 上划词生成正则表达式的过程:
- 选择一个来源字段(默认原始数据本身,_messsage 字段)。
- 选择抽取规则为正则抽取。
- 在规则下方的文本框中,划取想要抽取的文本内容,可快速选取一部分关键信息进行字段富化,并对字段内容起个名字。
如上图所示,用户不需要写任何正则表达式,只需要通过用户界面上的一些鼠标操作即可完成正则表达式的抽取。同时,鸿鹄系统会在文本框中把用户所有已抽取过的字段所匹配的文本内容做高亮显示,如下图所示:
此外,当用户完成了一个字段划取的操作后,在下方的整体预览表格中可预览到正则抽取及其应用到原始数据后的具体结果、原始数据富化出的字段等。
需要注意的是:有一些原始数据显示的数据都为 none 的原因是划词抽取只针对用户所选择的一条样例事件,并生成后续的正则表达式,可能无法匹配到原始数据中所有的信息。
在上述情况下,如捕获组的信息过于笼统的话,建议通过手动编辑正则表达式的方式对其进行修改。
因此,最佳实践为划词与手动编辑相结合生成正则表达式。如最后的 detail 信息,无需将正则表达式写得过于详细,可对正则表达式进行简化,能更精准获得 IP 字段、time 字段以及 detail 字段。此外,在第一步抽取的信息可能较粗,可对其富化出的字段进行进一步详细抽取。
如下,可针对第一步富化得到的 IP 地址信息,进一步通过 IP 地址抽取规则,得到详细的地理位置信息。
类似地,针对第一步提取出的时间信息—time 字段,通过 UI 划词的正则抽取,可得到详细的年月日以及时区信息。
最后针对包含两部分子信息的日志详细信息 detail 字段,可对键值对信息做额外提取。首先通过正则表达式抽取,将日志详细信息提取成两部分;其次,对只包含键值对文本信息的部分进行键值对抽取。这样,首先通过正则抽取缩小范围,可避免误抽取。
在上述示例中,首先通过划词抽取和用户手动编辑正则表达式相结合的方式,将原始数据切割成三部分;其后,针对第一步抽取出的若干子字段再进行一次细致的字段抽取,从而将原始非结构化日志数据富化出所需的额外信息;最后对该规则进行预览后进行保存。
4、抽取规则预览
在建立完抽取规则后,鸿鹄系统会自动将抽取规则与数据源类型进行绑定,无需用户手工操作。通过用户界面建立的属于该抽取规则应用的所有规则都可进行预览,如下图所示为来源字段信息和抽取方式,无需额外编程或第三方系统集成。
5、查询结果
下面对应用字段抽取规则前后的查询结果进行对比。
- 原始的查询结果:通过 select* from dataset,只能查询到系统中预保存的一些原始字段,如数据来源、数据的数据源类型以及抽取时间等。
- 应用字段抽取规则后:同样的查询,会展示出富化的新字段。因此,引用了抽取规则后,可以非常快速地完成查询的读时建模。
四、问答环节
Q1:鸿鹄系统中字段抽取与索引时字段抽取的差别?
A1:鸿鹄系统中字段抽取:在数据写入的时候,不需要对数据做任何预处理,不需要预先定义数据包含哪些列,有哪些特定的格式;查询时,通过一个灵活的动态规则,根据用户的需求对相关字段进行提取。
索引时字段抽取:在查询时将一些字段预先提取出来落到磁盘上,可加速查询时的查询效率,不需要通过额外的抽取规则生成那些列,但会增加磁盘的开销。
基于用户的实际场景,如数据查询快还是数据查询灵活,进行分别处理:若数据包含特定几列,希望加快这些列的查询速度,则可使用索引词的字段抽取;数据非常灵活,希望保持数据查询时的灵活性,则是建议定义字段抽取规则完成查询时的字段抽取。
Q2:是否可通过日志的 IP 地址直接识别出国家和省市区的信息?
A2:首先通过正则抽取或其他抽取方式,将日志中包含 IP 地址文本内容做提取,去除额外的干扰项;数据中没有任何干扰项,只包含 IP 地址的文本内容,则可直接使用IP 地址进行国家和省市区信息的抽取。
Q3:读时建模和写时建模的性能比较?
A3:读时建模下计算引擎通常缺少 SQL 的优化能力,鸿鹄系统中读时建模在查询时设定的动态规则会额外消耗算力,相比写时建模会有性能上的损失。
若用户场景是不需要额外灵活的数据富化的过程,或数据相对较固定,则可利用鸿鹄系统中的固化视图和预查询功能,进行加速,使得读时建模与写时建模的查询速度差异较小。
Q4:最佳实践中需使用自定义的数据源类型,是否可使用鸿鹄系统中自带的数据源类型来接收数据?
A4:用户在初始使用鸿鹄系统时,或者非常明确只有 json 和 csv 的数据类型,可使用系统内置的数据源类型。但仍推荐使用自定义数据源类型。其原因是若修改某个数据类型的绑定规则,会导致数据影响面大,一方面会降低查询效率,另一方面会出现误抽取。
若用户后续会对数据做额外查询时加工,处理实际的业务场景,推荐用户针对每个业务场景自建一个自定义的数据源类型来接收该场景数据。
Q5:在 UI 界面上生成字段规则后,后续是否可修改?
A5:点击规则应用列表页面的右侧一列操作栏的“笔图标”编辑功能按钮,会进入到字段抽取页面,可对用户已定义好的某个特定规则进行修改和调试。
若用户已对某个特定的数据源类型绑定好一个具体的规则,可在查询页面点击抽取新字段按钮,进入到前述的字段抽取页面,系统会预先加载选定的数据源类型及其对应的抽取规则,用户可对现有的抽取规则进行修改,并可预览修改后的效果。