hbase的sql解決方案是怎樣的

hbase的sql解決方案是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司網站建設公司一直秉承“誠信做人,踏實做事”的原則,不欺瞞客戶,是我們最起碼的底線! 以服務為基礎,以質量求生存,以技術求發(fā)展,成交一個客戶多一個朋友!專注中小微企業(yè)官網定制,成都網站制作、網站建設,塑造企業(yè)網絡形象打造互聯(lián)網企業(yè)效應。

    最近的需求是希望能用MySQL、sqlserver這樣的sql來進行hbase的數(shù)據(jù)查詢,這樣不但查詢比起hbase自帶的查詢語言更符合使用習慣,也能夠整合mybatis、hibernate的框架,寫起來不用考慮這么多。我上網一搜:“hbase  sql查詢”,phoenix有最多的教程貼。被這么多人使用,肯定有它的獨到之處,并且劣勢不會那么難以接受,那么我先用phoenix試試效果,看看感受如何。

    首先phoenix的安裝并不困難,簡單來說下載對應hbase版本的phoenix,解壓之后把對應包放入每個hbase RegionServer的lib下面,重啟hbase就可以了。我的hadoop是cdh 6.3.0版本,在安裝的時候沒有遇到什么困難。之后進入phoenix的安裝位置的bin目錄,執(zhí)行sqlline.py,就能在shell中進入phoenix的使用界面了。

hbase的sql解決方案是怎樣的

安裝成功,先試試phoenix的一些基礎操作,比如!tables,create table等等。都沒有問題,使用習慣也和mysql差不多。比較大的不同之處在于插入和更新都用的是upsert,這和hbase也是比較類似的。

    在linux上使用也沒有問題,那么接下來就是使用javaApi進行連接。連接方式也并不困難,和其它組件差不多,配置連接信息然后就能連接了。具體怎么配網上教程很多,我就不做搬運工了。隨便找個鏈接【十二】Phoenix Java API操作        同質化內容那么多,總要說點自己的東西。值得一提的是phoenix是用jdbc連接的,配置看上去就和mysql的連接一樣,顯然這是十分友好的。在按照上面教程操作過后,我感覺十分欣喜,不愧是眾多教程所推薦的中間件,使用起來太舒爽了(除了手動加兩個phoenix的包,也不知道能不能在pom文件里面配置自動加載這樣不值一提的小問題),就連我這樣的小白都能輕松使用。不過教程上面的表都是直接建立在默認命名空間的,假如我想建立在指定命名空間,那應該怎么辦呢?

  按照之前的習慣,我直接將表名改為 命名空間.表名,但是報了錯,表示沒有找到namespace.table這張表。是因為我用的.出錯了嗎?我將.改為:,但還是報錯,報錯信息只是將namespace.table改為namespace:table,說明錯誤類型都是一樣的,錯誤不在這里。

  上網搜索“phoenix  指定命名空間”,大量的帖子告訴了我一件事:phoenix想要使用命名空間映射,需要額外的配置。這里要說一下,很多教程寫的不完全一樣,有的多一些有的少一些,按照經驗來說,多配置一些更不容易出問題。給出一個配置比較全的帖子:HBase - Phoenix的安裝使用教程3(SCHEMA的啟用、操作、關閉)  。在我看各種關于如何開啟phoenix命名空間映射帖子的時候,有些帖子提到這個功能不但無法正常使用,反而還把原本正常的功能弄出問題了。關于如何關閉在上面這個帖子里面也有,我在使用過程中沒有遇到,給大家看看以防萬一。

    我當時看的帖子是cdh版的,帖子現(xiàn)在找不到了,配置內容是在web頁面完成的,配置內容更多一些,我把完成后的結果給大家看看,步驟基本都差不多,方法不同而已。

hbase的sql解決方案是怎樣的

hbase的sql解決方案是怎樣的

分別在客戶端和服務端配置信息,并將這兩個配置寫入phoenix的bin目錄的hbase.site.xml文件內。

hbase的sql解決方案是怎樣的

    之后重啟hbase,在shell中進入phoenix,就能夠使用create schema 來創(chuàng)建命名空間了。

    再試試用java api來連接,先將之前下載的hbase.site.xml換成現(xiàn)在的,然后再次連接,報錯配置信息錯誤,和我之前新加的phoenix配置有關。感覺像是我哪里配置沒配好,找半天也找不到。本著先能用的方式在創(chuàng)建phoenix連接的時候手動加入配置:

Properties pros = new Properties();
pros.setProperty("phoenix.schema.isNamespaceMappingEnabled", "true");
pros.setProperty("phoenix.schema.mapSystemTablesToNamespace", Boolean.toString(true));

之后再創(chuàng)建的連接就沒有問題了。能夠直接查詢多個命名空間下面的表,相當于跨庫查詢。要注意的一點是:當你使用shell進入phoenix創(chuàng)建命名空間下面的表時,需要先use schema,然后才能創(chuàng)建表。但是在你使用java api進行創(chuàng)建的時候就不需要這么麻煩,直接 create table schema.table即可,不需要像shell中一樣那么麻煩。假如像shell中一樣先use schema 再create table反而會報錯。關于這一點我倒是沒看到有教程提到,明明這才是比較有價值的東西。

舉個栗子:

public static void selectTable() throws SQLException{
    	String sql = "select * from ENTERPRISE_INFORMATION.TEST_PHOENIX_API a left join ENTERPRISE_INFORMATION.TEST_PHOENIX_API2 b on a.mykey = b.mykey ";
    	rs = stat.executeQuery(sql);
    	JSONArray array = resultSetToJosnArray(rs);
    	System.out.println(array.toJSONString());
    }
    
    public static void testCreateTable() throws SQLException {
        String sql="create table ENTERPRISE_INFORMATION.test_phoenix_api2(mykey integer not null primary key ,mycolumn varchar )";
        stat.executeUpdate(sql);
        conn.commit();
    }
 
    public static void upsert() throws SQLException {
        String sql1="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(1,'test4')";
        String sql2="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(2,'test5')";
        String sql3="upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(3,'test6')";
        stat.executeUpdate(sql1);
        stat.executeUpdate(sql2);
        stat.executeUpdate(sql3);
        conn.commit();
    }
 
    public static void delete() throws SQLException {
        String sql1="delete from ENTERPRISE_INFORMATION.test_phoenix_api where mykey = 1";
        stat.executeUpdate(sql1);
        conn.commit();
    }
 
    public static void deleteTable() throws SQLException {
    	String sql = "drop table ENTERPRISE_INFORMATION.test_phoenix_api";
    	stat.executeUpdate(sql);
    	conn.commit();    	

    創(chuàng)建連接之后,執(zhí)行的表名直接使用schema.table即可,不加雙引號的情況下,無論大小寫都會被轉換成大寫。在執(zhí)行select的時候,要使用rs = stat.executeQuery(sql);在增刪改的時候,使用stat.executeUpdate(sql)。假如在增刪改的時候使用executeQuery,可能會報錯。另外還要注意一點,phoenix在識別string類型數(shù)據(jù)的時候要使用單引號而不是雙引號,雙引號會報錯無法識別,這一點無論是在shell還是java api執(zhí)行的時候都是一樣的,比如我上面的sql:

"upsert into ENTERPRISE_INFORMATION.test_phoenix_api2 values(1,'test4')";

test4是用單引號包起來的,這一點一定要注意。

    我之前使用的是squirrel-3.7.1來進行phoenix的圖形化界面操作。配置比較簡單,需要把phoenix的驅動加入,之后寫下phoenix的jdbc連接就可以了。使用還算,并且能夠連接多種數(shù)據(jù)庫。但是在我進行phoenix命名空間映射后,就無法連接上了。報錯和我之前通過java api連接報錯一樣,缺少關于phoenix.schema的配置。這一點沒法解決,我真找不到哪里的配置有問題。網上大把的教程沒能解決我這個問題,最后我只有放棄squirrel,而是使用shell來操作phoenix。

    以上都是小問題,還在我的接受范圍之內。那么接下來就是要將phoenix和hbase已有的表進行映射。按照我對phoenix的理解,phoenix在使用上是和mysql一樣的,schema映射為命名空間,table假如沒有就在hbase中新建一個表并且將它們映射在一起,我操作phoenix中的表就能將修改轉換成hbase的語句;假如table和hbase已有表名一樣那么就新建映射,操作還是一樣的。那么最好hbase中的表名本身就是大寫,我就不用特地用雙引號修飾表名,寫起來方便很多。

    事實上我的想法沒有錯,只要映射的表名相同,那么就能夠通過phoenix來修改hbase的數(shù)據(jù)。但是當我通過phoenix修改已有數(shù)據(jù)的時候,我發(fā)現(xiàn)了一件奇怪的事——phoenix不能看見hbase已有數(shù)據(jù),但是假如把phoenix表刪掉的話,hbase表也會一起被刪掉,這說明映射是成功的。但是為什么在phoenix中會看不到數(shù)據(jù)呢?在hbase中是能夠看到的數(shù)據(jù)的,當我嘗試用phoenix往映射表中加數(shù)據(jù),再在hbase中查看數(shù)據(jù)時,發(fā)現(xiàn)了一件奇怪的事:

hbase創(chuàng)表(通過sqoop將mysql表導入hbase):

sqoop import \
--connect jdbc:mysql://192.168.49.201:3306/envir \
--username root \
--password Hskj123456! \
--table hs_apply_detailinfo_r  \
--hbase-table ENVIR:HS_APPLY_DETAILINFO_R \
--m 1 \
--column-family 0  \
--hbase-create-table \
--hbase-row-key ID

phoenix創(chuàng)表:

CREATE TABLE envir.hs_apply_detailinfo_r (
  ID varchar primary key,
  APPLY_TYPE varchar ,
  APPLY_ID varchar ,
  MAT_CD varchar ,
  MAT_NUM double ,
  PRODUCE_TIME date ,
  OUTDATE_TIME date,
  SUP_CD varchar
)

phoenix修改數(shù)據(jù):

upsert envir.hs_apply_detailinfo_r (ID,APPLY_ID) values ('10','2');

    在phoenix中查看envir.hs_apply_detailinfo_r的數(shù)據(jù),能看到新加的數(shù)據(jù),并且只有這一條,hbase導入的表的數(shù)據(jù)是沒有的。再到hbase中scan一下,發(fā)現(xiàn)了表中新加了數(shù)據(jù),而不是修改原來row為10 ,列為0:APPLY_ID的單元格,而是新加了一個單元格,列限定符為十六進制碼,而不是我在phoenix中輸入的APPLY_ID;并且值也不是我所輸入的字符串2,而是一串十六進制碼。在hue中,我也無法查看由phoenix映射的表的數(shù)據(jù)。

    這個問題比較大,直接影響到我是否會繼續(xù)使用phoenix,但是我又不是很明白哪里出了問題,在網上一直搜索,大概知道了問題出在phoenix在保存字符的時候處理方式和hbase是不一樣的,假如phoenix表字段要映射到hbase表字段,要加上column_encoded_bytes=0;并且字段屬性要修改,能用unsigned_的盡量用unsigned_。

Phoenix 映射已存在 HBase 表,查詢不到數(shù)據(jù)

phoenix映射hbase中數(shù)據(jù)類型問題

所以phoenix表的創(chuàng)建應該改為:

CREATE TABLE envir.hs_apply_detailinfo_r(
  "ID" varchar primary key,
  "info"."APPLY_TYPE" VARBINARY,
  "info"."APPLY_ID" VARBINARY,
  "info"."MAT_CD" varchar,
  "info"."MAT_NUM" UNSIGNED_DOUBLE,
  "info"."PRODUCE_TIME" UNSIGNED_DATE,
  "info"."OUTDATE_TIME" UNSIGNED_DATE,
  "info"."SUP_CD" varchar)column_encoded_bytes=0;

    我將列族改為了info,所以上面用sqoop導入的時候也應該將--column-family改為info。0是在phoenix不指定列族的時候默認列族。

    修改之后,表字段映射的問題解決了,我能修改row=10,列為info:APPLY_TYPE單元格的值了。但是數(shù)值的問題依然沒有解決,我在phoenix輸入的值為‘2’,在hbase查看的結果依然是十六進制碼。這個問題有點無解,太底層了,我看了phoenix官網給出的關于數(shù)據(jù)類型轉換的介紹(http://phoenix.apache.org/language/datatypes.html) ,里面沒有解決辦法。其它網友也遇到了類似的問題,給出的解決辦法是:當用hbase存儲的時候,先用Bytes.toBytes()壓縮成phoenix的形式,這樣就能用phoenix來獲得hbase所插入的數(shù)據(jù)了。

    此外,phoenix存儲hbase的int時會有問題,會報錯字段長度不夠。還是以上的hbase表和phoenix表,假如我先創(chuàng)建phoenix表,再通過sqoop將數(shù)據(jù)導入hbase,就會報錯字段長度不夠(hbase-presto-phoenix遇到的坑)。那么假如要使用phoenix,我就需要放棄很多東西,數(shù)據(jù)的導入不能用sqoop導入,而要手寫map/reduce;數(shù)據(jù)的查詢修改都要使用phoenix,不然無法正確識別。從mysql向HBase+Phoenix遷移數(shù)據(jù)的心得總結   中寫了一些解決方案,但是我看不懂,對我來說太難了,而且太麻煩了。與其繼續(xù)堅持下去,不如換個合適的中間件來滿足需求。

    我同事用了antdb(antdb官網),我大概看了它的使用過程,和phoenix感覺差不多,創(chuàng)建一個虛擬的mysql來映射hbase表,讓用戶可以像修改mysql一樣修改hbase數(shù)據(jù)。但是不能設置主鍵,一些像phoenix的特性不知道有沒有,并且在我使用過程中RegionServer直接被停了,不知道什么原因。感覺太不成熟,也沒有什么教程貼來教教我如何用,還是當做備用方案,先去看看simplehbase如何使用吧。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

網頁名稱:hbase的sql解決方案是怎樣的
本文鏈接:http://muchs.cn/article30/gppjpo.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供App設計、靜態(tài)網站網站建設、服務器托管、外貿網站建設、云服務器

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿網站制作