郭超:阿里雲Cassandra背後的故事

你們好,我是阿里雲數據庫產品事業部的玄陵,真名郭超。node

本次的分享大概分三個部分:Cassandra雲數據庫簡介、Cassandra雲數據庫特性以及Q&A。數據庫

咱們先了解一下Cassandra雲數據庫在阿里雲上的部署和架構。首先這個架構主要反映了三個方向:​安全

  • 安全保障和VPC隔離:在阿里雲上,Cassandra數據庫的不一樣用戶有不一樣的VPC。經過VPC隔離和白名單,能夠保證在阿里雲上用戶之間的數據是相對安全的。由於每一個用戶有本身的VPC環境,在本身的VPC環境下只能訪問本身的VPC數據。不一樣的VPC之間是不能夠互相訪問與之無關的VPC帳號的數據的。在同VPC下,能夠實現單DC或多DC容災的部署。
  • 高可用:阿里雲上Cassandra的高可用性分爲單DC以內replica級別的高可用以及DC之間容災的高可用。
  • 功能豐富:具備備份和遷移等功能。每一個VPC環境下的用戶的集羣能夠經過咱們本身實現的系統備份到OSS上面。阿里雲OSS能夠提供極致的數據可靠性的服務。

接下來咱們深刻了解一下單個DC和集羣的狀況。網絡

  • 運維自動化能夠提供自主運維。咱們本身實現的Cassandra-mate的服務能夠實現一些運維的自動化,好比compaction的調優、節點擴容和增長節點、以及監控和報警。
  • 爲了追求高性能,咱們在內核定製以及性能加強方面作了一些相關的改進。
  • 靈活易用,咱們的雲服務是百分百兼容Apache Cassandra CQL的協議。

除此以外,咱們其它的架構和Apache Cassandra幾乎是同樣的。多線程

接下來咱們介紹一下Cassandra雲數據庫的特性:架構

  • 開箱即用:免除運維煩惱
  • 彈性伸縮、線性擴展:在雲環境下,利用雲的資源能夠進行快速的擴容和縮容,這點很是符合Cassandra現有的特性。
  • 高可用、多活:多副本、持續可寫、就近讀取,這個是Cassandra自帶的。
  • 備份恢復:在Cassandra的基礎上咱們作了一些配置,好比全量和增量備份和恢復,從而保證至關高的數據可靠性,以防DBA的誤操做(好比刪庫)形成數據不可用。
  • 細粒度監控:能讓性能數據一目瞭然。

即將上線的服務包括:併發

  • 安全加固:SSL+TDE全鏈路加密
  • 審計日誌:訪問記錄、有據可查
  • CloudDBA:自動診斷、智能優化

接下來,咱們介紹一些咱們在功能上作的優化。因爲時間關係,咱們只能重點介紹一部分功能優化。運維

第一點,咱們作了一些自動化運維手段。性能

這個事情的背景是因爲Cassandra是一個去中心化的數據庫,社區建議用戶作repair,目的主要是保證Cassandra三個或多個副本之間的一致性。Repair可以把副本上的數據作一個修復或者補齊,保證副本的數據是一致的。Repair是必需要作的,然而在咱們的使用場景中,repair會引入一些問題:優化

  • 擴容縮容會增長運維難度:在目前阿里雲的部署環境下,一個用戶對應一個或多個cluster,當用戶增多,須要管理的集羣規模或數量就很是多,這會給咱們repair的運維帶來比較大的困難。
  • 當某個集羣擴容或縮容時,咱們須要對repair作一些相應的調整,這也會增大運維的難度。Repair的過程會產生極大的資源開銷,會影響咱們線上的一些服務。
  • 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。這樣的部署模式會引入一些問題:

  • ​咱們看到寫入鏈是先寫入commitlog,再寫入memtable,而後再返回給客戶。那麼當咱們把一個commitlog部署在Cloud Disk 1上面,它的寫入吞吐會受到Cloud Disk 1的限制。另外commitlog如今在社區也是不支持部署在多盤上面的。
  • ​第二個點是在咱們這個雲上面涉及到產品形態的設計。首先,commitlog這個盤對咱們不會產生費用,咱們只售賣sstable的文件存儲。那麼若是這樣去設計的話,額外的commitlog存儲會產生額外的費用,繼而產生對客戶的額外費用,這樣對客戶來講相對不太公平。
  • ​第三,若是咱們有四塊盤,咱們拿出一塊盤給commitlog,其它的給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也設置一些報警。

相關文章
相關標籤/搜索