分布式數據庫HBase 參考答案_第1頁
分布式數據庫HBase 參考答案_第2頁
分布式數據庫HBase 參考答案_第3頁
分布式數據庫HBase 參考答案_第4頁
分布式數據庫HBase 參考答案_第5頁
已閱讀5頁,還剩23頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

《分布式數據庫HBase》參考答案第1章數據庫概述練習題答案1.選擇題(1)ABC;(2)C;(3)ABCD;2.簡答題(1)常見的關系型數據庫有哪些?答:常見的關系型數據庫有Oracle公司的Oracle和MySQL、IBM公司的DB2、Microsoft公司的Access和SQLServer.(2)分布式數據庫與關系型數據庫有什么區別?答:分布式數據庫將數據分散存儲在多臺獨立的計算機上,而關系型數據庫將數據集中存儲在一臺計算機上。傳統的關系型數據庫采用二維表的儲存方式,以行和列的方式進行存儲。分布式數據庫通常以數據集的方式,將大量數據集中存儲在一起,類似于鍵值對、圖結構或者文檔。分布式數據庫與關系型數據庫在數據存儲、數據結構、應用場景、可靠性和管理復雜性等方面存在明顯的區別。第2章HBase簡介與安裝練習題答案1.單選題(1)A;(2)A;(3)D;(4)A;(5)C;(6)A2.多選題(1)BCD;(2)ABCD;(3)AB第3章HBase原理與架構練習題答案1.HBase的核心組件有哪些?(1)Client。Client是整個HBase系統的入口,可以通過Client直接操作HBase。(2)ZooKeeper。ZooKeeper是一個開放源代碼的分布式應用程序協調服務,是Hadoop和HBase的重要組件。(3)HMaster。HMaster管理HRegionServer的負載均衡,調整HRegion的分布。例如,在Region分片后,HMaster負責將HRegion分配至HRegionserver;在HRegionserver宕機后,HMaster會將HRegionserver內的HRegion遷移至其他HRegionserver上。(4)HRegionServer。HRegionServer主要負責響應用戶的I/O請求,在HDFS文件系統中讀/寫數據,是HBase中核心的模塊。HRegionServer內部管理了一系列HRegion,HRegion對應了Table中的一個Region,HRegion由多個HStore組成。2.請簡要描述HBase的讀流程。(1)Client先訪問zookeeper,獲取hbase:meta表位于哪個RegionServer。(2)訪問對應的RegionServer,獲取hbase:meta表,根據讀請求的namespace:table/rowkey,查詢出目標數據位于哪個RegionServer中的哪個Region中。并將該table的region信息以及meta表的位置信息緩存在客戶端的metacache,方便下次訪問。(3)與目標RegionServer進行通訊;(4)分別在BlockCache(讀緩存),MemStore和StoreFile(HFile)中查詢目標數據,并將查到的所有數據進行合并。此處所有數據是指同一條數據的不同版本(timestamp)或者不同的類型(Put/Delete)。(5)將從文件中查詢到的數據塊(Block,HFile數據存儲單元,默認大小為64KB)緩存到BlockCache。(6)將合并后的最終結果返回給客戶端。3.請簡要描述HBase的寫流程。(1)Client先訪問zookeeper,獲取hbase:meta表位于哪個RegionServer。(2)訪問對應的RegionServer,獲取hbase:meta表,根據讀請求的namespace:table/rowkey,查詢出目標數據位于哪個RegionServer中的哪個Region中。并將該table的region信息以及meta表的位置信息緩存在客戶端的metacache,方便下次訪問。(3)與目標RegionServer進行通訊;(4)將數據順序寫入(追加)到WAL;(5)將數據寫入對應的MemStore,數據會在MemStore進行排序;(6)向客戶端發送ack;(7)等達到MemStore的刷寫時機后,將數據刷寫到HFile。第4章HBaseShell練習題答案1.如何在命令行中啟動HBaseShell?答:在命令行中啟動HBaseShell,可以執行以下命令:hbaseshell這條命令將啟動HBaseShell,并顯示一個命令提示符,表示HBaseShell已經就緒。用戶可以在提示符下輸入各種HBaseShell命令進行操作。2.列出至少三個HBaseShell中用于獲取幫助的命令。答:help:這個命令用于查看HBaseShell的所有命令的列表。通過輸入help并回車,你將看到一個包含所有可用命令的列表,這些命令按功能分類組織。help'command-name':如果你想要獲取特定命令的詳細信息或使用方法,可以在help命令后面加上命令的名稱。例如,輸入helpcreate將顯示關于create命令的詳細信息,包括其用途、語法和參數等。version:這個命令用于查看當前HBase的版本信息。雖然它主要用于版本檢查,但它也可以幫助你確認你正在使用的HBaseShell的版本,以及任何與版本相關的注意事項或限制。3.描述HBase中命名空間的作用,并給出創建新命名空間的命令示例。答:在HBase中,命名空間(Namespace)是一個用于組織和隔離不同表集合的機制。通過命名空間,你可以將相關的表組織在一起,并在邏輯上將它們與其他表隔離開來。這種隔離有助于更好地管理、監控和維護HBase集群中的表。hbase(main):006:0>create_namespace'ns1'4.如果你想在Student表中添加一個新的列族Scores,應該使用哪個命令?答:在HBase中,如果你想在Student表中添加一個新的列族Scores,應該使用alter命令。具體的命令如下:hbase(main):001:0>alter'student',{NAME=>'scores'}5.如果要刪除Student表中行鍵為001,列族為info,列名為name的數據,應該使用哪個命令?答:在HBase中,刪除特定行鍵、列族和列名的數據,需要使用delete命令。為了刪除student表中行鍵為001,列族為info,列名為name的數據,應該使用以下命令:hbase(main):001:0>delete'student','001','info:name'6.假設你負責管理一個HBase數據庫,其中存儲了用戶信息?,F在需要創建一個新的表來存儲用戶的訂單信息,每個訂單包含訂單號、商品名稱和數量。請設計表結構,并給出創建表、插入數據、查詢數據的HBaseShell命令示例。答:為了存儲用戶的訂單信息,我們可以在HBase中創建一個名為user_orders的表。在這個表中,行鍵(RowKey)可以是訂單號,這樣便于唯一標識和檢索每個訂單。列族(ColumnFamily)可以包含商品名稱和數量等信息。以下是表結構的設計:表名:user_orders列族:order_details:用于存儲訂單詳情,如商品名稱和數量。在HBase中,列名通常是列族名和列限定符的組合,用冒號(:)分隔。因此,我們可以將商品名稱作為列限定符,數量作為該列的值。HBaseShell命令示例如下:(1)創建表hbase(main):001:0>create'user_orders','order_details'(2)插入數據假設我們有一個訂單,訂單號為ORDER123,包含商品ProductA數量為5和商品ProductB數量為3。插入這些數據的命令如下:hbase(main):002:0>put'user_orders','ORDER123','order_details:ProductA',5hbase(main):003:0>put'user_orders','ORDER123','order_details:ProductB',3(3)查詢數據要查詢訂單ORDER123中所有商品的信息,我們可以使用get命令:hbase(main):004:0>get'user_orders','ORDER123'如果要查詢特定商品的信息,比如商品ProductA的數量,可以使用scan命令結合過濾器:hbase(main):005:0>scan'user_orders',{FILTER=>"KeyOnlyFilter(||)ANDColumnPrefixFilter('order_details:ProductA')"}第5章HBaseAPI練習題答案1.描述HBaseAPI在大數據生態系統中的位置和作用。答:HBaseAPI在大數據生態系統中占據核心位置,是連接外部系統與HBase的關鍵橋梁。它提供了豐富的操作接口,支持創建表、插入、查詢和刪除數據等操作,滿足大數據存儲和管理的需求。同時,HBaseAPI支持多種編程語言,提高了開發的靈活性和效率。作為大數據存儲層的重要組成部分,HBaseAPI與其他大數據處理和分析工具緊密集成,實現數據的聯合查詢和實時分析。它使得大數據應用能夠高效處理海量數據,為業務決策提供有力支持。2.為什么Java是處理HBase數據的首選語言?答:Java是處理HBase數據的首選語言,主要因為HBase本身由Java編寫,因此JavaAPI對HBase的支持十分完善,提供了豐富的操作接口。此外,Java擁有強大的社區支持和豐富的生態系統,為開發者提供了豐富的資源和幫助。Java的跨平臺性也確保了HBase應用的廣泛適用性。同時,Java在大數據處理方面具備優勢,能夠高效處理海量數據,并提供強大的并發處理能力。因此,Java是處理HBase數據的理想選擇,能夠滿足開發者的需求并提升數據處理效率。3.創建一個用戶信息表:假設你正在開發一個用戶管理系統,需要存儲用戶的基本信息,如用戶名、密碼、郵箱和電話號碼。你可以使用HBase創建一個表來存儲這些信息。(1)使用JavaAPI,創建一個名為"user_info"的表,并定義列族"basic_info"。(2)插入一些示例數據,如用戶名、密碼、郵箱和電話號碼。(3)使用JavaAPI查詢表中的數據,并驗證數據的正確性。答:確保有一個運行中的HBase實例,并且已經在項目中包含了HBase的Java客戶端庫。以下是一個Java示例,用于創建名為"user_info"的表,定義列族"basic_info",插入示例數據,并查詢驗證數據。importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.hbase.HBaseConfiguration;importorg.apache.hadoop.hbase.TableName;importorg.apache.hadoop.hbase.client.*;importorg.apache.hadoop.hbase.util.Bytes;importjava.io.IOException;publicclassHBaseUserInfoExample{publicstaticvoidmain(String[]args)throwsIOException{//創建HBase配置對象Configurationconfig=HBaseConfiguration.create();config.set("hbase.zookeeper.quorum","localhost");//設置ZooKeeper的地址,根據實際情況修改config.set("perty.clientPort","2181");//設置ZooKeeper的端口號//創建HBase連接try(Connectionconnection=ConnectionFactory.createConnection(config);Adminadmin=connection.getAdmin()){//創建名為"user_info"的表,包含列族"basic_info"TableNametableName=TableName.valueOf("user_info");if(!admin.tableExists(tableName)){TableDescriptorBuildertableDescriptorBuilder=TableDescriptorBuilder.newBuilder(tableName);tableDescriptorBuilder.setColumnFamily(ColumnFamilyDescriptorBuilder.of("basic_info"));admin.createTable(tableDescriptorBuilder.build());System.out.println("Table'user_info'createdsuccessfully.");}else{System.out.println("Table'user_info'alreadyexists.");}//插入示例數據try(Tabletable=connection.getTable(tableName)){Putput=newPut(Bytes.toBytes("user1"));//設置行鍵為"user1"put.addColumn(Bytes.toBytes("basic_info"),Bytes.toBytes("username"),Bytes.toBytes("john_doe"));put.addColumn(Bytes.toBytes("basic_info"),Bytes.toBytes("password"),Bytes.toBytes("password123"));put.addColumn(Bytes.toBytes("basic_info"),Bytes.toBytes("email"),Bytes.toBytes("john.doe@"));put.addColumn(Bytes.toBytes("basic_info"),Bytes.toBytes("phone"),Bytes.toBytes("1234567890"));table.put(put);System.out.println("Datainsertedsuccessfully.");}//查詢并驗證數據try(Tabletable=connection.getTable(tableName);ResultScannerscanner=table.getScanner(newScan())){for(Resultresult:scanner){byte[]rowKey=result.getRow();System.out.println("Rowkey:"+Bytes.toString(rowKey));for(Cellcell:result.rawCells()){Stringfamily=Bytes.toString(CellUtil.cloneFamily(cell));Stringqualifier=Bytes.toString(CellUtil.cloneQualifier(cell));Stringvalue=Bytes.toString(CellUtil.cloneValue(cell));System.out.println(""+family+":"+qualifier+"="+value);}}}}}}4.使用過濾器優化查詢:假設你正在開發一個電商網站,需要存儲商品信息,并能夠根據不同的條件進行查詢。你可以使用HBase存儲商品信息,并使用過濾器來優化查詢。(1)使用JavaAPI創建一個名為"products"的表,并定義列族"info"。(2)插入一些示例數據,包括商品ID、名稱、價格和描述等信息。(3)使用JavaAPI創建一個過濾器,僅選擇價格低于100元的商品。(4)使用帶有過濾器的查詢來獲取滿足條件的商品列表,并驗證結果。答:確保有一個運行中的HBase實例,并且已經在項目中包含了HBase的Java客戶端庫。下面是一個Java示例,用于創建一個名為"products"的表,定義列族"info",插入示例數據,并使用過濾器來查詢價格低于100元的商品。importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.hbase.*;importorg.apache.hadoop.hbase.client.*;importorg.apache.hadoop.hbase.filter.*;importorg.apache.hadoop.hbase.util.Bytes;importjava.io.IOException;publicclassHBaseProductExample{publicstaticvoidmain(String[]args)throwsIOException{//創建HBase配置對象Configurationconfig=HBaseConfiguration.create();config.set("hbase.zookeeper.quorum","localhost");//設置ZooKeeper的地址,根據實際情況修改config.set("perty.clientPort","2181");//設置ZooKeeper的端口號//創建HBase連接try(Connectionconnection=ConnectionFactory.createConnection(config);Adminadmin=connection.getAdmin()){//創建名為"products"的表,包含列族"info"TableNametableName=TableName.valueOf("products");if(!admin.tableExists(tableName)){TableDescriptorBuildertableDescriptorBuilder=TableDescriptorBuilder.newBuilder(tableName);tableDescriptorBuilder.setColumnFamily(ColumnFamilyDescriptorBuilder.of("info"));admin.createTable(tableDescriptorBuilder.build());System.out.println("Table'products'createdsuccessfully.");}else{System.out.println("Table'products'alreadyexists.");}//插入示例數據try(Tabletable=connection.getTable(tableName)){Putput1=newPut(Bytes.toBytes("product1"));put1.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("ProductA"));put1.addColumn(Bytes.toBytes("info"),Bytes.toBytes("price"),Bytes.toBytes("50"));put1.addColumn(Bytes.toBytes("info"),Bytes.toBytes("description"),Bytes.toBytes("DescriptionforProductA"));Putput2=newPut(Bytes.toBytes("product2"));put2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("name"),Bytes.toBytes("ProductB"));put2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("price"),Bytes.toBytes("150"));put2.addColumn(Bytes.toBytes("info"),Bytes.toBytes("description"),Bytes.toBytes("DescriptionforProductB"));table.put(put1);table.put(put2);System.out.println("Datainsertedsuccessfully.");}//創建過濾器,僅選擇價格低于100元的商品Filterfilter=newSingleColumnValueFilter(Bytes.toBytes("info"),//列族Bytes.toBytes("price"),//列限定符CompareOperator.LESS,//比較操作符newBinaryComparator(Bytes.toBytes("100"))//比較的值);//使用帶有過濾器的查詢來獲取滿足條件的商品列表try(Tabletable=connection.getTable(tableName);ResultScannerscanner=table.getScanner(newScan().setFilter(filter))){for(Resultresult:scanner){byte[]rowKey=result.getRow();StringrowKeyStr=Bytes.toString(rowKey);System.out.println("Rowkey:"+rowKeyStr);for(Cellcell:result.rawCells()){Stringfamily=Bytes.toString(CellUtil.cloneFamily(cell));Stringqualifier=Bytes.toString(CellUtil.cloneQualifier(cell));Stringvalue=Bytes.toString(CellUtil.cloneValue(cell));System.out.println(""+family+":"+qualifier+"="+value);}}}}}}第6章HBase模式設計與優化練習題答案1.選擇題(1)D;(2)B;(3)B;(4)B;(5)D;(6)B;(7)A;(8)B;(9)B;(10)B2.思考題(1)行鍵設計對HBase表性能有何影響,你會如何設計一個高效的行鍵?答:①行鍵設計對HBase表性能的影響查詢性能:行鍵決定數據在HBase中的存儲順序,因此直接影響查詢效率。合理的行鍵設計可以減少全表掃描,提高查詢速度。數據分布:行鍵影響數據在HBaseRegion中的分布。糟糕的行鍵設計可能導致數據熱點問題,造成某些Region負載過重,影響整體性能。數據壓縮和存儲:行鍵的長度和唯一性影響存儲效率和壓縮比率。較短的行鍵可以節省存儲空間。②高效行鍵設計策略避免數據熱點:通過在行鍵中引入隨機化元素(如哈希前綴)或使用復合鍵(如用戶ID+時間戳),避免所有請求集中在一個Region。考慮查詢模式:設計行鍵時應優先考慮常見的查詢模式,使得常用查詢能通過行鍵前綴快速定位數據。簡短且唯一:行鍵應盡可能簡短,以節省存儲空間,但仍需保持唯一性以避免數據覆蓋。(2)列族在HBase表設計中扮演什么角色,如何合理規劃列族以優化性能和存儲?答:①列族在HBase表設計中扮演的角色數據分組、存儲管理、內存管理。②合理規劃列族策略保持列族數量適中,通常建議1-3個列族,以避免過多的I/O操作和內存消耗。按訪問模式分組,將訪問頻率、存儲時間相似的列放在同一個列族,以優化塊緩存和存儲配置。列族名稱簡短,列族名稱在每個數據單元中存儲,簡短名稱可以節省存儲空間。(3)如何利用HBase的TTL特性管理數據生命周期,有哪些具體應用場景?答:TTL(TimetoLive)用于自動刪除超過指定時間的數據,幫助管理數據的生命周期。常用于日志管理系統、緩存系統和時間序列數據中,自動清除過期數據,減少存儲壓力并優化查詢性能。(4)HBase表的動態擴展性如何影響Schema設計,你在設計中如何考慮這一特性?答:①動態擴展性的影響Schema靈活性:HBase允許動態添加或刪除列,因此在設計Schema時可以考慮未來可能的變化和擴展需求,而無需預先定義所有可能的列。預分區策略:為了支持數據的動態擴展,可以在Schema設計中使用預分區策略,確保當數據量增加時能夠均勻分布在各個Region中。表的適應性:動態擴展性要求Schema設計能夠適應數據規模和訪問模式的變化,例如預留字段或設計靈活的RowKey結構。②設計考慮預留字段:在行鍵或列族設計時考慮未來可能需要的擴展,避免Schema的過度固定化。預分區:在表創建時預先定義分區,確保數據在RegionServer之間均勻分布,避免數據傾斜。模塊化設計:將Schema設計得更模塊化,允許不同模塊的數據獨立擴展和變化,而不會影響整體Schema的穩定性。(5)在設計HBase表時,應如何平衡數據冗余和容錯性需求?答:①關于平衡數據冗余和容錯性數據冗余:通過數據冗余(如多副本存儲、數據重復寫入)來提高容錯性,但這會增加存儲成本和管理復雜度。容錯性:在HBase中,數據的高可用性和容錯性主要通過HDFS的多副本機制和HBase的自動恢復功能來實現。②策略必要的冗余:根據業務需求,決定哪些數據需要冗余存儲。對于關鍵數據,可以采用多副本或定期備份的方式來提高容錯性。優化存儲:避免過度冗余,對于非關鍵數據,可以通過減少副本數量或使用壓縮技術來節省存儲空間。多級容錯:結合HDFS的多副本存儲和應用層的數據校驗機制,提供多級別的容錯保護,既保證數據的高可用性,又控制存儲成本。第七章MapReduceOnHBase練習題答案1.實驗名稱HBase中的MapReduce。2.實驗目的(1)掌握MapReduce與Hbase結合的方法。(2)掌握Hbase對MapReduce結果的操作。3.實驗內容統計每個單詞出現的頻率,實現對指定目錄或文件中單詞的出現次數進行統計,并將結果保存到指定的HBase表。4.實驗步驟統計每個單詞出現的次數步驟1:新建Maven工程hbase_mr。打開IDEA,在菜單欄中依次選擇file->new->NewProject,如圖7-1所示。圖7-1新建工程步驟2:選擇新建項目類型Maven,選擇ProjectSDK,如圖7-2所示。圖7-2選擇工程類型步驟3:設置項目名和存儲路徑,添加組名,如圖7-3所示。圖7-3設置工程參數步驟4:添加依賴。在工程左側結構的pom.xml中添加依賴,具體依賴如下。<dependencies>

<dependency>

<groupId>org.apache.hadoop</groupId>

<artifactId>hadoop-client</artifactId>

<version>3.1.4</version>

</dependency>

<dependency>

<groupId>org.apache.hadoop</groupId>

<artifactId>hadoop-auth</artifactId>

<version>3.1.4</version>

</dependency>

<!--/artifact/org.apache.hbase/hbase-client-->

<dependency>

<groupId>org.apache.hbase</groupId>

<artifactId>hbase-client</artifactId>

<version>2.4.6</version>

</dependency>

<dependency>

<groupId>org.apache.hbase</groupId>

<artifactId>hbase-mapreduce</artifactId>

<version>2.4.6</version>

</dependency>

<dependency>

<groupId>org.apache.hbase</groupId>

<artifactId>hbase-server</artifactId>

<version>2.4.6</version>

</dependency>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>org.testng</groupId>

<artifactId>testng</artifactId>

<version>6.14.3</version>

<scope>test</scope>

</dependency>

</dependencies>添加完成后打開Maven界面,點擊右上角圖標更新依賴,如圖7-4所示。圖7-4更新依賴示意圖步驟5:開發MR程序實現功能,分別編寫WordCountMapper類、WordCountReducer類和WordCount類。其中在靜態類WordCountMapper實現map()方法,在map()方法對讀入的每個單詞key構造生成(key,1)。WordCountReducer將map傳輸過來的鍵值對進行計數,實現單詞統計。WordCount類中設置設置Map處理類,設置Reduce處理類以及設置輸入和輸出目錄。具體實現代碼如下。importjava.io.IOException;

importorg.apache.hadoop.conf.Configuration;

importorg.apache.hadoop.fs.Path;

importorg.apache.hadoop.io.IntWritable;

importorg.apache.hadoop.io.LongWritable;

importorg.apache.hadoop.io.Text;

importorg.apache.hadoop.mapreduce.Job;

importorg.apache.hadoop.mapreduce.Mapper;

importorg.apache.hadoop.mapreduce.Reducer;

importorg.apache.hadoop.mapreduce.lib.input.FileInputFormat;

importorg.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

importorg.apache.hadoop.util.GenericOptionsParser;

publicclassWordCount{

//計數變量

privatestaticfinalIntWritableONE=newIntWritable(1);

/**

*@authorMapper<LongWritable,Text,Text,IntWritable>中LongWritable,IntWritable是Hadoop數據類型表示長整型和整形

*<p>

*LongWritable,Text表示輸入類型(比如本應用單詞計數輸入是偏移量(字符串中的第一個單詞的其實位置),對應的單詞(值))

*Text,IntWritable表示輸出類型輸出是單詞和他的個數

*注意:map函數中前兩個參數LongWritablekey,Textvalue和輸出類型不一致

*所以后面要設置輸出類型要使他們一致

*/

//Map過程

publicstaticclassWordCountMapperextendsMapper<LongWritable,Text,Text,IntWritable>{

/***

*/

@Override

protectedvoidmap(LongWritablekey,Textvalue,Mapper<LongWritable,Text,Text,IntWritable>.Contextcontext)

throwsIOException,InterruptedException{

//默認的map的value是每一行,我這里自定義的是以空格分割

String[]vs=value.toString().split("\\s");

for(Stringv:vs){

//寫出去

context.write(newText(v),ONE);

}

}

}

//Reduce過程

/***

*@author

*Text,IntWritable輸入類型,從map過程獲得既map的輸出作為Reduce的輸入

*Text,IntWritable輸出類型

*/

publicstaticclassWordCountReducerextendsReducer<Text,IntWritable,Text,IntWritable>{

@Override

protectedvoidreduce(Textkey,Iterable<IntWritable>values,

Reducer<Text,IntWritable,Text,IntWritable>.Contextcontext)throwsIOException,InterruptedException{

intcount=0;

for(IntWritablev:values){

count+=v.get();//單詞個數加一

}

context.write(key,newIntWritable(count));

}

}

publicstaticvoidmain(String[]args){

Configurationconf=newConfiguration();

try{

//得到一個Job并設置名字

Jobjob=Job.getInstance(conf,"wordcount1");

//設置Jar使本程序在Hadoop中運行

job.setJarByClass(WordCount.class);

//設置Map處理類

job.setMapperClass(WordCountMapper.class);

//設置map的輸出類型,因為不一致,所以要設置

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

//設置Reduce處理類

job.setReducerClass(WordCountReducer.class);

//設置輸入和輸出目錄

FileInputFormat.addInputPath(job,newPath("hdfs://master:8020/user/root/words.txt"));

FileOutputFormat.setOutputPath(job,newPath("hdfs://master:8020/hbase/wordcount"));

//啟動運行

System.exit(job.waitForCompletion(true)?0:1);

}catch(IOExceptione){

e.printStackTrace();

}catch(ClassNotFoundExceptione){

e.printStackTrace();

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}步驟6:打開IDEA中Maven界面,同時選擇clean和package,點擊運行將代碼打成jar包。打包過程如圖7-5所示。圖7-5打包過程上傳jar包到集群,通過yarn調度執行提交任務。[root@masteropt]#yarnjarhbase_mr-1.0-SNAPSHOT.jarcom.huan.mr1.WordCount步驟7:查看HDFS上文件以及文件內容。具體代碼如下。如圖7-6所示。[root@masteropt]#hdfsdfs-ls/hbase/wordcount圖7-6wordcount文件讀取單詞計數結果,代碼如下。如圖7-7所示。[root@masteropt]#hdfsdfs-cat/hbase/wordcount/part-r-00000圖7-7wordcount文件內容第8章HBase綜合實戰練習題答案1.實驗名稱MySQL數據遷移到HBase2.實驗目的(1)掌握JavaAPI操作MySQL數據庫的方法。(2)掌握JavaAPI操作HBase的方法。3.實驗內容將MySQL數據庫中學生信息表studentInfo、課程信息表courseInfo和成績表gradeInfo的數據聚合到HBase同一張表中,將studentInfo表映射到HBase的StuInfo列族,將gradeInfo和courseInfo表信息映射到Grades列族中。(1)MySQL數據庫到HBase的表設計。(2)實現MySQL數據庫數據讀取。(3)HBase表的創建。(4)HBase表連接以及數據查詢4.實驗步驟(1)創建Coursesel.sql文件步驟1:SQL文件內容如下:SETNAMESutf8mb4;SETFOREIGN_KEY_CHECKS=0;--------------------------------Tablestructureforcourseinfo------------------------------DROPTABLEIFEXISTS`courseinfo`;CREATETABLE`courseinfo`(`課程號`int(11)NOTNULL,`課程名`char(20)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,`教師`char(20)CHARACTERSETutf8COLLATEutf8_general_ciNULLDEFAULTNULL,PRIMARYKEY(`課程號`)USINGBTREE)ENGINE=InnoDBCHARACTERSET=utf8COLLATE=utf8_general_ciROW_FORMAT=Compact;--------------------------------Recordsofcourseinfo------------------------------INSERTINTO`courseinfo`VALUES(1,'Spark','liu');INSERTINTO`courseinfo`VALUES(2,'Scala','zhang');INSERTINTO`courseinfo`VALUES(3,'Python','sun');--------------------------------Tablestructureforgradeinfo------------------------------DROPTABLEIFEXISTS`gradeinfo`;CREATETABLE`gradeinfo`(`學號`int(11)NOTNULL,`課程號`int(11)NOTNULL,`成績`int(3)NULLDEFAULTNULL,PRIMARYKEY(`學號`,`課程號`)USINGBTREE)ENGINE=InnoDBCHARACTERSET=utf8COLLATE=utf8_general_ciROW_FORMAT=Compact;--------------------------------Recordsofgradeinfo------------------------------INSERTINTO`gradeinfo`VALUES(1,1,80);INSERTINTO`gradeinfo`VALUES(1,2,90);INSERTINTO`gradeinfo`VALUES(2,1,85);INSERTINTO`gradeinfo`VALUES(2,2,78);INSERTINTO`gradeinfo`VALUES(2,3,88);INSERTINTO`gradeinfo`VALUES(3,1,98);INSERTINTO`gradeinfo`VALUES(3,2,80);--------------------------------Tablestructureforstudentinfo------------------------------DROPTABLEIFEXISTS`studentinfo`;CREATETABLE`studentinfo`(`學號`int(11)NOTNULL,`姓名`char(20)CHARACTERSETutf8COLLATEutf8_general_ciNOTNULL,`年齡`int(11)NULLDEFAULTNULL,`性別`tinyint(1)NULLDEFAULTNULL,PRIMARYKEY(`學號`)USINGBTREE)ENGINE=InnoDBCHARACTERSET=utf8COLLATE=utf8_general_ciROW_FORMAT=Compact;--------------------------------Recordsofstudentinfo------------------------------INSERTINTO`studentinfo`VALUES(1,'zhangsan',18,1);INSERTINTO`studentinfo`VALUES(2,'lisi',18,0);INSERTINTO`studentinfo`VALUES(3,'wanwu',19,1);SETFOREIGN_KEY_CHECKS=1;步驟2:登陸MySQL,創建數據庫,代碼如下。createdatabasecoursesel;步驟3:導入數據,代碼如下。usecoursesel;sourcecoursesel.sql;步驟4:查看數據是否導入,代碼如下。showtables;返回結果如圖8-1所示。圖8-1MySQL表(2)通過JavaAPI讀取MySQL數據中學生信息表StudentInfo內容步驟1:注冊數據庫的驅動,代碼如下。Class.forName("com.mysql.jdbc.Driver");步驟2:打開數據庫鏈接,代碼如下。#打開mysql數據庫連接Stringurl="jdbc:mysql://localhost:3306/coursesel";Stringusername="root";Stringpassword="******";conn=DriverManager.getConnection(url,username,password);stmt=conn.createStatement();其中,url參數localhost為本地數據庫,如果遠程數據庫可使用ip:port形式,例如“3:3306”。接下來兩個參數分別為連接數據庫的用戶名和密碼,最后一個為用到的具體數據庫名。步驟3:獲取學生表studentinfo基本信息,代碼如下。Stringsql="select*fromstudentinfo";rs=stmt.executeQuery(sql); LinkedListlink=newLinkedList(); while(rs.next()){ intid=rs.getInt("學號");//?? Stringname=rs.getString("姓名"); System.out.println(id+""+name); link.add(id); }返回結果如圖8-2所示.圖8-2studentinfo查詢結果步驟4:獲取課程信息。通過以上獲取查詢的結果,返回的學生學號為LinkedList結構,存儲多行數據。然后針對每個學生從gradeinfo和courseinfo表中獲取課程信息,代碼如下。for(Objectobj:link){ StringsqlCourse="SELECTcourseinfo.課程名,gradeinfo.成績"+"FROMstudentinfo,courseinfo,gradeinfo" +"WHEREstudentinfo.學號=gradeinfo.學號"+"andcourseinfo.課程號=gradeinfo.課程號" +"andstudentinfo.學號="+obj; stmt=conn.createStatement(); rs1=stmt.executeQuery(sqlCourse); while(rs1.next()){ StringcourseName=rs1.getString(1); intcou=rs1.getInt(2); System.out.println(courseName+""+cou); } }經過此查詢后可以獲取每個學生的選課信息和成績,顯示結果如圖8-3所示。圖8-3獲取學生課程信息3.將MySQL數據導入HBase表步驟1:創建HBase表,通過JavaAPI連接HBase,創建表courseGrade。具體實現代碼如下。//建立與HBase的連接Configurationconf=HBaseConfiguration.create();//配置與HBase連接的參數conf.set("hbase.master","master:16000");conf.set("hbase.rootdir","hdfs://master:8020/hbase");conf.set("hbase.zookeeper.quorum","master,slave1,slave2");conf.set("perty.clientPort","2181");連接HBase后,實例化admin,使用addFamily()方法依次添加兩個列族,admin使用createTable()方法創建表。具體代碼如下:HTableDescriptorht=newHTableDescriptor("courseGrade"); ht.addFamily(newHColumnDescriptor("StuInfo")); ht.addFamily(newHColumnDescriptor("Grades")); //創建表 if(admin.tableExists(tableName)){ if(admin.isTableEnabled(tableName)){ admin.disableTable(tableName); System.out.println("禁用表"); } admin.deleteTable(tableName); System.out.println("已刪除表"+tableName.toString()); }admin.createTable(ht);步驟2:將MySQL數據導入HBase的courseGrade表。向列族中插入數據。連接MySQL數據庫讀取結果集,將查詢到的studentinfo表的學號信息作為rowKey,表中的姓名、年齡、性別作為列族StuInfo的列。通過MySQL連接查詢語句,指定查詢條件為學號,查詢到對應的課程名和成績作為列族Grades的列名和對應的單元格值。具體代碼如下所示:importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.Statement;importorg.apache.hadoop.hbase.TableName;importorg.apache.hadoop.hbase.client.ConnectionFactory;importorg.apache.hadoop.hbase.client.Put;importorg.apache.hadoop.hbase.client.Table;importorg.apache.hadoop.hbase.util.Bytes;importorg.apache.hadoop.conf.Configuration;importorg.apache.hadoop.hbase.HBaseConfiguration;import.URLDecoder;import.URLEncoder;publicclassMySQLToHBase{publicstaticvoidmain(String[]args)throwsException{//MySQLconnectionsetup ResultSetrs1=null; Class.forName("com.mysql.jdbc.Driver");StringmysqlUrl="jdbc:mysql://localhost:3306/coursesel?characterEncoding=utf-8";StringmysqlUser="root";StringmysqlPassword="123456";java.sql.ConnectionmysqlConn=DriverManager.getConnection(mysqlUrl,mysqlUser,mysqlPassword);Statementstmt=mysqlConn.createStatement();ResultSetrs=stmt.executeQuery("SELECT*FROMstudentinfo");//HBaseconnectionsetupConfigurationconf=HBaseConfiguration.create();//AddHBaseconfigurationsettingshere(e.g.,zookeeperquorum,HBasemaster,etc.)conf.set("hbase.master","master:16000"); conf.set("hbase.rootdir","hdfs://master:8020/hbase"); conf.set("hbase.zookeeper.quorum","master,slave1,slave2"); conf.set("perty.clientPort","2181");org.apache.hadoop.hbase.client.ConnectionhbaseConn=ConnectionFactory.createConnection(conf);Tabletable=hbaseConn.getTable(TableName.valueOf("courseGrade"));//IterateoverMySQLresultsandwritetoHBasewhile(rs.next()){introwKey=rs.getInt("學號");//AdjustthistomatchyourrowkeyPutput=newPut(Integer.toString(rowKey).getBytes());Stringname=rs.getString("姓名");intage=rs.getInt("年齡");intsex=rs.getInt("性別");System.out.println

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論