实验4熟悉常用的HBase操作.docx
《实验4熟悉常用的HBase操作.docx》由会员分享,可在线阅读,更多相关《实验4熟悉常用的HBase操作.docx(20页珍藏版)》请在冰豆网上搜索。
实验4熟悉常用的HBase操作
实验4熟悉常用的HBase操作
姓名:
包生友专业年级:
软件143学号:
*******699
1.实验目的
1.理解HBase在Hadoop体系结构中的角色;
2.熟练使用HBase操作常用的Shell命令;
3.熟悉HBase操作常用的JavaAPI。
2.实验环境
操作系统:
Linux
Hadoop版本:
2.6.0或以上版本
HBase版本:
1.1.2或以上版本
JDK版本:
1.6或以上版本
JavaIDE:
Eclipse
3.实验内容和完成情况
1.编程实现以下指定功能,并用Hadoop提供的HBaseShell命令完成相同任务:
(完整可执行代码见代码/QuestionOne.java)
(1)列出HBase所有的表的相关信息,例如表名;
Shell:
List
图1列出HBase所有表的相关信息
编程:
//
(1)列出HBase所有的表的相关信息,例如表名、创建时间等
publicstaticvoidlistTables()throwsIOException{
init();//建立连接
HTableDescriptorhTableDescriptors[]=admin.listTables();
for(HTableDescriptorhTableDescriptor:
hTableDescriptors){
System.out.println("表名:
"+hTableDescriptor.getNameAsString());
}
close();//关闭连接
}
(2)在终端打印出指定的表的所有记录数据;
Shell:
scan's1'
图2打印指定表的所有记录数据
编程:
//
(2)在终端打印出指定的表的所有记录数据
publicstaticvoidgetData(StringtableName)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Scanscan=newScan();
ResultScannerscanner=table.getScanner(scan);
for(Resultresult:
scanner){
printRecoder(result);
}
close();
}
//打印一条记录的详情
publicstaticvoidprintRecoder(Resultresult)throwsIOException{
for(Cellcell:
result.rawCells()){
System.out.print("行健:
"+newString(CellUtil.cloneRow(cell)));
System.out.print("列簇:
"+newString(CellUtil.cloneFamily(cell)));
System.out.print("列:
"+newString(CellUtil.cloneQualifier(cell)));
System.out.print("值:
"+newString(CellUtil.cloneValue(cell)));
System.out.println("时间戳:
"+cell.getTimestamp());
}
}
(3)向已经创建好的表添加和删除指定的列族或列;
p.s:
此题请先在Shell中创建s1作为示例表:
create's1','score'
a)在s1表,添加数据:
Shell:
put's1','zhangsan','score:
Math','69'
图3给s1添加数据
编程:
//向表添加数据
publicstaticvoidinsertRow(StringtableName,StringrowKey,StringcolFamily,Stringcol,Stringval)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Putput=newPut(rowKey.getBytes());
put.addColumn(colFamily.getBytes(),col.getBytes(),val.getBytes());
table.put(put);
table.close();
close();
}
insertRow("s1",'zhangsan','score','Math','69')
b)在s1表,删除指定的列:
Shell:
delete's1','zhangsan','score:
Math'
图4删除数据
编程:
//删除数据
publicstaticvoiddeleteRow(StringtableName,StringrowKey,StringcolFamily,Stringcol)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Deletedelete=newDelete(rowKey.getBytes());
//删除指定列族
delete.addFamily(Bytes.toBytes(colFamily));
//删除指定列
delete.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
table.delete(delete);
table.close();
close();
}
deleteRow("s1",'zhangsan','score','Math')
(4)清空指定的表的所有记录数据;
Shell:
truncate's1'
图5清空指定表的所有记录数据
编程:
//(4)清空指定的表的所有记录数据
publicstaticvoidclearRows(StringtableName)throwsIOException{
init();
TableNametablename=TableName.valueOf(tableName);
admin.disableTable(tablename);
admin.deleteTable(tablename);
HTableDescriptorhTableDescriptor=newHTableDescriptor(tableName);
admin.createTable(hTableDescriptor);
close();
}
(5)统计表的行数。
Shell:
count's1'
图6统计表的行数
编程:
//(5)统计表的行数
publicstaticvoidcountRows(StringtableName)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Scanscan=newScan();
ResultScannerscanner=table.getScanner(scan);
intnum=0;
for(Resultresult=scanner.next();result!
=null;result=scanner.next()){
num++;
}
System.out.println("行数:
"+num);
scanner.close();
close();
}
2.现有以下关系型数据库中的表和数据,要求将其转换为适合于HBase存储的表并插入数据:
学生表(Student)
学号(S_No)
姓名(S_Name)
性别(S_Sex)
年龄(S_Age)
2015001
Zhangsan
male
23
2015003
Mary
female
22
2015003
Lisi
male
24
课程表(Course)
课程号(C_No)
课程名(C_Name)
学分(C_Credit)
123001
Math
2.0
123002
ComputerScience
5.0
123003
English
3.0
选课表(SC)
学号(SC_Sno)
课程号(SC_Cno)
成绩(SC_Score)
2015001
123001
86
2015001
123003
69
2015002
123002
77
2015002
123003
99
2015003
123001
98
2015003
123002
95
1学生Student表
p.s:
主键的列名是随机分配的,因此无需创建主键列
创建表:
create'Student','S_No','S_Name','S_Sex','S_Age'
图7创建Student表
插入数据:
插入数据shell命令
第一行数据
put'Student','s001','S_No','2015001'
put'Student','s001','S_Name','Zhangsan'
put'Student','s001','S_Sex','male'
put'Student','s001','S_Age','23'
第二行数据
put'Student','s002','S_No','2015002'
put'Student','s002','S_Name','Mary'
put'Student','s002','S_Sex','female'
put'Student','s002','S_Age','22'
第三行数据
put'Student','s003','S_No','2015003'
put'Student','s003','S_Name','Lisi'
put'Student','s003','S_Sex','male'
put'Student','s003','S_Age','24'
图8添加数据并查看
图9添加3个学生
2课程Course表
创建表:
create'Course','C_No','C_Name','C_Credit'
图10创建Course表
插入数据:
插入数据shell命令
第一行数据
put'Course','c001','C_No','123001'
put'Course','c001','C_Name','Math'
put'Course','c001','C_Credit','2.0'
第二行数据
put'Course','c002','C_No','123002'
put'Course','c002','C_Name','Computer'
put'Course','c002','C_Credit','5.0'
第三行数据
put'Course','c003','C_No','123003'
put'Course','c003','C_Name','English'
put'Course','c003','C_Credit','3.0'
图11添加数据
图12添加3个课程
3选课表
创建表:
create'SC','SC_Sno','SC_Cno','SC_Score'
图13创建表SC
插入数据:
插入数据shell命令
第一行数据
put'SC','sc001','SC_Sno','2015001'
put'SC','sc001','SC_Cno','123001'
put'SC','sc001','SC_Score','86'
第二行数据
put'SC','sc002','SC_Sno','2015001'
put'SC','sc002','SC_Cno','123003'
put'SC','sc002','SC_Score','69'
第三行数据
put'SC','sc003','SC_Sno','2015002'
put'SC','sc003','SC_Cno','123002'
put'SC','sc003','SC_Score','77'
第四行数据
put'SC','sc004','SC_Sno','2015002'
put'SC','sc004','SC_Cno','123003'
put'SC','sc004','SC_Score','99'
第五行数据
put'SC','sc005','SC_Sno','2015003'
put'SC','sc005','SC_Cno','123001'
put'SC','sc005','SC_Score','98'
第六行数据
put'SC','sc006','SC_Sno','2015003'
put'SC','sc006','SC_Cno','123002'
put'SC','sc006','SC_Score','95'
图14插入数据
图15数据显示
图16QuestionOne运行后控制台消息
同时,请编程完成以下指定功能:
(完整可执行代码见代码/QuestionTwo.java)
(1)createTable(StringtableName,String[]fields)
创建表,参数tableName为表的名称,字符串数组fields为存储记录各个域名称的数组。
要求当HBase已经存在名为tableName的表的时候,先删除原有的表,然后再创建新的表。
代码:
publicstaticvoidcreateTable(StringtableName,String[]fields)throwsIOException{
init();
TableNametablename=TableName.valueOf(tableName);
if(admin.tableExists(tablename)){
System.out.println("tableisexists!
");
admin.disableTable(tablename);
admin.deleteTable(tablename);//删除原来的表
}
HTableDescriptorhTableDescriptor=newHTableDescriptor(tablename);
for(Stringstr:
fields){
HColumnDescriptorhColumnDescriptor=newHColumnDescriptor(str);
hTableDescriptor.addFamily(hColumnDescriptor);
}
admin.createTable(hTableDescriptor);
close();
}
(2)addRecord(StringtableName,Stringrow,String[]fields,String[]values)
向表tableName、行row(用S_Name表示)和字符串数组files指定的单元格中添加对应的数据values。
其中fields中每个元素如果对应的列族下还有相应的列限定符的话,用“columnFamily:
column”表示。
例如,同时向“Math”、“ComputerScience”、“English”三列添加成绩时,字符串数组fields为{“Score:
Math”,”Score;ComputerScience”,”Score:
English”},数组values存储这三门课的成绩。
代码:
publicstaticvoidaddRecord(StringtableName,Stringrow,String[]fields,String[]values)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
for(inti=0;i!
=fields.length;i++){
Putput=newPut(row.getBytes());
String[]cols=fields[i].split(":
");
put.addColumn(cols[0].getBytes(),cols[1].getBytes(),values[i].getBytes());
table.put(put);
}
table.close();
close();
}
(3)scanColumn(StringtableName,Stringcolumn)
浏览表tableName某一列的数据,如果某一行记录中该列数据不存在,则返回null。
要求当参数column为某一列族名称时,如果底下有若干个列限定符,则要列出每个列限定符代表的列的数据;当参数column为某一列具体名称(例如“Score:
Math”)时,只需要列出该列的数据。
代码:
publicstaticvoidscanColumn(StringtableName,Stringcolumn)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Scanscan=newScan();
scan.addFamily(Bytes.toBytes(column));
ResultScannerscanner=table.getScanner(scan);
for(Resultresult=scanner.next();result!
=null;result=scanner.next()){
showCell(result);
}
table.close();
close();
}
//格式化输出
publicstaticvoidshowCell(Resultresult){
Cell[]cells=result.rawCells();
for(Cellcell:
cells){
System.out.println("RowName:
"+newString(CellUtil.cloneRow(cell))+"");
System.out.println("Timetamp:
"+cell.getTimestamp()+"");
System.out.println("columnFamily:
"+newString(CellUtil.cloneFamily(cell))+"");
System.out.println("rowName:
"+newString(CellUtil.cloneQualifier(cell))+"");
System.out.println("value:
"+newString(CellUtil.cloneValue(cell))+"");
}
}
(4)modifyData(StringtableName,Stringrow,Stringcolumn)
修改表tableName,行row(可以用学生姓名S_Name表示),列column指定的单元格的数据。
代码:
publicstaticvoidmodifyData(StringtableName,Stringrow,Stringcolumn,Stringval)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Putput=newPut(row.getBytes());
put.addColumn(column.getBytes(),null,val.getBytes());
table.put(put);
table.close();
close();
}
(5)deleteRow(StringtableName,Stringrow)
删除表tableName中row指定的行的记录。
publicstaticvoiddeleteRow(StringtableName,Stringrow)throwsIOException{
init();
Tabletable=connection.getTable(TableName.valueOf(tableName));
Deletedelete=newDelete(row.getBytes());
//删除指定列族
//delete.addFamily(Bytes.toBytes(colFamily));
//删除指定列
//delete.addColumn(Bytes.toBytes(colFamily),Bytes.toBytes(col));
table.delete(delete);
table.close();
close();
}
图17QuestionTwo运行后控制台消息
3.利用HBase和MapReduce完成如下任务:
假设HBase有2张表,表的逻辑视图及部分数据如下所示:
表逻辑视图及部分数据
书名(bookName)
价格(price)
DatabaseSystemConcept
30$
ThinkinginJava
60$
DataMining
25$
要求:
从HBase读出上述两张表的数据,对“price”的排序,并将结果存储到HBase中。
操作方法如下:
create'book','bookName'
put'book','val_60$','bookName:
','ThinkinginJava'
put'book','val_20$','bookName:
','DatabaseSystemConcept'
put'book','val_30$','bookName:
','DataM