SpringBoot整合Hbase的实现示例

简介

当单表数据量过大的时候,关系性数据库会出现性能瓶颈,这时候我们就可以用NoSql,比如Hbase就是一个不错的解决方案。接下来是用Spring整合Hbase的实际案例,且在最后会给出整合中可能会出现的问题,以及解决方案。这里我是用本地Windows的IDEA,与局域网的伪分布Hbase集群做的连接,其中Hbase集群包括的组件有:Jdk1.8、Hadoop2.7.6、ZooKeeper3.4.10、Hbase2.0.1,因为这里只是开发环境,所以做一个伪分布的就好,之后部署的时候再按生产环境要求来即可

整合步骤

目录结构

pom.xml

这里要导入Hbase连接所需要包,需要找和你Hbase版本一致的包

<dependency>
 <groupId>org.apache.hbase</groupId>
 <artifactId>hbase-client</artifactId>
 <version>2.0.1</version>
</dependency>

hbase-site.xml

我是用的配置文件连接方法,这个配置文件你在hbase的安装目录下的conf目录就可以找到,然后你直接把它复制到项目的resources目录下就好,当然你也可以用application.properties配置文件外加注入和代码的方式代替这个配置文件

HBaseConfig.java

这里因为只需连接Hbase就没连接Hadoop,如果要连接Hadoop,Windows下还要下载winutils.exe工具,后面会介绍

@Configuration
public class HBaseConfig {
 @Bean
 public HBaseService getHbaseService() {
  //设置临时的hadoop环境变量,之后程序会去这个目录下的\bin目录下找winutils.exe工具,windows连接hadoop时会用到
  //System.setProperty("hadoop.home.dir", "D:\\Program Files\\Hadoop");
  //执行此步时,会去resources目录下找相应的配置文件,例如hbase-site.xml
  org.apache.hadoop.conf.Configuration conf = HBaseConfiguration.create();
  return new HBaseService(conf);
 }
}

HBaseService.java

这是做连接后的一些操作可以参考之后自己写一下

public class HBaseService {
 private Logger log = LoggerFactory.getLogger(HBaseService.class);
 /**
  * 管理员可以做表以及数据的增删改查功能
  */
 private Admin admin = null;
 private Connection connection = null;
 public HBaseService(Configuration conf) {
  try {
   connection = ConnectionFactory.createConnection(conf);
   admin = connection.getAdmin();
  } catch (IOException e) {
   log.error("获取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.add(ColumnFamilyDescriptorBuilder.newBuilder(
      Bytes.toBytes(cf)).build());
   });
   //表 table
   TableDescriptor tableDesc = TableDescriptorBuilder
     .newBuilder(TableName.valueOf(tableName))
     .setColumnFamilies(cfDesc).build();
   if (admin.tableExists(TableName.valueOf(tableName))) {
    log.debug("table Exists!");
   } else {
    admin.createTable(tableDesc);
    log.debug("create table Success!");
   }
  } catch (IOException e) {
   log.error(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.add(tableName.getNameAsString());
   }
  } catch (IOException e) {
   log.error("获取所有表的表名失败", 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 = table.getScanner(scan);
   for (Result r : rs) {
    // 每一行数据
    Map<String, String> columnMap = new HashMap<>();
    String rowKey = null;
    // 行键,列族和列限定符一起确定一个单元(Cell)
    for (Cell cell : r.listCells()) {
     if (rowKey == null) {
      rowKey = Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength());
     }
     columnMap.put(
       //列限定符
       Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()),
       //列族
       Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
    }
    if (rowKey != null) {
     result.put(rowKey, columnMap);
    }
   }
  } catch (IOException e) {
   log.error(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) {
   log.error(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 Put(Bytes.toBytes(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.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columns[i]), Bytes.toBytes(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) {
   log.error(MessageFormat.format(
     "为表添加 or 更新数据失败,tableName:{0},rowKey:{1},familyName:{2}",
     tableName, rowKey, familyName), e);
  }
 }
 /**
  * 根据表名获取table
  */
 private Table getTable(String tableName) throws IOException {
  return connection.getTable(TableName.valueOf(tableName));
 }

 /**
  * 关闭流
  */
 private void close(Admin admin, ResultScanner rs, Table table) {
  if (admin != null) {
   try {
    admin.close();
   } catch (IOException e) {
    log.error("关闭Admin失败", e);
   }
   if (rs != null) {
    rs.close();
   }
   if (table != null) {
    rs.close();
   }
   if (table != null) {
    try {
     table.close();
    } catch (IOException e) {
     log.error("关闭Table失败", e);
    }
   }
  }
 }
}

HBaseApplicationTests.java

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class HBaseApplicationTests {
 @Resource
 private HBaseService hbaseService;
 //测试创建表
 @Test
 public void testCreateTable() {
  hbaseService.creatTable("test_base", Arrays.asList("a", "back"));
 }
 //测试加入数据
 @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 = hbaseService.getResultScanner("test_base");
  System.out.println("-----遍历查询全表内容-----");
  result2.forEach((k, value) -> {
   System.out.println(k + "--->" + value);
  });
 }
}

运行结果

Hbase数据库查询结果

IDEA的遍历结果

报错与解决方案

报错一

解决方案:

这是参数配置的有问题,如果你是用hbase-site.xml配置文件配置的参数,那么检查它,用代码配置就检查代码参数

报错二

解决方案:

更改windows本地hosts文件,C:\Windows\System32\drivers\etc\hosts,添加Hbase服务所在主机地址与主机名称,这里你如果保存不了hosts文件,把它拉出到桌面改好再拉回即可

报错三

解决方案:

这是因为在Windows下连接Hadoop需要一个叫Winutils.exe的工具,并且从源代码可知,它会去读你Windows下的环境变量,如果你不想在本地设置,可以用方法System.setProperty()设置实时环境变量,另外,如果你只用Hbase,其实这个报错并不影响你使用Hbase服务

代码地址

https://github.com/xiaoxiamo/SpringBoot_HBase

到此这篇关于SpringBoot整合Hbase的实现示例的文章就介绍到这了,更多相关SpringBoot整合Hbase内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅谈HBase在SpringBoot项目里的应用(含HBaseUtil工具类)

    背景: 项目这两个月开始使用HBase来读写数据,网上现成的HBase工具类要么版本混杂,要么只是Demo级别的简单实现,各方面都不完善: 而且我发现HBase查询有很多种方式,首先大方向上有 Get 和 Scan两种,其次行键.列族.列名(限定符).列值(value).时间戳版本等多种组合条件,还有各种过滤器的选择,协处理器的应用,所以必须根据自己项目需求和HBase行列设计来自定义HBase工具类和实现类! 经过我自己的研究整理,在此分享下初步的实现方案吧 ~ 注:HBase版本:1.3.0

  • 基于springboot集成hbase过程解析

    这篇文章主要介绍了基于springboot集成hbase过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 springboot-habse: https://github.com/spring-projects/spring-hadoop-samples/tree/master/hbase 依赖: <dependency> <groupId>org.springframework.data</groupId> &

  • SpringBoot整合Hbase的实现示例

    简介 当单表数据量过大的时候,关系性数据库会出现性能瓶颈,这时候我们就可以用NoSql,比如Hbase就是一个不错的解决方案.接下来是用Spring整合Hbase的实际案例,且在最后会给出整合中可能会出现的问题,以及解决方案.这里我是用本地Windows的IDEA,与局域网的伪分布Hbase集群做的连接,其中Hbase集群包括的组件有:Jdk1.8.Hadoop2.7.6.ZooKeeper3.4.10.Hbase2.0.1,因为这里只是开发环境,所以做一个伪分布的就好,之后部署的时候再按生产环

  • springboot 整合hbase的示例代码

    目录 前言 HBase 定义 HBase 数据模型 物理存储结构 数据模型 1.Name Space 2.Region 3.Row 4.Column 5.Time Stamp 6.Cell 搭建步骤 1.官网下载安装包: 2.配置hadoop环境变量 3.修改 hbase-env.cmd配置文件 4.修改hbase-site.xml 文件 5.启动hbase服务 6.hbase客户端测试 Java API详细使用 1.导入客户端依赖 2.DDL相关操作 3.DML相关操作 插入数据与查询数据 H

  • Redis和springboot 整合redisUtil类的示例代码

    一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 二.在application.yml 配置redis服务器 spring: # 环境 dev|test|prod profiles: active: dev servle

  • SpringBoot整合OpenCV的实现示例

    简介 接下来会讲解怎么用SpringBoot整合OpenCV 初始化SpringBoot项目 这里正常初始一个SpringBoot项目 依赖文件 在安装目录下找到以下两个文件,如果不知道怎么安装OpenCV,可查看这篇文章,Windows下安装OpenCV opencv\build\java\opencv-420.jar opencv\build\java\x64\opencv_java420.dll 在resource目录下新建一个lib文件夹,然后将两个文件复制到resource\lib下

  • springboot整合spring-retry的实现示例

    1.背景 本系统调用外围系统接口(http+json),但是发现有时外围系统服务不太稳定,有时候会出现返回一串xml或者gateway bad的信息,导致调用失败,基于这一原因,采用基于springboot,整合spring-retry的重试机制到系统工程中,demo已经放到github上. 2.解决方案 简要说明:demo工程基于springboot,为了方便验证,采用swagger进行测试验证. 2.1 pom文件 <?xml version="1.0" encoding=&

  • SpringBoot整合Redis管道的示例代码

    目录 1. Redis 之管道(pipeline) 2. SpringBoot 整合 Redis 管道实例 1. Redis 之管道(pipeline) 执行一个Redis命令,Redis客户端和Redis服务器就需要执行以下步骤: 客户端发送命令到服务器: 服务器接受命令请求,执行命令,产生相应的结果: 服务器返回结果给客户端: 客户端接受命令的执行结果,并向用户展示. Redis命令所消耗的大部分时间都用在了发送命令请求和接收命令结果上面,把任意多条Redis命令请求打包在一起,然后一次性地

  • 聊聊springboot 整合 hbase的问题

    springboot 整合 hbase 要确定这三个端口外包可以访问 如果是127.0.0.1 可以参考修改 Linux下Hbase安装配置 <property> <name>hbase.master.ipc.address</name> <value>0.0.0.0</value> </property> <property> <name>hbase.regionserver.ipc.address</

  • SpringBoot整合JWT的实现示例

    目录 一. JWT简介 二. Java实现JWT(SpringBoot方式整合) JWT总结 一. JWT简介 1. 什么是JWT? JWT(JSON Web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准. 它将用户信息加密到token里,服务器不保存任何用户信息.服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证:应用场景如用户登录.JWT详细讲解请见 github:https://github.com/jwtk/jjwt 2. 为什么使用JWT

  • SpringBoot整合WebService的实现示例

    目录 SpringBoot搭建WebService程序 一.定义规范接口 二.搭建WebService服务端 三.搭建WebService客户端 WebService是一种传统的SOA技术架构,它不依赖于任何的编程语言,也不依赖于任何的技术平台,可以直接基于HTTP协议实现网络应用间的数据交互. 面向服务架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来.接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台.操作

  • Springboot整合FreeMarker的实现示例

    目录 一.项目搭建 1.新建模块 2.导入依赖 :将不相关的依赖删掉 3.新建软件包,放入student实体类 4.新建StudentMapper接口 5.Springboot04Application内引用mapper 6.application.yml文件配置 7.测试 8.将切面.util包.启动器导入 9.新建service层 10.新建controller层 11.运行启动类Springboot04Application,访问localhost:8080网址 二.freemarker介

随机推荐