1. 程式人生 > >elasticsearch原始碼分析之啟動過程(二)

elasticsearch原始碼分析之啟動過程(二)

最近開始廣泛的使用elasticsearch,也開始寫一些java程式碼了,為了提高java程式碼能力,也為了更加深入一點了解elasticsearch的內部運作機制,所以開始看一些elasticsearch的原始碼了。對於這種廣受追捧的開源專案,細細品讀一定會受益匪淺,所以我會盡可能地細分成很多部分,下面我們從啟動過程開始!

首先從main開始,從start指令碼可以看出,從org.elasticsearch.bootstrap.ElasticSearch開始執行。

初始化

真正的初始化在Bootstrap的init中,首先是對command的解析,並將引數置於system property中,在建立Bootstrap例項的時候,會啟動一個keepAliveThread執行緒,並setDaemon(false),執行緒啟動之後就進入到await狀態;此外,利用Runtime.getRuntime().addShutdownHook方法加入一個Hook,在程式退出時觸發該Hook(注:退出是指ctrl+c或者kill -15,但如果用kill -9 那是沒辦法的),在該Hook中會對之前的執行緒做countDown操作,其實這個執行緒相當於一個heartbeat,用以來表示ES程序是否還活著。

配置的載入

這裡配置的載入會從三個部分來載入配置,分別是啟動命令、配置檔案和jvm/os環境。

1、從command來判斷是不是後臺啟動,日誌的初始化,然後寫入pid。

2、獲取JVM資訊,如果是使用client vm則會給出提示(建議使用server vm,畢竟ES需要很大的資源,可以用-server來強制使用server vm)。 預設是開啟jvm 版本檢查的,如果不檢查可能會導致es資料的損壞。針對不同公司的jvm vendor會有不同的處理方式,
如果是Oracle的,以下幾個編譯方案時可能影響ES:如果是IBM的,對版本比較會有要求,要求版本必須大於2.8,不然可能會導致index損壞。

3、檢查其他的一些外部資源;首先不能用root啟動ES,否則就會強制關閉。對於mlockall的配置我們其實是建議設為true的,因為這樣可以保障ES不會去佔用其他系統的記憶體、swap等資源。那麼ES是怎麼來鎖住記憶體的呢,這裡用到了JNA,這裡lock的mem會有兩個層面的,分別是hard和soft。對於某些原因lock失敗的情況,可能需要調整/etc/security/limits.conf中對於當前使用者的soft/hard memlock unlimited配置。

4.初始化兩種probes,分別是ProcessProbe和Osprobe,這兩個probe將會提供給ES的stats api所需要的一些ES程序和OS層面的資訊。

5、增加shutdown的hook,當叢集shutdown的時候,會主動呼叫node的close方法,即讓本node安全退出。

6、接下來才是對於node的配置的初始化,這部分的配置來自配置檔案,通過nodeSettings建立nodeBuilder,而node的初始化就是通過nodeSettings來建立的。

Node的建立

其實上文已經提到了node例項是通過nodeBuilder來完成的,這裡使用了Guice的Injector進行注入與獲取例項。elasticsearch裡面的元件基本都是用上面的方式進行模組化管理,elasticsearch對guice進行了封裝,通過ModulesBuilder類構建es的模組,一個es節點包括下面模組:

看名字就大體知道是每個module是幹嘛的了吧。
這裡有必要簡單介紹下Guice,不然看到這裡好多人會看不懂。Guice是google開源的一個依賴注入的框架,比起spring更加的輕量級,關鍵點:

  • 使用@injectguice會掃描inject註釋,並對方法中出現的引數例項尋找對應註冊的例項進行初始化。
  • bind介面將介面跟具體實現類繫結。
  • 使用 Injector 引導應用程式。

因此可以看到每個module裡面都有一個方法configure()用於將物件和實現類作繫結。

Node的啟動

Node的啟動其實就是node裡每個元件的啟動,同樣的,分別呼叫不同的例項的start方法來啟動這個元件,如下:

這些元件我後面會挑一些來細細地講解。

到目前為止,整個ES的啟動就已經完成!