SpringBoot整合Hbase的实现⽰例
简介
当单表数据量过⼤的时候,关系性数据库会出现性能瓶颈,这时候我们就可以⽤NoSql,⽐如Hbase就是⼀个不错的解决⽅案。接下来是⽤Spring整合Hbase的实际案例,且在最后会给出整合中可能会出现的问题,以及解决⽅案。这⾥我是⽤本地Windows的IDEA,与局域⽹的伪分布Hbase集做的连接,其中Hbase集包括的组件有:Jdk1.8、Hadoop2.7.6、ZooKeeper3.4.10、Hbase2.0.1,因为这⾥只是开发环境,所以做⼀个伪分布的就好,之后部署的时候再按⽣产环境要求来即可
整合步骤
⽬录结构
这⾥要导⼊Hbase连接所需要包,需要和你Hbase版本⼀致的包
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.0.1</version>
</dependency>
我是⽤的配置⽂件连接⽅法,这个配置⽂件你在hbase的安装⽬录下的conf⽬录就可以到,然后你直接把它复制到项⽬的resources⽬录下就好,当然你也可以⽤application.properties配置⽂件外加注⼊和代码的⽅式代替这个配置⽂件
HBaseConfig.java
这⾥因为只需连接Hbase就没连接Hadoop,如果要连接Hadoop,Windows下还要下载⼯具,后⾯会介绍
@Configuration
public class HBaseConfig {
@Bean
public HBaseService getHbaseService() {
//设置临时的hadoop环境变量,之后程序会去这个⽬录下的\bin⽬录下⼯具,windows连接hadoop时会⽤到
//System.setProperty("hadoop.home.dir", "D:\\Program Files\\Hadoop");
//执⾏此步时,会去resources⽬录下相应的配置⽂件,例如l
org.f.Configuration conf = ate();
return new HBaseService(conf);
}
}
HBaseService.java
这是做连接后的⼀些操作可以参考之后⾃⼰写⼀下
public class HBaseService {
private Logger log = Logger(HBaseService.class);
/**
* 管理员可以做表以及数据的增删改查功能
*/
private Admin admin = null;
private Connection connection = null;
public HBaseService(Configuration conf) {
try {
connection = ateConnection(conf);
admin = Admin();
} catch (IOException e) {
<("获取HBase连接失败!");
}
}
/**
* 创建表 create <table>, {NAME => <column family>, VERSIONS => <VERSIONS>}
*/
public boolean creatTable(String tableName, List<String> columnFamily) {
try {
//列族column family
List<ColumnFamilyDescriptor> cfDesc = new ArrayList<>(columnFamily.size());
columnFamily.forEach(cf -> {
cfDesc.wBuilder(
});
//表 table
TableDescriptor tableDesc = TableDescriptorBuilder
.newBuilder(TableName.valueOf(tableName))
.
setColumnFamilies(cfDesc).build();
if (admin.tableExists(TableName.valueOf(tableName))) {
log.debug("table Exists!");drop table if exists admin
log.debug("create table Success!");
}
} catch (IOException e) {
<(MessageFormat.format("创建表{0}失败", tableName), e);
return false;
} finally {
close(admin, null, null);
}
return true;
}
/**
* 查询所有表的表名
*/
public List<String> getAllTableNames() {
List<String> result = new ArrayList<>();
try {
TableName[] tableNames = admin.listTableNames();
for (TableName tableName : tableNames) {
result.NameAsString());
}
} catch (IOException e) {
<("获取所有表的表名失败", e);
} finally {
close(admin, null, null);
}
return result;
}
/**
* 遍历查询指定表中的所有数据
*/
public Map<String, Map<String, String>> getResultScanner(String tableName) {
Scan scan = new Scan();
return this.queryData(tableName, scan);
}
/**
* 通过表名及过滤条件查询数据
*/
private Map<String, Map<String, String>> queryData(String tableName, Scan scan) {
// <rowKey,对应的⾏数据>
Map<String, Map<String, String>> result = new HashMap<>();
ResultScanner rs = null;
//获取表
Table table = null;
try {
table = getTable(tableName);
rs = Scanner(scan);
for (Result r : rs) {
// 每⼀⾏数据
Map<String, String> columnMap = new HashMap<>();
String rowKey = null;
// ⾏键,列族和列限定符⼀起确定⼀个单元(Cell)
for (Cell cell : r.listCells()) {
if (rowKey == null) {
rowKey = RowArray(), RowOffset(), RowLength());
}
columnMap.put(
//列限定符
//列族
}
if (rowKey != null) {
result.put(rowKey, columnMap);
}
}
} catch (IOException e) {
<(MessageFormat.format("遍历查询指定表中的所有数据失败,tableName:{0}", tableName), e);
} finally {
close(null, rs, table);
}
return result;
}
/**
* 为表添加或者更新数据
*/
public void putData(String tableName, String rowKey, String familyName, String[] columns, String[] values) {
Table table = null;
try {
table = getTable(tableName);
putData(table, rowKey, tableName, familyName, columns, values);
} catch (Exception e) {
<(MessageFormat.format("为表添加 or 更新数据失败,tableName:{0},rowKey:{1},familyName:{2}", tableName, rowKey, familyName), e); } finally {
close(null, null, table);
}
}
private void putData(Table table, String rowKey, String tableName, String familyName, String[] columns, String[] values) {
try {
//设置rowkey
Put put = new Bytes(rowKey));
if (columns != null && values != null && columns.length == values.length) {
for (int i = 0; i < columns.length; i++) {
if (columns[i] != null && values[i] != null) {
put.Bytes(familyName), Bytes(columns[i]), Bytes(values[i]));
} else {
throw new NullPointerException(MessageFormat.format(
"列名和列数据都不能为空,column:{0},value:{1}", columns[i], values[i]));
}
}
}
table.put(put);
log.debug("putData add or update data Success,rowKey:" + rowKey);
table.close();
} catch (Exception e) {
<(MessageFormat.format(
"为表添加 or 更新数据失败,tableName:{0},rowKey:{1},familyName:{2}",
tableName, rowKey, familyName), e);
}
}
/**
* 根据表名获取table
*/
private Table getTable(String tableName) throws IOException {
Table(TableName.valueOf(tableName));
}
/**
* 关闭流
*/
private void close(Admin admin, ResultScanner rs, Table table) {
if (admin != null) {
admin.close();
} catch (IOException e) {
<("关闭Admin失败", e);
}
if (rs != null) {
rs.close();
}
if (table != null) {
rs.close();
}
if (table != null) {
try {
table.close();
} catch (IOException e) {
<("关闭Table失败", e);
}
}
}
}
}
HBaseApplicationTests.java
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class HBaseApplicationTests {
@Resource
private HBaseService hbaseService;
//测试创建表
@Test
public void testCreateTable() {
}
//测试加⼊数据
@Test
public void testPutData() {
hbaseService.putData("test_base", "000001", "a", new String[]{
"project_id", "varName", "coefs", "pvalues", "tvalues",
"create_time"}, new String[]{"40866", "mob_3", "0.9416",
"0.0000", "12.2293", "null"});
hbaseService.putData("test_base", "000002", "a", new String[]{
"project_id", "varName", "coefs", "pvalues", "tvalues",
"create_time"}, new String[]{"40866", "idno_prov", "0.9317",
"0.0000", "9.8679", "null"});
hbaseService.putData("test_base", "000003", "a", new String[]{
"project_id", "varName", "coefs", "pvalues", "tvalues",
"create_time"}, new String[]{"40866", "education", "0.8984",
"0.0000", "25.5649", "null"});
}
//测试遍历全表
@Test
public void testGetResultScanner() {
Map<String, Map<String, String>> result2 = ResultScanner("test_base");
System.out.println("-----遍历查询全表内容-----");
result2.forEach((k, value) -> {
System.out.println(k + "--->" + value);
});
}
}
运⾏结果
Hbase数据库查询结果
IDEA的遍历结果
报错与解决⽅案
报错⼀
解决⽅案:
这是参数配置的有问题,如果你是⽤l配置⽂件配置的参数,那么检查它,⽤代码配置就检查代码参数
解决⽅案:
更改windows本地hosts⽂件,C:\Windows\System32\drivers\etc\hosts,添加Hbase服务所在主机地址与主机名称,这⾥你如果保存不了hosts⽂件,把它拉出到桌⾯改好再拉回即可
报错三
解决⽅案:
这是因为在Windows下连接Hadoop需要⼀个叫的⼯具,并且从源代码可知,它会去读你Windows下的环境变量,如果你不想在本地设置,可以⽤⽅法System.setProperty()设置实时环境变量,另外,如果你只⽤Hbase,其实这个报错并不影响你使⽤Hbase服务
代码地址
到此这篇关于SpringBoot整合Hbase的实现⽰例的⽂章就介绍到这了,更多相关SpringBoot整合Hbase内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论