一招徹底幫你搞定HashMap源碼,項目實戰

ES 集群架構演進之路

1、初始階段

訂單中心ES初始階段如一張白紙,架設方案基本沒有,很多配置都是保持集群默認配置。整個集群部署在集團的彈性云上,ES集群的節點以及機器部署都比較混亂。同時按照集群維度來看,一個ES集群會有單點問題,顯然對于訂單中心業務來說也是不被允許的。

2、集群隔離階段

和很多業務一樣,ES集群采用的混布的方式。但由于訂單中心ES存儲的是線上訂單數據,偶爾會發生混布集群搶占系統大量資源,導致整個訂單中心ES服務異常。

顯然任何影響到訂單查詢穩定性的情況都是無法容忍的,所以針對于這個情況,先是對訂單中心ES所在的彈性云,遷出那些系統資源搶占很高的集群節點,ES集群狀況稍有好轉。但隨著集群數據不斷增加,彈性云配置已經不太能滿足ES集群,且為了完全的物理隔離,最終干脆將訂單中心ES集群部署到高配置的物理機上,ES集群性能又得到提升。

3、節點副本調優階段

ES的性能跟硬件資源有很大關系,當ES集群單獨部署到物理機器上時,集群內部的節點并不是獨占整臺物理機資源,在集群運行的時候同一物理機上的節點仍會出現資源搶占的問題。所以在這種情況下,為了讓ES單個節點能夠使用最大程度的機器資源,采用每個ES節點部署在單獨一臺物理機上方式。

但緊接著,問題又來了,如果單個節點出現瓶頸了呢?我們應該怎么再優化呢?

ES查詢的原理,當請求打到某號分片的時候,如果沒有指定分片類型(Preference參數)查詢,請求會負載到對應分片號的各個節點上。而集群默認副本配置是一主一副,針對此情況,我們想到了擴容副本的方式,由默認的一主一副變為一主二副,同時增加相應物理機。

訂單中心ES集群架設示意圖

如圖,整個架設方式通過VIP來負載均衡外部請求:

整個集群有一套主分片,二套副分片(一主二副),從網關節點轉發過來的請求,會在打到數據節點之前通過輪詢的方式進行均衡。集群增加一套副本并擴容機器的方式,增加了集群吞吐量,從而提升了整個集群查詢性能。

下圖為訂單中心ES集群各階段性能示意圖,直觀地展示了各階段優化后ES集群性能的顯著提升:

當然分片數量和分片副本數量并不是越多越好,在此階段,我們對選擇適當的分片數量做了進一步探索。分片數可以理解為MySQL中的分庫分表,而當前訂單中心ES查詢主要分為兩類:單ID查詢以及分頁查詢。

分片數越大,集群橫向擴容規模也更大,根據分片路由的單ID查詢吞吐量也能大大提升,但聚合的分頁查詢性能則將降低;分片數越小,集群橫向擴容規模也更小,單ID的查詢性能也會下降,但分頁查詢的性能將會提升。

所以如何均衡分片數量和現有查詢業務,我們做了很多次調整壓測,最終選擇了集群性能較好的分片數。

4、主從集群調整階段

到此,訂單中心的ES集群已經初具規模,但由于訂單中心業務時效性要求高,對ES查詢穩定性要求也高,如果集群中有節點發生異常,查詢服務會受到影響,從而影響到整個訂單生產流程。很明顯這種異常情況是致命的,所以為了應對這種情況,我們初步設想是增加一個備用集群,當主集群發生異常時,可以實時的將查詢流量降級到備用集群。

那備用集群應該怎么來搭?主備之間數據如何同步?備用集群應該存儲什么樣的數據?

考慮到ES集群暫時沒有很好的主備方案,同時為了更好地控制ES數據寫入,我們采用業務雙寫的方式來搭設主備集群。每次業務操作需要寫入ES數據時,同步寫入主集群數據,然后異步寫入備集群數據。同時由于大部分ES查詢的流量都來源于近幾天的訂單,且訂單中心數據庫數據已有一套歸檔機制,將指定天數之前已經關閉的訂單轉移到歷史訂單庫。

所以歸檔機制中增加刪除備集群文檔的邏輯,讓新搭建的備集群存儲的訂單數據與訂單中心線上數據庫中的數據量保持一致。同時使用ZK在查詢服務中做了流量控制開關,保證查詢流量能夠實時降級到備集群。在此,訂單中心主從集群完成,ES查詢服務穩定性大大提升。

5、現今:實時互備雙集群階段

期間由于主集群ES版本是較低的1.7,而現今ES穩定版本都已經迭代到6.x,新版本的ES不僅性能方面優化很大,更提供了一些新的好用的功能,所以我們對主集群進行了一次版本升級,直接從原來的1.7升級到6.x版本。

集群升級的過程繁瑣而漫長,不但需要保證線上業務無任何影響,平滑無感知升級,同時由于ES集群暫不支持從1.7到6.x跨越多個版本的數據遷移,所以需要通過重建索引的方式來升級主集群,具體升級過程就不在此贅述了。

主集群升級的時候必不可免地會發生不可用的情況,但對于訂單中心ES查詢服務,這種情況是不允許的。所以在升級的階段中,備集群暫時頂上充當主集群,來支撐所有的線上ES查詢,保證升級過程不影響正常線上服務。同時針對于線上業務,我們對兩個集群做了重新的規劃定義,承擔的線上查詢流量也做了重新的劃分。

備集群存儲的是線上近幾天的熱點數據,數據規模遠小于主集群,大約是主集群文檔數的十分之一。集群數據量小,在相同的集群部署規模下,備集群的性能要優于主集群。

然而在線上真實場景中,線上大部分查詢流量也來源于熱點數據,所以用備集群來承載這些熱點數據的查詢,而備集群也慢慢演變成一個熱數據集群。之前的主集群存儲的是全量數據,用該集群來支撐剩余較小部分的查詢流量,這部分查詢主要是需要搜索全量訂單的特殊場景查詢以及訂單中心系統內部查詢等,而主集群也慢慢演變成一個冷數據集群。

同時備集群增加一鍵降級到主集群的功能,兩個集群地位同等重要,但都可以各自降級到另一個集群。雙寫策略也優化為:假設有AB集群,正常同步方式寫主(A集群)異步方式寫備(B集群)。A集群發生異常時,同步寫B集群(主),異步寫A集群(備)。

ES 訂單數據的同步方案

MySQL數據同步到ES中,大致總結可以分為兩種方案:

  • 方案1:監聽MySQL的Binlog,分析Binlog將數據同步到ES集群中。
  • 方案2:直接通過ES API將數據寫入到ES集群中。

考慮到訂單系統ES服務的業務特殊性,對于訂單數據的實時性較高,顯然監聽Binlog的方式相當于異步同步,有可能會產生較大的延時性。且方案1實質上跟方案2類似,但又引入了新的系統,維護成本也增高。所以訂單中心ES采用了直接通過ES API寫入訂單數據的方式,該方式簡潔靈活,能夠很好的滿足訂單中心數據同步到ES的需求。

由于ES訂單數據的同步采用的是在業務中寫入的方式,當新建或更新文檔發生異常時,如果重試勢必會影響業務正常操作的響應時間。

所以每次業務操作只更新一次ES,如果發生錯誤或者異常,在數據庫中插入一條補救任務,有Worker任務會實時地掃這些數據,以數據庫訂單數據為基準來再次更新ES數據。通過此種補償機制,來保證ES數據與數據庫訂單數據的最終一致性。

遇到的一些坑

1、實時性要求高的查詢走DB

推薦閱讀:ES 幾十億數據檢索 3 秒返回。

對于ES寫入機制的有了解的同學可能會知道,新增的文檔會被收集到Indexing Buffer,然后寫入到文件系統緩存中,到了文件系統緩存中就可以像其他的文件一樣被索引到。

然而默認情況文檔從Indexing Buffer到文件系統緩存(即Refresh操作)是每秒分片自動刷新,所以這就是我們說ES是近實時搜索而非實時的原因:文檔的變化并不是立即對搜索可見,但會在一秒之內變為可見。

當前訂單系統ES采用的是默認Refresh配置,故對于那些訂單數據實時性比較高的業務,直接走數據庫查詢,保證數據的準確性。

2、避免深分頁查詢

ES集群的分頁查詢支持from和size參數,查詢的時候,每個分片必須構造一個長度為from+size的優先隊列,然后回傳到網關節點,網關節點再對這些優先隊列進行排序找到正確的size個文檔。

假設在一個有6個主分片的索引中,from為10000,size為10,每個分片必須產生10010個結果,在網關節點中匯聚合并60060個結果,最終找到符合要求的10個文檔。

由此可見,當from足夠大的時候,就算不發生OOM,也會影響到CPU和帶寬等,從而影響到整個集群的性能。所以應該避免深分頁查詢,盡量不去使用。

3、FieldData與Doc Values

FieldData:

線上查詢出現偶爾超時的情況,通過調試查詢語句,定位到是跟排序有關系。排序在es1.x版本使用的是FieldData結構,FieldData占用的是JVM Heap內存,JVM內存是有限,對于FieldData Cache會設定一個閾值。

如果空間不足時,使用最久未使用(LRU)算法移除FieldData,同時加載新的FieldData Cache,加載的過程需要消耗系統資源,且耗時很大。所以導致這個查詢的響應時間暴漲,甚至影響整個集群的性能。針對這種問題,解決方式是采用Doc Values。

Doc Values:

Doc Values是一種列式的數據存儲結構,跟FieldData很類似,但其存儲位置是在Lucene文件中,即不會占用JVM Heap。隨著ES版本的迭代,Doc Values比FieldData更加穩定,Doc Values在2.x起為默認設置。

最后

給大家送上一份福利,領取方式:戳這里免費下載

Java架構進階面試及知識點文檔筆記

這份文檔共498頁,其中包括Java集合,并發編程,JVM,Dubbo,Redis,Spring全家桶,MySQL,Kafka等面試解析及知識點整理

image

Java分布式高級面試問題解析文檔

其中都是包括分布式的面試問題解析,內容有分布式消息隊列,Redis緩存,分庫分表,微服務架構,分布式高可用,讀寫分離等等!

image

互聯網Java程序員面試必備問題解析及文檔學習筆記

image

Java架構進階視頻解析合集

[外鏈圖片轉存中…(img-le8kcp1M-1626256905464)]

互聯網Java程序員面試必備問題解析及文檔學習筆記

[外鏈圖片轉存中…(img-woJ1dwmN-1626256905464)]

Java架構進階視頻解析合集

image

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385626.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385626.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385626.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【信號】信號集、sigprocmask、sigpending

一、信號集操作函數 內核通過讀取未決信號集來判斷信號是否應被處理。信號屏蔽字mask可以影響未決信號集。而我們可以在用程序自定義set來改變mask,來達到屏蔽指定信號目的。 sigset_t set; // typedef unsigned long sig…

一招讓你拿下seata分布式事務框架,看這篇文章準沒錯!

第一階段:架構師筑基必備技能 我覺得,但凡是個成年人應該都清楚扎實的基本功對自己的工作幫助有多重要。從各大招聘網站的招聘要求來看,第一條都明確說明需要扎實的Java基礎。因此,一般筆試以及面試的第一輪,對基礎的…

函數signal、sigaction

二、函數sigaction 修改信號處理動作(通常在Linux用來注冊一個信號的捕捉函數) #inlcude<signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 參數&#xff1a; act&am…

一文了解OOM及解決方案,你還看不明白?

InnoDB總體結構 首先我們來看官網的一張圖(圖片來源于MySQL官網)&#xff1a; 從上圖中可以看出其主要分為兩部分結構&#xff0c;一部分為內存中的結構(上圖左邊)&#xff0c;一部分為磁盤中的結構(上圖右邊) 內存結構 InnoDB內存中的結構主要分為&#xff1a;Buffer Pool,…

信號 09 | 函數pause

函數pause 調用該函數可以造成進程主動掛起&#xff0c;等待信號喚醒&#xff0c;調用該系統調用的進程處于阻塞狀態(主動放棄CPU)直到有信號遞達將其喚醒。 將進程置為可中斷睡眠狀態。然后 它調用schedule()&#xff0c;使linux進程調度器找到另一個進程來運行。pause使調用…

一文搞懂JVM架構和運行時數據區,全網最新

1.Java基礎面試知識點 Java中和equals和hashCode的區別int、char、long各占多少字節數int與integer的區別探探對Java多態的理解String、StringBuffer、StringBuilder區別什么是內部類&#xff1f;內部類的作用抽象類和接口區別抽象類的意義抽象類與接口的應用場景抽象類是否可…

一條正確的Java職業生涯規劃,幫你突破瓶頸

面試題模塊介紹&#xff1a; 一、Java 基礎 JDK 和 JRE 有什么區別&#xff1f; 和 equals 的區別是什么&#xff1f;兩個對象的 hashCode()相同&#xff0c;則 equals()也一定為 true&#xff0c;對嗎&#xff1f;final 在 java 中有什么作用&#xff1f;java 中的 Math.roun…

【線程】線程基本函數

一、pthread_self函數 功能&#xff1a;獲取線程ID。 pthread_t pthread_self(void); 線程ID&#xff1a;pthread_t類型&#xff0c;本質&#xff1a;在Linux為無符號整數(%lu)&#xff0c;其他系統可能是結構體實現線程ID是進程內部識別標志。&#xff08;兩個進程間&#…

一條正確的Java職業生涯規劃,順利通過阿里Java崗面試

珍藏版&#xff08;1&#xff09;——Mybatis入門 1.什么是MyBatis 2.為什么我們要用Mybatis? 3.Mybatis快速入門 3.1 導入開發包 3.2準備測試工作 3.3 創建mybatis配置文件 3.4 編寫工具類測試是否獲取到連接 3.5 創建實體與映射關系文件 3.6 編寫DAO 4.Mybatis工作…

線程控制 12 | 線程屬性

本節作為指引性介紹&#xff0c;linux下線程的屬性是可以根據實際項目需要&#xff0c;進行設置&#xff0c;之前我們討論的線程都是采用線程的默認屬性&#xff0c;默認屬性已經可以解決絕大部分開發遇到的問題。如我們對程序的性能提出更高的要求那么需要設置線程屬性&#x…

一次違反常規的Java大廠面試經歷,系列教學

第一部分 Java相關以及答案 答案 第二部分算法跟編程 第三部分html&JavaScript&ajax部分 答案 第四部分Javaweb部分 答案 第五部分數據庫部分 答案 第六部分XML部分 答案 第七部分.流行的框架與新技術 答案 第八、九部分.軟件工程與設計模式以及j2ee部分 最后 筆者…

函數perror、strerror

perror函數 函數原型&#xff1a; #include<stdio.h> void perror(const char *msg); 測試代碼&#xff1a; #include<unistd.h> #include<errno.h> #include<stdio.h>int main() {int ret;ret close(10);if(ret -1) {perror("close error…

一次違反常規的Java大廠面試經歷,重難點整理

目錄 Kafka的基本介紹Kafka的設計原理分析Kafka數據傳輸的事務特點Kafka消息存儲格式副本&#xff08;replication&#xff09;策略Kafka消息分組&#xff0c;消息消費原理Kafak順序寫入與數據讀取消費者&#xff08;讀取數據&#xff09; Kafka的基本介紹 Kafka是最初由Lin…

一步搞定你疑惑的數據結構與算法系列,原理+實戰講解

螞蟻金服一面&#xff1a; 下午杭州的電話&#xff0c;問有沒有空&#xff0c;果斷有空&#xff0c;雖然感覺略顯緊張&#xff0c;有點懵逼。 面試的題目&#xff1a; HashMap和Hashtable的區別實現一個保證迭代順序的HashMap說一說排序算法&#xff0c;穩定性&#xff0c;復…

互斥量(互斥鎖)

一、互斥量mutex Linux提供一把互斥鎖mutex(也稱之為互斥量)每個線程在對資源操作前都嘗試先加鎖&#xff0c;成功加鎖才能操作&#xff0c;操作結束后解鎖。資源還是共享的&#xff0c;線程間也還是競爭的&#xff0c;但通過鎖將資源的訪問變為互斥操作&#xff0c;而后與時間…

一眼就能看懂的Java自學手冊,終局之戰

珍藏版&#xff08;1&#xff09;——Mybatis入門 1.什么是MyBatis 2.為什么我們要用Mybatis? 3.Mybatis快速入門 3.1 導入開發包 3.2準備測試工作 3.3 創建mybatis配置文件 3.4 編寫工具類測試是否獲取到連接 3.5 創建實體與映射關系文件 3.6 編寫DAO 4.Mybatis工作…

Centos 6.x

1. centos升級gcc教程&#xff1a;鏈接 2. 虛擬機中的Centos聯通網絡&#xff1a;鏈接 3. 虛擬機安裝Centos7系統教程&#xff1a;鏈接

Java虛擬機學習集錦是我攢來的,帶你碾壓面試官!

1. 一致性&#xff08;Consistency&#xff09; 一致性&#xff08;Consistency&#xff09;是指多副本&#xff08;Replications&#xff09;問題中的數據一致性。可以分為強一致性、順序一致性與弱一致性。 1.1 強一致性&#xff08;Strict Consistency&#xff09; 也稱為…

Java虛擬機學習集錦是我攢來的,看這篇文章準沒錯!

一面 介紹一下自己 問項目經歷, 聊"數據同步" 接著聊上了 K8S 的項目 有沒有什么鉆研得比較深得技術&#xff1f;&#xff08;大佬&#xff1a;kubernetes, golang, prometheus, java&#xff09; kubernetes 的架構是怎么樣的? 這個問題很大&#xff0c;拆成 …

文件描述符、函數open和openat

文件描述符 pcb&#xff1a;結構體一個進程有一個文件描述符&#xff1a;1024文件描述符&#xff1a;尋找磁盤文件函數open和openat 函數原型&#xff1a; include<sys/stst.h> #include<fcntl.h>int open(const char *pathname, int flags); int open(const ch…