HBase是基于列存储的NoSQL数据库,与现在常见的关系型数据库sql server、Oracle或者mySQL相比它不遵循了ACID结构,它是对传统的SQL的一种补充,它是根据CAP理论而形成的满足一个分布式系统的非关系型数据库。与传统的数据库相比它的优势是能够对数据进行简单的增加或者修改,并能够平滑的伸缩。因此在现在云计算和大数据领域具有广泛的用途,同时也成为Hadoop生态系统中的重要一环。
现今NoSQL数据库种类繁多,大致分为四种:
(1)、Key/Value键值对存储的数据库 Redis,Berkeley DB
(2)、面向列存储的数据库 Cassandra,HBase
(3)、面向文档存储的数据库 CouchDB,MongoDB
(4)、面向图形存储的数据库 Neo4J,InfoGrid
首先还是列出HBase代码编写的大致模板结构以供参考:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//1、创建HBase表格 private static Configuration conf = null; static{ Configuration HBASE_CONFIG = new Configuration(); conf = HBaseConfiguration.create(HBASE_CONFIG); } public static void createHBaseTable(String tableName,String[] ColumnFamilys){ HBaseAdmin admin = new HBaseAdmin(conf); if(admin.tableExists(tableName)) System.out.println("Table is already existing"); else{ HTableDescriptor tableDesc = new HTableDescriptor(tableName); for(int i=0;i<ColumnFamilys.length;++i){ tableDesc.addFamily(new HColumnDescriptor(ColumnFamilys[i])); } admin.createTable(tableDesc); } } //2、删除表格 public static void deleteHBaseTable(String tableName){ try{ HBaseAdmin admin = new HBaseAdmin(conf); admin.disableTable(tableName); //先禁用表 admin.deleteTable(tableName); //再删除表 } catch(Exception e){ } } //3、插入单行数据 public static void insertHBaseTableRow(String tableName,String rowKey,String ColumnFamily,String qualifier,String value) throws Exception{ try{ HTable table = new HTable(conf,tableName); Put put = new Put(Bytes.toBytes(rowKey)); put.add(Bytes.toBytes(columnFamily),Bytes.toBytes(qualifier),Bytes.toBytes(value)); table.put(put); } catch(IOException e){ } } //4、删除数据 public static void deleteHBaseTableRow(String tableName,String rowKey){ HTable table = new HTable(conf,tableName); List list = new ArrayList(); Delete del = new Delete(Bytes.toBytes(rowKey)); list.add(del); table.delete(list); } //5、获取单行数据 public static void getSignalRow(String tableName,String rowKey){ HTable table = new HTable(conf,tableName); Get get = new Get(Bytes.toBytes(rowKey)); Result rs = table.get(get); for(KeyValue kv:rs.raw()){ System.out.println(Bytes.toString(kv.getRow()) + " "); System.out.println(Bytes.toString(kv.getFamily()) + ":"); System.out.println(Bytes.toString(kv.getQualifier()) + " "); System.out.println(kv.getTimeStamp() + " "); System.out.println(Bytes.toString(kv.getValue())) } } //6、获取表中所有数据 public static void getAllRow(String tableName){ HTable table = new HTable(conf,tableName); Scan scan = new Scan(); ResultScanner rss = table.getScanner(scan); for(Result rs:rss){ for(KeyValue kv:rs.raw()){ System.out.println(Bytes.toBytes(kv.getRow()) + " "); System.out.println(Bytes.toBytes(kv.getFamily()) + ":"); System.out.println(Bytes.toBytes(kv.getQualifier()) + " "); System.out.println(kv.getTimeStamp() + " "); System.out.println(Bytes.toBytes(kv.getValue())) } } }
HBase是Master/Salve结构的面向列存储的数据库,其目录结构如下
上面是一个Table所包含的的目录,而hbase下也存在相应的目录,其中有
(1)、.logs目录:该目录存储了有HLog管理的WAL Log文件,每个HRegionServer中都会保持一个HLog实例,并在HRegion初始化时,将HLog作为其构造方法的参数传入,每一个HRegion会对应该目录下的一个Log文件。HLog是HBase的日志类,下写入时进行Write Ahead Log(WAL),该日志文件主要用于数据恢复
(2)、.oldlogs目录:该目录存储着一些不再需要的日志文件。当WAL日志持久化到存储文件中时,记录这些操作的日志文件已经不再需要,这时这些日志文件将被移动到.oldlogs目录下。而这些旧的日志会在一个默认时间段后被Master进程清理掉。默认的时间是60000ms,即旧的HLog文件在.oldlogs目录中一般默认保留10min。这个可以通过修改hbase.master.logcleaner.ttl参数改变
(3)、.corrupt目录:这个目录主要用于处理WAL日志记录过程中产生的错误。当日志文件进行split时发生错误时,有问题的WAL日志会被移到.corrupt目录下,而split则继续进行。
HBase的数据模型如下图:
组成部件说明:
Row Key: Table主键 行键 Table中记录按照Row Key排序
Timestamp: 每次对数据操作对应的时间戳,也即数据的version number
Column Family: 列簇,一个table在水平方向有一个或者多个列簇,列簇可由任意多个Column组成,列簇支持动态扩展,无须预定义数量及类型,二进制存储,用户需自行进行类型转换
而HBase的操作也是分读写两种操作:
1、HBase读取数据的序列图如下
2、HBase写数据的序列图如下