Hbase简介
This commit is contained in:
parent
818a881d84
commit
a8c8dd0b70
@ -99,7 +99,7 @@ TODO
|
|||||||
|
|
||||||
## 九、HBase
|
## 九、HBase
|
||||||
|
|
||||||
1. Hbase 简介
|
1. [Hbase 简介](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase简介.md)
|
||||||
2. [HBase系统架构及数据结构](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%8F%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.md)
|
2. [HBase系统架构及数据结构](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E5%8F%8A%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.md)
|
||||||
3. [HBase基本环境搭建(Standalone /pseudo-distributed mode)](https://github.com/heibaiying/BigData-Notes/blob/master/notes/installation/Hbase%E5%9F%BA%E6%9C%AC%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md)
|
3. [HBase基本环境搭建(Standalone /pseudo-distributed mode)](https://github.com/heibaiying/BigData-Notes/blob/master/notes/installation/Hbase%E5%9F%BA%E6%9C%AC%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md)
|
||||||
4. [HBase常用Shell命令](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%20Shell.md)
|
4. [HBase常用Shell命令](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%20Shell.md)
|
||||||
|
70
notes/Hbase简介.md
Normal file
70
notes/Hbase简介.md
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Hbase简介
|
||||||
|
<nav>
|
||||||
|
<a href="#一Hadoop的局限">一、Hadoop的局限</a><br/>
|
||||||
|
<a href="#二HBase简介">二、HBase简介</a><br/>
|
||||||
|
<a href="#三HBase-Table">三、HBase Table</a><br/>
|
||||||
|
<a href="#四Phoenix">四、Phoenix</a><br/>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
## 一、Hadoop的局限
|
||||||
|
|
||||||
|
HBase是一个构建在Hadoop文件系统之上的面向列的数据库管理系统。既然有了Hadoop为什么还需要HBase ? 这里首先介绍一下Hadoop的限制。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://github.com/heibaiying/BigData-Notes/blob/master/pictures/hbase.jpg"/> </div>
|
||||||
|
|
||||||
|
Hadoop擅长存储任意的、半结构甚至非结构化的数据,主要通过HDFS来存储,使用MapReduce来处理。但是Hadoop只能执行批处理,并且只能以顺序方式访问数据。这意味着即使是最简单的工作,也必须搜索整个数据集。面对日益复杂的业务需求,需要一个新的解决方案来实现对海量数据的随机访问。实现数据的随机访问是传统的RDBMS所擅长的,但其却不能存储海量的数据。在这种情况下,必须有一种新的方案来解决海量数据存储和随机访问并存的问题,HBase就是其中之一。
|
||||||
|
|
||||||
|
> 注:HBase,Cassandra,couchDB,Dynamo和MongoDB都能存储海量数据并支持随机访问。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 二、HBase简介
|
||||||
|
|
||||||
|
HBase是一个构建在Hadoop文件系统之上的面向列的数据库管理系统。
|
||||||
|
|
||||||
|
HBase是一种类似于Google’s big table的数据模型,它是Hadoop生态系统的一部分,它将数据存储在HDFS上,客户端可以通过HBase实现对HDFS上数据的随机访问。它具有以下特性:
|
||||||
|
|
||||||
|
- 线性和模块化的可扩展性;
|
||||||
|
- 提供一致的读写操作;
|
||||||
|
- 支持数据分片;
|
||||||
|
- 支持RegionServers之间的自动故障转移;
|
||||||
|
- 易于使用的Java 客户端 API;
|
||||||
|
- 支持BlockCache和布隆过滤器;
|
||||||
|
- 过滤器支持谓词下推。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 三、HBase Table
|
||||||
|
|
||||||
|
HBase是一个面向列的数据库管理系统,这里更为确切的而说,HBase是一个面向列族的数据库管理系统。表 schema 仅定义列族,表具有多个列族,每个列族可以包含任意数量的列,列由多个单元格(cell )组成,单元格可以存储多个版本的数据,多个版本数据以时间戳进行区分。
|
||||||
|
|
||||||
|
下图为Hbase中一张表的:
|
||||||
|
|
||||||
|
+ RowKey为行的唯一标识,所有行按照RowKey的字典序进行排序;
|
||||||
|
+ 该表具有两个列族,分别是personal和office;
|
||||||
|
+ 其中列族personal拥有name、city、phone三个列,office拥有tel、addres两个列。
|
||||||
|
|
||||||
|
<div align="center"> <img src="https://github.com/heibaiying/BigData-Notes/blob/master/pictures/HBase_table-iteblog.png"/> </div>
|
||||||
|
|
||||||
|
> 图片引用自博客:HBase 是列式存储数据库吗(https://www.iteblog.com/archives/2498.html)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 四、Phoenix
|
||||||
|
|
||||||
|
Phoenix是HBase的开源SQL中间层。使得您可以使用标准JDBC API而不是常规HBase客户端API来操作HBase上的数据。
|
||||||
|
|
||||||
|
简单来说,如果你要直接使用HBase,你就只能通过它的Java API来进行调用,虽然官网介绍它的API是简单易用的,但相比于使用一行SQL就能实现数据的查询过滤,原生的API还是过于复杂,Phoenix 的理念是`we put sql SQL back in NOSQL`,即你可以使用标准的SQL就能完成对HBase中数据的操作。
|
||||||
|
|
||||||
|
Phoenix完全使用Java编写,作为HBase内嵌的JDBC驱动。Phoenix查询引擎会将SQL查询转换为一个或多个HBase scan,并编排并行执行以生成标准的JDBC结果集,同时Phoenix还拥有二级索引等Hbase不具备的特性,这使得Phoenix具有接近原生HBase API的性能表现。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 参考资料
|
||||||
|
|
||||||
|
1. [HBase - Overview](https://www.tutorialspoint.com/hbase/hbase_overview.htm)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ Row Key是用来检索记录的主键。访问HBase Table中的行,只有三
|
|||||||
|
|
||||||
+ 全表扫描
|
+ 全表扫描
|
||||||
|
|
||||||
Row Key (行键)可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在HBase内部,Row Key保存为字节数组。存储时,数据按照Row Key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将经常一起读取的行存储放到一起(位置相关性)。
|
Row Key (行键)可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在HBase内部,Row Key保存为字节数组。存储时,数据按照Row Key的字典序(byte order)排序存储。
|
||||||
|
|
||||||
需要注意以下两点:
|
需要注意以下两点:
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Storm 核心概念核心概念详解
|
# Storm 核心概念详解
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<a href="#一storm核心概念">一、Storm核心概念</a><br/>
|
<a href="#一storm核心概念">一、Storm核心概念</a><br/>
|
||||||
@ -15,9 +15,10 @@
|
|||||||
<a href="#25-executor线程">2.5 executor线程</a><br/>
|
<a href="#25-executor线程">2.5 executor线程</a><br/>
|
||||||
<a href="#26-并行度">2.6 并行度</a><br/>
|
<a href="#26-并行度">2.6 并行度</a><br/>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
## 一、Storm核心概念
|
## 一、Storm核心概念
|
||||||
|
|
||||||
|
下图为Storm为运行流程图:
|
||||||
|
|
||||||
<div align="center"> <img src="https://github.com/heibaiying/BigData-Notes/blob/master/pictures/spout-bolt.png"/> </div>
|
<div align="center"> <img src="https://github.com/heibaiying/BigData-Notes/blob/master/pictures/spout-bolt.png"/> </div>
|
||||||
|
|
||||||
### 1.1 Topologies(拓扑)
|
### 1.1 Topologies(拓扑)
|
||||||
|
200
notes/storm编程模型.md
Normal file
200
notes/storm编程模型.md
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
# Storm 编程模型
|
||||||
|
|
||||||
|
## 一、简介
|
||||||
|
|
||||||
|
下图为Strom的运行流程图,也是storm的编程模型图,在storm 进行流处理时,我们需要自定义实现自己的spout(数据源)和bolt(处理单元),并通过`TopologyBuilder`将它们之间进行关联,定义好数据处理的流程。
|
||||||
|
|
||||||
|
下面小结分别介绍如何按照storm内置接口分别实现spout和bolt,然后将其进行关联,最后将其提交到本地和服务器进行运行。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 二、IComponent
|
||||||
|
|
||||||
|
`IComponent`接口定义了Topology中所有组件(spout/bolt)的公共方法,我们实现spout或bolt都必须直接或者间接实现这个接口。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface IComponent extends Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 声明此拓扑的所有流的输出模式。
|
||||||
|
* @param declarer这用于声明输出流id,输出字段以及每个输出流是否是直接流(direct stream)
|
||||||
|
*/
|
||||||
|
void declareOutputFields(OutputFieldsDeclarer declarer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 声明此组件的配置。
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
Map<String, Object> getComponentConfiguration();
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 三、spout
|
||||||
|
|
||||||
|
### 3.1 ISpout接口
|
||||||
|
|
||||||
|
实现自定义的spout需要实现`ISpout`,其定义了spout的所有可用方法:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface ISpout extends Serializable {
|
||||||
|
/**
|
||||||
|
* 组件初始化时候被调用
|
||||||
|
*
|
||||||
|
* @param conf ISpout的配置
|
||||||
|
* @param context 应用上下文,可以通过其获取任务ID和组件ID,输入和输出信息等。
|
||||||
|
* @param collector 用来发送spout中的tuples,它是线程安全的,建议保存为此spout对象的实例变量
|
||||||
|
*/
|
||||||
|
void open(Map conf, TopologyContext context, SpoutOutputCollector collector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ISpout将要被关闭的时候调用。但是其不一定会被执行,如果在集群环境中通过kill -9 杀死进程时其就无法被执行。
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当ISpout从停用状态激活时被调用
|
||||||
|
*/
|
||||||
|
void activate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当ISpout停用时候被调用
|
||||||
|
*/
|
||||||
|
void deactivate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这是一个核心方法,主要通过在此方法中调用collector将tuples发送给下一个接收器,这个方法必须是非阻塞的。 * nextTuple/ack/fail/是在同一个线程中执行的,所以不用考虑线程安全方面。当没有tuples发出时应该
|
||||||
|
* 让nextTuple休眠(sleep)一下,以免浪费CPU。
|
||||||
|
*/
|
||||||
|
void nextTuple();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过msgId进行tuples处理成功的确认,被确认后的tuples不会再次被发送
|
||||||
|
*/
|
||||||
|
void ack(Object msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过msgId进行tuples处理失败的确认,被确认后的tuples会再次被发送进行处理
|
||||||
|
*/
|
||||||
|
void fail(Object msgId);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 BaseRichSpout抽象类
|
||||||
|
|
||||||
|
**通常情况下,我们实现自定义的Spout时不会直接去实现`ISpout`接口,而是继承`BaseRichSpout`。**`BaseRichSpout`继承自`BaseCompont`,同时实现了`IRichSpout`接口。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`IRichSpout`接口继承自`ISpout`和`IComponent`,自身并没有定义任何方法。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface IRichSpout extends ISpout, IComponent {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
BaseComponent 抽象类也仅仅是空实现了`IComponent`的`getComponentConfiguration`方法。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public abstract class BaseComponent implements IComponent {
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getComponentConfiguration() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`BaseRichSpout`通过继承自`BaseCompont`,同时实现了`IRichSpout`接口,并且空实现了其中部分方法。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public abstract class BaseRichSpout extends BaseComponent implements IRichSpout {
|
||||||
|
@Override
|
||||||
|
public void close() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void activate() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deactivate() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ack(Object msgId) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fail(Object msgId) {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
通过这样的设计,我们在继承`BaseRichSpout`实现自己的spout时,就只需要实现三个必须的方法:
|
||||||
|
|
||||||
|
+ open : 来源于ISpout,可以通过此方法获取用来发送tuples的`SpoutOutputCollector`;
|
||||||
|
+ nextTuple :来源于ISpout,必须在此方法内部才能调用`SpoutOutputCollector`发送tuple;
|
||||||
|
+ declareOutputFields :来源于IComponent,通过此方法声明发送的tuple的名称,这样下一个组件才能知道如何接受数据。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 四、bolt
|
||||||
|
|
||||||
|
通过上小结我们已经了解了storm如何对spout接口进行设计的,bolt接口的设计也是一样的。
|
||||||
|
|
||||||
|
### 4.1 IBolt 接口
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 在客户端计算机上创建的IBolt对象。会被被序列化到topology中(使用Java序列化),并提交给集群的主机(Nimbus)。
|
||||||
|
* Nimbus启动workers反序列化对象,调用prepare,然后开始处理tuples。
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IBolt extends Serializable {
|
||||||
|
/**
|
||||||
|
* 组件初始化时候被调用
|
||||||
|
*
|
||||||
|
* @param conf storm中定义的此bolt的配置
|
||||||
|
* @param context 应用上下文,可以通过其获取任务ID和组件ID,输入和输出信息等。
|
||||||
|
* @param collector 用来发送spout中的tuples,它是线程安全的,建议保存为此spout对象的实例变量
|
||||||
|
*/
|
||||||
|
void prepare(Map stormConf, TopologyContext context, OutputCollector collector);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理单个tuple输入。
|
||||||
|
*
|
||||||
|
* @param Tuple对象包含关于它的元数据(如来自哪个组件/流/任务)
|
||||||
|
*/
|
||||||
|
void execute(Tuple input);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IBolt将要被关闭的时候调用。但是其不一定会被执行,如果在集群环境中通过kill -9 杀死进程时其就无法被执行。
|
||||||
|
*/
|
||||||
|
void cleanup();
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 4.2 BaseRichBolt抽象类
|
||||||
|
|
||||||
|
同样的,在实现我们自己的bolt时,我们也通常是继承`BaseRichBolt`抽象类来实现。`BaseRichBolt`继承自`BaseComponent`抽象类,并实现了`IRichBolt`接口。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
`IRichBolt`接口继承自`IBolt`和`IComponent`,自身并没有定义任何方法。
|
||||||
|
|
||||||
|
```
|
||||||
|
public interface IRichBolt extends IBolt, IComponent {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
通过这样的设计,我们在继承`BaseRichBolt`实现自己的bolt时,就只需要实现三个必须的方法:
|
||||||
|
|
||||||
|
- prepare: 来源于IBolt,可以通过此方法获取用来发送tuples的`SpoutOutputCollector`;
|
||||||
|
- execute:来源于IBolt,处理tuple和发送处理完成的tuple;
|
||||||
|
- declareOutputFields :来源于IComponent,通过此方法声明发送的tuple的名称,这样下一个组件才能知道如何接受数据。
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 五、使用案例
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 六、提交到服务器运行
|
BIN
pictures/HBase_table-iteblog.png
Normal file
BIN
pictures/HBase_table-iteblog.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
BIN
pictures/storm-baseRichSpout.png
Normal file
BIN
pictures/storm-baseRichSpout.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
pictures/storm-baseRichbolt.png
Normal file
BIN
pictures/storm-baseRichbolt.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Loading…
x
Reference in New Issue
Block a user