Apache NIFI读取AWS S3日志到ES

434 阅读5分钟

一、NIFI简介

Apache NiFi 是一个强大的开源数据集成工具,主要用于自动化数据流的管理和处理。它提供了丰富的图形化界面和流式数据处理能力,可以帮助用户快速设计和管理数据流,从而实现数据的收集、转换、路由、存储等操作。

NiFi 的基本功能包括数据流的定义、实时数据处理、数据格式转换、批量处理等。它适用于各种场景,如物联网数据流处理、大数据管道集成、日志聚合、数据同步和数据迁移等。无论是处理批量数据还是实时数据,NiFi 都能为用户提供灵活、可扩展且可靠的解决方案。

与传统的 ETL 工具相比,NiFi 最大的特点是其流式架构和强大的可视化操作界面,允许用户通过拖拽式的方式构建数据流,而无需编写大量的代码。NiFi 在数据流设计的直观性和易用性方面具有显著优势,尤其适合复杂的数据集成和实时流数据处理场景。

二、场景介绍

这里通过一个日常常用场景来了解NIFI的功能。

读取aws s3 bucket中的日志文件,然后将日志文件写入到es中进行记录,同时针对日志中的某些关键字进行分析,将符合条件的日志单独再记录到额外的es index中。

这个场景是很贴合实际使用的一个场景,借助这个场景来看下NIFI怎么对于数据进行采集,清洗和传递的。

三、功能实现

功能规划

按照如下processor规划进行设计

功能NIFI Processsor描述
采集aws s3 bucket objectListS3获取bucket中的object list
FetchS3Object获取object的内容并且写入到nifi中
处理bucket object文件记录处理数据格式SplitJson根据jsonpath来将json array处理成为单独的json object(根据s3 object内容按需使用)
EvaluateJsonPath从 JSON 数据中提取特定的字段值,并将其作为属性(attributes)附加到NIFI flowfile中
对不同类型数据进行路由处理RouteOnAttribute根据不同条件来进行路由处理
将日志记录写入es组件PutElasticseachJson写入数据到es中
NIFI日志组建记录操作记录LogAttribute记录日志

这里可以先看下最终全局的workflow,在实现步骤分布解析处理细节配置

s3 bucket object示例数据展示

为了节省篇幅后续节点数据以“...”代替

[
  {
    "id": "0718b3f94d0e1ce8aa1bc169ee160fba378f7b1c",
    "reply_id": "0718b3f94d0e1ce8aa1bc169ee160fba378f7b1c",
    "project_id": 2898,
    "commit_id": null,
    "confidential": false,
    "diff_discussion": false,
    "expanded": true,
    "for_commit": false,
    "individual_note": true,
    "resolvable": false,
    "discussion_path": null,
    "resolved": false,
    "resolved_by_push": false,
    "resolved_by": null,
    "resolved_at": null,
    "resolve_path": "/ACD/TC/ic/cf/-/merge_requests/1/discussions/0718b3f94d0e1ce8aa1bc169ee160fba378f7b1c/resolve",
    "resolve_with_issue_path": "/ACD/TC/ic/cf/-/issues/new?discussion_to_resolve=0718b3f94d0e1ce8aa1bc169ee160fba378f7b1c&merge_request_to_resolve_discussions_of=1",
    "notes": [
      {
        "id": "1980891",
        "type": null,
        "attachment": null,
        "author": {
          "id": 832,
          "username": "marek.duk",
          "name": "Marek duk",
          "state": "active",
          "locked": false,
          "avatar_url": "https://secure.gravatar.com/avatar/cb22b4409fe3fadf3e6a7f062f8941402f42cfc4407e965ed1f171b37292f29b?s=80&d=identicon",
          "status_tooltip_html": null,
          "show_status": false,
          "availability": null,
          "path": "/marek.duk",
          "bot": false
        },
        "created_at": "2024-10-15T12:02:48.813Z",
        "updated_at": "2024-10-15T12:02:48.817Z",
        "system": true,
        "noteable_id": 219894,
        "noteable_type": "MergeRequest",
        "project_id": 2898,
        "resolvable": false,
        "confidential": false,
        "internal": false,
        "noteable_iid": 1,
        "commands_changes": {},
        "external_author": null,
        "note": "assigned to @marek.duk",
        "note_html": "<p data-sourcepos=\"1:1-1:24\" dir=\"auto\">assigned to <a href=\"/marek.duk\" data-reference-type=\"user\" data-user=\"832\" data-container=\"body\" data-placement=\"top\" class=\"gfm gfm-project_member js-user-link\" title=\"Marek duk\">@marek.duk</a></p>",
        "current_user": {
          "can_edit": false,
          "can_award_emoji": true,
          "can_resolve": false,
          "can_resolve_discussion": false
        }
      }
    ]
  },
...
]

实现步骤

listS3

配置bucket并且绑定Aws credentials service,这里采用accesskey进行身份验证。

FetchS3Object

配置拉取s3 object配置复用Lists3Aws credentials service服务进行认证,bucket等其他属性使用默认值从lists3 processor的attribute中获取。

SplitJson

配置处理s3 object文件内容拆分逻辑,由于我的原始数据是json array的形式保存在s3的文件中,因此这里直接使用"$"对跟路径进行split操作,拆分后的json为json array中的单个element(json object)。

这一步数据处理需要结合自己实际业务进行灵活调整

EvaluateJsonPath

配置author属性从json中读取路径为.notes[0].author.name字段的值,也就是kvauthor:.notes[0].author.name字段的值,也就是k-v是 author: .notes[0].authro.name

RouteOnAttribute

配置两个属性author_marek和author_troyqu,分别对应两个路由条件用来匹配日志记录中带有marek和troyqu字样的记录。这里是从EvaluateJsonPath中atttribute中的author字段的内容进行判断。

定义路由propeties后会对应出现符合路由的relationships,可以根据路由条件定义下一步操作。

PutElasticseachJson

写入nifi_local index

写入nifi_local_troyqu index,对应记录中包含"troyqu"关键字的记录

写入nifi_local_marek index,对应记录中包含"marek"关键字的记录

es认证service配置

数据写入es中

LogAttribute

这里配置LogAttribute可以查看最终日志方便进行回溯和查看。

Connection

在connection中可以配置背压(防止节点任务过载)等参数,通过背压等属性可以灵活调整节点负载。

背压:当节点任务处理缓慢,当达到背压阈值之后nifi会控制数据写入,防止过载

四、总结

  1. 这里可以看到nifi提供了全功能来实现抓取s3数据到es或者其他消费组件,可以结合自己业务需要来处理,nifi提供了丰富的组件支持。
  2. 在使用nifi的时候connection之间可以配置背压等参数来调整负载。
  3. 示例中的最终节点都是logattribute但是实际中需要考虑到最终一致性,以及结合业务要求针对异常记录进行最终一致性或者告警。