目录
引言
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。
Hbase应用场景:
电商平台:电商平台可以使用HBase来存储用户行为数据,如浏览记录、购买记录、搜索记录等,以实现对用户行为的实时分析,进而改进网站体验和销售策略。
社交网络:HBase可以作为社交网络平台的后端数据库,存储用户信息、关系和活动等数据。例如,微博、微信等社交网络应用都使用HBase来存储用户信息,并实现好友关系链、粉丝列表等功能。
实时分析:HBase可以与Spark、Storm等实时计算框架结合使用,实现实时数据分析和处理。例如,金融行业可以使用HBase来存储股票实时行情数据,并利用实时计算框架进行分析和预测。
物联网:随着物联网技术的发展,越来越多的设备产生海量的数据,如传感器数据、设备状态数据等。HBase可以作为物联网平台的后端数据库,存储这些数据,并支持实时数据分析和处理。推荐画像:用户画像,是一个比较大的稀疏矩阵,蚂蚁金服的风控就是构建在HBase之上
Hbase的存储机制:
HBase是BigTable的开源实现,基于HDFS,提供列式存储、高可靠性、高性能和实时读写功能。它主要通过行键检索数据,并支持单行事务。HBase主要用于存储结构化和半结构化数据,但查询功能相对简单,不支持复杂查询和强一致性事务。在HBase中,数据以字节数组形式存储,Hbase表中一般有以下特点:
存储能力大:一个表可以有数亿行,上百万列。
面向列:面向列(族)的存储和权限控制,列(族)独立检索。
稀疏:对于空(歹」,其并不占用存储空间。所以,表结构可以设计的非常稀疏。
Hbase系统架构:
ZooKeeper:ZooKeeper是一个分布式协调服务,用于管理HBase集群的状态信息、配置信息和领导者选举等任务。
HMaster:HBase的主节点,负责管理元数据信息和协调整个HBase集群的操作。HMaster并不存储数据,主要负责表的创建、删除、修改等元数据操作,同时负责Region的分配和负载均衡。HRegionServer:HRegionServer在Hbase中至关重要,主要是负责响应I/O请求、管理HRegion、数据存储与读写、预写日志记录以及负载均衡的功能。
HRegion:HRegion是数据存储的物理分区,当中的数据表可以被拆分为多个物理块,而每一块都对应一个。会根据表设定的阈值对表进行拆分,拆分之后的分区包含数据行的一个子集。
Hbase数据模型:
表(Table):
类似于关系型数据库中的表,但它是稀疏的,这意味着可以为不同的行存储不同的列。
表有一个行键(Row Key)作为主键,用于唯一标识每一行。
行键(Row Key):
行键是唯一的,并且是表的主键。
它可以是任意字符串(通常是字节数组),但通常设计为有序的,以便进行有效的范围扫描。由于HBase按照行键的字典顺序存储数据,因此行键的设计对性能至关重要。
列族(Column Family):
表被组织为列族。列族是表的列的集合,它们共享相同的存储参数和属性。
列族在表创建时定义,并且之后不能更改。但可以向现有表添加新的列族。
列族中的列是动态的,可以在运行时添加或删除。
列(Column):
列在HBase中是动态的,并且与行键和列族一起唯一标识一个单元格(Cell)。
列名由列族和列限定符组成,例如cf1:col1。
单元格存储实际的数据值,可以是任意类型的字节数组。
时间戳(Timestamp):
每个单元格都有一个与之关联的时间戳,表示数据版本的日期和时间。
当向HBase表中插入或更新数据时,如果不指定时间戳,则使用当前的系统时间。
HBase通过时间戳支持多版本并发控制(MVCC),允许用户检索数据的旧版本。
单元格(Cell):
单元格是HBase中存储数据的基本单位。它由行键、列族、列限定符和时间戳唯一标识。
单元格包含实际的数据值,该值是一个字节数组。
Row Key | Time Stamp | ColumnFamily contents | ColumnFamily anchor | ColumnFamily people |
"com.cnn.www" | t9 | anchor:cnnsi.com = "CNN" | ||
"com.cnn.www" | t8 | anchor:my.look.ca = "CNN.com" | ||
"com.cnn.www" | t6 | contents:html = "<html>…" | ||
"com.cnn.www" | t5 | contents:html = "<html>…" | ||
"com.cnn.www" | t3 | contents:html = "<html>…" | ||
"com.example.www" | t5 | contents:html = "<html>…" | people:author = "John Doe" |
- 上述表格有两行、三个列蔟(contens、ancho、people)
- “com.cnn.www”这一行anchor列蔟两个列(anchor:cssnsi.com、anchor:my.look.ca)、contents列蔟有个1个列(html)
- “com.cnn.www”在HBase中有 t3、t5、t6、t8、t9 5个版本的数据
Hbase操作:
创建表
-
HBase是没有schema的,就是在创建表的时候不需要指定表中有哪些列,只需要指定有多少个列蔟
create "表名","列蔟1", "列蔟2"
删除表
* 禁用表
disable "表名"
* 删除表
drop "删除表"
注意:要先禁用然后才可以删除。
新增数据/更新数据/删除数据/查询数据
新增:put "表名", "rowkey", "列蔟:列名", "值"
新增一列
更新:和新增是一样的。
删除数据
delete "表名", "rowkey", "列蔟:列名"
delete也是删除一个列
deleteall "表名", "rowkey"
删除一行
查询数据
get "表名", "rowkey"get是查询一行的数据
Hbase预分区:
HBase预分区的原理是将数据根据RowKey的哈希值进行分区,将数据均匀地分布在不同的区域中。HBase使用了一种称为“一致性哈希”的算法来实现预分区。
Hbase预分区操作方式:
在HBase中,主要有两种预分区方案:手动预分区和自动预分区。
手动预分区:在创建表时,通过命令或API进行预分区操作。用户可以自定义分区,也可以基于HBase提供的分区算法来实现。分区后,多个Region会被HBase的Master节点分配到不同的RegionServer上进行管理,从而保证负载均衡。
自动预分区:随着表中数据的增加,当某个Region中的数据达到一定的阈值时(这个阈值由HBase的配置参数决定),HBase会自动进行分区。通过这种方式,HBase可以根据数据的实际情况动态地调整分区的数量和大小,以适应数据的变化。
Hbase预分区的作用:
- 避免频繁的分区操作:在HBase中,当某个Region的数据量过大时,会进行分裂(Split)操作,产生新的Region。这个过程会耗费大量的资源,并对HBase的性能产生影响。通过预分区,可以避免频繁的分区操作,减少资源的消耗。
- 提高查询效率:由于数据被分散存储在多个分区中,查询时可以同时并发地从多个分区中读取数据,提高了查询的并发性能。
- 实现负载均衡:通过预分区,可以将数据均匀地分布到集群中的不同节点上,实现负载均衡。这样可以避免某个节点负载过高或过低的情况,提高HBase的整体性能。
Hbase java编程:
1.创建idea Maven项目
2.导入依赖
<repositories>
<repository>
<id>aliyun</id>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<target>1.8</target>
<source>1.8</source>
</configuration>
</plugin>
</plugins>
</build>
3.将以下三个配置文件复制到resource目录中:
1.hbase-site.xml
从Linux中下载:sz /export/server/hbase-2.1.0/conf/hbase-site.xml
2.core-site.xml
从Linux中下载:sz /export/server/hadoop-2.7.5/etc/hadoop/core-site.xml
3.log4j.properties
4.创建连接:
4.1建立HBase连接
4.2创建admin对象
public class TableAmdinTest {
private Configuration configuration;
private Connection connection;
private Admin admin;
@BeforeTest
public void beforeTest() throws IOException {
// 1. 使用HbaseConfiguration.create()创建Hbase配置
Configuration configuration = HBaseConfiguration.create();
// 2. 使用ConnectionFactory.createConnection()创建Hbase连接
connection = ConnectionFactory.createConnection(configuration);
// 3. 要创建表,需要基于Hbase连接获取admin管理对象
// 要创建表、删除表需要和HMaster连接,所以需要有一个admin对象
admin = connection.getAdmin();
}
@AfterTest
public void afterTest() throws IOException {
admin.close();
connection.close();
}
}
5.创建表(WATER_BILL):
@Test
public void createTableTest() throws IOException {
TableName tableName = TableName.valueOf("WATER_BILL");
// 1. 判断表是否存在
if(admin.tableExists(tableName)) {
// a) 存在,则退出
return;
}
// 构建表
// 2. 使用TableDescriptorBuilder.newBuilder构建表描述构建器
// TableDescriptor: 表描述器,描述这个表有几个列蔟、其他的属性都是在这里可以配置
TableDescriptorBuilder tableDescriptorBuilder = TableDescriptorBuilder.newBuilder(tableName);
// 3. 使用ColumnFamilyDescriptorBuilder.newBuilder构建列蔟描述构建器
// 创建列蔟也需要有列蔟的描述器,需要用一个构建起来构建ColumnFamilyDescriptor
// 经常会使用到一个工具类:Bytes(hbase包下的Bytes工具类)
// 这个工具类可以将字符串、long、double类型转换成byte[]数组
// 也可以将byte[]数组转换为指定类型
ColumnFamilyDescriptorBuilder columnFamilyDescriptorBuilder = ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("C1"));
// 4. 构建列蔟描述,构建表描述
ColumnFamilyDescriptor cfDes = columnFamilyDescriptorBuilder.build();
// 建立表和列蔟的关联
tableDescriptorBuilder.setColumnFamily(cfDes);
TableDescriptor tableDescriptor = tableDescriptorBuilder.build();
// 5. 创建表
admin.createTable(tableDescriptor);
}
运行:
打开hbase shell使用list命令可以看到表WATER_BILL 已经被创建出来。
总结:
Hbase作为一个基于Hadoop之上的NoSQL数据库,它比Hive更适合做一些高速查询随机访问非结构化数据的场景,而Hive则更偏向于分析,做为数据仓库。Hbase依靠其列式存储、高可靠性、高性能和实时读写直至今日依旧受到人们的喜爱。