《專家觀察 | 林尚泉:“小米結構化存儲系統及融合云平臺的設計與實踐”》要點:
本文介紹了專家觀察 | 林尚泉:“小米結構化存儲系統及融合云平臺的設計與實踐”,希望對您有用。如果有疑問,可以聯系我們。
由工業和信息化部指導,中國信息通信研究院主辦,業界知名組織云計算開源產業聯盟(OSCAR)承辦的2017全球云計算開源大會于4月19日-20日在北京國家會議中心順利召開.本文為本屆大會嘉賓分享的大會演講速記內容,敬請瀏覽.
嘉賓介紹:林尚泉
公司職務:小米科技開發工程師
大會演講速記
我是來自小米的云平臺的工程師林尚泉,下面我來給大家介紹一下小米結構化存儲系統以及融合云平臺的設計和實踐.
這個是今天的演講大綱,比較簡單.
結構化存儲是一個分布式NoSQL數據庫服務,對標AWS DynamoDB,我們的目標是要把它做成一個彈性可擴展、高可用、低延時、穩定可靠的數據庫服務.
首先介紹一下項目的背景,HBase在小米用的比較好,但是用著就發現了一些問題,包括一些認證和環境配置比較復雜,還有多語言支持的不太好等等,到后面我們還要支持生態鏈公司的一些結構化數據的存儲需求,所以我們需要在公網里面提供訪問.
HBase在公網直接提供訪問也不大方便,所以我們就做了這套服務,它是基于HBase的,對外提供無狀態的公網訪問,簡化了客戶的配置,支持多種主流語言的SDK,因為一個集群供多個用戶一起使用,所以需要支持多租戶的功能,包括訪問控制和流量控制,并且我們還在原生的HBase上做了一些功能擴展,因為原生的HBase是只支持按主鍵索引,沒有二級索引,也沒有數據類型的概念.
我們在上面做了一些功能擴展,包括數據類型、二級索引、stream、還有軟刪除和數據冷備等等這些功能.現在這個服務不僅支持了小米內部業務,包括MIUI、小米網等等,還支持了十幾家生態鏈公司的結構化存儲的業務.
看一下應用規模,我們在北京天津美國新加坡都有相應的集群,機器規模一百多臺,支持的業務數二十幾個,數據量一百多TB還有數千億行,看起來不是很多,但是前段時間統計,現在的數據量是以每兩個月翻倍的在增長,現在單集群的QPS大概是幾十萬級別.
這是結構化存儲一個典型的部署,分為主備結構、底層是Zookeeper/HDFS/HBase等系統,主集群使用ssd盤,備集群使用hdd盤,在HBase上面那層我們封了一層libsds,主要對HBase做了一些功能擴展,在libsds庫上,我們是直接對外提供服務的ThriftServer,使用Thrift 的RPC框架,支持多種語言的SDK,還有流量控制等功能.主集群是直接供用戶的線上訪問,備集群除了充當主集群的熱備之外還會給用戶跑一些離線作業.
下面首先介紹一下libsds庫,主要在HBase上做了以下的功能擴展,一個是規范化的數據模型,還有一些數據類型的支持,還有局部二級索引以及全局二級索引,下面分別介紹一下幾個功能,規范化的數據模型意思是在libsds那層,表是有schema的,
這個圖就是對應HBase的一個KeyValue,還支持了多種數據類型,包括各種基本類型和集合類型.
我們采用了HBase8201和SQLite編碼方案對RowKey進行編碼,保證跟原來的數據類型的順序是一致的,還可以支持逆序.
局部二級索引,這種二級索引是實體組內部的索引,索引數據是和原數據存在同一張表上的不同Column Family,我們實現了個基于正則表達式的前綴分割策略,確認保證同一個實體組鍵里面的數據是在同一個Hbase region上面,并且不能被split的,這兩個圖剛才介紹過,一個是原數據的,我們建了局部索引,除了寫原數據還會加一行索引數據,就是下面這個圖.
RowKey的排列是實體組鍵到索引鍵再到主鍵,可以看到原數據和索引數據的實體組鍵是一樣的,然后根據我們實現的前綴分割策略就可以保證原數據和索引數據在同一臺機器上,就可以比較簡單的去保證這兩個數據寫入的原子性.
我們是通過HBase Coprocessor來實現了indexObserver,也就是客戶發送Put或Delete請求后我們會攔截這個操作,然后再計算要上出來索引,再把它放到原來的數據里,最后再同一臺機器上一起落地,就可以保證原數據和索引數據的原子性.
還支持了多種類型的局部二級索引,其中包括EAGER類型,也就是更新刪除時同時刪除失效索引,是適合寫少讀多的場景,而LAZY索引是讀取判斷索引有效性,更新時不做額外操作,適合寫多讀少,還有IMMUTABLE是需要用戶保證數據的只讀性,就適合以只讀數據的一次性寫入,讀寫都不需要做額外的判斷,這種比較高效.
還支持了全局二級索引,和局部二級索引不一樣的地方是它的索引數據是單獨的存在一個HBase表里,我們采用了谷歌的percolator方案實現的,我們在hbase上實現了這套算法叫Themis,這個已經開源,這個算法可以保證跨表更新的原子性,Chronos為全局單調遞增時間戳.
全局二級索引數據對應的HBase的KeyValue跟局部二級索引不大一樣,是以索引鍵排在最前面,再到實體組鍵和主鍵,我們對局部二級索引和全局二級索引做了一下性能對比.這個圖是對某一張表建立了一個全局二級索引和局部二級索引,然后再寫,紅色是局部二級索引,藍色是全局二級索引
可以看到因為全局二級索引會涉及到分布式的事務,可以看到性能損耗比較大,局部二級索引比它有好個四倍左右,而讀的話同樣局部二級索引好個兩倍.
另外我們實現了stream功能,如果開了這個功能,用戶對表的修改除了在原來的數據CF上寫,還會封裝成一條消息在另一個CF里再寫一份,另外起一個MR job定期掃那個額外的CF,再把那個消息打到流式消息隊列里,用戶就會拿到流式消息隊列來消費這些數據.
其中包括兩種類型,一個是RECORD IMAGE,得到的消息是這行數據被修改以后最后的視圖,用戶拿著這種類型的消息就可以做一些最終一致的增量備份,另外是MUTATE LOG,就是每一行的修改日志,這種類型再結合一個定期打快照的功能,就可以把指定某一個表恢復到歷史任意一個時間點.
我們采用了facebook 的Thrift框架,對外屏蔽了一些復雜的配置,由于是使用了Thrift框架,很方便的可以支持多種語言的SDK.
ThriftServer主要對外提供一個無公網的http服務,對外屏蔽了HBase,用戶只需要拿到一個域名就可以直接訪問,簡化了認證和配置,支持了多種語言的SDK,多租戶包括訪問控制和流量控制.
ACL功能,我們是在HBase那里存了一份元數據表,它的格式是某一個表有哪些ACL信息,并且每一個節點會對元數據做本地緩存,假如有用戶發了一個修改ACL的請求,這個ThriftServer不僅要更新元數據表,還要在Zookeeper修改一個節點,因為所有的ThriftServer節點都監聽了Zookeeper的那個節點,就會收到一個通知進行更新,通過訪問元數據表更新本地緩存.
流量控制,SDS支持用戶每一個表進行預設置的讀寫配額,設置讀寫配額的時候SDS會檢查一下集群的能力,集群的能力是根據我們的一些性能測試得到的,做限流的時候是基于token bucket算法進行限流的,集群能力使用到80%的時候會提醒我們進行集群擴容.還實現了軟刪除的功能,因為要保證數據安全,
軟刪除就是用戶發一個刪表請求,要刪除一張表的時候,SDS后臺會先對這個表打一個快照,然后再去刪除這個表,這個時候會存一堆snapshot文件,在經過TTL 的時間后刪除,在刪除之前用戶可以通過restoretable通過clonesnapshot把表恢復出來.
而數據冷備我們實現了一個工具,是可以把HBase一些snapshot推到AWS S3,需要的時候再拉下來.結構化數據存儲系統暫時介紹到這里.
我們來看一下融合云平臺.這個是小米融合云平臺的控制臺的首頁,可以看到它除了剛才介紹的結構化存儲之外,還包括的文件存儲,團隊管理,流式消息隊列和深度學習等等的一些服務,我們的愿景是把它打造成一個閉環的集計算和存儲于一體的云服務平臺,更好的給小米的用戶和生態鏈公司進行服務.然后用戶要訪問上面的任何一個服務都要通過團隊管理,自己去申請一些team等等.
這個是我們融合云平臺的架構圖,中間主要的服務是Zookeeper、HDFS、HBase等等服務,在上面有SDS、FDS、EMQ,還有其他服務等等,外圍有一些公用的組件就是部署服務,我們為了方便我們集群的管理還有一些升級部署,我們開發了一套公用的部署系統,所有的部署都是通過融合云的部署系統.
還有一套公用的報警系統,并且用戶訪問的時候都要通過團隊認證管理提供一個統一的認證入口.下面來簡單介紹一下三模塊,融合云通過一個CloudManager進行了團隊認證管理,用戶可以對CloudManager發一些團隊管理請求,添加或刪除team等,這個模塊就會把這些信息存在MySql,比如用戶要訪問我們的結構化存儲或者文件存儲的服務,如果前端過來的請求,前端首先會把這個請求轉發到CloudManager這個模塊,CloudManager經過驗證以后會從MySQL讀出團隊信息,再放到http header里面再轉發到后端service.
如果通過SDK直接訪問service,要通過簽名進行認證才的,具體是service調CloudManager的RestfulAPI,這個Restful API會返回用戶的團隊信息,service再把這個解密,算一個簽名出來,再做對比.
融合云的部署系統是使用了我們小米發的Minos2.0,1.0已經開源,2.0實際上是在1.0的基礎上增加了一些認證授權的模塊,主要包括Tank管理服務器,集群每一個節點都用supervisor監控,提供了工具來給用戶做集群的升級等等,這些操作都需要經過CloudManager進行認證,主要是為了保證只有集群的owner或者對這個集群有相應的權限的用戶才可以進行相應的操作.
提供了一套統一的監控告警系統,小米其實在運維團隊也開發了一套open-falcon的告警系統,為什么自己還要再搞一套?因為那套在公網訪問是不太方便,因為我們這一套系統需要供很多的用戶一起用,需要數據隔離,并且那套是使用RRD來存儲數據,不保存原始數據,我們的很多用戶是有這個需求的.更重要的一個原因就是我們需要為用戶來監控其他服務的資源上面的一些指標提供一個統一的入口,例如用戶用了結構化存儲還有文件存儲等等,這些服務上面的資源的指標都可以通過我們統一的監控告警系統來進行統一的監控.
它的主要架構是這樣的,用戶是可以直接往我們的監控告警系統的ThriftServer發請求,包括兩種,一個是推送指標或者查詢指標,這種請求在ThriftServer直接轉發到OpenTSDB,再對這些指標進行保存,OpenTSDB支持數據的下采樣和聚合.
另外一種就是對指標監控要定制一些告警規則,用戶可以把這個告警規則的請求發到service,ThriftServer把這個規則存到SDS,告警用戶模塊是對用戶每一個指標都要過一遍,根據用戶定制的告警規則看有沒有觸發告警,因為需要有一些指標的內存狀態,所以就需要保證同一個指標必須發到模塊的同一個節點上.
另外還有一個Collector模塊,把我們所有小米融合云里面的子服務的指標,就是用戶關注的指標統一收集然后推送到我們的監控告警系統給用戶做統一監控.我今天的分享就到這里,謝謝.
文章來自微信公眾號:云計算開源產業聯盟
轉載請注明本頁網址:
http://www.snjht.com/jiaocheng/4165.html