Hbase相关基础知识
1. Hbase简介2. Hbase的数据模型3. Hbase特点4. Hbase与Hive区别5. Hbase简单代码示例参考链接
1. Hbase简介Hbase是一个分布式的、面向列的开源数据库,与关系型数据库不同的是,Hbase是一个适合于非结构化数据存储的数据库,并且它是基于列的而不是基于行的模式。利用Hbase技术可在廉价PC服务器上搭建起大规模结构化存储集群。
2. Hbase的数据模型Hbase数据存储结构中主要包括:表、行、列族、列限定符、单元格和时间戳,如下图所示:
表(table): 表的作用将存储在Hbase的数据组织起来。
行(row): 行由一个RowKey和多个列族组成,一个行有一个RowKey,用来唯一标示。行键没有数据类型,在Hbase存储系统中行键总是被看作一个byte数组。
列族(Column Family): 在行中的数据都是根据列族分组,由于列族会影响存储在Hbase中的数据的物理布置,所以列族会在使用前定义(在定义表的时候就定义列族),并且不易被修改。
在Hbase的存储系统中数据存储在相同的表中的所有行的数据都会有相同的列族(这和关系型数据库的表一样,每一行数据都有相同的列)。
列(Column): 存储在在列族中的数据通过列限定符或列来寻址的,列不需要提前定义(不需要在定义表和列族的时候就定义列),列与列之间也不需要保持一致。列和行键一样没有数据类型,并且在Hbase存储系统中列也总是被看作一个byte数组。
单元格(cell): 根据行键、列族和列可以映射到一个对应的单元格,单元格是Hbase存储数据的具体地址。在单元格中存储具体数据都是以Byte数组的形式存储的,也没有具体的数据类型。
时间戳(Timestamp): 时间戳是给定值的一个版本号标识,每一个值都会对应一个时间戳,时间戳是和每一个值同时写入Hbase存储系统中的。在默认情况下,时间戳表示数据服务在写入数据时的时间,但可以在将数据放入单元格时指定不同的时间戳值。
3. Hbase特点数据规模大,单表可容纳数十亿行,上百万列。无模式,不像关系型数据库有严格的Scheme,每行可以有任意多的列,列可以动态增加,不同行可以有不同的列,列的类型没有限制。稀疏,值为空的列不占存储空间,表可以非常稀疏,但实际存储时,能进行压缩。面向列族,面向列族的存储和权限控制,支持列族独立查询。数据多版本,利用时间戳来标识版本数据无类型,所有数据以字节数据形式存储 4. Hbase与Hive区别
Hive本质上还是让人用熟悉的SQL语言进行离线数据分析用的语言外壳,它只是在hadoop外面套了一层关系型数据库的外壳而已。
而Hbase是NOSQL的,支持实时 *** 作(增删改查)的分布式数据库,虽然底层还是hdfs,但它有自己的key-value/列存储模式。
object HbaseTest01 { // 设置用户 System.setProperty("HADOOP_USER_NAME", "app_frtfd_admin") // 设置SparkConf对象 var sparkConf: SparkConf = new SparkConf() sparkConf.setAppName("HiveTest01") sparkConf.setMaster("local") // 创建SparkContext对象 val sparkContext: SparkContext = new SparkContext(sparkConf) // HbaseConfiguration private val hbaseConf = HbaseConfiguration.create() // hbase连接 private val conn = ConnectionFactory.createConnection(hbaseConf) // hbaseAdmin private val hbaseAdmin = conn.getAdmin // HbaseContext private val hbaseContext = new HbaseContext(sparkContext, hbaseConf) def main(args: Array[String]): Unit={ // 表名 val tableName: String = "fct_frtfd:fct_ind_doc" val table: Table = conn.getTable(TableName.valueOf(tableName)) var scanner: ResultScanner = null var result: Result = null val resultList = new util.ArrayList[RowData] try { val s = new Scan() scanner = table.getScanner(s) result = scanner.next() while (result != null) { for (rowKv <- result.rawCells()) { val rowData = new RowData val family = new String(rowKv.getFamilyArray, rowKv.getFamilyOffset, rowKv.getFamilyLength, "UTF-8") val qualifier = new String(rowKv.getQualifierArray, rowKv.getQualifierOffset, rowKv.getQualifierLength, "UTF-8") val timeStamp = rowKv.getTimestamp.toString val rowKey = new String(rowKv.getRowArray, rowKv.getRowOffset, rowKv.getRowLength, "UTF-8") val value = new String(rowKv.getValueArray, rowKv.getValueOffset, rowKv.getValueLength, "UTF-8") rowData.setFamily(family) rowData.setQualifier(qualifier) rowData.setTimeStamp(timeStamp) rowData.setRowKey(rowKey) rowData.setValue(value) resultList.add(rowData) } result = scanner.next() } } catch { case e: IOException => } println(resultList.toString) } }参考链接
https://www.jianshu.com/p/5ce9b72e3341
https://blog.csdn.net/whdxjbw/article/details/81101200
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)