Upgrade to Pro — share decks privately, control downloads, hide ads and more …

如何在 Elasticsearch 實現敏捷的資料建模與管理 @ DevOpsDays Taipei 2023

Joe Wu
September 26, 2023

如何在 Elasticsearch 實現敏捷的資料建模與管理 @ DevOpsDays Taipei 2023

在面對不斷變化的商業需求,敏捷快速交付價值以及选代的精神已廣泛落實在 DevOps 的實踐之中,但是在使用 Elasticsearch 處理巨量日誌或資料時,一但需求改變或是有新的資料使用需求提出時,我們的應對及管理的策略為何? 如何在 Elasticsearch 來做到最佳的實踐?

工作坊將包含以下的內容:

敏捷的資料建模與管理的概念簡介
Elasticsearch Data Modeling 簡介
深入 Elasticsearch Data Modeling 的實作
Schema on read 與 Schema on write 的差異與實現方式
事先定義好的 Data Modeling
動態產生的 Data Modeling
Data Model 的选代

適合已經使用過 Elasticsearch,或至少稍微了解 Elasticsearch 的聽眾。

Joe Wu

September 26, 2023
Tweet

More Decks by Joe Wu

Other Decks in Technology

Transcript

  1. Joe Wu (喬叔) • 20+ Years Developer • 10+ Years

    Full-Cycle Developer • 10+ Years Backend Developer • Agile Practitioner / SCM / CSPO • Team Manager / Team Coach • Elastic Stack Expert • Technical Instructor / Technical Consultant • Entrepreneur (幣圈受災戶,現在療傷+養小孩復原中…) • 媒體/區塊鏈/影音串流/音樂串流/博弈/手機廠/軟體資訊安全/校務系統
  2. Donald Rumsfeld 唐納德·倫斯斐 There are known knowns; there are things

    we know we know. There are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns — the ones we don’t know we don’t know.
  3. Knowledge 知識 Known 已知 Unknown 未知 Awareness 意識 Known 已知

    Known Known Fact (事實) Known Unknown Known Risk (已知的風險) Unknown 未知 Unknown Known Hidden Fact (隱藏的事實) Unknown Unknown Unknown Risk (未知的風險) Donald Rumsfeld 唐納德·倫斯斐
  4. Unknown Known Unknown Known Unknown Known Known Unknown Unknown Known

    Known Unknown Known Unknown Known • Data Model 如何跟上敏捷的腳步? • 敏捷小步快跑的精神,更常遇到不確定性。 • 頻繁的異動 Data Model,相前相容很辛苦。
  5. 情境題:DevOpsDays Taipei 2023 電商平台 • 你現在是一個 DevOpsDays Taipei 2023 電商

    網站的 {SRE, Data, Backend, Full-Stack…} 工 程師。 • 接下來的幾個 Sprint 會陸續有不同的 Story 要完成。 • 我們今天不講敏捷開發,所以不會寫 User Story,會直接給你需求的結果或是當時的 情境。 • 歡迎體驗這 90 分鐘的電商 {SRE, Data, Backend, Full-Stack…} 工程師之旅… https://hackmd.io/@estraining/devopsdays2023
  6. Mapping is the process of defining how a document, and

    the fields it contains, are stored and indexed. • Mapping 定義了 documents 該如何被處理… • 這些 document 應該被怎樣 index? • 這份 document 的 fields 的資料型別是什麼? • 這些 fields 儲存時要包含哪些資訊? • 應該如何處理 object typed fields? • 新增的欄位如果沒有事先被定義,該如何處理? • 如果兩類 doc 間有關係存在,該如何管理? Elasticsearch 的 Data Model 定義 - Mapping 13
  7. Explicit Mapping 的宣告方式 15 • Create Index • Update Mapping

    PUT my-index { "mappings": { "properties": { "name": { "type": "text" }, "age": { "type": "integer" }, "birthday": { "type": "date" }, "email": { "type": "keyword" }, "salary": { "type": "double" } } } } PUT my-index/_mapping { "properties": { "name": { "type": "text" }, "age": { "type": "integer" }, "birthday": { "type": "date" }, "email": { "type": "keyword" }, "salary": { "type": "double" } } }
  8. 情境題:Sprint 1 收集電商訂單 Logs • 配合的後端工程師告訴你,這個 Sprint 會完成一個訂單系統,右方是訂單的資 料結構,每筆訂單完成都會產生一筆 Log

    記錄到 Elasticsearch,未來 Data Team 會要用這些訂單資料做數據分析。 • 溝通好會將訂單 Logs 資料寫入到 devopsdays-taipei-2023-ec-order 的 index 之中。 { "currency": "EUR", "customer_first_name": "Eddie", "customer_gender": "MALE", "customer_id": 38, "customer_last_name": "Underwood", "order_date": "2023-10-09T09:28:48+00:00", "order_id": 584677, "products": [ { "base_price": 11.99, "discount_percentage": 0, "quantity": 1, "manufacturer": "Elitelligence", "tax_amount": 0, "product_id": 6283, "category": "Men's Clothing", "sku": "ZO0549605496", "taxless_price": 11.99, "unit_discount_amount": 0, "min_price": 6.35, "_id": "sold_product_584677_6283", "discount_amount": 0, "created_on": "2016-12-26T09:28:48+00:00", "product_name": "Basic T-shirt - dark blue/white", "price": 11.99, "taxful_price": 11.99, "base_unit_price": 11.99 } ], "total_quantity": 2, "total_unique_products": 2, "type": "order", "user": "eddie" }
  9. 我們學到了什麼? • 我們應該要盡可能的事先準備好明確的 Mapping 定義,但有時總是會有 意外的狀況、非預期的資料欄位進入。 • 這些非預期的資料欄位也應該被良好的管理。 • Mapping

    中的欄位型態無法修改,一但被定義好之後,就不能修改。 • 這些非預期的資料欄位會被自動建立定義,但可能不符合我們預期。 • Index Mapping 其實是有版本选代的。
  10. • 當一個不存在的 Index 要被建立時,依定義好的”樣版”來進行建立。 Index Template 的建立方式 18 PUT _index_template/template_name

    { "index_patterns": ["index-na*", "*ex-name"], "priority": 123, /* 數字愈大,優先權愈高 */ "version": 1, /* 自行定義 */ "template": { "settings": { … }, "mappings": { … }, "aliases": { … } }, "_meta": { "custom_obj": { "test": "abc" } } /* 自行定義 */ }
  11. 情境題:Sprint 2 Index Mapping 的版本选代 • 由於先前的 Mapping 不符合使用,與後端溝通後可先刪除資料,後端會 重送一遍所有資料。

    • 我們將使用 Index Template 來定義新的 Index 建立時的規則 • devopsdays-taipei-2023-ec-order* 開頭的 Index 被建立時,將套用這個規則。 • 目前將 Index 取名為 devopsdays-taipei-2023-ec-order_v1 多加上版本號,未來可能 會有 v2。 • 前端使用上會以 Alias devopsdays-taipei-2023-ec-order 進行存取。 • 這個做法,也為了日後若資料量增加,可以切不同 Index 來存放。
  12. • 方法一:事先定義好明確的欄位定義:定義 Mapping 的方式 • Create Index • Update Mapping

    API • Index Template + Component Template • 方法二:事先定義好動態新增欄位的處理方式:Dynamic Mapping • 針對未事先定義的欄位,Elasticsearch 自動判斷欄位的型態,以提供適合的預設值。 • 若預設的規則不合用,這個機制能客製化嗎? Mapping 的設定方式 20
  13. Dynamic Mapping 的剖析 • Dynamic Field Mapping • Elasticsearch 內建的動態新增欄位判斷規則

    ◦ 可以在 Index Mapping 設定中,針對 dynamic 設定為 true, false, strict, runtime。 • 可針對 date 型態特別指定日期格式 ◦ Index Mapping 設定中,指定 dynamic_date_formats。 • Dynamic Template • 以自訂的規則來替動態新增的欄位建立 Mapping。 21
  14. Dynamic Field Mapping 22 JSON 的資料型態 Mapping 設定為 dynamic: true

    dynamic: runtime null 不會產生這個欄位 true or false boolean 浮點數 float double 整數 long 物件 object 不會產生這個欄位 陣列 依照陣列內的第一筆資料型態決定 字串判定為日期格式 date 字串判定為數字格式 float 或是 long double 或是 long 字串 text,並搭配 keyword 型態的子欄位 (fields)。 keyword
  15. Dynamic Template • 將 dynamic 設定為 true, runtime 時才會啟用。 •

    有新欄位出現時,會依照以下比對條件 (matching condition) 的設定,若是否符合,即套用指定的 Mapping 設定: • match_mapping_type:Elasticsearch 所判讀的資料型態。 • match 和 unmatch:欄位名稱的規則。 ◦ match_pattern:使用 Regex 比對欄位名稱。 • path_match 和 path_unmatch:欄位完整路徑的規則。 • Dynamic Template 可以設定很多組,會依照先後順序執行, 愈前面的若符合比對條件會優先採用。 • 在 dynamic template 定義中,可使用 {name} 與 {dynamic_type} 內建的 Placeholder。 23 PUT my-index/ { "mappings": { "dynamic_templates": [ { "my_template_name": { ... match conditions ... "mapping": { ... } } }, ... ] } }
  16. Dynamic Template 設定案例 1 • 將 String 型態的欄位,定義成 keyword, 而不是預設的

    text + keyword。 24 • 將 String 型態的欄位,且欄位名字是 long_ 開頭,同時不是 _text 結尾,就定 義成 long 型態。 PUT my-index/ { "mappings": { "dynamic_templates": [ { "keyword_strings": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ] } } PUT my-index/ { "mappings": { "dynamic_templates": [ { "string_as_long": { "match_mapping_type": "string", "match": "long_*", "unmatch": "*_text", "mapping": { "type": "long" } } } ] } }
  17. Dynamic Template 設定案例 2 • 將 name 物件裡除了 middle 之外的所有欄

    位,都 copy 到 full_name 的欄位,並指 定為 text 型態。 25 • 先針對字串欄位給予定義,再來針對所 有非字串的欄位,關閉 doc_values。 PUT my-index/ { "mappings": { "dynamic_templates": [ { "full_name": { "path_match": "name.*", "path_unmatch": "*.middle", "mapping": { "type": "text", "copy_to": "full_name" } } } ] } } PUT my-index/ { "mappings": { "dynamic_templates": [ { "keyword_strings": {"match_mapping_type":"string", … 略 } }, { "no_doc_values": { "match_mapping_type":"*", "mapping": { "type": "{dynamic_type}", "doc_values": false } } } ] } }
  18. Dynamic Template 的注意事項 • 要留意 Runtime Error: • Dynamic template

    的設定有些是無法在建立 template 時被檢查出來 ◦ 在沒有指定 match_mapping_type 時,假設符合的欄位會是字串,因此設定字串的 mapping, 但是文件 indexing 時的欄位卻是 long 的型態,就會在 indexing 時發生 validation error。 • 如果在 tempalte 中有使用 Placeholder,這樣也無法在建立 template 時驗證。 • dynamic 設定成 true 和 runtime 時,數值的預設型態是不一樣的。 • true 會判定成 float • runtime 會判定成 double • 若是先前沒使用 runtime,之後改用 runtime 會發生新文件判斷的型態不同,這種情 況要自行定義 Dynamic Template 來處理。 26
  19. 情境題:Sprint 3 建立適用的 Dynamic Template • 經過上個 Sprint 的教訓,我們決定與團隊一同定義一個屬於我們 Domain

    適用的 Dynamic Template,透過事先定義好動態新增欄位的處理方式, 來降低日後頻繁變動的溝通成本,也降低例外狀況的發生。 • 整理好的規則如下: 名稱 欄位名規則 判斷型態 Mapping 定義 id *_id keyword number_double *_price, price double number_float *_amount, *_percentage, quantity, *_quantity float date *_date, created_on date date string_as_text *_name string text + keyword field string_as_keyword string keyword
  20. 回顧: • 事先定義好明確的欄位定義:定義 Mapping 的方式 • Create Index • Update

    Mapping API • Index Template + Component Template • 事先定義好動態新增欄位的處理方式:Dynamic Mapping • Dynamic Field Mapping ◦ 針對未事先定義的欄位,Elasticsearch 自動判斷欄位的型態,以提供適合的預設值。 • Dynamic Template ◦ 若預設的規則不合用,以自訂的規則來替動態新增的欄位建立 Mapping。 事先定義好的 Data Model 28
  21. Schema on Write v.s Schema on Read • Schema on

    Write • 先苦後甘 ◦ 資料在寫入時,就先依定義好的方式解析資料。 • Elasticsearch 早期唯一提供的 Schema 設定策略。 • 查詢速度快、儲存空間使用較多。 • Schema on Read • 先甘後苦 ◦ 查詢當下才決定要用什麼樣的方式來解析資料。 ◦ (查詢時真的苦…) • 查詢速度慢、儲存空間使用較少。 • 7.11 版之後提出的新功能 - Runtime Fields。 • 苦到大部份要配合新的查詢功能 Async Search。 30
  22. Runtime Fields • Elasticsearch 7.11 推出的新功能。 • 在執行當下 (runtime),使用 Painless

    Script 所編寫的規則,從 _source 或 doc_value 當中擷取資料並進行處理,以產生新的欄位回傳。 • 使用 Runtime Fields 的好處 • 增加新的欄位時,不用 reindex 原來的資料。 ◦ 新增欄位的資料來源,只能從原本就存在 _source 中的資料擷取出來。 • 還不知道文件結構的全貌 或 還沒計劃好要怎麼使用時,就可以先匯入資料。 • 在 Query 時,將某個原先 indexed 欄位的值進行轉換後再回傳。 • 定義一個特殊用途的欄位,而不需要修改原本底層的資料結構定義。 31
  23. Runtime Fields 的使用方式 1 - Searching • 在 _search API

    執行時使用 • 在 runtime_mapping 定義 runtime fields 擷取資料的邏輯。 ◦ 在欄位中的 script 描述從 _source 擷取資料的處理邏輯。 • 產生出來的 runtime field 如同一般 field 可以用在 query, filter, aggregations, sort…等操作。 • 可以直接在 Query DSL 中以 fields 宣告要回傳的欄位有哪些。 • 在使用 painless script 編寫擷取的邏輯時 • 以效能考量,會優先從 doc_value 取資料。 • 如果沒有 doc_value 的資料可以用,再從 _source 取資料。 • 取出資料後,再處理成我們要的結果。 32
  24. Runtime Fields 的使用方式 1 - Searching • 我們直接宣告一個 Runtime field,並指定新欄位

    day_of_week 的擷取規則。 • 因為 @timestamp 是 date 型態的欄位,預設有啟用 doc_value,我們可直接取用。 • 我們使用 painless script 針對 date 型態所提供的 dayOfWeekEnum 函式,取出英文完整的星期值。 https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-datetime.html 33 GET my-index/_search { "runtime_mappings": { "day_of_week": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" } } }, "fields": [ "day_of_week" ] }
  25. Runtime Fields 的使用方式 2 - Mapping • 在 Index Mapping

    裡定義 Runtime Fields 的方法 • 在 mappings 中宣告 runtime 並指定 runtime fields 的擷取資料的邏輯。 • 在 mappings 中宣告 dynamic: runtime,讓欄位新增時,動態宣告為 runtime fields。 • 可以省去每次在 Searching 時都要定義同樣的描述。 34 注意:只要是 runtime fields,就算事先定義在 mapping 中,依然是 searching 時才會進行 處理,當下從 _source 或 doc_value 擷取資料,處理後並 emit (發出) 回傳值。
  26. Runtime Fields 的使用方式 2 - Mapping • 這次我們將剛才擷取 day_of_week 的

    runtime field 邏輯,直接定義到 mappings 中,並且指定擷取出來的資料型態為 keyword。 35 PUT my-index/ { "mappings": { "runtime": { "day_of_week": { "type": "keyword", "script": { "source": "emit(doc['@timestamp'].value.dayOfWeekEnum.getDisplayName(TextStyle.FULL, Locale.ROOT))" } } }, "properties": { "@timestamp": {"type": "date"} } } }
  27. 情境題:Sprint 4 事先所定義的欄位不足 • Product Owner 阿達和團隊說,我們推出了星期三免運費的活動,相信這 會為我們的業績帶來很好的成長,接下來會需要配合這個活動,專門針 對星期三的訂單進行數據的分析。 •

    Mapping 中只有定義一個 order_date 型態為 date 的欄位。 • 當我們在使用的時候,需要星期的資訊。 • 我們在 Searching 時能怎麼做?以前我們只能使用 Script Query… • 現在讓我們試著用 Runtime field 的方式來做。 36 Reference: Painless Scripting Language 官方有獨立一份文件,可以直接參考用 法。 https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-guide.html
  28. Dynamic Mapping 中指定 Runtime • 如果我們使用 dynamic: runtime • Dynamic

    Mapping 只是幫我們自動先判斷型態並 整理出擷取的規則,但之後都可以隨時修改。 37 PUT my-index { "mappings": { "dynamic": "runtime" } } JSON 的資料型態 Mapping 設定為 dynamic: true dynamic: runtime null 不會產生這個欄位 true or false boolean 浮點數 float double 整數 long 物件 object 不會產生這個欄位 陣列 依照陣列內的第一筆資料型態決定 字串判定為日期格式 date 字串判定為數字格式 float 或是 long double 或是 long 字串 text,並搭配 keyword 型態的子欄位 (fields)。 keyword
  29. Runtime Fields 的使用建議 • 專案初期,對於寫入 Elasticsearch 多樣性資料的不確定性,可以先使用 Runtime Fields 的功能來一步步發現需求並進行對應處理。

    • 但隨著時間愈久,有部份較明確的規則成熟時,應該開始著手定義資料 使用規範,並且更新 Dynamic Template 及 Index Template 定義、甚至增 加 Ingestion Pipeline 的資料前處理,讓新進入的資料使用新的規範管理。 • 並且在之後安排舊資料陸續進行 reindex,以提升查詢效能及儲存空間的 最佳化。 38 注意:使用上要特別留意 Runtime Error,特別是在 Production 環境中修改已經存 在的 Runtime field,有可能導致執行到一半的查詢結果前後不一致。
  30. 情境題:Sprint 5 當我們想將 Runtime Field 正式定義 • 隨著使用經過一段時間,我們確認了 day_of_week 的這個需求,是需要

    正式長久使用下去。 • 考量到查詢效率,我們應該將 Schema on Read 改為 Schema on Write。 • 我們需要把原先 runtime fields 的定義,改成靜態的欄位,所以要定義新的 Mapping。 • 因此新的資料也要寫到新的 Index 之中。 • 接著我們將 day_of_week 的欄位型態指定為 keyword,並使用 keyword 所新支援的 script 屬性來描述資料擷取的方式。 ◦ 這個定義將會在 Indexing 時期就執行。 • 之後我們就能使用同樣的方式來繼續使用 day_of_week 欄位。 39
  31. Async Search • Runtime fields 是在 Query 時執行 Script 即時運算,速度非常慢。

    • Elasticsearch 7.11 推出 Runtime Fields 時,也同步推出 Async Search。 • 讓我們能發送一個 Search 的請求,讓他在背景執行。 • 等到一段時間後,我們再去詢問執行的狀態。 • 執行過程中,可以先拿到已處理好的部份結果。 • 查詢時使用 POST /<index>/_async_search API,Query 方式如 _search 一樣 • 這邊要注意,使用的是 POST。 • 回傳結果會有個 id 的欄位,之後可使用此 id 查詢結果。 • 查詢執行狀態使用 GET /_async_search/status/<id> API。 • 取得結果使用 GET /_async_search/<id> API。 • 使用完刪除留存的結果資料 DELETE /_async_search/<id> API。 40
  32. Async Search • 一些重要的設定 • 執行的查詢,若是 wait_for_completion_timeout 沒有完成,才會以 Async 處理,並

    回傳 id 欄位。(預設 1 秒) • 如果因為 wait_for_completion_timeout 內就完成,在回傳中就已取得結果,但希望 結果能繼續留存,可使用 keep_on_completion (預設 false) 讓結果留存,這樣回傳的結 果也會有 id 欄位。 • keep_alive (預設 5d) 查詢完成的資料會留存多久。 • 分批拿回執行結果的設定: batched_reduce_size (預設 5) ◦ 如果查詢的結果量非常的大,我們可以把這個值調大,讓較小部份結果可優先被查詢。 41 注意:使用 Async Search 時,pre_filter_shard_size 固定為 1, ccs_minimize_roundtrips 預設為 false。(8.9 版之後,才開始支援 true)。
  33. Async Search 其他的細節 • 在背景查詢時,如果 Coordinating Node 掛了? • 一樣可以拿到

    Response,只是這個執行就不會再繼續了。 ◦ is_running 會是 false ◦ is_partial 會是 true • 查詢的結果會存在哪裡?會一直佔用 JVM Heap 嗎? • (官方文件沒有寫的細節…) • 其實會存在 .async_search 這個系統 Index 中。 • 不用擔心機器重啟後結果會結果會不見。 42 注意:為了避免佔用太大空間,預設不會讓 Async Search 查詢的結果,超過 search.max_async_search_response_size (10MB) 的大小。
  34. 回顧:無法事先定義好的 Data Model • Schema on Read v.s Schema on

    Write • Runtime Field 幫助我們有擁抱不確定性的勇氣 • 定義在 Searching 執行時 • 定義在 Mapping 裡 • Runtime Field 的執行效率是很差的,差到有 Async Search 這個功能一起推 出。 • 一但確認需求,後續新寫入的資料,應該優先以 Schema on Write 處理。 • Mapping 版本选代!
  35. Mapping 用久了也會需要 Refactoring • Elasticsearch 不支援 Mapping 的破壞性更新。 • 因為資料是在

    Indexing 當下依照 Mapping 進行處理。 • 事後修改 Mapping,也不會改變原先已 Indexing 的文件。 • 當我們定義新的 Mapping 之後,資料必須重新 Index 才能以新 Mapping 設定進行處理。 • Elasticsearch 提供以下兩個方式 • Update by Query API:在同一個 Index 中,擴充 Mapping 的定義,需要將既有的資料 重新 Index。 • Reindex API:從 A Index 將資料讀出並 Indexing 至 B Index 中。 45 注意:要執行這兩種方式,都需要所有欄位有存在 _source,不在 _source 裡的資 料在執行後將會遺失。
  36. • 運作的方式 ( Scroll API + Bulk API + Update

    API ) • 會使用 Scroll 進行查詢,並且將指定 Query 的內容建立 snapshot。 • 接著將查詢回來的結果,依照 script 的定義,一批一批的使用 _bulk 執行 update。 • 如果執行過程中發現 document 的 version 變化了 (過程中資料被更動了),則會依 conflicts (預設 abort ) 的設定決定要失敗或是繼續執行。 ◦ 如果執行失敗並中斷的話,先前已經 update 的文件,不會 rollback。 • 基本上 Scroll, Bulk, Update API 能使用的參數,幾乎都能用。 Update by Query 46 POST my-index/_update_by_query?conflicts=proceed { "script": { ...略... } "query": { ...略... } }
  37. Update by Query Asynchronously • 執行時指定 wait_for_completion=false 將會成為 Async Task。

    • 所建立的 task 會被新增為 Index .tasks 裡的文件。 47 POST my-index/_update_by_query?wait_for_completion=false { "script": {}, "query": {} } • 使用 _task API 取得 task 執行狀態與內容。 GET _tasks/<task_id> POST _tasks/<task_id>/_cancel • 也可使用 Task Cancel API 取消某個 update by query 的 task。
  38. 情境題:Sprint 6 將舊資料也轉成 Schema on Write • 接續著上一個情境題,雖然新增的資料已經會使用新的 Mapping 定義,

    但是我們已經有許多舊的資料,我們希望增加查詢的效率,要將舊資料 也先將 day_of_week 擷取出來,而不要 Runtime 時才執行。 • 首先要更新 Mapping,定義好 day_of_week 的欄位。 • 再來透過 _update_by_query 批次的資料讀取出來,重新 Indexing。 • 最後移除掉原先定義的 Runtime Field。 48
  39. Reindex API 49 • Reindex 是將 source Index 匯入至 destination

    Index 的工具 • 基本上與 update_by_query API 幾乎一樣,只是要求必須寫入到另外的 Index,所以不 是使用 Update API,而是使用 Index API,也因此不會有版本衝突的情況。 • 支援 Scroll API, Bulk API, Index API 大部份的參數。 • 配合 elasticsearch.yml 中 reindex.remote.whitelist 的設定,能將 Rmote 的 Index 匯入至本地的 Index。 注意:執行 Reindex 之前,必須先自行建立好 Index Mapping (或是 Index Template), 在 Reindex 時不會將原 Index 的 Index Settings 複製到新的 Index 中。
  40. POST _reindex?slices=5&refresh&wait_for_completion=false&requests_per_second=500 { "source": { "remote": { "host": "http://otherhost:9200", "username":

    "user", "password": "pass" }, "index": ["my-index-000001", "my-index-000002"], "_source": ["user.id", "_doc"], "query": { "match_all": {} } }, "dest": { "index": "my-new-index-000001", "routing": "=dog", #使用 keep, discard 或是`=`後面接固定值 "pipeline": "some_ingest_pipeline" }, "script": { "source": "ctx._source.tag = ctx._source-remove(\"flag\")", "lang": "painless" }, } Reindex API 的使用方式 50
  41. 回顧:如何在 Elasticsearch 實現敏捷的資料建模與管理 • Agile Data Modeling • Schema on

    Write • Mapping, Index Template, Dynamic Field Mapping, Dynamic Template • Schema on Read • Runtime Fields • Async Search • Schema Expansion or Destructive Update • Update by Query • Reindex 52
  42. Knowledge 知識 Known 已知 Unknown 未知 Awareness 意識 Known 已知

    Known Known Fact (事實) Known Unknown Known Risk (已知的風險) Unknown 未知 Unknown Known Hidden Fact (隱藏的事實) Unknown Unknown Unknown Risk (未知的風險) Donald Rumsfeld 唐納德·倫斯斐
  43. Data Out 資料怎麼用 Known 已知 Unknown 未知 Data In 資料長相

    Known 已知 Known Known Index Mapping Index Template Dynamic Template Known Unknown Runtime Field Unknown 未知 Unknown Known Dynamic Field Mapping Dynamic Template Unknown Unknown Runtime Field Exception Handling Ingest Pipeline Dead Letter Queue 喬叔 Elasticsearch Data Modeling
  44. Data Out 資料怎麼用 Known 已知 Unknown 未知 Data In 資料長相

    Known 已知 Known Known Index Mapping Index Template Dynamic Template Known Unknown Runtime Field Unknown 未知 Unknown Known Dynamic Field Mapping Dynamic Template Unknown Unknown Runtime Field Exception Handling Ingest Pipeline Dead Letter Queue 喬叔 Elasticsearch Data Modeling 如何擴大 Known Known 的範圍: • 透過團隊的溝通與合作,定義共同的 Data Model • 掌握技術,讓 Data Model 也能有快速选代的能力 • Code 要重構,Data Model 要需要重構