目錄
創(chuàng)新互聯(lián)是專業(yè)的思南網站建設公司,思南接單;提供成都網站設計、成都做網站,網頁設計,網站設計,建網站,PHP網站建設等專業(yè)做網站服務;采用PHP框架,可快速的進行思南網站開發(fā)網頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網站,專業(yè)的做網站團隊,希望更多企業(yè)前來合作!倒排索引
ES實現Master選舉
ES更新和刪除文檔的過程
寫入數據的底層原理
搜索的底層原理
并發(fā)情況下ES保證讀寫一致
分片介紹
延遲寫策略–近實時搜索–fresh
ES 在數據量很大的情況下(數十億級別)如何提高查詢效率
es深度分頁
es 生產集群的部署架構是什么?每個索引的數據量大概有多少?每個索引大概有多少個分片?
單詞ID:記錄每個單詞的單詞編號;
單詞:對應的單詞;
文檔頻率:代表文檔集合中有多少個文檔包含某個單詞
倒排列表:包含單詞ID及其他必要信息
DocId:單詞出現的文檔id
TF:單詞在某個文檔中出現的次數
POS:單詞在文檔中出現的位置
以單詞“加盟”為例,其單詞編號為6,文檔頻率為3,代表整個文檔集合中有三個文檔包含這個單詞,對應的倒排列表為{(2;1;<4>),(3;1;<7>),(5;1;<5>)},含義是在文檔2,3,5出現過這個單詞,在每個文檔的出現過1次,單詞“加盟”在第一個文檔的POS是4,即文檔的第四個單詞是“加盟”,其他的類似。
Elasticsearch的選主是ZenDiscovery模塊負責的,主要包含Ping(節(jié)點之間通過這個RPC來發(fā)現彼此)和Unicast(單播模塊包含一個主機列表以控制哪些節(jié)點需要ping通)這兩部分;
對所有可以成為master的節(jié)點(node.master: true)根據nodeId字典排序,每次選舉每個節(jié)點都把自己所知道節(jié)點排一次序,然后選出第一個(第0位)節(jié)點,暫且認為它是master節(jié)點。
如果對某個節(jié)點的投票數達到一定的值(可以成為master節(jié)點數n/2+1)并且該節(jié)點自己也選舉自己,那這個節(jié)點就是master。否則重新選舉一直到滿足上述條件。
補充:master節(jié)點的職責主要包括集群、節(jié)點和索引的管理,不負責文檔級別的管理;data節(jié)點可以關閉http功能。
刪除和更新也都是寫操作,但是Elasticsearch中的文檔是不可變的,因此不能被刪除或者改動以展示其變更;
磁盤上的每個段都有一個相應的.del文件。當刪除請求發(fā)送后,文檔并沒有真的被刪除,而是在.del文件中被標記為刪除。該文檔依然能匹配查詢,但是會在結果中被過濾掉。當段合并時,在.del文件中被標記為刪除的文檔將不會被寫入新段。
在新的文檔被創(chuàng)建時,Elasticsearch會為該文檔指定一個版本號,當執(zhí)行更新時,舊版本的文檔在.del文件中被標記為刪除,新版本的文檔被索引到一個新段。舊版本的文檔依然能匹配查詢,但是會在結果中被過濾掉。
1.數據先寫入到buffer里面,在buffer里面的數據時搜索不到的,同時將數據寫入到translog日志文件之中
2.如果buffer快滿了,或是一段時間之后,就會將buffer數據refresh到一個新的OS cache之中,然后每隔1秒,就會將OS cache的數據寫入到segment file之中,但是如果每一秒鐘沒有新的數據到buffer之中,就會創(chuàng)建一個新的空的segment file,只要buffer中的數據被refresh到OS cache之中,就代表這個數據可以被搜索到了。當然可以通過restful api 和Java api,手動的執(zhí)行一次refresh操作,就是手動的將buffer中的數據刷入到OS cache之中,讓數據立馬搜索到,只要數據被輸入到OS cache之中,buffer的內容就會被清空了。同時進行的是,數據到shard之后,就會將數據寫入到translog之中,每隔5秒將translog之中的數據持久化到磁盤之中
3.重復以上的操作,每次一條數據寫入buffer,同時會寫入一條日志到translog日志文件之中去,這個translog文件會不斷的變大,當達到一定的程度之后,就會觸發(fā)commit操作。
4.將一個commit point寫入到磁盤文件,里面標識著這個commit point 對應的所有segment file
5.強行將OS cache 之中的數據都fsync到磁盤文件中去。
解釋:translog的作用:在執(zhí)行commit之前,所有的而數據都是停留在buffer或OS cache之中,無論buffer或OS cache都是內存,一旦這臺機器死了,內存的數據就會丟失,所以需要將數據對應的操作寫入一個專門的日志問價之中,一旦機器出現宕機,再次重啟的時候,es會主動的讀取translog之中的日志文件的數據,恢復到內存buffer和OS cache之中。
將現有的translog文件進行清空,然后在重新啟動一個translog,此時commit就算是成功了,默認的是每隔30分鐘進行一次commit,但是如果translog的文件過大,也會觸發(fā)commit,整個commit過程就叫做一個flush操作,我們也可以通過ES API,手動執(zhí)行flush操作,手動將OS cache 的數據fsync到磁盤上面去,記錄一個commit point,清空translog文件
補充:其實translog的數據也是先寫入到OS cache之中的,默認每隔5秒之中將數據刷新到硬盤中去,也就是說,可能有5秒的數據僅僅停留在buffer或者translog文件的OS cache中,如果此時機器掛了,會丟失5秒的數據,但是這樣的性能比較好,我們也可以將每次的操作都必須是直接fsync到磁盤,但是性能會比較差。
如果時刪除操作,commit的時候會產生一個.del文件,里面講某個doc標記為delete狀態(tài),那么搜索的時候,會根據.del文件的狀態(tài),就知道那個文件被刪除了。
如果時更新操作,就是講原來的doc標識為delete狀態(tài),然后重新寫入一條數據即可。
buffer每次更新一次,就會產生一個segment file 文件,所以在默認情況之下,就會產生很多的segment file 文件,將會定期執(zhí)行merge操作
每次merge的時候,就會將多個segment file 文件進行合并為一個,同時將標記為delete的文件進行刪除,然后將新的segment file 文件寫入到磁盤,這里會寫一個commit point,標識所有的新的segment file,然后打開新的segment file供搜索使用。
總之,segment的四個核心概念,refresh,flush,translog、merge
查詢過程大體上分為查詢和取回這兩個階段,廣播查詢請求到所有相關分片,并將它們的響應整合成全局排序后的結果集合,這個結果集合會返回給客戶端。
查詢階段
當一個節(jié)點接收到一個搜索請求,這這個節(jié)點就會變成協(xié)調節(jié)點,第一步就是將廣播請求到搜索的每一個節(jié)點的分片拷貝,查詢請求可以被某一個主分片或某一個副分片處理,協(xié)調節(jié)點將在之后的請求中輪訓所有的分片拷貝來分攤負載。
每一個分片將會在本地構建一個優(yōu)先級隊列,如果客戶端要求返回結果排序中從from 名開始的數量為size的結果集,每一個節(jié)點都會產生一個from+size大小的結果集,因此優(yōu)先級隊列的大小也就是from+size,分片僅僅是返回一個輕量級的結果給協(xié)調節(jié)點,包括結果級中的每一個文檔的ID和進行排序所需要的信息。
協(xié)調節(jié)點將會將所有的結果進行匯總,并進行全局排序,最總得到排序結果。
取值階段
查詢過程得到的排序結果,標記處哪些文檔是符合要求的,此時仍然需要獲取這些文檔返回給客戶端
協(xié)調節(jié)點會確定實際需要的返回的文檔,并向含有該文檔的分片發(fā)送get請求,分片獲取的文檔返回給協(xié)調節(jié)點,協(xié)調節(jié)點將結果返回給客戶端。
可以通過版本號使用樂觀并發(fā)控制,以確保新版本不會被舊版本覆蓋,由應用層來處理具體的沖突;
另外對于寫操作,一致性級別支持quorum/one/all,默認為quorum,即只有當大多數分片可用時才允許寫操作。但即使大多數可用,也可能存在因為網絡等原因導致寫入副本失敗,這樣該副本被認為故障,分片將會在一個不同的節(jié)點上重建。
對于讀操作,可以設置replication為sync(默認),這使得操作在主分片和副本分片都完成后才會返回;如果設置replication為async時,也可以通過設置搜索請求參數_preference為primary來查詢主分片,確保文檔是最新版本。
分片可以是主分片或者是復制分片。
主分片
在一個多分片的索引中寫入數據時,通過路由來確定具體寫入哪一個分片中,大致路由過程如下:
shard = hash(routing) % number_of_primary_shards
routing 是一個可變值,默認是文檔的 _id ,也可以設置成一個自定義的值。routing 通過 hash 函數生成一個數字,然后這個數字再除以 number_of_primary_shards (主分片的數量)后得到余數 。這個在 0 到 number_of_primary_shards 之間的余數,就是所尋求的文檔所在分片的位置。
這解釋了為什么要在創(chuàng)建索引的時候就確定好主分片的數量并且永遠不會改變這個數量:因為如果數量變化了,那么所有之前路由的值都會無效,文檔也再也找不到了。
復制分片
復制分片只是主分片的一個副本,它可以防止硬件故障導致的數據丟失,同時可以提供讀請求,比如搜索或者從別的 shard 取回文檔。當索引創(chuàng)建完成的時候,主分片的數量就固定了,但是復制分片的數量可以隨時調整,根據需求擴大或者縮小規(guī)模
分片本身就是一個完整的搜索引擎,它可以使用單一節(jié)點的所有資源。主分片或者復制分片都可以處理讀請求——搜索或文檔檢索,所以數據的冗余越多,能處理的搜索吞吐量就越大。
分片的存儲
ES 集群中每個節(jié)點通過路由都知道集群中的文檔的存放位置,所以每個節(jié)點都有處理讀寫請求的能力。
在一個寫請求被發(fā)送到某個節(jié)點后,該節(jié)點即為協(xié)調節(jié)點,協(xié)調節(jié)點會根據路由公式計算出需要寫到哪個分片上,再將請求轉發(fā)到該分片的主分片節(jié)點上。假設 shard = hash(routing) % 4 = 0 ,則過程大致如下:
客戶端向 ES1節(jié)點(協(xié)調節(jié)點)發(fā)送寫請求,通過路由計算公式得到值為0,則當前數據應被寫到主分片 S0 上。
ES1 節(jié)點將請求轉發(fā)到 S0 主分片所在的節(jié)點 ES3,ES3 接受請求并寫入到磁盤。
并發(fā)將數據復制到兩個副本分片 R0 上,其中通過樂觀并發(fā)控制數據的沖突。一旦所有的副本分片都報告成功,則節(jié)點 ES3 將向協(xié)調節(jié)點報告成功,協(xié)調節(jié)點向客戶端報告成功。
為了提升寫的性能,ES 沒有每新增一條數據就增加一個段到磁盤上,而是采用延遲寫的策略。
每當有新增的數據時,就將其先寫入到內存中,在內存和磁盤之間是文件系統(tǒng)緩存,當達到默認的時間(1秒鐘)或者內存的數據達到一定量時,會觸發(fā)一次刷新(Refresh),將內存中的數據生成到一個新的段上并緩存到文件緩存系統(tǒng) 上,稍后再被刷新到磁盤中并生成提交點。
這里的內存使用的是ES的JVM內存,而文件緩存系統(tǒng)使用的是操作系統(tǒng)的內存。新的數據會繼續(xù)的被寫入內存,但內存中的數據并不是以段的形式存儲的,因此不能提供檢索功能。由內存刷新到文件緩存系統(tǒng)的時候會生成了新的段,并將段打開以供搜索使用,而不需要等到被刷新到磁盤。
性能優(yōu)化的殺手锏——filesystem cache
你往 es 里寫的數據,實際上都寫到磁盤文件里去了,查詢的時候,操作系統(tǒng)會將磁盤文件里的數據自動緩存到 filesystem cache 里面去。
es 的搜索引擎嚴重依賴于底層的 filesystem cache ,你如果給 filesystem cache 更多的內存,盡量讓內存可以容納所有的 idx segment file 索引數據文件,那么你搜索的時候就基本都是走內存的,性能會非常高。
性能差距究竟可以有多大?我們之前很多的測試和壓測,如果走磁盤一般肯定上秒,搜索性能絕對是秒級別的,1 秒、5 秒、10 秒。但如果是走 filesystem cache ,是走純內存的,那么一般來說性能比走磁盤要高一個數量級,基本上就是毫秒級的,從幾毫秒到幾百毫秒不等。
數據預熱
對于那些你覺得比較熱的、經常會有人訪問的數據,最好做一個專門的緩存預熱子系統(tǒng),就是對熱數據每隔一段時間,就提前訪問一下,讓數據進入 filesystem cache 里面去。這樣下次別人訪問的時候,性能一定會好很多。
冷熱分離
es 可以做類似于 mysql 的水平拆分,就是說將大量的訪問很少、頻率很低的數據,單獨寫一個索引,然后將訪問很頻繁的熱數據單獨寫一個索引。最好是將冷數據寫入一個索引中,然后熱數據寫入另外一個索引中,這樣可以確保熱數據在被預熱之后,盡量都讓他們留在 filesystem os cache 里,別讓冷數據給沖刷掉。
傳統(tǒng)方式(from&size)
需要實時獲取頂部的部分文檔。例如查詢最新的訂單。
Scroll
用于非實時查詢
需要全部文檔,例如導出全部數據
Search After
用于實時查詢
需要做到深度分頁
es 生產集群我們部署了 5 臺機器,每臺機器是 6 核 64G 的,集群總內存是 320G。
我們 es 集群的日增量數據大概是 2000 萬條,每天日增量數據大概是 500MB,每月增量數據大概是 6 億,15G。目前系統(tǒng)已經運行了幾個月,現在 es 集群里數據總量大概是 100G 左右。
目前線上有 5 個索引,每個索引的數據量大概是 20G,所以這個數據量之內,我們每個索引分配的是 8 個 shard,比默認的 5 個 shard 多了 3 個shard。
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧