1. 程式人生 > 程式設計 >Elasticsearch實戰 | 必要的時候,還得空間換時間!

Elasticsearch實戰 | 必要的時候,還得空間換時間!

1、應用場景

實時資料流通過kafka後,根據業務需求,一部分直接藉助kafka-connector入Elasticsearch不同的索引中。另外一部分,則需要先做聚類、分類處理,將聚合出的分類結果存入ES叢集的聚類索引中。如下圖所示:業務系統的分層結構可分為:接入層、資料處理層、資料儲存層、介面層。那麼問題來了?我們需要基於聚合(資料處理層)的結果實現檢索和聚合分析操作,如何實現更快的檢索和更高效的聚合分析效果呢?

2、方案選型

方案一:只建立一個索引,aggs_index。資料處理層的聚合結果存入ES中的指定索引,同時將每個聚合主題相關的資料存入每個document下面的某個field下。如下示意圖所示:

方案一示意圖

方案二:新建兩個索引:aggsindex以及aggsdetail_index。其中:1)aggs_index儲存事件列表資訊。2)aggsdetailindex儲存事件關聯的文章內容資訊。如下圖所示:

方案二示意圖

3、方案對比

方案一優點:節省儲存空間,只儲存關聯文章id,資料沒有重複儲存。方案一缺點:檢索、聚合慢,效能不能達標。方案一後續的所有操作,都需要先遍歷檢索這一堆IDs,然後再進行檢索、聚合分析操作。

操作例項如下(實際比這要複雜):第一步:通過事件id,獲取關聯文章id列表;第二步:基於關聯文章id列表,進行檢索和聚合操作。

POST  aggs_index/_search
{
  "_source": {
  "includes":[
    "title","abstract","publish_time","author"
    ]},"query":{
    "terms":{
      "_id":"["789b4cb872be00a04560d95bf13ec8f42c","792d9610b03676dc5644c2ff4db372dec4","817f5cff3dd0ec3564d45615f940cb7437","....."]
    }
  }
}複製程式碼

步驟2當id數量很多時,會有如下的錯誤提示:

{
  "error": {
    "root_cause": [
      {
        "type": "too_many_clauses","reason": "too_many_clauses:
        maxClauseCount is set to 1024"
      },複製程式碼

。。。

方案二優點:分開儲存,便於一個索引中進行檢索、聚合分析操作。空間換時間,極大的提升檢索效率、聚合速度。方案二缺點:同樣的資料,多儲存了一份。其對應的檢索操作如下:

POST  aggs_index/_search
{
  "_source": {
  "includes":[
    "title","query":{
    "term":{
      "topic_id":"WIAEgRbI0k9s1D2JrXPC"
    }
  }
}複製程式碼

是真的嗎?用事實說話:以下響應時間的單位為:ms。方案一要在N個(N接近10)索引,每個索引近千萬級別的資料中檢索。

兩方案對比

兩方案響應時間對比效果圖

4、小結

  • 由以上圖示,對比可知,方案二採取了空間換時間的策略,資料量多儲存了一份,但是效能提升了10餘倍。
  • 在實戰開發中,我們要理性的選擇儲存方案,在磁碟成本日漸低廉的當下,把效能放在第一位,使用者才能用的"爽“!

推薦閱讀:

《深入理解 Java 記憶體模型》讀書筆記

面試-基礎篇

Spring Boot 2.0 遷移指南

SpringBoot使用Docker快速部署專案

為什麼選擇 Spring 作為 Java 框架?

SpringBoot RocketMQ 整合使用和監控

Spring Boot 面試的十個問題

使用 Spring Framework 時常犯的十大錯誤

SpringBoot Admin 使用指南

SpringBoot Kafka 整合使用

SpringBoot RabbitMQ 整合使用

使用Arthas 獲取Spring ApplicationContext還原問題現場

上篇好文:

Elasticsearch索引增量統計及定時郵件實現