- Hbase是大数据NoSQL领域里非常重要的分布式KV数据库,是一个实时、高可靠、高性能、高伸缩的分布式存储系统,运行依赖于Hadoop HDFS、zk
- 因为是key-value结构的数据库,所以curd *** 作都是通过key去 *** 作value。与redis不同的是Hbase的key有点复杂。
- Key则是由Rowkey、Column Family : Column Qualifier、Timestamp、Type等几个维度组成。rowkey是Hbase的行键;column family(列族)与qualifier(列限定符即列名)共同组成了Hbase的列;timestamp表示的就是数据写入时的时间戳,主要用于标识Hbase数据的版本号;type代表Put/Delete的 *** 作类型
- 客户端连接hbase依赖于zookeeper,hbase存储依赖于hadoop
- 查数据时,携带key值,先连接集群的zk,然后访问zk的元数据信息找到对应的hbase,hbase集群通过机制查找到key对应的value。
- 更多原理 点此处
-
容量大:Hbase单表可以很庞大,加上其分布式、高伸缩性的特点,使得Hbase特别适合海量数据的永久性存储。
-
高性能:Hbase具有非常高的读写性能,基于LSM-Tree的数据结构使得Hbase写入数据性能强劲,另外得益于Hbase读路径上的各种设计及优化,Hbase读数据的性能也可以保持在毫秒级。
-
高可靠:因为数据写路径上是先写WAL日志,防止缓存数据的丢失,加上Hbase底层数据的多副本机制,保证了数据的可靠性。
-
原始支持Hadoop:Hbase底层存储基于HDFS,也原生集成了MapReduce做离线计算。Hbase这种架构体系也使得Hbase非常易于扩展。
-
无模式:Hbase的表是schema-free的,无需提前定义schema,只会在数据写入时才会增加列。
-
稀疏性:Hbase是表具有稀疏性,null值的列并不占用任何存储空,这一点和关系库不同,大大节省了存储空间。因为hbase是列式存储
-
多版本:Hbase支持多版本,每一个单元格包含timestamp时间戳,标识着数据的版本号。
-
数据分析能力弱:数据分析是Hbase的弱项,比如聚合运算、多维度复杂查询、多表关联查询等。所以,我们一般在Hbase之上架设Phoenix或Spark等组件,增强Hbase数据分析处理的能力。
-
原生不支持二级索引:默认Hbase只对rowkey做了单列索引,因此正常情况下对非rowkey列做查询比较慢。所以,我们一般会选择一个Hbase二级索引解决方案,目前比较成熟的解决方案是Phoenix,此外还可以选择Elasticsearch/Solr等搜索引擎自己设计实现。
-
原生不支持SQL:SQL查询也是Hbase的一个弱项,好在这块可以通过引入Phoenix解决,Phoenix是专为Hbase设计的SQL层。
-
引入hbase的client依赖包
org.apache.hbase hbase-client2.0.1 org.slf4j slf4j-apilog4j log4jorg.slf4j slf4j-log4j12 -
配置hbase集群信息
#配置集群的ip地址 hbase.zookeeper.quorum= 192.168.130.115,192.168.130.116 #zk的端口号 连接hbase实际上是通过zk连接的 hbase.zookeeper.property.clientPort= 2181
- 添加配置类并创建Hbase连接实例
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HbaseConfiguration; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import java.io.IOException; @org.springframework.context.annotation.Configuration public class ServiceHbase { @Value("${hbase.zookeeper.quorum}") private String zookeeperQuorum; @Value("${hbase.zookeeper.property.clientPort}") private String clientPort; @Bean("myConnection") public Connection getCon(){ Configuration entries = HbaseConfiguration.create(); entries.set("hbase.zookeeper.quorum",zookeeperQuorum); entries.set("hbase.zookeeper.property.clientPort",clientPort); try { return ConnectionFactory.createConnection(entries); } catch (IOException e) { e.printStackTrace(); } return null; } }
- 增删改查
import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.util.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; import java.io.IOException; @Service("myHbaseService") public class SerDemo { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired @Qualifier("myConnection") private Connection hbaseConnection; String tableName = "hello_ssx_tab"; String familyName = "family1"; public boolean addTab(){ try { // logger.info("获取hbaseAdmin对象用于 *** 作表"); Admin hbaseConnectionAdmin = hbaseConnection.getAdmin(); //判断表是否存在 TableName tableName1 = TableName.valueOf(this.tableName); boolean tableExists = hbaseConnectionAdmin.tableExists(tableName1); logger.info("表是否存在"+tableName+":"+tableExists); //如果表不存在就新建 if (!tableExists){ //表不存在 //表 描述建造者 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName1); //列族 描述建造者 ColumnFamilyDescriptorBuilder cfdb = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes(familyName)); //设置最大版本号 其实就是记录的轨迹信息,设置为3可以查询追溯到前1个版本前2个版本前三个版本,此功能相当于数据库的flashback闪回。默认1 cfdb.setMaxVersions(3); //创建列族 描述 ColumnFamilyDescriptor familyDescriptor = cfdb.build(); //将列族加入到表描述中 builder.setColumnFamily(familyDescriptor); //创建表 描述 TableDescriptor tableDescriptor = builder.build(); //创建表 hbaseConnectionAdmin.createTable(tableDescriptor); logger.info("表创建成功"+tableName); }else { logger.warn("表已经存在:"+tableName); } return hbaseConnectionAdmin.tableExists(tableName1); } catch (Exception e) { e.printStackTrace(); } return false; } public boolean setValue(String value,String colName,String rowKey){ //指定表名 TableName tableName1 = TableName.valueOf(this.tableName); try { //获取表对象 Table table = hbaseConnection.getTable(tableName1); //设置行键值 Put row001 = new Put(Bytes.toBytes(rowKey)); //设置列族,列,值 row001.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(colName),Bytes.toBytes(value)); //添加记录 table.put(row001); // logger.info("成功hbase添加数据信息:目标表:"+tableName+",目标行键:"+rowKey+",目标列族:"+familyName+",目标列:"+ colName +",目标值:"+value); return true; } catch (IOException e) { e.printStackTrace(); } return false; } public String getValue(String rowKey){ //指定表名 TableName tableName1 = TableName.valueOf(this.tableName); try { //设置表 Table table = hbaseConnection.getTable(tableName1); //指定要查询的行键 Get get = new Get(Bytes.toBytes(rowKey)); //查询返回结果 Result result = table.get(get); //获取结果集合 Cell[] cells = result.rawCells(); //遍历结果集 StringBuilder returnData = new StringBuilder(); for (Cell cell:cells){ byte[] bytes = CellUtil.cloneRow(cell); String s = Bytes.toString(bytes); logger.info("查询hbase数据信息:目标表:"+tableName+",目标行键:"+rowKey+",查询出的信息: 行键:"+s); returnData.append(s).append('n'); String s1 = Bytes.toString(CellUtil.cloneFamily(cell)); logger.info("查询hbase数据信息:目标表:"+tableName+",目标行键:"+rowKey+",查询出的信息: 列族:"+s1); returnData.append(s1).append('n'); String s2 = Bytes.toString(CellUtil.cloneQualifier(cell)); logger.info("查询hbase数据信息:目标表:"+tableName+",目标行键:"+rowKey+",查询出的信息: 列名:"+s2); returnData.append(s2).append('n'); String s3 = Bytes.toString(CellUtil.clonevalue(cell)); logger.info("查询hbase数据信息:目标表:"+tableName+",目标行键:"+rowKey+",查询出的信息: 值:"+s3); returnData.append(s3).append('n'); } return returnData.toString(); } catch (IOException e) { e.printStackTrace(); } return "查询失败"; } }
- 如果启动报错 UnknownHostException 的话 就在"C:WindowsSystem32driversetchosts"配置下 设置域名/host和IP的关系
- 以上就是简单的实例了,如果报错请 百度一下
- 本项目Gitee源码
- 如果是在windows系统开发环境搭建的话,windows本地电脑需要安装hadoop软件,并且配置环境变量,还要安装一个winutils-master软件。不然项目启动会报错找不到hadoop——home环境变量。
- 下载hadoop2压缩包,解压,然后配置window系统环境变量HADOOP_HOME和Path
- 下载winutils的windows版本,解压,选择一个和hadoop软件相近的版本,打开winutils的bin文件整体粘贴到hadoop软件下。
- hadoop文件bin文件夹下的hadoop.dll拷贝到C:WindowsSystem32目录下
- 可能需要重启IDEA或者电脑,完成
- 参考文章:https://www.jianshu.com/p/a65a95108620
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)