分布式数据库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数据库,其中存储了用户信息。现在需要创建一个新的表来存储用户的订单信息,每个订单包含订单号、商品名称和数量。请设计表结构,并给出创建表、插入数据、查询数据的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

提交评论