Logstash/elasticsearch 停止接受新數據
我已經建立了一個新的概念證明 logstash 系統
CentOS 6.6 (on Vmware 5.5) - single CPU VM with 12G RAM allocated
從 RPM 安裝的 Elasticsearch 和 Logstash……
# rpm -q elasticsearch logstash elasticsearch-1.7.1-1.noarch logstash-1.5.3-1.noarch JVM: 1.8.0_51
我輸入的數據是表單的簡單記錄……
M1234 z123 2015-01-31 23:28:09.417 8.55373
(欄位是機器名稱、使用者 ID、日期、時間、登錄時間 - 一切都是簡單的 US-ASCII)
下面的 Logstash 配置(此數據來自 MSSQL 數據庫,目前我正在導出到文本文件並將文件傳輸到 logstash 伺服器)。
這對於一天的日誌(11K 記錄)來說效果很好,但是當我嘗試處理這個日曆年的積壓工作時,它“掛起”。
這種情況的症狀是
- elasticsearch 仍然響應 - 搜尋和訪問配置仍然很好
- 索引中的文件數量停止上升
- 系統變得基本空閒 - 只有後台磁碟活動和最少的 CPU 使用率
- 如果我嘗試停止 logstash 程序(仍在執行),它只會以
kill -9
.這似乎發生在大約 200K 文件中。它不受索引數量的影響——我從每日索引開始,然後改為每週索引——它仍然停止在 200K 文件左右。
因為這是在單台機器上執行的概念證明,所以我將副本計數降低到 0,分片降低到 1——我認為這不會對這個問題產生任何影響。
儘管在兩者上都增加了詳細程度,但我在 logstash 或 elasticsearch 日誌中看不到任何錯誤。
我不認為系統記憶體、磁碟空間、文件描述符不足。
我不確定還能看什麼。這感覺像是一個微不足道的問題(對於 ELK),我在處理我們的郵件日誌的現有 ELK 設置上看不到這個問題(儘管它執行的是早期版本並且有多個彈性搜尋儲存節點)
儘管我確信輸入文件中沒有奇數字節序列,但我已
charset => "US-ASCII"
在file
輸入外掛節中明確將輸入聲明為 US_ASCII 。我不希望這會產生任何影響(測試仍在執行)。更新:雖然當導入停止時日誌中沒有什麼有趣的東西,但在
logstash
被要求關閉時記錄的行很有趣……{:timestamp=>"2015-08-03T10:17:39.104000+0100", :message=>["INFLIGHT_EVENTS_REPORT", "2015-08-03T10:17:39+01:00", {"input_to_filter"=>20, "filter_to_output"=>0, "outputs"=>[]}], :level=>:warn}
對我來說意味著問題出在過濾階段,而不是輸出到
elasticsearch
. 我已經通過首先擺脫elasticsearch
輸出並僅擁有stdout
. 這顯示了相同的行為 - 導入在一段時間後停止。放回
elasticsearch
輸出但清除該filter
部分中的所有內容給了我一個成功、完整的數據導入。我現在已經解決了這個問題-答案中的詳細資訊。
input { file { path => "/var/lib/clusters/*" type => "clusterF" start_position => "beginning" } } filter { mutate { remove_field => [ "path", "host" ] } # 13COMP014 nabcteam 2015-07-29 11:09:21.353 153.493 if [type] == "clusterF" { grok { match => { "message" => "%{NOTSPACE:client} +%{WORD:userid} +%{TIMESTAMP_ISO8601:datestamp} +%{BASE10NUM:elapsed:float}" } } } if [elapsed] < 0 { drop {} } if [elapsed] > 1000.0 { drop {} } if [userid] =~ "[a-z][0-9]{7}" { mutate { add_field => [ "userClass", "student" ] } } else if [userid] =~ "n[a-z].*" { mutate { add_field => [ "userClass", "staff" ] } } else { mutate { add_field => [ "userClass", "other" ] } } date { match => [ "datestamp", "ISO8601" ] } mutate { remove_field => [ "message" ] } } output { elasticsearch { bind_host => "clog01.ncl.ac.uk" protocol => "http" cluster => "elasticsearch" flush_size => 10 index => "clusters-%{+xxxx.ww}" } }
一旦我知道攤位正在附近發生,
filter
而不是output
這更容易找到。放回
elasticsearch
輸出但清除該filter
部分中的所有內容給了我一個成功、完整的數據導入。我編寫了一個簡單的
perl
腳本來根據grok
規範驗證輸入行 - 這向我展示了一些使用者 ID 包含連字元(這是我沒想到的)。在原始配置中替換+%{WORD:userid}
為我提供了一個工作設置。+%{NOTSPACE:userid}
我懷疑我首先應該做的是在成功時添加一個欄位,grok
並且僅在該欄位存在時才應用其他過濾器規則。我從中得到的主要寓意是,簡化這類問題很重要,否則潛在原因的搜尋空間太大。