註:文本整理自《ELKstack權威指南》
在 CRUD 章節,我們已經知道 ES 的數據寫入是如何操作的了。喜歡自己動手的讀者可能已經迫不及待的自己寫了程序開始往 ES 裏寫數據做測試。這時候大家會發現:程序的運行速度非常壹般,即使 ES 服務運行在本機,壹秒鐘大概也就能寫入幾百條數據。
這種速度顯然不是 ES 的極限。事實上,每條數據經過壹次完整的 HTTP POST 請求和 ES indexing 是壹種極大的性能浪費,為此,ES 設計了批量提交方式。在數據讀取方面,叫 mget 接口,在數據變更方面,叫 bulk 接口。mget 壹般常用於搜索時 ES 節點之間批量獲取中間結果集,對於 Elastic Stack 用戶,更常見到的是 bulk 接口。
bulk 接口采用壹種比較簡樸的數據積累格式,示例如下:
格式是,每條 JSON 數據的上面,加壹行描述性的元 JSON,指明下壹行數據的操作類型,歸屬索引信息等。
采用這種格式,而不是壹般的 JSON 數組格式,是因為接收到 bulk 請求的 ES 節點,就可以不需要做完整的 JSON 數組解析處理,直接按行處理簡短的元 JSON,就可以確定下壹行數據 JSON 轉發給哪個數據節點了。這樣,壹個固定內存大小的 network buffer 空間,就可以反復使用,又節省了大量 JVM 的 GC。
事實上,產品級的 logstash、rsyslog、spark 都是默認采用 bulk 接口進行數據寫入的。對於打算自己寫程序的讀者,建議采用 Perl 的 Search::Elasticsearch::Bulk 或者 Python 的 elasticsearch.helpers.* 庫。
在配置 bulk 數據的時候,壹般需要註意的就是請求體大小(bulk size)。
這裏有壹點細節上的矛盾,我們知道,HTTP 請求,是可以通過 HTTP 狀態碼 100 Continue 來持續發送數據的。但對於 ES 節點接收 HTTP 請求體的 Content-Length 來說,是按照整個大小來計算的。所以,首先,要確保 bulk 數據不要超過 /elastic/elasticsearch/pull/21626 這條記錄的進展。
(本文完)
文本整理自《ELKstack權威指南》