我有一个用于Logstash的基本HA设置-两个单独的AWS可用区中的两个相同节点。每个节点运行一个管道,该管道从数据库集群中提取数据集,然后将其下游输出到ELasticSearch集群以进行索引。这对于一个Logstash节点可以很好地工作,但是由于每个节点分别跟踪:sql_last_value
,因此并行运行的两个节点两次向ES发送相同的数据以进行索引。由于我在两个节点上都使用与文档ID相同的ID,因此所有重复的数据都将简单地更新,而不会插入两次。换句话说,每个数据集有1个插入和1个更新。显然,这不是很有效,并且会给ELK资源带来不必要的负载。随着添加其他Logstash节点,情况变得更糟。
有人知道如何设置并行Logstash节点的更好方法,因此如果每个节点都已经提取了相同的数据集,那么每个节点都不会提取相同的数据集?一个穷人的解决方案可能是在Logstash节点之间创建一个共享的NFS文件夹,并让每个节点都在其中写入:sql_last_value
,但是我不确定使用这种设置会遇到什么样的副作用,尤其是在较高的负载下。谢谢!
答案 0 :(得分:1)
我们有一个非常相同的场景:3个logstash实例,以服务器数据库作为数据源来确保高可用性。
在每个logstash实例上,按照以下逻辑安装并启用相同的jdbc-pipelines:
以下是简单情况的简化示例(id是结果集的一部分):
input{
jdbc{
...
statement => "select log_id, * from ..."
...
}
}
filter{...}
output{
elasticsearch{
...
index => "logs-%{+YYYY.MM.dd}"
document_id => "%{[log_id]}"
...
}
}
当您的数据缺少uniqe标识符并且您需要生成指纹
时,就会出现变体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将更新先前创建的文档,而不是重复您的数据。
为我们运作良好,请尝试一下!
答案 1 :(得分:1)
我更喜欢在不同Logstash实例的计划参数中使用公用的last_run_metadata_path
(在NFS或其他共享文件系统上)。
请检查输入的jdbc插件,以获取有关last_run_metadata_path
的更多详细信息