4

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

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

4

2 回答 2

3

我们有相同的场景:3 个 logstash 实例以确保服务器数据库作为数据源的高可用性。

在每个 logstash 实例上,按照以下逻辑安装并启用相同的 jdbc-pipelines:

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

下面是简单案例的简化示例(id 是结果集的一部分):

input{
  jdbc{
     ...
     statement => "select log_id, * from ..."
     ...
  }
}
filter{...}
output{
  elasticsearch{
    ...
    index => "logs-%{+YYYY.MM.dd}"
    document_id => "%{[log_id]}"
    ...
  }
}

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

input{
  jdbc{
     ...
     statement => "select * from ..."
     ...
  }
}
filter{
  fingerprint {
    method => "MD5"
    concatenate_all_fields => true
  }
}
output{
  elasticsearch{
    ...
    index => "logs-%{+YYYY.MM.dd}"
    document_id => "%{[fingerprint]}"
    ...
  }
}

在这两种方式中,当文档是一个 logstash 实例的结果集的一部分时,它们将被创建。所有其他 logstash 实例将在稍后获得相同的文档。使用 id/fingerprint 作为 _id 将更新先前创建的文档,而不是复制您的数据。

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

于 2019-05-28T16:15:01.703 回答
1

我更喜欢last_run_metadata_path在不同 Logstash 实例的调度参数中使用具有一定偏移量的通用(在 NFS 或其他共享文件系统上)。

请检查输入 jdbc 插件以获取有关last_run_metadata_path的更多详细信息

于 2020-04-06T10:38:07.627 回答