久久精品精选,精品九九视频,www久久只有这里有精品,亚洲熟女乱色综合一区
    分享

    干貨 | Elasticsearch 索引設計實戰指南

     銘毅天下 2021-12-24

    題記

    隨著 Elastic 的上市,ELK Stack 不僅在 BAT 的大公司得到長足的發展,而且在各個中小公司都得到非常廣泛的應用,甚至連“婚慶網站”都開始使用 Elasticsearch 了。隨之而來的是 Elasticsearch 相關部署、框架、性能優化的文章早已鋪天蓋地。

    初學者甚至會進入幻覺——“一鍵部署、導入數據、檢索&聚合、動態擴展, So Easy,媽媽再也不用擔心我的 Elastic 學習”!

    但,實際上呢?僅就 Elasticsearch 索引設計,請回答如下幾個問題:

    • 每天幾百 GB 增量實時數據的TB級甚至PB級別的大索引如何設計?
    • 分片數和副本數大小如何設計,才能提升 ES 集群的性能?
    • ES 的 Mapping 該如何設計,才能保證檢索的高效?
    • 檢索類型 term/match/matchphrase/querystring /match_phrase _prefix /fuzzy 那么多,設計階段如何選型呢?
    • 分詞該如何設計,才能滿足復雜業務場景需求?
    • 傳統數據庫中的多表關聯在 ES 中如何設計?......

    這么看來,沒有那么 Easy,坑還是得一步步的踩出來的。

    正如攜程架構師 WOOD 大叔所說“做搜索容易,做好搜索相當難!”,

    VIVO 搜索引擎架構師所說“ 熟練使用 ES 離做好搜索還差很遠!”。

    本文主結合作者近千萬級開發實戰經驗,和大家一起深入探討一下Elasticsearch 索引設計......

    索引設計的重要性

    在美團寫給工程師的十條精進原則中強調了“設計優先”。無數事實證明,忽略了前期設計,往往會帶來很大的延期風險。并且未經評估的不當的設計會帶來巨大的維護成本,后期不得不騰出時間,專門進行優化和重構。

    而 Elasticsearch 日漸成為大家非結構數據庫的首選方案,項目前期良好的設計和評審是必須的,能給整個項目帶來收益。

    索引層面的設計在 Elasticsearch 相關產品、項目的設計階段的作用舉重若輕。

    • 好的索引設計在整個集群規劃中占據舉足輕重的作用,索引的設計直接影響集群設計的好壞和復雜度。
    • 好的索引設計應該是充分結合業務場景的時間維度和空間維度,結合業務場景充分考量增、刪、改、查等全維度設計的。
    • 好的索引設計是完全基于“設計先行,編碼在后”的原則,前期會花很長時間,為的是后期工作更加順暢,避免不必要的返工。

    1、PB 級別的大索引如何設計?

    單純的普通數據索引,如果不考慮增量數據,基本上普通索引就能夠滿足性能要求。

    我們通常的操作就是:

    • 步驟 1:創建索引;
    • 步驟 2:導入或者寫入數據;
    • 步驟 3:提供查詢請求訪問或者查詢服務。

    1.1 大索引的缺陷

    如果每天億萬+的實時增量數據呢,基于以下幾點原因,單個索引是無法滿足要求的。在 360 技術訪談中也提到了大索引的設計的困惑。

    1.1.1 存儲大小限制維度

    單個分片(Shard)實際是 Lucene 的索引,單分片能存儲的最大文檔數是:2,147,483,519 (= Integer.MAX_VALUE - 128)。如下命令能查看全部索引的分隔分片的文檔大小:


    GET _cat/shardsapp_index 2 p STARTED 9443 2.8mb 127.0.0.1 Hk9wFwUapp_index 2 r UNASSIGNED app_index 3 p STARTED 9462 2.7mb 127.0.0.1 Hk9wFwUapp_index 3 r UNASSIGNED app_index 4 p STARTED 9520 3.5mb 127.0.0.1 Hk9wFwUapp_index 4 r UNASSIGNED app_index 1 p STARTED 9453 2.4mb 127.0.0.1 Hk9wFwUapp_index 1 r UNASSIGNED app_index 0 p STARTED 9365 2.3mb 127.0.0.1 Hk9wFwUapp_index 0 r UNASSIGNED

    1.1.2 性能維度

    當然一個索引很大的話,數據寫入和查詢性能都會變差。

    而高效檢索體現在:基于日期的檢索可以直接檢索對應日期的索引,無形中縮減了很大的數據規模。

    比如檢索:“2019-02-01”號的數據,之前的檢索會是在一個月甚至更大體量的索引中進行。

    現在直接檢索"index_2019-02-01"的索引,效率提升好幾倍。

    1.1.3 風險維度

    一旦一個大索引出現故障,相關的數據都會受到影響。而分成滾動索引的話,相當于做了物理隔離。

    1.2 PB 級索引設計實現

    綜上,結合實踐經驗,大索引設計建議:使用模板+Rollover+Curator動態創建索引。動態索引使用效果如下:


    index_2019-01-01-000001index_2019-01-02-000002index_2019-01-03-000003index_2019-01-04-000004index_2019-01-05-000005

    1.2.1 使用模板統一配置索引

    目的:統一管理索引,相關索引字段完全一致。

    1.2.2 使用 Rollver 增量管理索引

    目的:按照日期、文檔數、文檔存儲大小三個維度進行更新索引。使用舉例:


    POST /logs_write/_rollover { "conditions": { "max_age": "7d", "max_docs": 1000, "max_size": "5gb" }}

    1.2.3 索引增量更新原理

    一圖勝千言。

    索引更新的時機是:當原始索引滿足設置條件的三個中的一個的時候,就會更新為新的索引。為保證業務的全索引檢索,一般采用別名機制。

    在索引模板設計階段,模板定義一個全局別名:用途是全局檢索,如圖所示的別名:indexall。每次更新到新的索引后,新索引指向一個用于實時新數據寫入的別名,如圖所示的別名:indexlatest。同時將舊索引的別名 index_latest 移除。

    別名刪除和新增操作舉例:


    POST /_aliases{ "actions" : [ { "remove" : { "index" : "index_2019-01-01-000001", "alias" : "index_latest" } }, { "add" : { "index" : "index_2019-01-02-000002", "alias" : "index_latest" } } ]}

    經過如上步驟,即可完成索引的更新操作。

    1.2.4 使用 curator 高效清理歷史數據

    目的:按照日期定期刪除、歸檔歷史數據。

    一個大索引的數據刪除方式只能使用 delete_by_query,由于 ES 中使用更新版本機制。刪除索引后,由于沒有物理刪除,磁盤存儲信息會不減反增。有同學就反饋 500GB+ 的索引 delete_by_query 導致負載增高的情況。

    而按照日期劃分索引后,不需要的歷史數據可以做如下的處理。

    • 刪除——對應 delete 索引操作。

    • 壓縮——對應 shrink 操作。

    • 段合并——對應 force_merge 操作。

    而這一切,可以借助:curator 工具通過簡單的配置文件結合定義任務 crontab 一鍵實現。

    注意:7.X高版本借助iLM實現更為簡單。

    舉例,一鍵刪除 30 天前的歷史數據:

      [root@localhost .curator]# cat action.yml   actions: 1: action: delete_indices description: >- Delete indices older than 30 days (based on index name), for logstash- prefixed indices. Ignore the error if the filter does not result in an actionable list of indices (ignore_empty_list) and exit cleanly. options: ignore_empty_list: True disable_action: False filters: - filtertype: pattern kind: prefix value: logs_ - filtertype: age source: name direction: older timestring: '%Y.%m.%d' unit: days unit_count: 30

    2、分片數和副本數如何設計?

    2.1 分片/副本認知

    • 1、分片:分片本身都是一個功能齊全且獨立的“索引”,可以托管在集群中的任何節點上。

    數據切分分片的主要目的:

    (1)水平分割/縮放內容量 。 

    (2)跨分片(可能在多個節點上)分布和并行化操作,提高性能/吞吐量。 

    注意:分片一旦創建,不可以修改大小。

    • 2、副本:它在分片/節點出現故障時提供高可用性。

    副本的好處:因為可以在所有副本上并行執行搜索——因此擴展了搜索量/吞吐量。

    注意:副本分片與主分片存儲在集群中不同的節點。副本的大小可以通過:number_of_replicas動態修改。

    2.2 分片和副本實戰中設計

    最常見問題答疑

    2.2.1 問題 1:索引設置多少分片?

    Shard 大小官方推薦值為 20-40GB, 具體原理呢?Elasticsearch 員工 Medcl 曾經討論如下:

    Lucene 底層沒有這個大小的限制,20-40GB 的這個區間范圍本身就比較大,經驗值有時候就是拍腦袋,不一定都好使。

    Elasticsearch 對數據的隔離和遷移是以分片為單位進行的,分片太大,會加大遷移成本。

    一個分片就是一個 Lucene 的庫,一個 Lucene 目錄里面包含很多 Segment,每個 Segment 有文檔數的上限,Segment 內部的文檔 ID 目前使用的是 Java 的整型,也就是 2 的 31 次方,所以能夠表示的總的文檔數為Integer.MAXVALUE - 128 = 2^31 - 128 = 2147483647 - 1 = 2,147,483,519,也就是21.4億條。

    同樣,如果你不 forcemerge 成一個 Segment,單個 shard 的文檔數能超過這個數。

    單個 Lucene 越大,索引會越大,查詢的操作成本自然要越高,IO 壓力越大,自然會影響查詢體驗。

    具體一個分片多少數據合適,還是需要結合實際的業務數據和實際的查詢來進行測試以進行評估。

    綜合實戰+網上各種經驗分享,梳理如下:

    • 第一步:預估一下數據量的規模。一共要存儲多久的數據,每天新增多少數據?兩者的乘積就是總數據量。

    • 第二步:預估分多少個索引存儲。索引的劃分可以根據業務需要。

    • 第三步:考慮和衡量可擴展性,預估需要搭建幾臺機器的集群。存儲主要看磁盤空間,假設每臺機器2TB,可用:2TB0.85(磁盤實際利用率)0.85(ES 警戒水位線)。

    • 第四步:單分片的大小建議最大設置為 30GB。此處如果是增量索引,可以結合大索引的設計部分的實現一起規劃。

    前三步能得出一個索引的大小。分片數考慮維度:

    • 1)分片數 = 索引大小/分片大小經驗值 30GB 。
    • 2)分片數建議和節點數一致。設計的時候1)、2)兩者權衡考慮+rollover 動態更新索引結合。

    每個 shard 大小是按照經驗值 30G 到 50G,因為在這個范圍內查詢和寫入性能較好。

    經驗值的探推薦閱讀:

    Elasticsearch究竟要設置多少分片數?

    探究 | Elasticsearch集群規模和容量規劃的底層邏輯

    2.2.2 問題 2:索引設置多少副本?

    結合集群的規模,對于集群數據節點 >=2 的場景:建議副本至少設置為 1。

    之前有同學出現過:副本設置為 0,長久以后會出現——數據寫入向指定機器傾斜的情況。

    注意:

    單節點的機器設置了副本也不會生效的。副本數的設計結合數據的安全需要。對于數據安全性要求非常高的業務場景,建議做好:增強備份(結合 ES 官方備份方案)。

    3、Mapping 如何設計?

    3.1 Mapping 認知

    Mapping 是定義文檔及其包含的字段的存儲和索引方式的過程。例如,使用映射來定義:

    • 應將哪些字符串字段定義為全文檢索字段;
    • 哪些字段包含數字,日期或地理位置;
    • 定義日期值的格式(時間戳還是日期類型等);
    • 用于控制動態添加字段的映射的自定義規則。

    3.2 設計 Mapping 的注意事項

    ES 支持增加字段 //新增字段

    PUT new_index { "mappings": { "_doc": { "properties": { "status_code": { "type": "keyword" } } } } }
    • ES 不支持直接刪除字段
    • ES 不支持直接修改字段
    • ES 不支持直接修改字段類型 如果非要做靈活設計,ES 有其他方案可以替換,借助reindex。但是數據量大會有性能問題,建議設計階段綜合權衡考慮。

    3.3 Mapping 字段的設置流程

    索引分為靜態 Mapping(自定義字段)+動態 Mapping(ES 自動根據導入數據適配)。

    實戰業務場景建議:選用靜態 Mapping,根據業務類型自己定義字段類型。

    好處

    • 可控;
    • 節省存儲空間(默認 string 是 text+keyword,實際業務不一定需要)。

    設置字段的時候,務必過一下如下圖示的流程。根據實際業務需要,主要關注點:

    • 數據類型選型;
    • 是否需要檢索;
    • 是否需要排序+聚合分析;
    • 是否需要另行存儲。

    核心參數的含義,梳理如下:

    3.4 Mapping 建議結合模板定義

    索引 Templates——索引模板允許您定義在創建新索引時自動應用的模板。模板包括settings和Mappings以及控制是否應將模板應用于新索引。

    注意:模板僅在索引創建時應用。更改模板不會對現有索引產生影響。

    第1部分也有說明,針對大索引,使用模板是必須的。核心需要設置的setting(僅列舉了實戰中最常用、可以動態修改的)如下:

    • index.numberofreplicas 每個主分片具有的副本數。默認為 1(7.X 版本,低于 7.X 為 5)。
    • index.maxresultwindow 深度分頁 rom + size 的最大值—— 默認為 10000。
    • index.refresh_interval 默認 1s:代表最快 1s 搜索可見;

    寫入時候建議設置為 -1,提高寫入性能;

    實戰業務如果對實時性要求不高,建議設置為 30s 或者更高。

    3.5 包含 Mapping 的 template 設計萬能模板

    以下模板已經在 7.2 驗證 ok,可以直接拷貝修改后實戰項目中使用。

    PUT _template/test_template{ "index_patterns": [ "test_index_*", "test_*" ], "settings": { "number_of_shards": 1, "number_of_replicas": 1, "max_result_window": 100000, "refresh_interval": "30s" }, "mappings": { "properties": { "id": { "type": "long" }, "title": { "type": "keyword" }, "content": { "analyzer": "ik_max_word", "type": "text", "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } } }, "available": { "type": "boolean" }, "review": { "type": "nested", "properties": { "nickname": { "type": "text" }, "text": { "type": "text" }, "stars": { "type": "integer" } } }, "publish_time": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" }, "expected_attendees": { "type": "integer_range" }, "ip_addr": { "type": "ip" }, "suggest": { "type": "completion" } } }}

    4、分詞的選型

    主要以 ik 來說明,最新版本的ik支持兩種類型。ik_maxword 細粒度匹配,適用切分非常細的場景。ik_smart 粗粒度匹配,適用切分粗的場景。

    4.1 坑 1:分詞選型

    實際業務中:建議適用ik_max_word分詞 + match_phrase短語檢索。

    原因:ik_smart有覆蓋不全的情況,數據量大了以后,即便 reindex 能滿足要求,但面對極大的索引的情況,reindex 的耗時我們承擔不起。建議ik_max_word一步到位。

    4.2 坑 2:ik 要裝集群的所有機器嗎?

    建議:安裝在集群的所有節點上。

    4.3 坑 3:ik 匹配不到怎么辦?

    • 方案1:擴充 ik 開源自帶的詞庫+動態更新詞庫;原生的詞庫分詞數量級很小,基礎詞庫盡量更大更全,網上搜索一下“搜狗詞庫“。

    動態更新詞庫:可以結合 mysql+ik 自帶的更新詞庫的方式動態更新詞庫。

    更新詞庫僅對新創建的索引生效,部分老數據索引建議使用 reindex 升級處理。

    5、檢索類型如何選型呢?

    前提:5.X 版本之后,string 類型不再存在,取代的是text和keyword類型。

    • text 類型作用:分詞,將大段的文字根據分詞器切分成獨立的詞或者詞組,以便全文檢索。

    適用于:email 內容、某產品的描述等需要分詞全文檢索的字段;

    不適用:排序或聚合(Significant Terms 聚合例外)

    • keyword 類型:無需分詞、整段完整精確匹配。

    適用于:email 地址、住址、狀態碼、分類 tags。

    以一個實戰例子說明:

    PUT zz_test { "mappings": { "doc": { "properties": { "title": { "type": "text", "analyzer":"ik_max_word", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } } }GET zz_test/_mapping
    PUT zz_test/doc/1{ "title":"錘子加濕器官方致歉,難產后臨時推遲一個月發貨遭diss耍流氓"}

    POST zz_test/_analyze{ "text": "錘子加濕器官方致歉,難產后臨時推遲一個月發貨遭diss耍流氓", "analyzer": "ik_max_word"}

    ik_max_word的分詞結果如下:

    錘子、錘、子、加濕器、濕、器官、官方、方、致歉、致、歉、難產、產后、后、臨時、臨、時、推遲、遲、一個、 一個、 一、個月、 個、 月、 發貨、發、貨、遭、diss、耍流氓、耍、流氓、氓。

    5.1 term 精確匹配

    • 核心功能:不受到分詞器的影響,屬于完整的精確匹配。
    • 應用場景:精確、精準匹配。
    • 適用類型:keyword。
    • 舉例:term 最適合匹配的類型是 keyword,如下所示的精確完整匹配:
    POST zz_test/_search { "query": { "term": { "title.keyword": "錘子加濕器官方致歉,難產后臨時推遲一個月發貨遭diss耍流氓" } } }
    • 注意:如下是匹配不到結果的。
    POST zz_test/_search{ "query": { "term": { "title": "錘子加濕器" } }}
    • 原因:對于 title 中的錘子加濕器,term 不會做分詞拆分匹配的。且 ik_max_word 分詞也是沒有“錘子加濕器”這組關鍵詞的。

    5.2 prefix 前綴匹配

    • 核心功能:前綴匹配。
    • 應用場景:前綴自動補全的業務場景。
    • 適用類型:keyword。

    如下能匹配到文檔 id 為 1 的文章。

    POST zz_test/_search{ "query": { "prefix": { "title.keyword": "錘子加濕器" } }}

    5.3 wildcard 模糊匹配

    • 核心功能:匹配具有匹配通配符表達式 keyword 類型的文檔。支持的通配符:*,它匹配任何字符序列(包括空字符序列);?,它匹配任何單個字符。
    • 應用場景:請注意,選型務必要慎重!此查詢可能很慢多組關鍵次的情況下可能會導致宕機,因為它需要遍歷多個術語。為了防止非常慢的通配符查詢,通配符不能以任何一個通配符*或?開頭。

    • 適用類型:keyword。

    如下匹配,類似 MySQL 中的通配符匹配,能匹配所有包含加濕器的文章。

    POST zz_test/_search{ "query": { "wildcard": { "title.keyword": "*加濕器*" } }}

    5.4 match 分詞匹配

    • 核心功能:全文檢索,分詞詞項匹配。
    • 應用場景:實際業務中較少使用,原因:匹配范圍太寬泛,不夠準確。
    • 適用類型:text。
    • 如下示例,title 包含"錘子"和“加濕器”的都會被檢索到。
    POST zz_test/_search{ "profile": true, "query": { "match": { "title": "錘子加濕器" } }}

    5.5 match_phrase 短語匹配

    • 核心功能:match_phrase 查詢首先將查詢字符串解析成一個詞項列表,然后對這些詞項進行搜索; 只保留那些包含 全部 搜索詞項,且 位置"position" 與搜索詞項相同的文檔。

    • 應用場景:業務開發中 90%+ 的全文檢索都會使用 match_phrase 或者 query_string 類型,而不是 match。

    • 適用類型:text。

    • 注意:

    POST zz_test/_analyze{ "text": "錘子加濕器", "analyzer": "ik_max_word"}
    • 分詞結果:

    錘子, 錘,子, 加濕器, 濕,器。而:id為1的文檔的分詞結果:錘子, 錘, 子, 加濕器, 濕, 器官。所以,如下的檢索是匹配不到結果的。

    POST zz_test/_search{"query": { "match_phrase": { "title": "錘子加濕器" }}}

    如果想匹配到,怎么辦呢?這里可以字詞組合索引的形式。

    推薦閱讀:

    探究 | 明明存在,怎么搜索不出來呢?

    5.6 multi_match 多組匹配

    • 核心功能:match query 針對多字段的升級版本。
    • 應用場景:多字段檢索。
    • 適用類型:text。
    • 舉例:
    POST zz_test/_search{ "query": { "multi_match": { "query": "加濕器", "fields": [ "title", "content" ] } }}

    5.7 query_string 類型

    • 核心功能:支持與或非表達式+其他N多配置參數。
    • 應用場景:業務系統需要支持自定義表達式檢索。
    • 適用類型:text。
    POST zz_test/_search{ "query": { "query_string": { "default_field": "title", "query": "(錘子 AND 加濕器) OR (官方 AND 道歉)" } }}

    5.8 bool 組合匹配

    • 核心功能:多條件組合綜合查詢。
    • 應用場景:支持多條件組合查詢的場景。
    • 適用類型:text 或者 keyword。一個 bool 過濾器由三部分組成:
    { "bool" : { "must" : [], "should" : [], "must_not" : [], "filter": [] }}
    • must ——所有的語句都 必須(must) 匹配,與 AND 等價。
    • must_not ——所有的語句都 不能(must not) 匹配,與 NOT 等價。
    • should ——至少有一個語句要匹配,與 OR 等價。
    • filter——必須匹配,運行在非評分&過濾模式。
    小結:

    6、多表關聯如何設計?

    6.1 為什么會有多表關聯

    多表關聯是被問的最多的問題之一。幾乎每周都會被問到。

    主要原因:常規基于關系型數據庫開發,多多少少都會遇到關聯查詢。而關系型數據庫設計的思維很容易帶到 ES 的設計中。

    6.2 多表關聯如何實現

    方案一:多表關聯視圖,視圖同步 ES

    MySQL 寬表導入 ES,使用 ES 查詢+檢索。適用場景:基礎業務都在 MySQL,存在幾十張甚至幾百張表,準備同步到 ES,使用 ES 做全文檢索。

    將數據整合成一個寬表后寫到 ES,寬表的實現可以借助關系型數據庫的視圖實現。

    寬表處理在處理一對多、多對多關系時,會有字段冗余問題,如果借助:logstash_input_jdbc,關系型數據庫如 MySQL 中的每一個字段都會自動幫你轉成 ES 中對應索引下的對應 document 下的某個相同字段下的數據。

    • 步驟 1:提前關聯好數據,將關聯的表建立好視圖,一個索引對應你的一個視圖,并確認視圖中數據的正確性。

    • 步驟 2:ES 中針對每個視圖定義好索引名稱及 Mapping。

    • 步驟 3:以視圖為單位通過 logstash_input_jdbc 同步到 ES 中。

    方案二:1 對 1 同步 ES

    MySQL+ES 結合,各取所長。適用場景:關系型數據庫全量同步到 ES 存儲,沒有做冗余視圖關聯。

    ES 擅長的是檢索,而 MySQL 才擅長關系管理。

    所以可以考慮二者結合,使用 ES 多索引建立相同的別名,針對別名檢索到對應 ID 后再回 MySQL 通過關聯 ID join 出需要的數據。

    方案三:使用 Nested 做好關聯

    適用場景:1 對少量的場景。

    舉例:有一個文檔描述了一個帖子和一個包含帖子上所有評論的內部對象評論。可以借助 Nested 實現。

    Nested 類型選型——如果需要索引對象數組并保持數組中每個對象的獨立性,則應使用嵌套 Nested 數據類型而不是對象 Oject 數據類型。

    當使用嵌套文檔時,使用通用的查詢方式是無法訪問到的,必須使用合適的查詢方式(nested query、nested filter、nested facet等),很多場景下,使用嵌套文檔的復雜度在于索引階段對關聯關系的組織拼裝。

    方案四:使 ES6.X+ 父子關系 Join 做關聯

    適用場景:1 對多量的場景。

    舉例:1 個產品和供應商之間是1對N的關聯關系。

    Join 類型:join 數據類型是一個特殊字段,用于在同一索引的文檔中創建父/子關系。關系部分定義文檔中的一組可能關系,每個關系是父名稱和子名稱。

    當使用父子文檔時,使用has_child 或者has_parent做父子關聯查詢。

    方案三、方案四選型對比:

    注意:方案三&方案四選型必須考慮性能問題。文檔應該盡量通過合理的建模來提升檢索效率。

    Join 類型應該盡量避免使用。nested 類型檢索使得檢索效率慢幾倍,父子Join 類型檢索會使得檢索效率慢幾百倍。

    盡量將業務轉化為沒有關聯關系的文檔形式,在文檔建模處多下功夫,以提升檢索效率。

    干貨 | 論Elasticsearch數據建模的重要性

    干貨 | Elasticsearch多表關聯設計指南

    小結

    7、實戰中遇到過的坑

    如果能重來,我會如何設計 Elasticsearch 系統?

    來自累計近千萬實戰項目設計的思考。

    • 坑1: 數據清洗一定發生在寫入 es 之前!而不是請求數據后處理,拿勢必會降低請求速度和效率。

    • 坑2:高亮不要重復造輪子,用原生就可以。

    • 坑3:讓 es 做他擅長的事,檢索+不復雜的聚合,否則數據量+復雜的業務邏輯大會有性能問題。

    • 坑4:設計的工作必須不要省!快了就是慢了,否則無休止的因設計缺陷引發的 bug 會增加團隊的戳敗感!

    • 坑5:在給定時間的前提下,永遠不會有完美的設計,必須相對合理的設計+重構結合,才會有相對靠譜的系統。

    • 坑6:SSD 能提升性能,但如果系統業務邏輯非常負責,換了 SSD 未必達到預期。

    • 坑7:由于 Elasticsearch 不支持事務 ACID 特性,數據庫作為實時數據補充,對于實時數據要求嚴格的場景,必須同時采取雙寫或者同步的方式。這樣,一旦實時數據出現不一致,可以通過數據庫進行同步遞增更新。

    8、小結

    本文從選題和撰寫歷時2周+的時間,期間反復梳理了開發過程中遇到的問題、社區/QQ 群/知識星球等中大家提問的問題。

    將TOP N 大家最關注的問題也是實戰中得得確確容易混淆的問題梳理出來,目的是:讓更多的后來人看到,不要再走一遍彎路。

    相信經過幾天梳理的實戰文檔,能給你帶來幫助!感謝您的反饋和交流。

      轉藏 分享 獻花(0

      0條評論

      發表

      請遵守用戶 評論公約

      類似文章 更多

      主站蜘蛛池模板: 国产尤物精品自在拍视频首页| 日韩丝袜欧美人妻制服| 亚洲国内精品一区二区| 日本高清色WWW在线安全| 特级毛片A级毛片免费播放| 777奇米四色成人影视色区| 亚洲性日韩精品一区二区三区| 最新中文字幕AV无码专区不| 漂亮人妻中文字幕丝袜| 特黄三级又爽又粗又大| 亚洲色一色噜一噜噜噜| YY111111少妇影院| 欧美福利电影A在线播放| 国产精品视频第一区二区三区| 久章草在线毛片视频播放| 精品无人区一区二区三区| 国产破外女出血视频| 亚洲中文在线精品国产| 玩弄漂亮少妇高潮白浆| 国产又大又硬又粗| 在线播放免费人成毛片| 中文字幕国产精品日韩| 丰满人妻被黑人猛烈进入| 极品粉嫩国产18尤物在线观看 | 欧美成人精品高清在线观看| 精品少妇av蜜臀av| 免费久久人人爽人人爽AV | 久久人人爽人人爽人人av| 久久五十路丰满熟女中出| 无套内射视频囯产| 女人十八毛片A级十八女人 | 欧洲国产精品无码专区影院| 日韩中文字幕精品人妻| 亚洲欧美成人久久一区| 亚洲精品无码成人AV电影网| 亚洲AVAV天堂AV在线网阿V| 一个人免费视频观看在线WWW| 国产成人无码A区在线观| 国产精品大全中文字幕| 少妇扒开毛茸茸的B自慰| 自偷自拍亚洲综合精品|