HBase、MongoDB、cassandra比較

 前言

傳統數據庫遇到的問題,數據量很大的時候沒法存儲沒有很好的備份機制數據達到必定數量開始緩慢,很大的話基本沒法支撐;所以咱們須要探究更加合適的數據庫來支撐咱們的業務。html

 

HBase

什麼是HBase

Hbase(Hadoop Database)是創建在HDFS之上的分佈式、面向列的NoSQL的數據庫系統。node

 

HBase特色

優勢linux

    1. 海量存儲:適合存儲PB級別的海量數據,採用廉價PC存儲的狀況下,能在幾十到百毫秒內返回數據。
    2. 列式存儲(半結構化或非結構化數據):即列族存儲,對於數據結構字段不夠肯定或雜亂無章很是難按一個概念去進行抽取的數據適合用。
    3. 極易擴展:一個是基於上層處理能力(RegionServer)的擴展,提高Hbsae服務更多Region的能力。一個是基於存儲的擴展(HDFS),經過橫向添加Datanode的機器,進行存儲層擴容,提高Hbase的數據存儲能力和提高後端存儲的讀寫能力。
    4. 高併發:採用廉價PC,能得到高併發、低延遲、高性能的服務。
    5. 稀疏:列族中,能夠指定任意多的列,列數據爲空不會佔用存儲空間的,也提升了讀性能
    6. 多版本號數據:依據Row key和Column key定位到的Value可以有隨意數量的版本號值,版本號默認是單元格插入時的時間戳
    7. 適用於插入比查詢操做更頻繁的狀況:好比,對於歷史記錄表和日誌文件
    8. 數據類型單一:HBase中數據類型都是字符串
    9. 無模式:每一行都有一個能夠排序的rowKey和任意多的大相徑庭的列。

缺點git

    1. 單一RowKey固有的侷限性決定了它不可能有效地支持多條件查詢。
    2. 不適合於大範圍掃描查詢。
    3. 不直接支持 SQL 的語句查詢。
    4. 僅支持行級(單行)事務(HBase的事務是行級事務,能夠保證行級數據的原子性、一致性、隔離性以及持久性)。
    5. HBase的配置很是麻煩,最低的限度都須要包括Zookeeper ensemble、primary HMaster、secondary HMaster、RegionServers、active NameNode、standby NameNode、HDFS quorum journal manager及DataNodes。使用HBase需求大量的專業知識——甚至是最簡單的監視。RegionServer存在單點故障,當它發生故障時,一個新的RegionServer必須被選舉出,而在能夠投入以前,必須從新完成write-ahead日誌裏的內容,即故障恢復較慢,WAL回放較慢。HBase的API很是笨拙而且具備太強的Java特點,非Java客戶端只能委託給Thrit或者REST。

 

HBase的體系結構

 

 

值得參考的網址:http://www.javashuo.com/article/p-ynqtsygj-cn.html程序員

 

HBase使用場景

Hbase是一個經過廉價PC機器集羣來存儲海量數據的分佈式數據庫解決方案。它比較適合的場景歸納以下:github

    1. 是巨量大(百T、PB級別)
    2. 查詢簡單(基於rowkey或者rowkey範圍查詢)
    3. 不涉及到複雜的關聯

有幾個典型的場景特別適合使用Hbase來存儲:spring

    1. 海量訂單流水數據(長久保存)
    2. 交易記錄
    3. 數據庫歷史數據

 

如何使用HBase

三種模式單機模式,僞分佈式模式,分佈式模式sql

通常生產環境用的是分佈式模式,若是是學習的話,能夠用單機模式和僞分佈式模式。mongodb

 

安裝zookeeper數據庫

https://blog.csdn.net/weixin_41558061/article/details/80597174

全分佈式模式的Hbase集羣須要運行ZooKeeper實例,默認狀況下HBase自身維護着一組默認的ZooKeeper實例,能夠本身配置實例,這樣Hbase會更加健壯

注意:使用默認的實例時,HBase將自動啓動或中止ZooKeeper,當使用獨立的ZooKeeper實例時,須要用戶手動啓動和中止ZooKeeper實例

 

安裝Hadoop

hadoop分佈式安裝

 

安裝HBase

http://www.javashuo.com/article/p-ngsgoyep-cw.html

 

    hbase_home/conf/hbase-site.xml文件中的configuration加入:    
 1 <property>  
 2   <name>hbase.rootdir</name>  
 3   <value>hdfs://hadoop0:9000/hbase</value>
 4 </property>
 5 <property>
 6   <name>hbase.cluster.distributed</name>
 7   <value>true</value>
 8 </property>
 9 <property>
10   <name>hbase.zookeeper.quorum</name>
11   <value>hadoop0</value>
12 </property>
13 <property>
14   <name>dfs.replication</name>   //指定Hlog和Hfile副本數,此參數值並不能大於HDFS節點數,若是datanode只有一臺則此參數應該設置爲1
15   <value>1</value>
16 </property>

 

注意事項

1.關於Hadoop

  1.  目前的HBase只能依賴特定的Hadoop版本,HBae和Hadoop之間的RPC是版本話的,須要調用方與被調用方相互匹配,細微的差別可能致使通訊失敗

  2. 因爲Hadoop依賴於Hadoop,它要求Hadoop的JAR必須部署在HBase的lib目錄下。HBase使用的Hadoop版本必須與底層Hadoop集羣上使用的Hadoop版本一直,於是使用Hadoop集羣上運行的JAR替換HBase的lib目錄中依賴的Hadoop的JAR能夠避免版本不匹配的問題

  3. 集羣中全部的節點都要更新爲同樣的JAR,不然版本不匹配問題可能形成集羣沒法啓動或者假死現象

 

2.關於HBase Shell

  1.若是使用的分佈式模式,那麼在關閉Hadoop以前必定要確認HBase已經被正常關閉了

  2. 使用stop-hbase.sh關閉HBase時,控制檯會打印關於中止的信息,會週期性的打印 ".",關閉腳本須要幾分鐘完成,若是集羣中機器數量不少,那麼執行時間會更長

介紹比較全面的網址:http://www.javashuo.com/article/p-paqmevof-dg.html

 

瞭解完HBase後,可帶着問題看這一篇文章:https://blog.csdn.net/nosqlnotes/article/details/79647096 

 

MongoDB

什麼是MongoDB

MongoDB是一個介於關係數據庫和非關係數據庫之間,基於分佈式文件存儲,由C 語言編寫的數據庫。

 

MongoDB特色

優勢

高性能、易部署、易使用、高寫負載,存儲數據很是方便。

        • 面向文檔存儲(類JSON數據模式簡單而強大)
        • 動態查詢

        • 全索引支持,擴展到內部對象和內嵌數組

        • 查詢記錄分析

        • 快速,就地更新

        • 高效存儲二進制大對象 (好比照片和視頻)

        • 複製和故障切換支持

        • Auto- Sharding自動分片支持雲級擴展性

        • 支持RUBY,PYTHON,JAVA,C ,PHP,C#等多種語言。
        • MapReduce 支持複雜聚合

        • 商業支持,培訓和諮詢

 缺點

        • 不支持事務(進行開發時須要注意,哪些功能須要使用數據庫提供的事務支持)
        • MongoDB佔用空間過大 (不過這個肯定對於目前快速下跌的硬盤價格來講,也不算什麼缺點了)
          • 2.一、空間的預分配:
            當MongoDB的空間不足時它就會申請生成一大塊硬盤空間,並且申請的量都是有64M、128M、256M來增長直到2G爲單個文件的較大致積,而且隨着數量疊增,能夠在數據目錄下看到整塊生成並且不斷遞增的文件。

          • 2.二、刪除記錄不釋放空間:

            這很容易理解,爲避免記錄刪除後的數據的大規模挪動,原記錄空間不刪除,只標記「已刪除」便可,之後還能夠重複利用。

        • MongoDB沒有如MySQL那樣成熟的維護工具,這對於開發和IT運營都是個值得注意的地方
        • 在32位系統上,不支持大於2.5G的數據(不少操做系統都已經拋棄了32位版本,因此這個也算不上什麼缺點了,3.4版本已經放棄支持32 位 x86平臺)

 

MongoDB原理

mongodb在電腦磁盤文件系統之上,又包裝了本身的一套文件系統---gridfs,裏面存儲的是一個一個的json二進制對象,也就是Bson。

存儲容量需求超出單機磁盤容量時,用分片技術去解決

  詳情可參考網址:

http://www.javashuo.com/article/p-rmmcgnlx-ds.html

http://www.javashuo.com/article/p-shvescuy-ho.html

 

場景適用

適用場景

        MongoDB 的主要目標是在鍵/值存儲方式(提供了高性能和高度伸縮性)和傳統的RDBMS 系統(具備豐富的功能)之間架起一座橋樑,它集二者的優點於一身。根據官方網站的描述,Mongo 適用於如下場景。
● 網站數據:Mongo 很是適合實時的插入,更新與查詢,並具有網站實時數據存儲所需的複製及高度伸縮性。
● 緩存:因爲性能很高,Mongo 也適合做爲信息基礎設施的緩存層。在系統重啓以後,由Mongo 搭建的持久化緩存層能夠避免下層的數據源過載。
● 大尺寸、低價值的數據:使用傳統的關係型數據庫存儲一些數據時可能會比較昂貴,在此以前,不少時候程序員每每會選擇傳統的文件進行存儲。
● 高伸縮性的場景:Mongo 很是適合由數十或數百臺服務器組成的數據庫,Mongo 的路線圖中已經包含對MapReduce 引擎的內置支持。
● 用於對象及JSON 數據的存儲:Mongo 的BSON 數據格式很是適合文檔化格式的存儲及查詢。

不適場景

● 高度事務性的系統:例如,銀行或會計系統。傳統的關係型數據庫目前仍是更適用於須要大量原子性復瑣事務的應用程序。
● 傳統的商業智能應用:針對特定問題的BI 數據庫會產生高度優化的查詢方式。對於此類應用,數據倉庫多是更合適的選擇。
● 須要SQL 的問題。

 

如何使用MongoDB

linux平臺安裝MongoDB

http://www.runoob.com/mongodb/mongodb-linux-install.html

spring中集成MongoDB,經過引入MongoDB的maven依賴,引入約束mongo來配置spring託管

xmlns:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation=" 
    http://www.springframework.org/schema/data/mongo
    http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd"

 

  配置鏈接池

<!--鏈接池配置-->
<mongo:mongo host="${mongo.host}" port="${mongo.port}">
    <mongo:options connections-per-host="${mongo.options.connections-per-host}" threads-allowed-to-block-for-connection-multiplier="${mongo.options.threads-allowed-to-block-for-connection-multiplier}" connect-timeout="${mongo.options.connect-timeout}" max-wait-time="${mongo.options.max-wait-time}" auto-connect-retry="${mongo.options.auto-connect-retry}" socket-keep-alive="${mongo.options.socket-keep-alive}" socket-timeout="${mongo.options.socket-timeout}" slave-ok="${mongo.options.slave-ok}" write-number="${mongo.options.write-number}" write-timeout="${mongo.options.write-timeout}" write-fsync="${mongo.options.write-fsync}"/>
</mongo:mongo>
<!--鏈接池工廠配置-->
<mongo:db-factory dbname="${mongo.dbname}" username="${mongo.username}" password="${mongo.password}"  mongo-ref="mongo"/>
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
</bean>
<!--實體映射自動掃描注入的包-->
<mongo:mapping-converter>
    <mongo:custom-converters base-package="com.xyh.mongodb_model" />
</mongo:mapping-converter>

 

在實體類中加入相應的@Document、@id、@Indexed、@PersistenceConstructor註解,來實現對數據實例化對象進行增刪改查的操做。

詳細信息可參考網址:http://www.javashuo.com/article/p-yapknazt-bc.html

 

Cassandra

什麼是Cassandra

Cassandra是數據放置在具備多個複製因子的不一樣機器上,處理大量數據的分佈式架構的非關係數據庫。

 

Cassandra特色

優勢

               配置簡單

        不須要多模塊協同操做。

模式靈活
  使用Cassandra,像文檔存儲,你沒必要提早解決記錄中的字段。你能夠在系統運行時隨意的添加或移除字段。這是一個驚人的效率提高,特別是在大型部署上。

真正的可擴展性
  Cassandra是純粹意義上的水平擴展。爲給集羣添加更多容量,能夠指向另外一臺電腦。你沒必要重啓任何進程,改變應用查詢,或手動遷移任何數據。

多數據中心識別
  你能夠調整你的節點佈局來避免某一個數據中心起火,一個備用的數據中心將至少有每條記錄的徹底複製。

範圍查詢
  若是你不喜歡所有的鍵值查詢,則能夠設置鍵的範圍來查詢。


列表數據結構
  在混合模式能夠將超級列添加到5維。對於每一個用戶的索引,這是很是方便的。


分佈式寫操做
  有能夠在任何地方任什麼時候間集中讀或寫任何數據。而且不會有任何單點失敗。 

缺點
存儲那種巨大的(幾百T甚至P)的超大文件目前是無能爲力的。
 

原理

在Cassandra中,是無中心的P2P架構,網絡中的全部節點都是對等的,它們構成了一個環,節點之間經過P2P協議每秒鐘交換一次數據,這樣每一個節點都擁有其它全部節點的信息,包括位置、狀態等,以免單點故障。

寫請求

當寫事件發生時,首先由Commit Log捕獲寫事件並持久化;每一個數據中心選取一個Coordinator來完成它所在數據中心的數據複製;存儲結構相似LSM樹(Log-Structured Merge Tree)這種結構;Commit Log記錄每次寫請求的完整信息,此時並不會根據主鍵進行排序,而是順序寫入;寫入到Memtable時,Cassandra可以動態地爲它分配內存空間;當memtable中的數據刷到SSTable後,Commit Log中的數據將被清理掉;Cassandra對Update操做的處理和傳統關係數據庫徹底不同,並不當即對原有數據進行更新,而是會增長一條新的記錄,後續在進行Compaction時將數據再進行合併。Delete操做也一樣如此,要刪除的數據會先標記爲Tombstone,後續進行Compaction時再真正永久刪除。

 圖來源網址:https://www.yiibai.com/cassandra/cassandra-architecture.html

讀請求

讀取數據時,首先檢查Bloom filter,每個SSTable都有一個Bloom filter用來檢查partition key是否在這個SSTable,這一步是在訪問任何磁盤IO的前面就會作掉。若是存在,再檢查partition key cache。讀請求(Read Request)分兩種,一種是Rirect Read Request,根據客戶端配置的Consistency Level讀取到數據便可返回客戶端結果。一種是Background Read Repair Request,除了直接請求到達的節點外,會被髮送到其它複製節點,用於修復以前寫入有問題的節點,保證數據最終一致性。

行緩存和鍵緩存請求流程圖

圖來源網址:http://www.javashuo.com/article/p-ymhcqiej-ms.html

可參考網址:http://www.javashuo.com/article/p-qfyvgfjz-en.html

 

如何使用Cassandra

Cassandra集羣搭建

https://github.com/maomao1994/TPC-H/blob/master/Cassandra-CQL/Cassandra-CQL%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA.md

https://blog.csdn.net/ch648966459/article/details/51671276/#commentBox

 

代碼應用

引入pom.xml

<dependency>
 <groupId>com.datastax.cassandra</groupId>
 <artifactId>cassandra-driver-core</artifactId>
 <version>3.1.1</version>
</dependency> 
<dependency> 
 <groupId>com.datastax.cassandra</groupId>
 <artifactId>cassandra-driver-extras</artifactId>
 <version>3.1.1</version>
</dependency>

 

鏈接代碼

String[] hosts = new String[]{"192.168.1.1", "192.168.1.2", "192.168.1.3"};//cassandra主機地址 //認證配置
        AuthProvider authProvider = new PlainTextAuthProvider("ershixiong", "123456"); LoadBalancingPolicy lbp = new TokenAwarePolicy( DCAwareRoundRobinPolicy.builder().withLocalDc("myDC").build() ); //讀超時或鏈接超時設置
        SocketOptions so = new SocketOptions().setReadTimeoutMillis(3000).setConnectTimeoutMillis(3000); //鏈接池配置 //PoolingOptions poolingOptions = new PoolingOptions().setConnectionsPerHost(HostDistance.LOCAL, 2, 3); //集羣在同一個機房用HostDistance.LOCAL 不一樣的機房用HostDistance.REMOTE 忽略用HostDistance.IGNORED
        PoolingOptions poolingOptions= new PoolingOptions() .setMaxRequestsPerConnection(HostDistance.LOCAL, 64)//每一個鏈接最多容許64個併發請求
                .setCoreConnectionsPerHost(HostDistance.LOCAL, 2)//和集羣裏的每一個機器都至少有2個鏈接
                .setMaxConnectionsPerHost(HostDistance.LOCAL, 6);//和集羣裏的每一個機器都最多有6個鏈接 //查詢配置 //設置一致性級別ANY(0),ONE(1),TWO(2),THREE(3),QUORUM(4),ALL(5),LOCAL_QUORUM(6),EACH_QUORUM(7),SERIAL(8),LOCAL_SERIAL(9),LOCAL_ONE(10); //能夠在每次生成查詢statement的時候設置,也能夠像這樣全局設置
        QueryOptions queryOptions = new QueryOptions().setConsistencyLevel(ConsistencyLevel.ONE); //重試策略
        RetryPolicy retryPolicy = DowngradingConsistencyRetryPolicy.INSTANCE; int port = 9042;//端口號
 String keyspace = "keyspacename";//要鏈接的庫,能夠不寫
 Cluster cluster = Cluster.builder() .addContactPoints(hosts) .withAuthProvider(authProvider) .withLoadBalancingPolicy(lbp) .withSocketOptions(so) .withPoolingOptions(poolingOptions) .withQueryOptions(queryOptions) .withRetryPolicy(retryPolicy) .withPort(port) .build(); Session session = cluster.connect(keyspace);

 

具體可參考:https://blog.csdn.net/u010003835/article/details/52516571

scylla、hazelcast你們也能夠私下研究一下。 

結論

當你僅僅是存儲海量增加的消息數據,存儲海量增加的圖片,小視頻的時候,你要求數據不能丟失,你要求人工維護儘量少,你要求能迅速經過添加機器擴充存儲,那麼毫無疑問,Cassandra如今是佔據上風的。

可是若是你但願構建一個超大規模的搜索引擎,產生超大規模的倒排索引文件(固然是邏輯上的文件,真實文件實際上被切分存儲於不一樣的節點上),那麼目前HDFS+HBase是你的首選。

相關文章
相關標籤/搜索