技術乾貨|融雲高性能消息數據存儲引擎的設計解析!

2018年10月22日,QCon全球軟件開發大會上海站成功落下帷幕。融雲聯合創始人兼首席架構師李淼再次受邀出席大會,並進行《高性能消息數據存儲引擎的設計解析》的主題演講,爲參會者深入剖析了融雲首次公開的最新技術研究成果“數據存儲引擎設計”。

作爲互聯網通信雲獨角獸的融雲每天要存儲的消息量高達數十億條,多年來融雲一直致力於消息存儲的優化,從原型階段的MySQL到後來的Redis、LevelDB,融雲不停的探索實踐。隨着業務的發展和數據的持續增長,融雲需要一個既能滿足業務需求,又能滿足大業務量的消息數據存儲,因此融雲研究院在2017年決定研發可以滿足自身業務特點的高性能消息存儲服務(內部代號RCTSDB),並使用全新設計的數據存儲引擎。

以下內容摘自李淼演講實錄。

融雲消息存儲歷程
首先是融雲在開始時的原型產品驗證階段,大概是在2013年初創階段,爲了驗證融雲的即時通信業務模式,此時的消息都是存儲在MySQL中,其特點是開發簡單,可以滿足各種產品需求。

在原型驗證通過後,正式上線前融雲將離線消息遷移到了Redis中以滿足性能需求,而歷史消息則繼續保存在MySQL中。

融雲經過一年多業務飛速的發展,要存儲的消息越來越多,而Redis集羣也幾乎每1-2個月就要進行擴容。當時處於對成本的考量,融雲決定採用相對低廉的磁盤存儲方案。此時融雲做了很多選型,最終決定採用基於levelDB作爲存儲引擎並自研DB。但是當時的由於levelDB數據歸併消耗高,數據淘汰困難等問題,運行兩個月後替換了原來的Redis存儲方案。

目前融雲的線上情況是Redis存儲離線消息,levelDB存儲歷史消息,而融雲的業務也相對進入了平穩期,Redis最近一次擴容是在2018年的5、6月份,根據業務增速情況可以支持到2018年底。

存儲架構相對穩定,爲什麼融雲還要啓動自研存儲項目呢?
 滿足一些複雜的業務場景需求
基於目前的存儲方案,一些需求實現起來非常困難,而這些需求都是來自客戶,從而制約產品的演進,所以融雲急需一個替代方案;
 降低整體的成本投入
融雲線上的Redis集羣成本是所有設備投入的一半以上,對於存儲的優化,顯然是可以持續降低公司運營成本;
 簡化部署模型
對於Redis的部署不是很複雜,但是融雲除了公有云的業務以外還有私有云項目,繼續使用Redis對客戶側的運維部署成本就會變的很高;
 源碼可控
之前融雲使用過很多的開源產品,當這些產品不能滿足業務需求時,融雲又急需某些特性時,這就需要和作者聯繫,但是大部分時候作者都不能及時響應或者根本不在其計劃內,而這時融雲只能等或者自己改,自己改的又回饋不了開源產品的主幹上,或者當開源產品更新沒辦法合併,這樣就迫使融雲必須啓動自研存儲項目。

即時通信類產品,自研存儲需具備哪些特點?
 快速的數據淘汰能力
數據淘汰的過程不能對系統產生任何的影響;
 避免數據合併
相對於levelDB來講,當寫入很多操作的時候levelDB的數據合併經常會發生CPU報警,導致寫入查詢響應速度慢等情況;
 讀寫性能要求高
至少不能比融雲現有使用的Redis速度慢;
 開發使用靈活
在融雲存儲引擎設計過程中,不僅只是存儲數據,而是當作開發框架來進行設計的,在各操作點上都提供Hook,從而能夠滿足各種業務場景需求。

站在前人的肩膀上遠眺
融雲在存儲引擎設計過程中借鑑很多已有的成熟方案,並將這些方案進行優化整合,最終完成了自有的引擎設計。下面將羅列一些方案,並向前人致敬。
 數據寫入採用WAL模式
數據在寫入內存時同時記錄,當服務宕機或重啓的時候可以根據這些恢復內存數據。這些都是按照磁盤順序寫入,可以變相的提高存儲引擎性能。一般主流的數據庫都會採用這種模式完成數據寫入。
 借鑑InfluxDB中的LSM數據結構
LSM數據結構是目前一些新興數據庫採用的數據結構,像LevelDB、RocksDB、HBase、Cassandra等。即時通訊消息具備時序數據的特點,而InfluxDB更是時序數據庫中的佼佼者,融雲對InfulxDB做了一些改造,使其更適合存儲一些時序數據
 借鑑whiskey 的 K / V 分離存儲設計
whiskey 是2016年發表的一篇論文,主要解決了LSM中大數量寫入後頻繁數據歸併的問題,在LSM這種數據結構中,數據的Key和Value值都是要寫入內存的,當數據到達內存設定的閾值時進行歸檔處理。對於value值較大的數據來說,這個歸檔就會變得特變頻繁,而whiskey的理念是將value單獨保存至另外的文件位置,LSM結構內保存的是Key以及這個Value所在文件的偏移量和長度,以此來降低歸檔頻。按照論文上的介紹,歸檔頻率可以降低一個數量級。
 借鑑MyISAM的存儲文件設計
在文件設計這塊融雲一共經歷四版改動,最終殊途同歸。融雲發現Mysql中MyISAM引擎的文件設計很有類似之處。

融雲消息存儲引擎設計

  1. 存儲邏輯劃分
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!

  2. 存儲文件規劃
    關於Table文件分爲三種文件進行組織存儲:
     xxx.data 數據存儲文件;
     xxx.index 數據索引文件;
     xxx.info table信息文件。
    文件並沒有按照Table文件進行劃分存儲,是按照序號字段進行排序,爲的是在設計過程中解決主從複製,提高便捷性。

  3. 數據寫入邏輯
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!

  4. 數據文件設計
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!
  5. 日誌文件設計
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!

  6. 索引文件設計
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!
  7. 信息文件設計
    技術乾貨|融雲高性能消息數據存儲引擎的設計解析!

內存優化
 在M_block中融雲重度依賴跳錶這種數據結構,融雲的存儲引擎是用java寫的,主要考慮是後面可移植的問題。起初融雲採用了java裏面內置的ConcurrentSkipList,但是其內存消耗很高,這個主要是java的中對象內存分配的規則導致的。所以融雲重寫了SkipList,放棄了java中的對象模式。重新造的輪子其內存消耗只有原始 1/4,同時也犧牲了一些東西,例如:刪除跳錶內的數據時,其刪除的數據所佔的內存無法釋放,但是對於即時通信消息來講基本上不存在刪除的場景,同樣一些時序數據也極少存在刪除場景;
 索引數據融雲進行了一系列緊湊處理。優化後40億級的索引數據,只消耗內存400MB。放棄java對象模式,直接採用byte數值的方式進行數據組織;
 對很多的對象又做了一些細節處理,想辦法把Java本身的一些內存模型給抹平掉,通過這種方式來降低內存利用率;
 最後融雲做了LIRS的緩存機制。

存儲優化
 索引數據前綴壓縮,降低磁盤的寫入量;
 數值數據採用VarInt編碼;
 業務數據QuickLZ壓縮,平衡了存儲及CPU的使用率;
 數據寫入採用雙循環可變長度Buffer,使數據寫入過程中是沒有直接操作的,有效降低延遲的產生;
 重複數據引用寫入,該優化對於即時通信場景有顯著成效。

服務端架構
該架構主要包含Broker,以及一些數據的分組Master、Slaver,這些數據是根據ZooKeeper進行管理,同時向Broker進行彙報。在Broker上會開設不同的端口去設置各種不同的協議。最後是DB manger,主要是用於管理引擎的各種數據查詢的插件,就像前文提到的該引擎除了是用於數據存儲外還是開發框架,程序員在架構上可以靈活按照熟悉的開發語言去直接操作這些數據。

技術乾貨|融雲高性能消息數據存儲引擎的設計解析!
數據存儲引擎項目將在年底開源
李淼在會上表示,爲了促進產業內的技術交流,融雲會在未來兩個月時間對數據存儲引擎項目進行開源,開源前除了對引擎做一些優化以外,還會補充一些相關的文檔,同時爲了方便開發者集成參考還會對代碼增加一些註釋。項目開源後意味着融雲是國內首家將自研的消息存儲引擎開源的雲通信廠商,也正在爲中國的開源環境貢獻自己應盡的力量。

關於融雲:融雲,安全、可靠的全球互聯網通信雲服務商,向開發者和企業提供即時通訊和實時音視頻通信雲服務,據艾瑞等權威數據顯示,融雲即時通訊雲業務市場份額穩居第一。目前,已有數十萬互聯網用戶及上千家企業級用戶通過融雲實現了場景化溝通,並從中獲益,包括招商銀行、工商銀行、交通銀行、民生銀行、中國移動、四川航空、CCTV微視、中聯重科、58 趕集、大河報業、新東方、陸金所、易車網、豬八戒、蔚來汽車、得到APP、荔枝 FM、汽車之家、優酷來瘋、攜程愛玩、聚力視頻、百姓網等知名企業及應用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章