使用 JDBC 输入插件在多个节点上运行 Logstash

dem*_*isx 5 elasticsearch logstash elastic-stack logstash-jdbc

我有一个 Logstash 的基本 HA 设置 - 两个不同的 AWS 可用区中有两个相同的节点。每个节点都运行一个管道,从数据库集群中提取数据集,然后将其输出到下游的 ELasticSearch 集群进行索引。这对于一个 Logstash 节点来说效果很好,但是由于每个节点单独跟踪,所以并行运行的两个节点将相同的数据发送两次到 ES 进行索引:sql_last_value。由于我在两个节点上使用与文档 ID 相同的 ID,因此所有重复数据都会被简单更新,而不是被插入两次。换句话说,每个数据集有 1 次插入和 1 次更新。显然,这效率不高,并且会给 ELK 资源带来不必要的负载。随着额外 Logstash 节点的添加,情况会变得更糟。

\n\n

有谁知道应该如何设置并行 Logstash 节点的更好方法,因此如果每个节点已被另一个先前节点提取,则每个节点都不会提取相同的数据集 xe2x80x99?一个可怜的 man\xe2\x80\x99s 解决方案可能是在 Logstash 节点之间创建一个共享 NFS 文件夹并让每个节点写入:sql_last_value其中,但我不确定此设置可能会遇到什么样的副作用,尤其是在较高负载下。谢谢你!

\n

ibe*_*xit 3

我们有完全相同的场景:3个logstash实例,以多个数据库作为数据源来确保高可用性。

\n\n

在每个logstash实例上安装并启用相同的jdbc管道,遵循以下逻辑:

\n\n
    \n
  • 在结果集中为每个文档查找唯一标识符(主键等),或使用结果中的字段(MD5、SHA,而不是 UUID)生成指纹。这个标识符需要稳定!当返回相同的实体时,它在其他 Logstash 节点上必须相同。
  • \n
  • 在elasticsearch-output中使用id或指纹作为文档_id。
  • \n
\n\n

这是简单情况的简化示例(id 是结果集的一部分):

\n\n
input{\n  jdbc{\n     ...\n     statement => "select log_id, * from ..."\n     ...\n  }\n}\nfilter{...}\noutput{\n  elasticsearch{\n    ...\n    index => "logs-%{+YYYY.MM.dd}"\n    document_id => "%{[log_id]}"\n    ...\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当您的数据缺乏唯一标识符并且您需要生成指纹时,就会出现变体

\n\n
input{\n  jdbc{\n     ...\n     statement => "select * from ..."\n     ...\n  }\n}\nfilter{\n  fingerprint {\n    method => "MD5"\n    concatenate_all_fields => true\n  }\n}\noutput{\n  elasticsearch{\n    ...\n    index => "logs-%{+YYYY.MM.dd}"\n    document_id => "%{[fingerprint]}"\n    ...\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

在这两种方式中,当文档成为一个 Logstash 实例的结果集的一部分时,就会创建这些文档。所有其他 Logstash 实例稍后都会获得相同的文档。使用 id/指纹作为 _id 将更新以前创建的文档,而不是复制您的数据。

\n\n

对我们来说效果很好,尝试一下!

\n