Elasticsearch

Logstash/elasticsearch 停止接受新數據

  • August 3, 2015

我已經建立了一個新的概念證明 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並且僅在該欄位存在時才應用其他過濾器規則。

我從中得到的主要寓意是,簡化這類問題很重要,否則潛在原因的搜尋空間太大。

引用自:https://serverfault.com/questions/710332