⑴ Elasticsearch如何保證數據不丟失
[TOC]
數據寫入請求達到時,以需要的數據格式組織並寫入磁碟的過程叫做數據提交,對應es就是創建倒排索引,維護segment文件
如果我們同步的方式,來處理上述過程,那麼系統的吞吐量將很低
如果我們以非同步的方式,先寫入內存,然後再非同步提交到磁碟,則有可能因為機器故障而而丟失還未寫入到磁碟中的數據
為了解決這個問題,一般的存儲系統都會設計transag log (事務日誌)或這write ahead log(預寫式日誌)。它的作用時,將最近的寫入數據或操作以日誌的形式直接落盤,從而使得即便系統崩潰後,依然可以基於這些磁碟日誌進行數據恢復。
Mysql有redo undo log ,而HBASE、LevelDB,RockDB等採用的LSM tree則提供了write ahead log 這樣的設計,來保證數據的不丟失
上述論述中,數據以同步方式落盤會有性能問題,為什麼將translog和wal直接落盤不影響性能?原因如下:
es默認是每個請求都會同步落盤translog ,即配置 index.translog.rability 為 request 。當然對於一些可以丟數據的場景,我們可以將 index.translog.rability 配置為 async 來提升寫入translog的性能,該配置會非同步寫入translog到磁碟。具體多長時間寫一次磁碟,則通過 index.translog.sync_interval 來控制
前面說了,為了保證translog足夠小,所以translog不能無限擴張,需要在一定量後,將其對應的真實業務數據以其最終數據結構(es是倒排索引)提交到磁碟,這個動作稱為flush ,它會實際的對底層Lucene 進行一次commit。我們可以通過 index.translog.flush_threshold_size 來配置translog多大時,觸發一次flush。每一次flush後,原translog將被刪除,重新創建一個新的translog
elasticsearch本身也提供了flush api來觸發上述commit動作,但無特殊需求,盡量不要手動觸發
對每個shard採用副本機制。保證寫入每個shard的數據不丟
前述translog只是保證數據不丟,為了其記錄的高效性,其本身並不維護復雜的數據結構。 實際的業務數據的會先寫入到in-memory buffer中,當調用refresh後,該buffer中的數據會被清空,轉而reopen一個segment,使得其數據對查詢可見。但這個segment本身也還是在內存中,如果系統宕機,數據依然會丟失。需要通過translog進行恢復
其實這跟lsm tree非常相似,新寫入內存的業務數據存放在內存的MemTable(對應es的in-memory buffer),它對應熱數據的寫入,當達到一定量並維護好數據結構後,將其轉成內存中的ImmutableMemTable(對應es的內存segment),它變得可查詢。
https://www.cnblogs.com/niceshot/p/14321372.html
https://ezlippi.com/blog/2018/04/elasticsearch-translog.html
https://stackoverflow.com/questions/19963406/refresh-vs-flush
https://qbox.io/blog/refresh-flush-operations-elasticsearch-guide/
https://www.elastic.co/guide/en/elasticsearch/reference/current/index-moles-translog.html#index-moles-translog-retention
https://www.elastic.co/guide/cn/elasticsearch/guide/current/translog.html
⑵ ES (elasticsearch)集群數據冷熱分離實現
導語
這種打標簽的操作可以通過滾動,重啟集群實例,因為涉及到重啟後的數據恢復問題,可能滾動重啟的時間會比較長(根據數據量大小和分片數量決定),可以通過如下的方式,增加數據恢復的最大並行度和數據恢復的最大帶寬進行調整,逐步調大到不影響集群業務性能為止。
1、ES 集群異構,機器硬體資源配置不一,有高性能 CPU 和 SSD 存儲集群,也有大容量的機械磁碟集群,比如我們的場景就是存放冷數據的集群,伺服器都是多年前買的一批滿配的 4T Dell R70,但是新擴容的熱節點機器均為 DELL 高性能 SSD 磁碟和 CPU 的 R740 機器。
2、對於時間型數據來說,一般是當前的數據,寫入和查詢較為集中,所以高性能的資源應該優先提供給這些數據使用。
3、集群的搜索和寫入性能,取決於最慢節點的性能。
1、ES 的索引已經按照天或者月的時間維度生成索引。
2、 歷史 數據相對於近期數據來說沒有高頻度的查詢需求。
本文實現策略:最新的天和月索引均為熱數據,其他索引根據查詢周期不同,調整為冷數據。當然業務不同策略不同,具體實現策略還是需要根據實際的業務場景來決定。
前置條件
需要修改 ES 集群配置文件,對節點進行打標簽操作,配置如下:
熱數據實例:
冷數據實例:
修改集群配置需要進行重啟實例生效
這種打標簽的操作可以通過滾動,重啟集群實例,因為涉及到重啟後的數據恢復問題,可能滾動重啟的時間會比較長(根據數據量大小和分片數量決定),可以通過如下的方式,增加數據恢復的最大並行度和數據恢復的最大帶寬進行調整,逐步調大到不影響集群業務性能為止。
設置數據恢復的最大並行度
設置數據恢復的最大帶寬
新增索引實現冷熱數據分離
集群滾動重啟完成之後,已經具備了冷熱數據分離的條件,那麼如何讓新增索引自動成為熱數據呢?
答案就是修改 ES 索引的模板,為 ES 索引打 tag,配置實例如下:
只要在索引模板中打了熱標簽的索引,就會在創建的時候自動分布在集群中實例打了熱標簽的節點上。
歷史 索引實現冷熱數據遷移
那麼 歷史 的 ES 數據如何讓其從熱節點遷移到冷節點呢?
答案就是,通過 api 修改 ES 索引的標簽,將其變更為冷標簽,這樣 ES 索引就會自動遷移到集群中打了冷標簽的實例上,配置如下:
實際生產中會將制定好的冷熱數據規則編寫成腳本,放到計劃任務中,來定時定點的運行,達到熱數據自動遷移為冷數據的目的。
熟悉 ES 的同學知道,JVM heap 分配不能超過 32GB,對於使用物理機部署 ES 的環境來說,一台機器的內存往往就動輒 192G 或者 256G,如果只跑一個 ES 實例,只能利用到 32G 的 heap,而且還無法充分發揮 CPU 和 IO 資源,這樣顯然是不經濟的。
因為我們常常會部署單機多實例的 ES 節點,在多實例配置中除了要隔離日誌和數據目錄之外,還需要增加以下兩個配置,不然一台物理機宕機,可能會因為多個副本存在一個 ES 物理機上面導致業務受到影響。
# 執行檢查以防止基於主機名和主機地址在單個主機上分配同一分片的多個實例。 默認為 false,表示默認情況下不執行檢查。 此設置僅適用於在同一台計算機上啟動多個節點的情況。這個我的理解是如果設置為 false,則同一個節點上多個實例可以存儲同一個 shard 的多個副本沒有容災作用了。
⑶ es可以一天存百萬條數據么
es不可以一天存百萬條數據。es一天最大的存儲量是90萬條數據,所以es不可以一天存百萬條數據。es全稱ElasticSearch,是一個基於Lucene的搜索伺服器。
⑷ ES中的索引生命周期管理
ILM :索引生命周期管理,即 Manage the index lifecycle 。
索引的生命周期有四個階段:
索引的生命周期策略指定了適用於哪些階段、在每個階段中執行哪些操作以及何時在各個階段之間進行轉換。
當索引滿足一定條件之後,將不再寫入數據,而是自動創建一個索引,所有的數據將寫入新的索引。
使用滾動索引能夠:
官方推薦使用 data stream 數據流來管理時間序列數據。每個數據流都需要一個 索引模板 ,其中包括:
數據流專為追加數據而設計,其中數據流名稱可用作操作(讀取、寫入、翻轉、收縮等)目標。如果需要更新數據,可以使用 索引別名 來管理時間序列數據。
ILM 會根據你的配置: 索引大小 、 文檔數量 、 所在階段 ,當滿足這些條件時,自動實現 rollover 。
要讓 ILM 管理索引,必須要在 index.lifecycle.name 索引設置中指定有效的策略。
要為滾動索引創建生命周期策略,你要創建該策略並把它加入到 索引模板 中。
可以通過 Kibana 管理頁面設置,也可以通過API設置。
可以通過 Kibana 管理頁面設置,也可以通過API設置。
如果要給滾動索引設置策略,需要手動創建第一個被該策略管理的索引,並指定為可寫索引。
索引的名稱必須跟索引模板里定義的模式相匹配,並且以數字結尾。
你可以在創建索引的時候指定一個策略,也可以直接將策略應用到一個已經存在的索引上通過 Kibana 管理或者更新設置的API。一旦你應用了策略, ILM 立即會開始管理該索引。
查看錯誤:
重新運行報錯的一步:
查看 ILM 狀態:
終止 ILM :
開啟 ILM :
設置 index.lifecycle.indexing_complete 為 true 。
舉個例子,如果你要改變一系列新索引的名稱,並保留之前根據你配置的策略產生的索引數據,你可以:
相關連接: https://www.elastic.co/guide/en/elasticsearch/reference/7.9/index-lifecycle-management.html
獲取最新文章,可關注博客地址: https://jenkinwang.github.io/
⑸ ES聚合分析一網打盡(二) 數據統計相關操作
Cardinality Aggregation
類似於mysql的distinct,不過精度達不到100%
計算總共有多少個製造商
控制數據的准確度
計算製造商和類別的所有搭配的個數
返回結果
如上所見,manufacturer類別為21,category類別為6,但是組合類別為64,驗證了製造商並不是做所有的類別的商品。
missing value
可以對不存在該field的值做統計,將所有不存在的作為一個單獨的處理
Extended Stats Aggregation
擴展統計結果,增加了平方和、方差、標准差、標准差區間(std_deviation_bounds)
通過sigma控制std_deviation_bounds返回幾個標准差間隔,默認為2,可以通過具體值為[avg+std_deviation*sigma,avg-std_deviation*sigma]
script、value script、missing與avg基本相同,簡單示例如下
script:
value script:
missing:
⑹ es加節點會平衡數據嗎
es加節點會平衡數據。一個集群cluster由一個或者多個節點組成,具有相同的cluster.name,協同工作,分項數據和負載。當有新的節點加入或者刪除了一個節點時,集群回感知到並能夠平衡數據。es集群會自動做負載均衡,如果我們現在加一個es節點到集群中來的話,es會按照一定的規則將部分shard分配到新的節點上去。
es主節點作用
主節點的主要職責是負責集群層面的相關操作,管理集群變更,如創建或刪除索引,跟蹤哪些節點是群集的一部分,並決定哪些分片分配給相關的節點。主節點也可以作為數據節點,但穩定的主節點對集群的健康是非常重要的,默認情況下任何一個集群中的節點都有可能被選為主節點。
⑺ ES筆記—基礎之數據類型篇
描述:檢測給定變數的數據類型,結果如下:
描述:只有一個值,即特殊的 undefined,表示變數未初始化。
包含 undefined 值的變數與尚未定義的變數還是不一樣的
令人困惑的是:對未初始化的變數執行 typeof 操作符會返回 undefined 值,而對未聲明的變數執行 typeof 操作符同樣也會返回 undefined 值。
描述:只有一個值,即特殊的值是 null。
從邏輯角度來看, null 值表示一個空對象指針,而這也正是使用 typeof 操作符檢測 null 值時會返回"object"的原因。
定義的變數准備在將來用於保存對象,那麼最好將該變數初始化為 null 而不是其他值。
實際上, undefined 值是派生自 null 值的,因此 ECMA-262 規定對它們的相等性測試要返回 true:
描述:該類型只有兩個字面值: true 和 false。
Boolean()函數,接受一個參數,將該值轉換成布爾值。事實上,很多情況都會隱式的調用該函數,比如判斷語句、循環語句、以及比較運算等等。
下表給出了各種數據類型及其對應的轉換規則。
描述:使用 IEEE754 格式來表示整數和浮點數值。 支持二進制(010101)、十進制(100)、十六進制(0XFFAA)
浮點數值,就是該數值中必須包含一個小數點,並且小數點後面必須至少有一位數字。
對於那些極大或極小的數值,可以用 e 表示法(即科學計數法)表示的浮點數值表示。
浮點數值的最高精度是 17 位小數,但在進行算術計算時其精確度遠遠不如整數。
isFinite(num)函數,接受一個數值作為參數,若該值在最小值與最大值之間,則返回布爾值true。
NaN(非數值),一個特殊數值,自身也不相等,用於表示一個本來要返回數值的操作數未返回數值的情況。
isNaN(param)函數,接受一個參數,該參數可以是任何數據類型,而函數會幫我們確定這個參數是否「不是數值」(會執行類型轉換),任何不能被轉換為數值的值都會返回布爾值true。
Number(param)函數,接受一個參數,將其轉為Number類型,規則如下:
parseInt(param1, param2)函數,接受兩個參數,第一個是轉為整數的值,第一個是基數類型(十進制、十六進制、二進制等等)。
parseFloat(param1, param2)函數,同上,區別是遇到第一個(.)會解析成小數點。
描述:用於表示由零或多個 16 位 Unicode 字元組成的字元序列,即字元串。
字元串可以由雙引號(")或單引號(')表示,因此下面兩種字元串的寫法都是有效的:
String 數據類型包含一些特殊的字元字面量,也叫轉義序列,用於表示非列印字元,或者具有其
他用途的字元。
ECMAScript 中的字元串是不可變的,也就是說,字元串一旦創建,它們的值就不能改變。要改變某個變數保存的字元串,首先要銷毀原來的字元串,然後再用另一個包含新值的字元串填充該變數。
把一個值轉換為一個字元串有兩種方式。第一種是使用幾乎每個值都有的 toString()方法。
通過傳遞基數, toString()可以輸出以二進制、八進制、十六進制,乃至其他任意有效進制格式表示的字元串值。
轉型函數 String(),這個函數能夠將任何類型的值轉換為字元串。 String()函數遵循下列轉換規則:
描述:對象其實就是一組數據和功能的集合。對象可以通過執行 new 操作符後跟要創建的對象類型的名稱來創建。而創建 Object 類型的實例並為其添加屬性和(或)方法,就可以創建自定義對象。
Object 類型是所有它的實例的基礎,Object 類型所具有的任何屬性和方法也同樣存在於更具體的對象中。
⑻ excel如何把一年的數據,以連續7天為周期,可以迅速取出每個周期的數據
打開excel,選中需要按周匯總的數據。如圖中數據需要按周匯總,表中選取周一到周日,需要統計各人每周的工作量。
excel如何按周統計匯總數據(任意周期/步長)
在插入選項卡中 選插入數據透視表,選中待分析待數據(這里選中表中3列)。
excel如何按周統計匯總數據(任意周期/步長)
3
設計數據透視表,在行中選擇日期(默認會出現按月匯總,需要刪掉)。
⑼ ES數據副本模型
ES裡面的每一個索引(Index)由多個shard組成,每一個shard有多個副本。這些副本被稱為"同步組"。當增加或者刪除文檔時,這些副本之間必須保持同步,以便讓所有副本都能包含相同的文檔。如果同步失敗,有可能會導致從一個副本讀的結果和從另外一個副本上讀的結果不一致。在shard的所有副本之間保持數據同步並同時對外提供一致的讀服務,我們這樣的處理過程稱之為「數據復制模型"。
ES的「數據復制模型」是一種「主-備」式的模型,這種模型在微軟的研究論文中有專門的介紹。基於這種模型,「同步組" 的所有副本中間會有一個專門的「Primary shard」角色,除了」Primary shard「之外的其餘副本都被稱為」replica shard「。 Primary shard是所有文檔的索引操作(文檔寫操作)的入口點, 其負責索引操作的校驗,確保這些索引操作是正確且合法的。當索引操作校驗通過後, primary shard會負責把索引操作復制並傳遞給replica shard,讓「同步組」裡面所有副本會進行相同的寫操作,進而保持所有副本上包含的文檔是一致的。
根據文檔的doc ID,ES首先會識別出來一個文檔的索引操作應該由哪個「同步組」來執行,這個「同步組」也就是存儲該文檔的目的容器。在「同步組"被識別出來後,該文檔的索引操作就被傳遞給「同步組」中的當前primary shard。Primary shard 負責校驗並傳遞同樣的文檔索引操作給其他的relica shard。因為replica shard有可能會因為各種可能原因造成離線,所以ES並不要求primary shard一定要復制操作給所有的replica shard。事實上,primary shard維護了一個可以接收索引操作的replica shard列表。這個列表被稱為「in-sync 副本列表」, 列表數據由master node來維護。 primary shard需要把文檔的索引操作復制傳遞給in-sync列表中每一個relica shard。
下面是primary shard處理的基本流程:
1.校驗操作請求,如果有結構類的錯誤(例如,object filed 卻存儲了一個數字),就拒絕此請求
2.如果校驗通過,本地先執行索引操作,例如索引或者刪除文檔。在本地操作過程中,也會做一些校驗,如果校驗失敗(例如keyword欄位的值太長,超過Lucene索引長度限制),也會拒絕請求。
3.轉發索引操作給當前in-sync裡面的所有replica shard。如果有多個replica shard,轉發操作會並行來執行
4.當所有replica 都成功執行了和本地一樣的索引操作,並且給primary shard 發回了成功確認,primary shard 就會發成功確認給客戶端。
在執行索引操作的過程中,每一步都可能會出現問題,比如磁碟壞了、node down掉了、node之間網路不通了、或者配置錯誤了等等,也許會導致索引操作在primary shard執行成功,在一個或者多個replica shard 卻執行失敗了。這些都是失敗的情況,雖然並不是經常出現,但是primary shard必須處理各種異常的情況。
一種場景是primary shard自己出問題了,在這種情況下 ,primary shard 所在的node會發消息給master node告知這種異常情況出現了 。索引操作會等待master node選出新的primary shard並把索引操作轉發給新的primary shard。當然這種等待不是無限期的,預設會等待1分鍾。當然master node也不是被動等待通知,master node會主動持續監測node的健康狀態,並根據健康狀態來決定是否選出新的primary shard。一種典型的情況就是當primary shard所在node 網路不通的時候,master node會認為 primary shard所在node可能down死掉了,就會選出新的primary shard,並更新in-sync 列表。
另外一種場景就是索引操作在primary shard上執行成功,但是在replica shard執行卻失敗了。當然被定義失敗的各種情況有很多,比如索引操作在replica上的確失敗了(比如replica shard所在硬碟出問題了)、primary shard和replica shard之間網路原因導致索引操作請求沒有到達replica shard、或者primary shard沒有收到replica shard的成功確認等等。這些復雜的情況導致的共同結果就是:primary shard 沒有收到in-sync列表裡面的所有replica shard的索引操作成功確認。為了解決這樣的問題,primary shard 會發消息給master node ,請求master node 刪除出問題的replica shard。當primary shard 收到master node 成功刪除問題replica shard的確認消息時,primary shard會發索引操作成功確認給客戶端。要注意的是,master node同時會通知另外一個node會構建一個新的replica shard,以保證系統處在一個健康狀態。
當轉發操作請求給replica shards的時候,primary shard會根據replica shard的響應情況來確認自己仍然是活躍的primary shard。某些情況下,因為網路原因,primary shard 也許已經被master node給降級了,但是primary shard還沒收到這種降級通知,所以會繼續處理進來的索引操作請求。當老的primary shard把索引操作請求轉發給其他replica shard時,replica shard發現請求來自於一個已經不合法的primary shard,就會拒絕請求並發響應給這個不合法的primary shard。當這個不合法的primary shard收到拒絕的響應時候,就會和master node聯系,獲取最新的狀態信息。在從master node發回的信息中,老的primary shard發現自己已經被「推翻統治」,就會把索引操作請求轉發給新的primary shard。
因為各種原因,所有的replica shards可能都會失效。在這種情況下,primary 會自己處理索引操作,而不會等待任何外部的確認(因為沒有replica shards了)。看起來似乎有點怪怪的,這主要是因為primary shards不能自己定義而只能依賴master nodereplica shards是否失敗。這就意味著,master node知道primary shards 是唯一的正常工作的副本。我們要保證master node不會把其他任何過期的shard 副本定義成新的primary,也保證發到primary shard的索引操作請求不會丟失。但是不可否認,primary shard上的物理硬體出問題了,肯定也會導致數據丟失。
ES中的讀可以是通過ID的輕量級查找,也可以是重量級的非常消耗CPU的復雜聚合計算。ES的「主-備」模型的優雅之處在於它保持所有副本的數據一致的,這樣「同步組」中的任何單個副本都可以對外提供讀服務。
當集群中的一個node收到讀請求時,該node負責轉發讀請求給相關的shards、聚合shards的響應並把響應發送給客戶端。我們這樣的node稱之為本次請求的協調node。協調node上的基本讀的處理流程如下:
1.根據請求,解析出來要轉發的「同步組」。多數搜索需要查詢多個「同步組",每個"同步組」是可能包含了搜索結果的一部分數據。但是如果是根據id檢索一個文檔,可以根據routing演算法,計算出一個包含該文檔的「同步組」。
2.從每一個要轉發「同步組」裡面選出一個活躍的shard。這個shard可以是primary,也可以是replica。預設情況下,ES使用round robin的策略在「同步組"裡面選擇shard。把請求轉發給選出來的shards
3.合並各個shard的響應並發響應給客戶端。要注意的是,如果根據id檢索文檔,因為轉發shard是一個,所以就不存在合並的過程了。
當一個shard沒有成功執行讀請求、轉發響應給協調node時,協調node會從該shard所在的」同步組「中選擇另外一個shard,然後把讀請求轉發給它。重復性的「失敗-選擇」可能會導致最後「同步組"裡面沒有shard 可用。在某些情況下,ES更青睞快速響應,而不是搜索結果的完整性,例如_search。即使缺失了部分查詢結果,ES也希望能快速響應給客戶端,而不是等待問題解決(搜索結果是否完整會在響應頭有體現)。
基本讀、基本寫流程定義了ES作為一個系統,是如何支持讀和寫操作的。但是實踐中,讀寫操作可能是同時並發執行的,所以讀、寫流程是相互影響的。此模型有一些優雅的點,如下:
1.高效讀
正常情況下,每次讀請求操作只會被「同步組」裡面shard執行一次。在異常情況下,有可能會出現「同步組」裡面的多個shard執行了多次讀操作,例如協調node在shard沒有響應的情況下,會重新選擇另外一個shard,再次發出讀請求操作。
2.未確認讀
因為primary shard首先在本地執行索引操作,然後才轉發索引操作給replica shard。在索引操作完全確認之前,primary shard執行了一個讀請求操作,就能讀到還沒確認的數據。
3.預設兩個副本
在一些基於投票的系統中,要實現容錯,有可能最少需要的副本數是3. 但是基於ES的模型,僅維護兩個副本,就可以實現容錯。
失敗的時候,可能會出現下面的情況:
1.單個shard有可能會讓索引操作執行的更慢
因為primary shard需要等待in-sync裡面所有replica shard執行完並響應才能發確認給客戶端,所以任何一個處理慢的shard都會拉低本次索引操作的處理速度。這是為了實現前面提到的高效讀而付出的成本代價。當然,單個慢的shard也會拉低路由到此shard上的讀請求操作處理速度,進而影響那次search(因為search是由多個shard的讀請求組成)。
2.臟讀
一個孤立的primary shard可能會暴露將不會被確認的但是已經被寫到本地的數據。這是因為孤立的primary只有在發索引操作請求給replica或者跟master node時才能知道自己已經被孤立了。因為數據已經被寫入本地了,如果此時有讀請求過來,讀請求就可能會讀到剛剛已經寫進去的數據。為了降低這種風險,primary 會定期(預設每1秒)ping master node,如果發現已經找不到master了,就會拒絕索引操作。