开发者学堂课程【NiFi 知识精讲与项目实战(第一阶段): FlowFile 属性】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/705/detail/12519
FlowFile 属性
内容介绍:
一、使用属性
二、共同属性
三、提取属性
四、添加用户自定义属性
五、路由属性
六、表达式语言/在 Property 值中使用 attribute
七、表达式语言中的自定义属性
八、总结
一、使用属性
1.下面了解在 NiFi 当中 FlowFile 的属性如何使用,这个属性不是处理器的属性,而是 FlowFile 的属性。在 NiFi 当中每一个 FlowFile 都会拥有多个属性,这些属性会在 FlowFile 整个生命周期当中产生变化。FlowFile 概念非常强,提供了三个主要优势。
(1)首先,FlowFile 允许在流中做出一些路由的知识,可以满足某些条件,支持按照条件去分发,这样可以使用 RouteOnAttribute 或者 RouteOnContent 这些类似的处理器进行实现。
(2)其次,也可以利用属性配置处理器,也就是通过 FlowFile 的属性来影响处理器的属性。处理器的配置是依赖于数据的,比如 PutFile 这个处理器可以使用 FlowFile 当中的 Attributes 来获取到每一个 FlowFile 的存储位置,之前在进行 PutFile 的时候存储位置是自己协持进去的,但是可以通过 FlowFile 当中的一些属性来动态的获取到每一个不同的流文件,应该写到哪一个目录中。每一个 FlowFile 的目录和文件名都可能是不同的,这涉及到 NiFi 表达式语言。每一个流当中都有 Flow filename 属性,处理器可以通过这样一个配置 $(filename) ,就可以获取到当前 FlowFile 流文件当中的 filename 的属性值。通过这样的配置就可以实现动态的写入目录。
(3)最后属性提供了一些有关数据的非常重要的上下文信息。在查看 FlowFile 历史的演变记录的过程会很有帮助,也可以在历史面板数据当中搜索特定的属性,也可以查看更多的上下文。通过这样的方式可以很好的理解整个已有的逻辑是如何进行的。
关于 FlowFile 属性会分为几块来讲解。首先是 FlowFile 的共同属性,FlowFile 也可以提取属性,以及 FlowFile 可以使用一些自定义的属性,还有属性路由包括表达式语言可以在属性中进行使用,以及表达式语言他本身也可以使用自定义属性。
2、每个 FlowFile 都拥有多个属性,这些属性将在 FlowFile 的生命周期中发生变化。FlowFile 的概念非常强大,并提供三个主要优点。
•首先,它允许用户在流中做出路由决策,以便满足某些条件的 FlowFiles 可以与其他 FlowFiles 进行不同地处理。这可以由 RouteOnAttribute 和其他类似的处理器完成的。
•其次,利用属性配置处理器:处理器的配置依赖于数据本身。例如, Put File 能够使用 Attributes 来知道每个 FlowFile 的存储位置,而每个 FlowFile 的目录和文件名属性可能不同(结合表达式语言,比如每个流都有filename 属性,组件中就可以这样配置文件名:$(filename) ,就可以获取到当前 FlowFlle 中 filename 的属性值)。
•最后,属性提供了有关数据的极有价值的上下文。在查看 FlowFile 的 Provenance 数据时非常有用,它允许用户搜索符合特定条件的 Provenance 数据,并且还允许用户在检查 Provenance 事件的详细信息时查看此上下文。通过简单地浏览该上下文,用户能够知道为什么以这样或那样的方式处理数据。
二、共同属性
1、每个 FlowFile 都会有很多相同的属性。首先都有一个叫 filename 的属性,filename 指的是 FlowFile 如果存储在本地的文件名,也就是说数据实际上都在磁盘上进行存储。path 属性定义的 FlowFile 文件在系统上存储的目录。uuid 属性指的是一个唯一的标识符,用来区分 FlowFile 与其他系统中的 FlowFile,相当于数据库中的主件是一样的。entryData 是时间类型的属性,它主要指的是 FlowFile 从创建开始的创建日期,这个属性是一个数字,表示的是从1970年1月1日到现在为止的毫秒数。lineageStartData 这也是一个时间类型的属性,他指的是 NiFi 可以对 FlowFile 进行复制、合并、还有拆分,这一系列操作都会产生一个新的、子的 FlowFile。lineageStart 表示的就是某一个子 FlowFile 他的最早的副节点进入系统的时间,这个值也是一个数字。最后一个叫做 fileSize,这个属性主要表示 FlowFile 文本内容的大小,就是字节数。这几个属性都是 NiFi 系统自动生成的,用户不能对他进行改变。
2、每个 FlowFile 都有一组属性:
filename:可用于将数据存储到本地或远程文件系统的文件名。
path:可用于将数据存储到本地或远程文件系统的目录的名称。
uuid:一个通用唯一标识符,用于区分 FlowFile 与系统中的其他 FlowFiles。
entryDate:FlowFile 进入系统的日期和时间(即已创建)。此属性的值是一个数字,表示自1970年1月1日午夜 (UTC) 以来的毫秒数。
lineageStartDate:任何时候克隆,合并或拆分 FlowFile ,都会导致创建子 FlowFile 。该值表示当前 Flowhile 最早的祖先进入系统的日期和时间。该值是一个数字,表示自1970年1月1日午夜(UTC)以来的毫秒数。
fileSize:此属性表示 FlowFile 内容占用的字节数。
需要注意的是 uuid , entryDate , lineageStartDate ,和 fileSize 属性是系统生成的,不能改变。
三、提取属性
1、NiFi 提供了很多种不同的处理器,用来从 FlowFile 文件中提取属性。在之前处理器分类中已经提到过,有一个分类就叫做属性提取。
包含了有 JSON 类型的 FlowFile 如何提取属性。这就是构建自定义处理器非常常用典型的用法。编写这些处理器就是为了理解数据如何进行流转,使用这些属性信息可以在路由的时候或者在处理数据的时候,方便进行调用,后面通过案例为大家进行讲解。
2、NiFi 提供了几种不同的处理器,用于从 FlowFiles 中提取属性。在之前的处理器分类中已经提到过。这是构建自定义处理器的一个非常常见的用例,其实编写处理器是为了理解特定的数据格式,并从 FlowFile 的内容中提取相关信息,创建属性来保存该信息,以便可以决定如何路由或处理数据。
四、添加用户自定义的属性
1、可以添加自定义的一些属性,NiFi 除了可以从 FlowFile 的内容当中提取属性以外,还允许通过自定义一些属性把他添加到 FlowFile 的属性中,有一个叫做 UpdateAttribute 处理器,专门做这样的功能。可以把属性选项卡上的 + 按钮,去添加一些新的 FlowFile 属性。然后外部界面自动的提示去输入属性的名称,还有属性的具体值,对于 UpdateAttribute 的处理,可以去添加自定义属性来方便编辑的效果。属性值也可以包含一些表达式语言,就像刚才所说的 NiFi 表达式,这样的话就可以在其他的属性基础之上进行修改,生成一个新的属性。比如说要把 FlowFile 里的主机名和日期添加到文件名前面,可以通过添加这个 ${hostname()}-${now():format(yyyy-dd-MM")}-$(filename) 表达式语言来实现这个功能。刚开始大家可能不太理解这个语言,在后续的过程中我会进行讲解。除了添加一组自定义属性外,Update 还具有一些高级的处理,可以配置一些规则,就是什么时候添加属性,什么时候不添加属性。
2、NIFI 除了提供能够将特定信息从 FlowFile 内容提取到属性中的处理器之外,NIFI 还允许用户将自定义属性添加到每个 FlowFile 中的特定位置。UpdateAtribute 就是专为此目的而设计。用户可以通过单击属性选项卡右上角的+按钮,在配置对话框中向处理器添加新属性。然后 UI 会提示用户输入属性的名称,然后输入值。对于此UpdateAtribute 处理的每个 FlowFile,都会添加用户自定义属性。Attribute 的名称将与添加的属性的名称相同。
属性的值也可以包含表达式语言。这样就允许基于其他属性修改或添加属性。例如,如果想要将处理文件的主机名和日期添加到文件名之前,可以通过添加 ${hostname()}-${now():format
(yyyy-dd-MM")}-$(filename) 来实现来实现。刚开始大家可能不太理解这是什么意思,在后续的课程中会进行讲解。
除了添加一组自定义的属性外,UpdateAttribute 还具有一个高级 UI,允许用户配置一组规则,以便在何时添加属性。要访问此功能,请在配置对话框的属性选项卡中,单击 Advanced 对话框底部的按钮。将弹出此处理器特定的 UI 界面。在此 UI 中,用户可以配置规则引擎,实质上是指定必须匹配的规则,以便将已配置的属性添加到FlowFile。
五、路由属性
1.NiFi 有一个非常强的功能,就是可以根据属性进行不同的路由。执行这个操作的处理器有一个叫做 RouteOnAttribute,刚才提到还有一个叫 RouteOnContent,但是推荐大家使用 RouteOnAttribute。这个处理器和 UpdateAtribute 一样,可以添加自定义的属性进行配置,也可以通过点击属性配置选项卡当中的 + 按钮,来向处理器添加任意数量的自定义属性。每一个 FlowFile 的属性和配置的属性进行对比,如果添加的新的自定义属性满足了 FlowFile,那么这个属性的值就会返回一个处。下面会再讲解表达式语言,现在讲根据属性进行路由功能。
2.在匹配成功以后,处理器就会把匹配成功的 FlowFile 发送到后续的处理器当中。这时候也可以用一些选项,比如说 "Route to Property name" 这个方法意思很显然,就是按照自定义属性的名称进行分发。如果使用这个方法,处理器会使用添加的自定义属性的名称来创建一个关联关系,然后可以通过这个关联关系去连接不同的下游处理器,这样就实现了分发的目的。比如说这个时候有一个新的属性名叫做 begin-with-r,他的值是"$(filename:startswith('r')" ,也就是说用 r 做开头的这些文件名都会匹配成功,添加一个 begin-with-r 这个属性。所有以 r 开头的直接 FlowFile,都会路由到一个叫做 begin-with-r 关系当中去,也就是这个关系和这个属性名是一致的。
六、表达式语言/在 Property 值中使用 attribute
1、表达式语言也可以在属性当中使用。当从 FlowFile 的内容当中去提取属性的时候,并且把这些属性添加到自定义的属性新属性上的时候,必须有一种可以灵活使用这些内容的机制。否则没有办法进行自定义属性的添加,NiFi 表达式语言就可以实现这样一个功能。但是大家要注意一点,并不是所有的处理器都允许使用表达式语言,但是大部分都可以。该怎样判断处理器可以使用表达式语言呢?在处理器配置选项卡当中有一个“?”图标,每一个属性后面都会有一个问号图标,只需要把鼠标点击一下这个问号,就会看到提示信息。这个提示信息就会提示当前这个属性是不是可以使用表达式语言?如果可以使用,就可以在这里面进行一些灵活的操作。对于支持表达式语言的属性,可以通过 ${和结束标记} 这样的方式来添加一些变量,表达式可以像属性名一样,比如说有一个 uuid Attribute 这样的属性,他是公共的属性。这个时候要想使用这个变量,就可以用 ${uilid} ,通过这样的方式来获取到 uuid 的值。如果属性名以字母以外的任何字符开头,或者说它包含了一些特殊的字符,比如说句号(.)或下划线(_),这时候需要添加引号,比如说有一个变量叫 My Attribute Name ,这时可以很显然的发现它里面是有空格的,这个时候必须对变量名加上单引号或者是双引号,来引用这个属性获取它的值。
2、除了去获取属性值以外,还可以对这些属性进行比较或切割等等操作。例如,想判断 filename 这个属性值是不是区分大小写,要看他是否包含一个小写字母 r,可以通过 toLower()这样一个方法把 filename 转化成全部小写的值,然后再通过 contains ('r')方法和小写的 r进行对比。需要注意,和 JAVA 以及 scheal 语言不一样,它带入函数是通过冒号来调用的,而不是通过点,可以把多个方法连接在一块儿进行调用。比如说 filename:toLower() 这样一个函数之后,在后面又加了一个叫 contains 的函数,通过这样的方法可以很简洁的实现这个功能。
3、也可以在方法当中嵌入另外一个方法,学过 JAVA 或 scholar 就很好理解,比如说是 attr1 这样一个属性,第二个 equal 方法,equal 方法当中又可以再使用 NiFi 表达式,来引入另外一个变量 attr 2,作为传递给 equal 的方法。语言表达是包含的内容非常多,有各种各样的函数,这里面就先不展开讲解,大家可以通过访问 NiFi 的官网,来查看这些属性到底有哪些方法?大致上和 JAVA 和 scholar 是类似的。除此以外,表达式语言在程序里面也是有这样一些文档,可以通过一些快捷键方便提示函数名,比如 Ctrl+Space。大部分 WINDOWS 系统 Ctrl+Space 都已经被输入法占用了,除非把这个快捷键删除掉,因此没有什么用处。
4、当从 FlowFiles 的内容中提取属性并添加用户定义的属性时,除非有一些可以使用它们的机制,否则它们不会作为运算符进行计算。NiFi 表达式语言允许在配置流时访问和操作 FlowFile 属性值。并非所有处理器属性都允许使用表达式语言,但很多处理器都可以。为了确定属性是否支持表达式语言,用户可以将鼠标悬停在处理器配置对话框的属性选项卡中的 ?图标上,然后会有一个提示,显示属性的描述,默认值(如果有)以及属性是否支持表达式语言。
对于支持表达式语言的属性,可以通过在开始标记${和结束标记}中添加表达式来使用它。表达式可以像属性名一样简单。例如,要引用 uuid Attribute ,可以简单地使用 ${uilid}。如果属性名称以字母以外的任何字符开头,或者包含除数字,字母,句号(.)或下划线( )以外的字符,则需要加引号。例如,$(My Attribute Name}将无效,但S{MyAttribute Name'} 将引用属性 My Attribute Name。
除了引用属性值之外,还可以对这些属性执行许多功能和比较。例如,如果想检查 filename 属性是否不分大小写(大写或小写)地包含字母",可以使用表达式来完成$(filename:toLower():contains("")》。请注意,函数由冒号分隔。可以将任意数量的函数链接在一起,以构建更复杂的表达式。重要的是要明白,即使正在调用 filename:toLower(),这也不会改变 filename 属性的值,而只是返回给一个新的值。
也可以在一个表达式中嵌入另一个表达式。例如,如果想要将 attr1 Attribute 的值与 attr2 Attribute的值进行比较,可以使用以下表达式来执行此操作:${attr1:equals(${attra})}。
表达式语言包含许多不同的函数,官方文档 Expression Language Guide。
此外,此表达式语言指南内置于应用程序中,以便用户可以轻松查看哪些功能可用,并在输入时查看其文档。设置支持表达式语言的属性的值时,如果光标位于表达式语言的开始和结束标记内,则在关键字上按 Ctrl+Space 将弹出所可用的函数(快捷键冲突被占用会无法使用此功能),并将提供自动填充的功能。单击或使用键盘上下键指向弹出圆口中列出的某个功能会有提示,提示解释了该功能的作用,它所期望的参数以及函数的返回类型。
七、表达式语言中的自定义属性
1、表达式语言中也可以去使用自定义属性,在讲到 FlowFile 属性的时候提到可以添加用户自定义的属性,但那个是针对于 FlowFile 属性来说,现在在 FlowFile 当中可以使用表达式语言,而且表达式语言也可以调用自定义属性。自定义属性配合上表达式语言,灵活性就更高了。这就是如何使用 NiFi 的 FlowFile 属性。
2、除了使用 FlowFile 属性外,还可以定义表达式语言使用的自定义属性。定义自定义属性为处理和配置数据流提供了额外的灵活性。
八、总结
1、FlowFile 属性提到每一个 FlowFile 都有一些共同的属性,这些共同属性是不能修改的,是由 NiFi 自己设置的,包含有文件名、路径还有唯一标识符,以及创建日期和文件大小等等。共同属性是 NiFi 服务生成的,不能修改。除了共同属性之外 FlowFile 属性还可以提取属性值。比如说可以在处理器当中,把 FlowFile 属性拿出来,拿出来之后在根据属性值进行路由值的判断等等一些操作。还可以通过添加自定义属性这样的方式来增加新的 FlowFile 属性。首先,有一种处理器叫做 UpdateAtribute,这个处理器是专门来修改和操作 FlowFile 属性值的,他可以添加新的 FlowFile 属性,也可以修改旧的 FlowFile 属性。
2、可以根据属性进行路由,根据属性进行路由有一个处理器叫做 RouteOnAttribute,这个处理器就是为了实现根据 FlowFile 属性进行不同的路由功能 。通过这样一些方式,就可以进行负载均衡或者是逻辑判断这样一些功能。除此之外,还可以使用表达式语言去添加 FlowFile 属性,表达式语言这里只是进行一个大概的讲解,后续还会为大家进行扩展,这里面有一个典型的案例,比如说获取 filename 这样一个变量,如何转化为小写呢?可以通过冒号调用一个叫做 toLower 这样一个方法来获取他值的小写,然后可以继续调用 contanis 函数来判断这个值是不是包含 r,这就是 NiFi 表达式典型的用法,NiFi 表达式也可以去调用自定义属性,NiFi 也可以使用自定义属性,这样一来 NiFi 功能就非常灵活,非常的强大。