天天看點

叢集管理和分布式任務 Apache helix

這個題目寫的有點大,但是我一直想寫一個這方面文章,雖然我沒系統學過分布式系統理論,但是接觸了這麼多分布式系統之後,隐約感覺這些系統有很多共通之處。現在如果我讓你開發一個分布式系統,準确點叫分布式task系統,比如從kafka訂閱資料,然後寫到hdfs,歸檔。注意不光是能支援某一個topic,不隻是固定的partition數目,你該怎麼寫?

這個需求,其實可以使用jstorm來做,寫一些spout就可以了,或者弄個2層結構,spout-bolt,spout拉資料交給bolt,bolt寫到hdfs。jstorm本身就是一個分布式計算系統,确切地說是一個流計算系統,任務管理,消息傳輸,負載均衡,容災等,都由jstorm架構幫你完成。

那麼,如果讓你寫一個分布式存儲系統呢?分布式存儲比分布式計算可能要難一點,因為涉及到更多的資料一緻性問題,像hdfs,hbase,kafka其實都屬于分布式存儲系統,每個系統有自己的存儲特點和格式,對于hbase和kafka這種更接近資料庫類型的系統來講,寫資料意味着把資料交給你管理,每一條都要盡可能保證資料不丢,那麼基本流程可能是先寫wal,然後寫到記憶體,記憶體再異步刷到磁盤。對于kv存儲系統,磁盤中儲存資料的仍然是檔案,但是這個檔案可不簡單,并不是随便寫的檔案,通常都有自己的格式,這種格式一方面是為了友善存儲,提高存儲效率,另一方面這種檔案格式更多地是為了你搜尋或者随機檢索友善,比如b tree或者LSM等資料結構。之是以寫wal是為了容災考慮。

那有人說些wal是持久化,為什麼不直接寫資料庫檔案呢,原因很簡單,就是寫wal快,比寫資料庫檔案要快,為了提高寫性能考慮。雖然光寫記憶體更快,但是沒有持久化這些資料掉電之後,資料丢失怎麼辦。是以wal又叫redo log,即順序寫進去,寫入資料庫出現問題的時候,會從這裡找到重新做。

分布式資料庫,存儲系統之是以分布式,就是把資料分塊,分region,或者分partition存儲,每個partition又可以多個副本,同時副本又有主從。一般主副本接受讀寫請求,然後将請求轉發到其它副本,由這個主副本協調讀寫操作。

資料副本在全叢集要盡量均勻分布,一方面是為了防止存儲傾斜,有些機器容量都滿了,有些還很空閑,比如hdfs。另一方面又是為了讀寫考慮,要防止讀寫熱點,畢竟單點的qps,tps是有限制的,同時也為了容災考慮。基于均分分布原理,這些系統又有了rebalance的概念。

分布式存儲和分布式計算,其實有很多相同的地方,分布式存儲管理的單元是資料塊,partition,region等資料顆粒的副本,讀寫等,而分布式任務,管理的是一個作業的task,并發的task,task的狀态等。同樣存在task 負載均衡的問題,即排程的問題。

分布式系統一般都有一個協調服務,做分布式鎖,狀态管理,甚至心跳等。zookeeper基本上在大資料領域,用得比較多,同時也比較可靠。

說到這裡,不得不提一下Apache helix,這個東西基本上幫我實作了自己的想法,即使用zookeeper做一個分布式系統架構,利用這個架構,既可以開發分布式task,也可以做分布式存儲,它幫我們完成了分布式管理中的絕大多數工作。

從今天開始,我會用幾篇文章,講解一下apache helix的原理,架構以及實作細節。

繼續閱讀