架構學習筆記系列一

cdh0805010118發表於2018-06-22

學習永不止步

一致性hash

我是兩次遇到hash一致性相關問題:

  1. 需要設計電單車的智慧鎖平臺,如果線上有百萬個鎖接入鎖平臺,考慮到高可用,一個tcp服務存在單點問題;則需要設計支援百萬量級的實時線上管理平臺,所以需要在接入層考慮如何把鎖全部均衡的接入到各個鎖服務平臺,同時如果一個服務掛掉,則怎樣使鎖離線重連抖動最小,則考慮了在nginx層引入hash一致性;
  2. Amazon的Dynamo去中心化的高鍵值儲存系統,依賴hash一致性演算法。

我看了第一篇,寫得很不錯

一致性hash演算法

白話解析:一致性hash演算法

總結:
1.通過環的引入和hash計算節點值和目標值的對映,解決雪崩問題;
2.引入中間層虛擬節點列表,使得節點上儲存的資料儘量平衡

網際網路技術架構

微博架構

看了微博架構的全部文章,微博資料庫那些事兒:3個變遷階段背後的設計思想 一文,兩個點自己看明白了

1. 微博博文儲存面臨巨大挑戰。
    (1). 首先,我們將索引同內容進行了拆分,因為索引所需儲存空間較少,而內容儲存所需空間較大, 且這兩者的使用需求也不盡相同,訪問頻次也會不同,需要區別對待。
    (2). 然後,分別對索引和內容採用先 hash,再按照時間維度拆分的方式進行水平拆分,儘量保障每張 表的容量在可控範圍之內,以保證查詢的效能指標。
    (3). 最後,業務先通過索引獲得實際所需內容的 id,再通過內容庫獲得實際的內容,並通過部署 memcached 來加速整個過程,雖然看上去步驟變多,但實際效果完全可以滿足業務需求。

    後面作者也回答了這個問題。
    (1). 針對博文時間強相關,內容資料量大的特點。把內容和索引垂直拆分成兩類表,一類儲存索引和博文ID,一類儲存博文ID和博文內容資料;
    (2). 我們針對索引表的時間強相關特性,我們用redis做快取,以及索引表按時間特性水平拆分,DATETIME(now-expire)則進行歸檔;同時博文表也進行mod24值(1024:表示博文拆分表的總數量), 這1024個表也具有時間特性,整體超過某個時間,也進行歸檔。
    (3). 通過快取加速索引過程。

2. 印象最深的一次資料庫服務故障能否回憶並說幾點注意事項?
    一同事不小心執行了drop table命令,導致線上服務受影響。所以做了一個刪表需求流程, 具體如下:
    (1). 執行 rename table 操作,將 table rename 成 table—will-drop。 
    (2). 等待 24 小時之後再執行 drop 操作。

阿里架構

2017阿里技術精選 有兩篇文章能看懂一些知識:

1. 《阿里下一代資料庫技術:把資料庫裝入容器不再是神話》寫得能看懂一些.
    文章針對mysql的innodb儲存引擎讀寫比較均衡,底層是B+Tree,文章中有一句話寫得相當到位,“或者動不動 DBA 去找業務開發方 說你的儲存空間不夠了,佔用很多空間,能不能刪一些資料或者把這些資料匯入到成本 更低的儲存引擎裡。我們經常這麼幹,這裡說的直白一點,我相信大家都這麼幹過。”,我也遇到過,所以阿里團隊想利用rocksdb的壓縮率高的特性,rocksdb儲存引擎是使用的LSMTree(Log based Structure Merge Tree),相比較mysql的innodb引擎,特點是寫快、且順序寫入。利用rocksdb壓縮率高的特性,使得可以儲存時間更長的資料,減少冷熱資料的使用者感知。 我有一點非常好奇,怎麼把這兩種引擎相結合並同時使用呢?

    資料庫實現彈性排程,以前覺得純粹扯淡,因為資料庫是資源儲存,所以一般不會移動。但是作者提到了實現彈性排程的兩個前提:1. 資料庫容器化;2. 計算和儲存分離;對於後者,計算和儲存之間的網路通訊必須是可接受的
2.  《如何打造千萬級Feed流系統?阿里資料庫技術解讀》中提到的PG資料庫(PostgreSQL),說它的讀寫併發量大,所以我查了它的特性和應用場景。特性:穩定、效能好,(查詢、型別、功能和外掛)豐富;應用場景:LBS、OLAP實時線上分析。
3. 《深度解讀|阿里雲新一代關係型資料庫PolarDB》,這篇文章介紹了PolarDB優秀之處,在於使用了現代非常多的技術特性,包括:分散式架構、資料庫高可用、網路協議、儲存塊裝置、檔案系統和虛擬化。PolarDB把計算和儲存完全分離,計算上建立索引、快取等特性;儲存使用塊裝置儲存,並且採用業界流行的3節點備份,防止資料丟失。塊裝置節點同步通過改造後的並行raft演算法實現AP和最終一致性,計算和儲存通過RDMA協議使用高速網路進行通訊。並且100%相容mysql標準,同時讀寫速度比mysql快6倍
4. 《接下時序資料庫儲存的挑戰書,阿里HiTSDB誕生了》, 這篇文章我收穫頗多,寫得非常好。因為我瞭解一點點InfluxDB、Prometheus和小米的Open-falcon,這篇文章提到了時序資料庫的定位:插值、降精度和聚合。其中,插值:某個時間點數值缺失,這需要插值;降精度:取樣打點,每秒1個,則呈現一年的資料,呈現所有點不可能,則把精度提高到1天的時間維度;聚合:需要做一些報表統計;第二個收穫是由淺入深的講解了為什麼時間序列用RDBMS不合適,這就提到了B+ Tree、LSM Tree和SSTable。B+ Tree的特點是隨機讀、隨機寫。時間複雜度為LOG(N); 同時葉子節點是連結串列結構。文章提到如果每秒300W打點寫入,這種索引樹無法抗住,因為索引樹再磁碟上、同時隨機寫入速度慢;所以希望時序資料儲存是順序寫入,這種寫入時間複雜度是O(1), 這樣速度大大提高,同時為了減少磁碟IO,最好是記憶體索引;又因為索引過大,不可能全部儲存在記憶體中,所以希望部分所以在記憶體中計算,所以想引入LSM Tree(Log Based Structure Merge Tree),  若干個小索引在記憶體中,同時是順序寫。

降精度特別難優化,因為降精度是在時間維度上做的,首先要把時間序列維度拿出來然後再中間插值,而實際上SQL是不知道這件事情的,SQL是按點來操作的。所以RDBMS不適合做時序資料庫的儲存和計算。

所以引入基於LSM Tree的MyRocks儲存引擎,順序寫入效能每秒20W點。但是這個方案的缺點:
    1. tag重複儲存,儲存開銷大,壓縮率不高;
    2. MyRocks強調事務,內部鎖實現拖慢了簡單寫的效能;
    3. 由於多個索引降低了寫入速度,最終系統的寫效能大概5~6W點每秒;
    4. others

Elastic Search的時序儲存方案。我沒看明白,對ELK不熟悉。

基於列式儲存的時序儲存方案。產品有:Druid、inforbright。前者好像小米在使用。行式儲存的update和insert操作方便、快,但是select慢,需要遍歷所有索引或者儲存內容;列式儲存的列式存放在一起的,所以索引的建立非常方便、然後select方便快速,但是update和insert比較麻煩, 同時後者壓縮率非常高。 作者說列式儲存有些時序場景不太適合,因為列式儲存是把匯入的資料累積到一定程度,才會把一個包把它固定到磁碟上,但是時序資料如果查詢以前的老資料,這意味著要查該時間段內的每一個包。

基於流引擎的時序儲存方案。JStorm、Flink等,流引擎可以解決多維計算,它是個計算引擎,缺點:沒有辦法實時計算。

InfluxDB和OpenTSDB時序資料庫最大特點,能把時間線提取出來,它的思路是事先做一系列的標籤、先找到時間序列,在這個時間序列上再找到對應的點。時序資料是按照一個時間長度分片壓縮儲存在一起,這樣搜尋時不再需要搜尋全部時間片段,搜尋範圍比較小。

最後作者選了OpenTSDB,HBase作為資料儲存,可以保證它把一個小時的資料放到一個行裡,這樣壓縮率比較高,可以做到每行資料20個位元組左右,也就是說一個metric所對應一小時儲存的位元組資料可以壓縮到20位元組左右。
同時文章也指出OpenTSDB的劣勢:
    1. 時間序列的Meta Data以快取方式在所有的TSD節點上存在,資料量太多的時候,記憶體壓力大;
    2. RowScan做非字首查詢時,會掃過很多毋庸的RowKey;
    3. 每行只儲存一小時的打點資料,qualifier存在額外的開銷;
    4. 單點聚合,容易出現聚合效能瓶頸
    5. 壓縮率仍然不理想
後面團隊根據這些缺點,在OpenTSDB的基礎上,引入倒排索引、Facebook Gorilla高壓縮比演算法和分散式聚合引擎,推出HiTSDB時序資料庫,這個部分我理解比較困難。

有關B+ Tree、LSM Tree和SSTable的介紹,有一篇文章寫得很不錯,推薦:B+Tree VS. LSM

有關行式儲存和列式儲存,推薦文章介紹:一分鐘理解列式儲存

OpenTSDB推薦一篇好文:OpenTSDB通俗易懂的介紹, 重點在OpenTSDB的儲存方案上。

相關文章