你們好,我是阿里雲數據庫產品事業部的玄陵,真名郭超。node
本次的分享大概分三個部分:Cassandra雲數據庫簡介、Cassandra雲數據庫特性以及Q&A。數據庫
咱們先了解一下Cassandra雲數據庫在阿里雲上的部署和架構。首先這個架構主要反映了三個方向:安全
接下來咱們深刻了解一下單個DC和集羣的狀況。網絡
除此以外,咱們其它的架構和Apache Cassandra幾乎是同樣的。多線程
接下來咱們介紹一下Cassandra雲數據庫的特性:架構
即將上線的服務包括:併發
接下來,咱們介紹一些咱們在功能上作的優化。因爲時間關係,咱們只能重點介紹一部分功能優化。運維
第一點,咱們作了一些自動化運維手段。性能
這個事情的背景是因爲Cassandra是一個去中心化的數據庫,社區建議用戶作repair,目的主要是保證Cassandra三個或多個副本之間的一致性。Repair可以把副本上的數據作一個修復或者補齊,保證副本的數據是一致的。Repair是必需要作的,然而在咱們的使用場景中,repair會引入一些問題:優化
在介紹咱們的改進措施以前,我先來大概介紹一下repair的機制:在圖中咱們能夠看到三個副本ABC,第一步repair會在三個副本上構建全量的Merkle Tree,第二步會比較ABC副本的Merkle Tree之間數據的差別,第三步再經過一個相似於Steaming的過程把數據補齊。
咱們改進的目的是什麼呢?
咱們但願咱們repair的過程是自動化的,不須要引入人工干預。這樣當咱們雲上的集羣愈來愈多或者用戶擴容縮容的時候,咱們不須要人工的干預,這樣能夠下降雲上運維的複雜性,大大釋放了人力資源。第二個目的是但願整個repair的過程是一個開銷較小的過程,這樣能夠保證repair對線上服務的影響很小。
那麼咱們repair的大概原理是這樣的:咱們能夠在圖上看到ABC三個副本,每一個副本節點上都會有一個primary range主範圍。咱們會把primary range切分紅很小的組。每一個node只會負責修復本身primary range的數據,它不會去管別的數據。好比說B這個節點,它有一個primary range是A到B,除此以外它也會有C到A的副本數據,可是這個部分節點B無論,它只管A到B的數據的修復。這樣會下降咱們修復的數據量。
節點B只管A到B的primary range,咱們會把primary range切分紅很小的段,這個部分是爲了咱們後面作斷點續傳。咱們會針對每個sub_range作修復。這個服務是在Cassandra的kernel裏面,它是一個獨立的修復模塊。當Cassandra進程啓動後,這個服務會首先會將primary range切分紅sub_range。每個sub_range會有一個本身的task,而後這些task會進行排列。這以後,咱們會對全部的sub_ range從開頭到結尾進行輪詢scan。每次scan會把sub_range裏的數據拿出來,如今咱們設置的是每一次拿10條數據。咱們獨立實現的repair的module的讀寫鏈路和正常的讀寫鏈路是分開的,這樣的好處是repair不會影響正常的讀寫鏈路。
除此以外,官方建議,一輪repair應該在gc_grace_seconds範圍以內作完。那麼咱們能夠經過流控控制每個primary range修復的時間,也能夠控制每一次服務對線上的影響。每個sub-range作完以後,咱們會在一個system表裏面作記錄。好比當咱們修復到B節點的sub_range2時出現問題了,下一次B節點再啓動時會經過system表斷點續傳到sub_range2,而後sub_range2繼續完成任務。這樣作的好處是不少過程能夠徹底自動化,獨立的修復鏈路不會影響正常的讀寫鏈路,除此以外還能夠下降對線上服務的影響以及有一個可控的修復時間。
接下來咱們就性能加強方面選一個點進行詳細介紹。
咱們的性能加強基於咱們阿里雲的部署形態,咱們的底層使用的是盤古提供的塊存儲設備。咱們能夠看到Cassandra原有的架構是上面是LSM,底下是咱們如今用的Ext4文件系統,而後是一些操做系統的處理(好比Logical Volume和Volume Group),最終落到下面是有一個單獨的disk放commitlog,其餘的disk會放sstable。這樣的部署模式會引入一些問題:
那麼咱們的優化方式就是把底層經過LVM條帶,能夠把下層的cloud disk1-4 bind起來。這樣當從上層寫入時,不管是sstable仍是commitlog,均可以充分利用四塊盤的資源,而不是隻有disk 1寫commitlog,其它disk 二、三、4寫sstable。咱們是把四塊盤的併發能力全用起來。當寫入一個commitlog,它不僅是被寫入disk 1。經過LVM條帶,commitlog和sstable會被分紅chunk,併發地寫入disk 一、二、三、4。
這樣的好處一是能夠利用LVM的條帶化和多盤的並行能力提升寫入性能。如今咱們的寫入性能比以前提升了20%以上,這是一個平均數,比較極致的提升會更多。第二,咱們的四塊盤既能夠提供commitlog也能夠提供sstable,咱們就不須要額外的一塊盤放commitlog,這樣的性價比是最高的。另外,假設咱們四塊盤加起來的容量是80個G,它們對應的IOPS和一塊80個G盤的IOPS是同樣的,可是前者的價格會比後者低。經過這個方式,咱們能夠把整個Cassandra產品的價格下降。第三,咱們底層所用的盤古能夠提供比較極致的數據可靠性(9個9)。咱們能夠利用盤古的數據可靠性和LVM的條帶化保證數據節點的數據可靠性,由於若是單塊盤的數據可靠性不高時,LVM條帶化是用不起來的。
除此以外,咱們作了一些功能性的加強。
第一,咱們支持全量和增量的備份恢復。原有的Cassandra並無一個機制能夠把增量的備份恢復作到同一的系統裏面。咱們如今能作到的是,假設原集羣是三個節點,咱們能夠恢復到對應的三個節點。咱們如今在雲上的宗旨是恢復到對等節點。
咱們的備份和恢復分爲兩部分:全量的備份恢復和增量的備份恢復。
首先咱們在圖上有snapshot這個點,咱們會對各個節點併發地作snapshot,作完snapshot咱們會有一個全量的sstable。在打完snapshot這個時間點之後,咱們會開始作增量的備份。增量的備份咱們分兩部分:一是incremental backup是社區已有的功能,咱們在此基礎上作了一個表級別的備份恢復的點。除此以外,咱們還作了一個增量commitlog的數據備份恢復。
可能有的用戶會問,增量的incremental backup和commitlog的數據實際上是有重疊的,咱們後面會對此作一些介紹,解釋咱們爲何這樣作。
咱們經過snapshot打徹底量的快照之後,把每一個節點的數據備份到阿里雲的oss上面去。當用戶選擇恢復的時候,咱們會對用戶全部的sstable作對等拓撲的恢復,每一個節點的token範圍也是對等映射的。這樣作的好處是能夠不經過sstableloader的方式把sstable load進去,這樣恢復的速度是最快的。咱們只須要作一個對等拷貝,而後作一個單節點的nodetool refresh就能夠了。
增量咱們經過incremental backup及WAL log online archive來作。咱們在雲上作了這樣的一個優化:每次從memtable flush下來的sstable會經過incremental backup產生hard link到對應的backups目錄,同時擴容節點的時候,streaming生成的SSTable也會產生hard link。咱們會把hard link對應的SSTable也備份。
除此以外,咱們利用了Cassandra原有的archive功能,把每一個節點寫入的WAL log也作一個備份。當每一個commitlog生成的時候,它都會把一個hard link到用戶指定的地方。由於archive是須要重啓集羣和節點的,咱們在這裏作的一個優化使之無需重啓。咱們作了一個在線歸檔的功能,只要用戶點擊某個命令,開啓incremental backup log的歸檔,咱們會有對應的進程把log收到OSS上面去。由於咱們的備份恢復是對等拓撲的,節點在恢復的時候都會對應到與它相關的token的節點上去。它恢復的時候能夠作本節點的nodetool flush以及本節點的commitlog replay,而且這個replay是online replay。
這樣的好處是備份恢復的時間是最短的。Incremental backup和commitlog的組合可讓恢復的時間是最短的,由於咱們經過incremental backup的sstable篩選出須要恢復的WAL log/commitlog,而後作一個歸檔。這樣的話能夠避免log的replay的時間愈來愈多。
接下來我會介紹一下咱們的數據遷移。
Cassandra原有的數據遷移分爲COPY TO/FROM命令和文件級別的sstableloader兩種。COPY TO/FROM是一個多線程讀寫key value的操做,當數據量比較大時,它的速度會比較慢。就sstableloader來講,O一、O二、O3節點上的數據都須要被load,load到新的集羣時可能會有一些冗餘。另外實時新增的數據可能處理得不會很融洽。
在這裏,咱們啓動了阿里雲的BDS服務。不管原集羣和目標集羣是對等或不對等拓撲,它們均可以經過BDS高效遷移。
原有的sstableloader方案中,原集羣全部節點都須要進行一個相似於streaming的過程,並在目標集羣進行一個拖數據的過程。原集羣中節點o1的文件可能和目標集羣中的節點n一、n二、n3都會有重疊。原集羣o1中的文件複製到目標集羣可能要有一個三副本的放大。當原集羣有三個副本,目標集羣也三個副本時,一份數據經過sstableloader可能會有九倍的放大。這會產生冗餘。
當使用BDS,咱們把原集羣和目標集羣作了數據範圍的映射。原集羣的primary range的數據咱們只會遷移到目標集羣的primary range,副本節點的數據會遷移到副本節點。咱們的副本擺放策略默認使用SimpleStrategy,根據這個副本擺放策略咱們作一個副本範圍的一一映射。當某個sstable在目標集羣上橫跨了多個節點時,咱們會對於這個sstable作一個切分,切分後須要把對應的數據複製到對應的節點上面去。這樣能夠避免數據的冗餘。
除此以外,咱們還作了文件級別的遷移,速度比較快。另外咱們也支持增量數據的遷移,包括增量的commitlog和incremental backup。咱們支持實時的增量數據的遷移需求,用戶只須要經過咱們的BDS服務,無需額外操做便可完成無縫遷移。
最後,我來介紹一下咱們監控報警的大概模式。咱們會分三個層面來介紹。
首先是OS操做系統層面。
由於Cassandra是share-nothing的架構,它是直接寫本地的文件系統。對於本地的文件系統的error咱們會作實時探測,對網絡包package的異常處理咱們也會作監控。在這裏像file system error這樣的相對比較重要的error,咱們會經過unavailable這樣的異常報給Ops服務。咱們也會對Cassandra的daemon death進行實時監控,在Cassandra每個進程的機制下面,咱們都會有個單獨的agent來發出system error,包括網絡和內存的異常。另外Cassandra daemon的判活還有gc。關於gc,咱們比較關注的是時間比較長的後續狀況,超過500毫秒咱們會經過發出unavailable異常報給Ops同窗。
第二個層面是Logs層面異常的收集。
第一是slow cql,就是讀的時候比較慢的cql,咱們會收集。gc log是Cassandra本身的GCInspector的log,還有warn log好比large partition。這些咱們會經過SLS收集,以後相關的報警也會告訴咱們值班的同窗,最上層是Cassandra本身的metric的信息。Metric信息咱們會分兩類進行處理。第一是展現給用戶的Metric,好比容量、compaction等,是咱們以爲用戶會比較關心的,會經過CMS給用戶。全量的80%的metric也會經過CMS鏈路報給咱們本身的Ops同窗。經過這種方式,咱們能夠對metric也設置一些報警。