Logstash Multiple Pipelines


作為生產者和消費者之間數據流的一個中心組件,需要一個 Logstash 實例負責驅動多個並行事件流的情況。默認情況下,這樣的使用場景的配置讓人並不太開心,使用者會遭遇所謂的條件地獄(Conditional hell)。因為每個單獨的 Logstash 實例默認支持一個管道,該管道由一個輸入、若干個過濾器和一個輸出組成,如果要處理多個數據流,就要到處使用條件判斷。

條件地獄(Conditional hell)

已知的在一個管道中實現多個獨立流的方法是使用條件判斷。主要方式是在輸入部分通過標簽標記事件,然后在過濾器中和輸出階段創建條件分支,對貼有不同標簽的事件,應用不同的插件集。這種方式雖然可以解決問題,但在實際的使用中卻非常的痛苦!下面是一個簡單的 demo 片段:

input {
  beats { port => 3444  tag => apache   }
  tcp { port => 4222  tag => firewall   }
}
filter {
   if "apache" in [tags] {  
    dissect { ... }
   } else if "firewall" in [tags] {  
    grok { ... }
   }  
}
output {
   if "apache" in [tags] {  
    elasticsearch { ... }
   } else if "firewall" in [tags] {  
    tcp { ... }
   }  
}

對應的 Logstash 管道配置已經被條件語句包裹的十分臃腫,而它們的唯一目的是保持流的獨立性。
雖然使用條件實現獨立的多個流是可行的,但是很容易看出,由於存在單個管道和處理的單個階段,隨着復雜性的增加,配置會變得非常冗長,很難管理。下圖展示了包含兩個流的簡單管道:

不幸的是,這並不是該方案的唯一缺陷。

缺乏擁塞隔離

如果您熟悉 Logstash 的工作原理,就會知道管道的輸出部分接收到一批事件,並且在所有事件和完成所有輸出之前不會移動到下一批事件。這意味着,對於上面的管道,如果 TCP 套接字目標不可達,Logstash將不會處理其他批次的事件,這也就意味着 Elasticsearch 將不會接收事件,並且會對 TCP 輸入和 Beats 輸入施加反壓力。

不同的數據流需要以不同的方式處理

如果 TCP - > Grok - > TCP 數據流處理大量的小數據,而 Beats -> Dissect -> ES 數據流中的單個數據體積大但是數量少。那么前一個數據流希望有多個 worker 並行並其每一批次處理更多事件,第二個數據流則期望使用少量的 worker 和每批次處理少量的事件。使用單個管道,無法為單個數據流指定獨立的管道配置。

通過多個 Logstash 實例解決問題

上述問題可以通過在同一台機器上運行多個 Logstash 實例來解決,然后可以獨立地管理這些實例。但是即使這樣的解決方案也會產生其他問題:

  • 需要管理多個實例(通過 init 系統管理多個后台服務)
  • 每個 Logstash 的實例也意味着一個獨立的 JVM
  • 需要監視每個 Logstash 實例

這種方式其實很糟糕!

多個管道

從 Logstash 6.0 開始,引入了 Multiple Pipelines,才完美的解決了這個問題。Multiple Pipelines 的配置非常簡單:在配置文件  pipelines.yml 中添加新的 pipeline 配置並指定其配置文件就可以了。下面是一個簡單的 demo 配置:

- pipeline.id: apache
  pipeline.batch.size: 125
  queue.type: persisted
  path.config: "/path/to/config/apache.cfg"
  queue.page_capacity: 50mb
- pipeline.id: test
  pipeline.batch.size: 2
  pipeline.batch.delay: 1
  queue.type: memory
  config.string: "input { tcp { port => 3333 } } output { stdout {} }"

這個 YAML 文件包含一個散列(或字典)列表,其中每個散列表示一個管道,鍵和值為該管道設置名稱。被省略的設置值返回到它們的默認值。

配置多個管道

下面來看一個真實點的例子,筆者在 Ubuntu 18.04 Server 中安裝了 Logstash 6.2.4,除了在默認的配置文件目錄(/etc/logstash/conf.d)中添加配置文件外,創建新的目錄 /etc/logstash/myconf.d,並在 /etc/logstash/myconf.d 目錄下創建 Logstash 配置文件 krtest.conf。然后在 /etc/logstash/pipelines.yml 文件中添加新的 pipeline 配置:

- pipeline.id: main
  path.config: "/etc/logstash/conf.d/*.conf"
- pipeline.id: krtest path.config: "/etc/logstash/myconf.d/krtest.conf"

其中 pipeline.id 為 main 的管道是默認的配置,我們新添加了 id 為 krtest 的管道並指定了對應的配置文件路徑。啟動 Logstash,如果你安裝的 X-Pack 插件就可以在 Kibana->Monitoring->Logstash 中看到新添加的名稱為 krtest 的管道:

使用 Multiple Pipelines 后,我們的 Logstash 配置文件就可以寫得像下面的代碼一樣簡練(不再需要那么多的條件語句)了:

input {
    beats {
        port => 5064
    }
}
filter {
    grok { ... }
}
output {
    elasticsearch { ... }
}

參考:
Multiple Pipelines
Introducing Multiple Pipelines in Logstash


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM