Cassandra是一套開源分佈式NoSQL數據庫系統。由Facebook開發,主要用於儲存收件箱等簡單格式數據,集GoogleBigTable的數據模型與Amazon Dynamo的徹底分佈式的架構於一身。
2008年,Facebook將 Cassandra 開源,並被Digg、Twitter等知名公司引入,成爲了一種流行的分佈式結構化數據存儲方案。
Cassandra是一個混合型的非關係的數據庫,相似於Google的BigTable。其主要功能比Dynamo (分佈式的Key-Value存儲系統)更豐富,但支持度卻不如文檔存儲MongoDB(介於關係數據庫和非關係數據庫之間的開源產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。支持的數據結構很是鬆散,是相似json的bjson格式,所以能夠存儲比較複雜的數據類型)。node
Cassandra的應用場景
Cassandra具備常見NoSQL 分佈式數據庫,其自帶的命令行工具完備,兼容性強,甚至Windows機器均可以安裝,所以維護、升級都相對比較簡單。它有着很人性化的Web管理界面,兼容大部分SQL語法。能夠設置多個「中心」,這一點跟Hadoop based的HBase / Hive 很不同。
Cassandra讀寫性能和可擴展很是好。因爲它是一堆數據庫節點共同構成的一個分佈式網絡服務,只要對Cassandra 的一個節點就行寫操做,會被複制到其餘節點上去。同理,對Cassandra的一個節點進行讀操做,也會被路由到某個節點上面去讀取。所以,對於一個Cassandra羣集來講,擴展性能是比較簡單的事情,只管在羣集裏面添加節點就能夠了。很是適合金融、電商等記錄系統日誌、產品的目錄管理、實時數據存儲等等要求高的行業。
咱們把Cassandra應用在了數據對象服務的數據提供上,因爲有多個「中心」,又減小了對於Hadoop環境的依賴,在維護管理上會很是便捷,又能大幅提高數據的存儲以及查詢性能。docker
Cassandra docker安裝初體驗
啓動Cassandra docker實例:
$ docker run --name some-cassandra -d cassandra:tag
some-cassandra指定的容器名稱,tag是指定所需Cassandra版本的標記。具體參考docker hub。
創建集羣以及在已有集羣上擴展機器:
假設第一臺機器的IP地址是10.42.42.42第二臺機器人的IP地址10.43.43.43,請使用公開的八卦端口啓動第一臺機器:
$ docker run --name some-cassandra -d -e CASSANDRA_BROADCAST_ADDRESS=10.42.42.42 -p 7000:7000 cassandra:tag
而後在第二臺機器上啓動一個Cassandra容器,暴露的八卦端口和種子指向第一臺機器:
$ docker run --name some-cassandra -d -e CASSANDRA_BROADCAST_ADDRESS=10.43.43.43 -p 7000:7000 -e CASSANDRA_SEEDS=10.42.42.42 cassandra:tag
這樣就創建好了一個倆臺Cassandra機器的集羣了,能夠進行cqlsh的體驗了。數據庫
Cassandra應用實踐
Cassandra沒有像BigTable或Hbase那樣選擇中心控制節點,而選擇了無中心的P2P架構,網絡中的全部節點都是對等的,它們構成了一個環,節點之間經過P2P協議每秒鐘交換一次數據,這樣每一個節點都擁有其它全部節點的信息,包括位置、狀態等。json
客戶端能夠鏈接集羣中的任一個節點來鏈接整個集羣,和客戶端創建鏈接的節點叫協做者(coordinator),Cassandra至關於一個代理,負責定位該次請求要發到哪些實際擁有本次請求所需數據的節點上去獲取,但如何獲取並返回,主要根據客戶端要求的一致性級別(Consistency Level)來肯定。
好比:ONE指只要有一個節點返回數據就能夠對客戶端作出響應,QUONUM指須要返回幾個根據用戶的配置數目,ALL指等於數據複製份數的全部節點都返回結果才能向客戶端作出響應,對於數據一致性要求不是特別高的能夠選擇ONE,這是最快的一種方式。
Cassandra的數據分發和複製一般是一塊兒的,數據用表的形式來組織,用主鍵來識別應該存儲到哪些節點上,行的copy稱做replica。當一個集羣被建立時,至少要指定以下幾個配置:Virtual Nodes,Partitioner,Replication Strategy,Snitch。
數據複製策略有兩種,一種是SimpleStrategy,適合一個數據中心的狀況,第一份數據放在Partitioner肯定的節點,後面的放在順時針找到的節點上,它不考慮跨數據中心和機架的複製。另一種是NetworkTopologyStargegy,第一份數據和前一種同樣,第二份複製的數據放在不一樣的機架上,每一個數據中心能夠有不一樣數據的replicas。
Partitioner策略有三種,默認是Murmur3Partitioner,使用MurmurHash。RandomPartitioner,使用Md5 Hash。ByteOrderedPartitioner使用數據的字節進行有順分區。Cassandra默認使用MurmurHash,這種有更高的性能。
那麼若是Cassandra集羣動態擴展怎麼辦?數據怎麼流動呢?若是是依次按順序流動那麼效率很是低下。這裏就要提到Cassandra 的一個Vnode (virtual nodes)概念。就是把一個節點分紅默認是256個Vnode來擁有較多不連續的hash值範圍,以達到數據的負載的目的。緩存
Cassandra 的寫請求網絡
先爲了可以持久化與宕機恢復會寫入CommitLog數據結構
– 對應的配置: commitlog_directory
同時寫入Memtable
– Memtable : 內存之中的數據結構 架構
每當Memtable的數據達到必定條件時將數據Flush到SSTable
– 條件在配置文件之中定義
• memtable_heap_space_in_mb
• memtable_offheap_space_in_mb
– SSTable
• 真正存儲到了硬盤之上:data_file_directories
• SSTable是不可變的,每次會將SSTable徹底刪除再新寫一個 運維
Flush以後,CommitLog會被自動刪除。
若是客戶端配置了Consistency Level是ONE,意味着只要有一個節點寫入成功,就由代理節點(Coordinator)返回給客戶端寫入完成。固然這中間有可能會出現其它節點寫入失敗的狀況,Cassandra本身會經過Hinted Handoff或Read Repair 或者Anti-entropy Node Repair方式保證數據最終一致性。dom
Cassandra的讀請求
上面提到,Cassandra在讀取數據有優點。在讀取時,Cassandra首先檢查Bloom filter,每個SSTable都有一個Bloom filter用來檢查partition key是否在這個SSTable,這一步是在訪問任何磁盤IO的前面就會作掉。若是存在,再檢查partition key cache,而後再作以下操做:
若是在cache中能找到索引,到compression offset map中找擁有這個數據的數據塊,從磁盤上取得壓縮數據並返回結果集。若是在cache中找不到索引,搜索partition summary肯定索引在磁盤上的大概位置,而後獲取索引入口,在SSTable上執行一次單獨的尋道和一個順序的列讀取操做,下面也是到compression offset map中找擁有這個數據的數據塊,從磁盤上取得壓縮數據並返回結果集。讀取數據時會合並Memtable中緩存的數據、多個SSTable中的數據,才返回最終的結果。
讀請求(Read Request)分兩種,一種是Rirect Read Request,根據客戶端配置的Consistency Level讀取到數據便可返回客戶端結果。一種是Background Read Repair Request,除了直接請求到達的節點外,會被髮送到其它複製節點,用於修復以前寫入有問題的節點,保證數據最終一致性。
客戶端讀取時,Coordinator首先聯繫Consistency Level定義的節點,發送請求到最快響應的複製節點上,返回請求的數據。若是有多個節點被聯繫,會在內存比較每一個複製節點傳過的數據行,若是不一致選取最近的數據(根據時間戳)返回給客戶端,並在後臺更新過時的複製節點,這個過程被稱做Read Repair。
Cassandra的數據整理
更新操做不會當即更新,這樣會致使隨機讀寫磁盤,效率不高,Cassandra會把數據順序寫入到一個新的SSTable,並打上一個時間戳以標明數據的新舊。它也不會立馬作刪除操做,而是用Tombstone來標記要刪除的數據。Compaction時,將多個SSTable文件中的數據整合到新的SSTable文件中,當舊SSTable上的讀請求一完成,會被當即刪除,空餘出來的空間能夠從新利用。
雖然Compcation沒有隨機的IO訪問,但仍是一個重量級的操做,通常在後臺運行,並經過限制它的吞吐量來控制,`compaction throughput mb per sec參數能夠設置,默認是16M/s。另外,若是key cache顯示整理後的數據是熱點數據,操做系統會把它放入到page cache裏以提高性能。簡單來講,它的合併的策略有兩種。
一、SizeTieredCompactionStrategy :每次更新不會直接更新原來的數據,這樣會形成隨機訪問磁盤,性能不高,而是在插入或更新直接寫入下一個sstable,這樣是順序寫入速度很是快,適合寫敏感的操做。可是,由於數據分佈在多個sstable,讀取時須要屢次磁盤尋道,讀取的性能不高。爲了不這樣狀況,會按期在後臺將類似大小的sstable進行合併,這個合併速度也會很快,默認狀況是4個sstable會合並一次,合併時若是沒有過時的數據要清理掉,會須要一倍的空間,所以最壞狀況須要50%的空閒磁盤。
二、LeveledCompactionStrategy:建立固定大小默認是5M的sstable,最上面一級爲L0下面爲L1,下面一層是上面一層的10倍大小。這種整理策略讀取很是快,適合讀敏感的狀況,最壞只須要10%的空閒磁盤空間,它參考了LevelDB的實現。
後記從Demo搭建到擴展到生產環境上,充分體驗到了Cassandra的易用和可擴展性。它極大下降了環境的配置和解決問題之間的運維時間,能把更多的時間轉到實際開發中。