一、進(jìn)行遷移的原因
由于業(yè)務(wù)的發(fā)展,使用mysql進(jìn)行建立索引進(jìn)行搜索已經(jīng)造成數(shù)據(jù)流的瓶頸卡在了數(shù)據(jù)庫(kù)io,例如每次dump全表的時(shí)候,會(huì)造成壓力過(guò)大,造成耗時(shí)很長(zhǎng),并且當(dāng)前的數(shù)據(jù)量基本上已經(jīng)達(dá)到了億級(jí)別的數(shù)據(jù)量,如果希望mysql能更好的提供服務(wù),下一步必須考慮分庫(kù)分表才可以;基于這種情況下,考慮使用hbase用來(lái)進(jìn)行數(shù)據(jù)的存儲(chǔ),因?yàn)閔base所能承受的數(shù)據(jù)量遠(yuǎn)大于mysql,并且對(duì)列的擴(kuò)展也很方便
二、關(guān)系型數(shù)據(jù)庫(kù)與Nosql的一些區(qū)別
(1)存儲(chǔ)方式的區(qū)別
在類似mysql,sqlserver,oracle等關(guān)系型數(shù)據(jù)庫(kù),數(shù)據(jù)的存儲(chǔ)是按照行進(jìn)行存儲(chǔ)的,如下圖所示:
但是在hbase里面,所有的數(shù)據(jù)是基于列進(jìn)行存儲(chǔ)的,如下所示:
其中hbase的邏輯模型如下所示:
其中:com.cnn.ww對(duì)應(yīng)的是rowkey,相當(dāng)于mysql的主鍵的概念
contents,anchor:這兩個(gè)對(duì)應(yīng)的是列族的概念,在物理的存儲(chǔ)上,同一個(gè)列族的數(shù)據(jù)存儲(chǔ)在相同文件
cnnsi.com,mylook.ca:對(duì)應(yīng)的是列族下面的列,在hbase中列是可以動(dòng)態(tài)增加的
對(duì)應(yīng)的方格數(shù)據(jù)表示的是單元數(shù)據(jù),即對(duì)應(yīng)rowkey,cf:column下面的具體的值
其中tn:表示的是時(shí)間戳,單元數(shù)據(jù)的不同版本
其中有一張存儲(chǔ)結(jié)構(gòu)如下:
(2)CRUD一些區(qū)別
CRUD是數(shù)據(jù)庫(kù)的最基本也是最常用的操作,在hbase里面也有對(duì)應(yīng)的命令,例如建表語(yǔ)句對(duì)于mysql的在此不詳述,對(duì)于hbase shell的如下所示
create ‘table’,‘columnfamily’
即可以創(chuàng)建一個(gè)名為table,列族為columnfamily的表,其他的一些blocksize,version數(shù)據(jù)為默認(rèn)
讀取數(shù)據(jù)的時(shí)候,在hbase語(yǔ)句如:get ‘table’,'row',‘cf:column’即可得到對(duì)應(yīng)的數(shù)據(jù)
更新數(shù)據(jù)的時(shí)候,在hbase中沒(méi)有對(duì)應(yīng)更新的概念,只是會(huì)有一個(gè)新的版本,從時(shí)間戳上可以體現(xiàn)出來(lái),所用的語(yǔ)句為
put ‘table’,‘row’,‘cf:name’,‘value’
即可將value的值賦給對(duì)應(yīng)cf列族,name的列
刪除數(shù)據(jù)的區(qū)別,在mysql中刪除數(shù)據(jù)只能是直接刪除一行,或者將某一列置為空,在hbase里面可以直接刪除某一列
(3)索引的區(qū)別
在mysql中可以建立索引,或者過(guò)濾查詢,但是在hbase中,只支持按照rowkey進(jìn)行查詢速率最快
(4)從mysql到nosql的發(fā)展的思考
關(guān)系型數(shù)據(jù)庫(kù)的歷史已經(jīng)很久,但是當(dāng)數(shù)據(jù)量膨脹之后,例如對(duì)于mysql數(shù)據(jù)庫(kù),當(dāng)數(shù)據(jù)量為上億或者更多的時(shí)候,如果按照索引進(jìn)行查詢,可能效果 也不是特別的明顯,最后只能按照主鍵進(jìn)行查詢,或者逐漸發(fā)展為分庫(kù)分表的模式,但是分庫(kù)分表又給運(yùn)維以及使用帶來(lái)了很大的麻煩;于是這個(gè)時(shí)候,nosql數(shù)據(jù)庫(kù)主鍵發(fā)展,nosql簡(jiǎn)稱not only sql,是在數(shù)據(jù)量暴增的當(dāng)前逐漸發(fā)展壯大起來(lái),以nosql里面的hbase作為例子,支持TB以及PB的數(shù)據(jù),并且列的擴(kuò)展特別的靈活
(5)hbase為什么可以存儲(chǔ)海量的數(shù)據(jù)呢
其實(shí)hbase可以看做是mysql分庫(kù)分表后的結(jié)果,只是不同的是mysql分庫(kù)分表后支持索引等,但是對(duì)于hbase僅僅支持rowkey作為主鍵索引,從書中可以知道,hbase的數(shù)據(jù)是按照列進(jìn)行存儲(chǔ)的,并且當(dāng)數(shù)據(jù)過(guò)大的時(shí)候,會(huì)按照行進(jìn)行分裂,如下如所示:
把不同的region放到了不同的機(jī)器,并且最后還有master進(jìn)行管理,即相當(dāng)于對(duì)行列進(jìn)行了一個(gè)劃分,從而存儲(chǔ)大量的數(shù)據(jù)
三、數(shù)據(jù)遷移遇到的一些問(wèn)題
(1)聯(lián)合索引的問(wèn)題
在mysql中會(huì)有一些聯(lián)合索引的情況,例如存在一個(gè)商品與分類對(duì)應(yīng)關(guān)系的表,需要得到某一個(gè)商品的所有分類,也希望可以得到某一個(gè)分類的所有商品,在mysql中直接按照聯(lián)合索引可以達(dá)到要求,但是在hbase的時(shí)候只能按照rowkey查詢?nèi)绾无k呢
經(jīng)過(guò)閱讀相關(guān)的數(shù)據(jù)得到有如下兩種的解決辦法
1、構(gòu)建寬表
在hbase中,允許行跟行之間的列是不同的,只要有共同的列族即可,那么對(duì)于上述的情況,可以構(gòu)建一個(gè)按照分類為rowkey的寬表,如下所示
分類id,作為rowkey
product_id,作為列名字
value存儲(chǔ)為是否刪除
上述即可rowkey為分類id,可以直接從row得到所有的product_id,然后自己過(guò)濾是否刪除
2、構(gòu)建高表
什么是構(gòu)建高表呢,也就是說(shuō)不需要那么多的列,只是存儲(chǔ)多行,因?yàn)樵趆base里面是按照字典順序排序的,因此可以進(jìn)行如下的設(shè)計(jì)
分類id_商品id,作為rowkey
只要scan以1開頭的行,就可以得到所有的數(shù)據(jù)
上述兩種辦法從本質(zhì)上來(lái)說(shuō),都是構(gòu)建了一個(gè)二級(jí)索引來(lái)存儲(chǔ)數(shù)據(jù)