hbase的学习逻辑_大数据系列——Hbase学习笔记

1. Hbase简介

Hadoop-Database根据'bigtable'论文实现的

分布式 可扩展的大数据存储技术

随机访问 实时读写海量数据

存储数 '十亿行 百万列'的数据

高可靠性、高性能、面向列、可伸缩的分布式存储系统

hbase的底层存储基于hdfs

利用Zookeeper作为协调工具

2. Hbase是什么?

分布式开源数据库,基于hadoop分布式文件系统(HDFS)

模仿提供了Google文件系统的BigTable数据库所有功能

处理非常庞大的表

数十亿行 百万列

利用mapreduce计算数据,利用zookeeper协调资源

HBase是一款NoSQL

3. 行存储和列存储

行存储:mysql oracle底层基于行存储数据的

查询数据需要全表扫描,效率较低

对数据压缩支持不太好

列存储:hbase底层基于列存储数据的

查询数据不需做全表扫描

支持较好的数据压缩

4. Hbase的特点

可以分布式存储海量的数据

具有容错能力强,数据高可靠的特点

HBase是一个列式NoSQL数据库

数据存储的结构是按照列进行存储

5. Hbase的安装部署

==安装hbase高可用集群之前首先要保证zookeeper和hadoop已经安装完成==

准备安装包

hbase-1.1.5-bin.tar.gz

集群的规划

uplooking01: master

uplooking02: master

uplooking03: regionserver

uplooking04: regionserver

uplooking05: regionserver

解压安装包

[root@uplooking01: /soft]:

tar -zxvf hbase-1.1.5-bin.tar.gz -C /opt/

重命名

[root@uplooking01: /opt]:

mv hbase-1.1.5/ hbase

配置环境变量

[root@uplooking01: /opt]:

#配置HBASE的环境变量

export HBASE_HOME=/opt/hbase

export PATH=$PATH:$HBASE_HOME/bin

配置vim hbase-env.sh

[root@uplooking01: /opt/hbase/conf]:

vim  hbase-env.sh

export JAVA_HOME=/opt/jdk

export HBASE_MANAGES_ZK=false #不使用hbase自带的zookeeper

export HBASE_CLASSPATH=/opt/hadoop/etc/hadoop

配置hbase-site.xml

[root@uplooking01: /opt/hbase/conf]:

vim  hbase-site.xml

hbase.rootdir

hdfs://ns1/hbase

hbase.tmp.dir

/opt/hbase/tmp

hbase.cluster.distributed

true

hbase.zookeeper.quorum

uplooking03:2181,uplooking04:2181,uplooking05:2181

配置 regionservers

[root@uplooking01: /opt/hbase/conf]:

vim regionservers

uplooking03

uplooking04

uplooking05

分发文件

[root@uplooking01: /opt]:

scp -r hbase uplooking02:/opt

scp -r hbase uplooking03:/opt

scp -r hbase uplooking04:/opt

scp -r hbase uplooking05:/opt

scp /etc/profile uplooking02:/etc/

scp /etc/profile uplooking03:/etc/

scp /etc/profile uplooking04:/etc/

scp /etc/profile uplooking05:/etc/

source /etc/profile(所有节点都做,要使环境变量生效)

启动hbase集群

start-hbase.sh

单独启动master

[root@uplooking02:/]

hbase-daemon.sh start master

注意事项

==启动hbase集群一定要保证整个集群的时间一致==

==附加(一般不会有这种情况)==

如果启动集群执行start-hbase.sh,master节点可以启动,但是regionserver节点不能启动,但是单独启动regionserver(hbase-daemon.sh start regionserver)是可以启动的,也没有问题,name就需要拷贝一个jar包,

将HADOOP_HOME/share/hadoop/common/lib下的htrace-core-3.0.4.jar  复制到$HBASE_HOME/lib下

6. Hbase的体系结构(模型)

6.1 逻辑结构(模型)

表(table)

划分数据集合的概念,和传统的db中的表的概念是一样的

行键(rowKey)

对应关系数据库中的主键,作用就是唯一标示一行记录

获取hbase中的一个记录(数据),要通过行键来获取

行键是字节数组, 任何字符串都可以作为行键

表中的行根据行键(row key)进行排序 ,数据按照Row key的字节序(byte order)排序存储

列簇(列族)columnFamily

简单的认为是一系列“列”的集合

列限定符(column Qualifier)

或者叫列

每个列簇都可以有多个列

时间戳(version)

在单元格中可以存放多个版本的数据

单元格(cell)

主要用来存储数据

单元格的定位要通过三级定位才能定位到具体的单元格

三级定位

行键+(列族:列)+时间戳

6.2 物理结构(模型)

Zookeeper

分布式协调

Master

HMaster没有单点问题,HBase中可以启动多个HMaster

负责Table和Region的管理工作

管理用户对Table的增、删、改、查操作

RegionServer的负载均衡

调整Region分布 ,在Region Split后,负责新Region的分配

在HRegionServer停机后,负责失效HRegionServer上的Regions迁移

RegionServer

RegionServer主要负责响应用户I/O请求

向HDFS文件系统中读写数据,是HBase中最核心的模块

HLog部分和多个Region部分

Hlog

HLog保存着用户操作hbase的日志

==实现了Write Ahead Log (WAL)预写日志==

Hlog会删除已存储到StoreFile中的数据

Region

区域

保存了row-key的固定区域范围的数据

一个Hregion对应一个Region

一个Hregion对应多个Hstore

Hstore

对应一个列簇(列族)

一个Hstore包含一个MemStore(内存储) 和多个StoreFile

MemStore

内存储

内存中的一块区域,一个Hstore对应一个MemStore

当MemStore中的内容存放不下了就会刷出到硬盘以一个个的StoreFile存储

StoreFile

其实就是数据的存储位置

对HFile的封装**

Hfile

Hadoop File

Hdfs的一个文件对象

7. Hbase读写数据的流程

zookeeper(寻找元数据信息)

get /hbase/meta-region-server

找到提供元数据信息访问的regionserver

找"hbase:meta"表,再去查找要请求哪个regionser来读写数据

8. Hbase的Shell操作

列出所有的命名空间(相当于mysql中的show databases)

list_namespace

列出指定命名空间下的所有表

list_namespace_tables 'ns1'

创建命名空间

create_namespace 'ns1'

创建表

create 'ns1:t1','f1'

禁用表,因为删除表之前首先需要禁用了

disable 'ns1:t1'

启用表

enable 'ns1:t1'

删除表

drop 'ns1:t1'

添加数据

put 'ns1:t1','row001','f1:name','xiaohua'

查询数据

get 'ns1:t1','row001',{COLUMN=>'f1:name'}

删除数据

delete 'ns1:t1','row001','f1:name'

删除一行数据

deleteall 'ns1:t1','row001'

统计表的行数

count 'ns1:t1'

9. Hbase中的版本数据

创建Hbase表时指定列族的显示版本数

create 'ns1:t1',{NAME=>'f1',VERSIONS=>3}

修改Hbase表中的列族的显示版本数

alter 'ns1:t1',{NAME=>'f1',VERSIONS=>5}

查询指定版本数的数据

get 'ns1:t1',{COLUMN=>'f1:name',VERSIONS=>3}

==版本号的作用==

根据显示的版本数,查询出来想要版本的时间戳,根据时间戳找出具体值

10. Hbase中API的基本操作

UTF-8

1.1.5

org.apache.hbase

hbase-client

${hbase-version}

org.apache.hbase

hbase-server

${hbase-version}

org.apache.hive

hive-hbase-handler

2.1.0

junit

junit

4.12

public class HbaseTest {

//添加数据

@Test

public void testPut() throws IOException {

Configuration conf = HBaseConfiguration.create();

//指定zk的地址

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

Connection conn = ConnectionFactory.createConnection(conf);

Table table = conn.getTable(TableName.valueOf("ns1:t1"));

Put put = new Put(Bytes.toBytes("row001"));

put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("admin02"));

table.put(put);

}

//删除数据

@Test

public void testDelete() throws IOException {

Configuration conf = HBaseConfiguration.create();

//指定zk的地址

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

Connection conn = ConnectionFactory.createConnection(conf);

Table table = conn.getTable(TableName.valueOf("ns1:t1"));

Delete delete = new Delete(Bytes.toBytes("row001"));

table.delete(delete);

}

//查询数据

@Test

public void testGet() throws IOException {

Configuration conf = HBaseConfiguration.create();

//指定zk的地址

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

Connection conn = ConnectionFactory.createConnection(conf);

Table table = conn.getTable(TableName.valueOf("ns1:t1"));

Get get = new Get(Bytes.toBytes("row001"));

Result result = table.get(get);

String s = Bytes.toString(result.getValue(Bytes.toBytes("f1"),Bytes.toBytes("name")));

System.out.println(s);

}

}

11. Hbase中的API的管理操作

public class HbaseAdminTest {

private Connection connection;

@Before

public void init() throws Exception {

Configuration conf = new Configuration();

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

connection = ConnectionFactory.createConnection(conf);

}

/**

* 创建表

*

* @throws Exception

*/

@Test

public void testCreateTable() throws Exception {

//获取管理对象

Admin admin = connection.getAdmin();

HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("t2"));

HColumnDescriptor hcd = new HColumnDescriptor(Bytes.toBytes("f1"));

htd.addFamily(hcd);

admin.createTable(htd);

}

/**

* 列出所有的表

* @throws Exception

*/

@Test

public void testListTableNames() throws Exception {

//获取管理对象

Admin admin = connection.getAdmin();

TableName[] tableNames = admin.listTableNames("ns1:.*");

for (TableName tableName : tableNames) {

System.out.println(tableName);

}

}

}

12. Hbase高级查询

//查询数据

@Test

public void testScan() throws IOException {

Configuration conf = HBaseConfiguration.create();

//指定zk的地址

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

Connection conn = ConnectionFactory.createConnection(conf);

Table table = conn.getTable(TableName.valueOf("ns1:t1"));

Scan scan = new Scan();

byte[] cf = Bytes.toBytes("f1");

byte[] column = Bytes.toBytes("name");

Filter filter = new SingleColumnValueFilter(cf, column, CompareFilter.CompareOp.EQUAL, Bytes.toBytes("admin123"));

scan.setFilter(filter);

//获取包含多行数据的对象

ResultScanner resultScanner = table.getScanner(scan);

for (Result result : resultScanner) {

System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("f1"), Bytes.toBytes("age"))));

}

}

13. 百万数据的插入

13.1 mysql百万数据写入

​ 耗时约20分钟

自己测试10分钟

8800000ms,插入15851742tiao数据

13.2 hbase百万数据的写入

/**

* 百万数据的插入

*/

public class HbaseMiTest {

private Connection connection;

@Before

public void init() throws Exception {

Configuration conf = new Configuration();

conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");

connection = ConnectionFactory.createConnection(conf);

}

@Test

public void test01() throws IOException {

HTable table = (HTable) connection.getTable(TableName.valueOf("ns1:t1"));

//不使用每个put操作都刷出一次

table.setAutoFlush(false);

long startTime = System.currentTimeMillis();

for (int i = 0; i < 1000000; i++) {

Put put = new Put(Bytes.toBytes("row" + i));

//关闭预写日志,但是不建议使用,因为这样做不安全

put.setWriteToWAL(false);

put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("admin" + i));

table.put(put);

if (i % 100000 == 0) {

table.flushCommits();

}

}

table.flushCommits();

long endTime = System.currentTimeMillis();

System.out.println("总耗时:" + (endTime - startTime) + "ms");

}

}

大约耗时27s

自己测试,1分20秒 590/80=7.4倍

查询一行是9秒

97602ms,插入15851742tiao数据 8800/175=50倍

14. Hbase中的手动切分region

​ split 'ns1:t1','row040'

15. Hbase手动移动region

​ move 'f6e6164514db53d660c5414df1f3864e','uplooking05,1602

**0,1539222350164'**

16. Hbase中row-key的设计

行健的热点问题

​ 是由于行健相似、连续且数据量过大操作成单region的数据量过大,进而影响读写效率

​ 行健应该尽量的随机、不要出现连续行健。

​ 常见的行健设计就是,比如手机号码倒置+时间戳,比如随机前缀+关系型数据库中的主键

​ 因为hbase提供的查询内容非常非常low,但是所有关于hbase的查询只能通过rowkey,所以

​ 在设计行健的时候,应该考虑将尽量多的查询条件放到rowkey中去,形成的行健就成为复合键

列族的设计:

​ cf1----->"columnFamily"

​ cf2----->"cf"

​ 建议hbase表是高表,不建议宽表,因为宽表拥有的列族很多,操作并跨越的文件(HFile)就很多,效率会有相应影响,

​ 反之建议使用高表,列族不宜过多(列族一般使用一个)。

​ 在设计表的时候,各个列/列族名称不宜过长,因为hbase需要对这些数据在内存中做缓存,做索引,进而影响内存容量,所以建议不易过长,以便能够在内存中容纳更多的数据。至于阅读性,有项目文档搞定。

17. Hbase中客户端工具

​ HbaseExplorer

系统化地阐述了数据挖掘和知识发现技术的产生、发展、应用和相关概念、原理、算法。对数据挖掘中的主要技术分支,包括关联规则、分类、聚类、序列、空间以及Web挖掘等进行了理论剖析和算法描述。本书的许多工作是作者们在攻读博士学位期间的工作总结,一方面,对于相关概念和技术的阐述尽量先从理论分析入手,在此基础上进行技术归纳。另一方面,为了保证技术的系统性,所有的挖掘模型和算法描述都在统一的技术归纳框架下进行。同时,为了避免抽象算法描述给读者带来的理解困难,本书的所有典型算法都通过具体跟踪执行实例来进一步说明。本书共分8章,各章相对独立成篇,以利于读者选择性学习。在每章后面都设置专门一节来对本章内容和文献引用情况进行归纳,它不仅可以帮助读者对相关内容进行整理,而且也起到对本内容相关文献的注释性索引功能。第1章是绪论,系统地介绍了数据挖掘产生的商业和技术背景,从不同侧面剖析了数据挖掘的概念和应用价值;第2章给出了知识发现的过程分析和应用体系结构设计;第3章对关联规则挖掘的原理和算法进行全面阐述;第4章给出分类的主要理论和算法描述;第5章讨论聚类的常用技术和算法;第6章对时间序列分析技术和序列挖掘算法进行论述;第7章系统地介绍了Web挖掘的主要研究领域和相关技术及算法;第8章是对空间数据挖掘技术和算法的分析和讲述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值