Hadoop生态系统

HBase 简介

--HBase – Hadoop Database,是一个高可靠性、高性能(秒级别读取)、面向列、可伸缩、实时读写的分布式数据库。

--利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。

--HBase利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为分布式协调服务。

--HBase主要存储非结构化和半结构化的松散数据。

注意:HBASE是免费的,存储能力强;在国内使用比较活跃。如新浪微博数据的存储是由redis存储,现在正往HBASE转移。

具体细节参考文档:http://abloz.com/hbase/book.html

HBase 数据模型


概念的理解

Row Key:HBASE的主键,用来检索记录。

--决定一行数据

--按照字典顺序排序

--Row key只能存储64k的字节数据

Column Family列族 &qualifier

--列族在创建表的时候声明,一个列族可以包含多个列,列中的数据都是以二进制形式存在,没有数据类型。因此列中可以存储多种格式的数据如图片视频等信息。

--HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先给出。如 create ‘test’, ‘course’;

--列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如course:math, course:english, 新的列族成员(列)可以随后按需、动态加入;
--权限控制、存储以及调优都是在列族层面进行的;
--HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。

Cell单元格

由行和列的坐标交叉决定;
单元格是有版本的;
单元格的内容是未解析的字节数组;
由{row key, column( =<family> +<qualifier>), version} 唯一确定的单元。
cell中的数据是没有类型的,全部是字节码形式存贮。

timestamp:时间戳

每个 cell都保存着同一份数据的多个版本。版本通过时间戳来索引

物理存储。

 1、Table 在行的方向上分割为多个HRegion,一个region由[startkey,endkey)表示,每个HRegion分散在不同的RegionServer中。



2、region按大小分割的,每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,Hregion就会等分会两个新的Hregion。当table中的行不断增多,就会有越来越多的Hregion。


3、Hregion是Hbase中分布式存储和负载均衡的最小单元。最小单元就表示不同的Hregion可以分布在不同的HRegion server上。但一个Hregion是不会拆分到多个server上的。

4、由上图看出HBase表的中的数据不可能全部存储在一台机器中,它是分布式存储在多台机器上,这样在读写的时候的都是操作不同的机器,提高了读写的效率。

总之:一个表被分割为了多个region,每个region保存着一个rowkey范围的数据,这些region被保存在了多台机器中。

注意:region是分布式存储以及负载均衡的最小的单元。

一个region保存着一个rowkey范围的数据。

表中的数据是根据行键按照字典顺序进行排序的。

5、HRegion虽然是分布式存储的最小单元,但并不是存储的最小单元。

事实上,HRegion由一个或者多个Store组成,每个store保存一个columns family。

每个Strore又由一个memStore和0至多个StoreFile组成。如图:

StoreFile以HFile格式保存在HDFS上。

HBase 架构

Client
--包含访问HBase的接口、并维护cache来加快对HBase的访问。
Zookeeper
--保证任何时候,集群中只有一个master
--存贮所有Region的寻址入口。
--实时监控Region server的上线和下线信息。并实时通知Master
--存储HBase的schema和table元数据

Master(集群的主节点)
--为Region server分配region
--负责Region server的负载均衡
--发现失效的Region server并重新分配其上的region
--管理用户对table的增删改操作

RegionServer(集群的从节点)

--Region server维护Master分配给它的region,处理对这些region的IO请求

--Region server负责切分在运行过程中变得过大的region。

Region 

--HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据
--每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region(裂变)
--当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Regionserver 上。

Memstore 与 storefile

一个region由多个store组成,一个store对应一个CF(列族)

store包括位于内存中的memstore和位于磁盘的storefile;写操作先写入memstore,当memstore中的数据达到某个阈值,hregionserver会启动flashcache进程写入storefile,每次写入形成单独的一个storefile

当storefile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction),在合并过程中会进行版本合并和删除工作(majar),形成更大的storefile。
当一个region所有storefile的大小和数量超过一定阈值后,会把当前的region分割为两个,并由hmaster分配到相应的regionserver服务器,实现负载均衡
客户端检索数据,先在memstore找,找不到再找storefile

HRegion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的HRegion可以分布在不同的 HRegion server上。
HRegion由一个或者多个Store组成,每个store保存一个columns family。
每个Strore又由一个memStore和0至多个StoreFile组成。如图:StoreFile以HFile格式保存在HDFS上。

HBase优化


HBASE的伪分布式搭建

在itcast02上搭建HBase的伪分布式
前提环境:Java环境变量的配置。
                  HBase的安装以及环境变量的配置。

1.hbase-env.sh中配置JAVA_HOME
2.配置hbase-site.xml如下
<property>
<name>hbase.rootdir</name>
<value>file:///home/testuser/hbase</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/testuser/zookeeper</value>
</property>

启动HBase

start-hbase.sh

Hbase的命令操作

执行hbase的命令行

迁移到 hbase的bin目录下 执行 hbase shell命令

使用命令行的方式创建表和插入数据。

创建表:

create 'people',{NAME=>'info',VERSIONS=>3},{NAME=>'data',VERSIONS=>1}

查看所有的表:list命令。

查看指定表的描述:describe。

插入数据:put命令。

如:往列族info中插入数据

put 'people', 'rk0001', 'info:name', 'cls'

put 'people', 'rk0001', 'info:gender', 'femal'

put 'people','rk0001', 'info:size', '36'

往列族data中插入数据

put 'people', 'rk0001', 'data:torrent', '种子'

其中rk0001为hbase的主键;info为列族;name为info列族下的列;cls为列name的值。

查看数据:scan 'people'

这个时候返回的数据为一行4列,其中行数由主键决定。

往另一个主键中插入数据

put 'people', 'rk0002', 'info:name', 'bdyjy'

put 'people', 'rk0002', 'info:gender', 'female'

这个时候返回了两行数据。

同一列插入多次数据

put 'people','rk0001', 'info:size', '37'

put 'people','rk0001', 'info:size', '37.5'

在这里不要认为是把原来的数据覆盖掉了。而是它有自己的历史记录。

scan 'people', {COLUMNS => 'info', VERSIONS=>3}

注意:当再次插入put 'people','rk0001', 'info:size', '38'

也就是说同一列中插入的数据超过版本号后会将某条原来的数据删除。

HBase的完全分布式安装

首先保证 Hadoop集群正常运行, 启动!!
1、环境准备
   hostname、hosts、网络、防火墙
   时间同步!!!
yum install ntp -y
ntpdate 202.120.2.101(时间服务器)
2、免密钥
   主 -> 从
   主 -> 主
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
ssh-copy-id nodeX
3、上传压缩包  解压
      配置环境变量
4、修改配置文件
   hbase-env.sh   JAVA_HOME;  HBASE_MANAGES_ZK=false
   hbase-site.xml
   regionservers
   backup-masters
   hdfs-site.xml
  1)hbase-site.xml

 <property>
<name>hbase.rootdir</name>
<value>hdfs://ns1/hbase</value>  #####ns1为nameservice的值
</property>
<property>
<name>hbase.cluster.distributed</name>               ####是否是分布式   
<value>true</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>                      ##Zookeeper的集群节点
<value>weeked11,weekend12,weekend13</value>
</property>
 2)regionservers
    weekend11
    weekend12
    weekend13
3)backup-masters
    vi backup-masters
    weekend12
 4)hdfs-site.xml 复制到hbase的conf目录下

5、同步配置文件 !!! 
6、启动集群
   在Master 执行start-hbase.sh(在哪台节点上启动,哪台节点就是Master、这里我们weekend10上启动)
搭建过程出错:
看日志 分析问题
删除hdfs  /hbase目录
删除ZooKeeper当中 /hbase结点  zkCli.sh   rmr /hbase
修改错误  配置文件
重新启动集群

整个集群启动后查看Zookeeper某个节点

Java API的方式操作Hbase

public class HBaseDemo {
HBaseAdmin admin;
HTable hTable;
Configuration conf;
String TN = "phone";
@Before
public void begin() throws Exception {
conf = new Configuration(true);
// hbase ZooKeeper集群 伪分布式-那一台服务器
conf.set("hbase.zookeeper.quorum", "weekend11,weekend12,weekend13");
admin = new HBaseAdmin(conf);
hTable = new HTable(conf, TN);
}
@After
public void end() throws Exception {
if (admin != null) {
admin.close();
}
if (hTable != null) {
hTable.close();
}
}
@Test
public void createTable() throws Exception {
// 判断创建的表是否存在
if (admin.tableExists(TN)) {
//禁用创建的表
admin.disableTable(TN);
admin.deleteTable(TN);
}
HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(TN));// 设置表名
         HColumnDescriptor cf = new HColumnDescriptor("cf");// 创建列族
cf.setInMemory(true);// 设置缓存
desc.addFamily(cf);// 将创建的列族添加到表中
admin.createTable(desc);
}
@Test
public void insertDB() throws Exception {
// 参数 rowkey
Put put = new Put("123123".getBytes());
put.add("cf".getBytes(), "name".getBytes(), "xiaoming".getBytes());
put.add("cf".getBytes(), "age".getBytes(), "11".getBytes());
put.add("cf".getBytes(), "sex".getBytes(), "man".getBytes());
hTable.put(put);
}
@Test
public void getDB1() throws Exception {
Get get = new Get("123123".getBytes());
get.addColumn("cf".getBytes(), "name".getBytes());
Result rs = hTable.get(get);
Cell cell = rs.getColumnLatestCell("cf".getBytes(), "name".getBytes());
System.out.println(new String(CellUtil.cloneValue(cell)));

}

/**
* 模拟 通话详单 十个用户 产生一百条通话记录 rowkey: 手机号_(大数-时间戳)
*/
@Test
public void insertDB2() throws Exception {
List<Put> puts = new ArrayList<Put>();
for (int i = 0; i < 10; i++) {
// 自己的手机号
String pnum = getPhoneNum("186");
for (int j = 0; j < 100; j++) {
// 通话时间
String dateStr = getDate("2017");
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String rowkey = pnum + "_" + (Long.MAX_VALUE - sdf.parse(dateStr).getTime());
// 对方手机号
String dnum = getPhoneNum("177");
// 主叫0被叫1类型
String type = r.nextInt(2) + "";
// 通话时长
String telLength = r.nextInt(100) + "";
Put put = new Put(rowkey.getBytes());
put.add("cf".getBytes(), "dnum".getBytes(), dnum.getBytes());
put.add("cf".getBytes(), "type".getBytes(), type.getBytes());
put.add("cf".getBytes(), "telLength".getBytes(), telLength.getBytes());
put.add("cf".getBytes(), "date".getBytes(), dateStr.getBytes());
puts.add(put);
} }

hTable.put(puts);
}
/**
* 查询 某个用户 某个月 通话记录 范围查找
*/
@Test
public void scanDB1() throws Exception {

Scan scan = new Scan();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
// 18688166887手机号 一月份 的所有通话记录
String startRowkey = "18688166887_" + (Long.MAX_VALUE - sdf.parse("20170201000000").getTime());
String stopRowkey = "18688166887_" + (Long.MAX_VALUE - sdf.parse("20170101000000").getTime());
scan.setStartRow(startRowkey.getBytes());
scan.setStopRow(stopRowkey.getBytes());
ResultScanner rss = hTable.getScanner(scan);
for (Result rs : rss) {
System.out
.print(new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
System.out.print(
"  " + new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
System.out.print("  "
+ new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "telLength".getBytes()))));
System.out.println(
"  " + new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
}
}
/**
* 查询某个用户 所有的主叫类型的 通话记录 18688166887 cf:type=0 过滤器

* @throws Exception
*/
@Test
public void scanDB2() throws Exception {
FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ALL);
PrefixFilter filter1 = new PrefixFilter("18688166887".getBytes());

list.addFilter(filter1);
SingleColumnValueFilter filter2 = new SingleColumnValueFilter("cf".getBytes(), "type".getBytes(),
CompareOp.EQUAL, "0".getBytes());
list.addFilter(filter2);
Scan scan = new Scan();
scan.setFilter(list);
ResultScanner rss = hTable.getScanner(scan);
for (Result rs : rss) {
System.out.print(new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
System.out.print("  " + new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
System.out.print("  "+ new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "telLength".getBytes()))));
System.out.println("  " + new String(CellUtil.cloneValue(rs.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
}
}
/**
* 删除 cell ??
*/
Random r = new Random();
/**
* 随机生成测试手机号码 prefix: 手机号码前缀 eq:186
*/
public String getPhoneNum(String prefix) {
return prefix + String.format("%08d", r.nextInt(99999999));
}
/**
* 随机生成时间

* @param year年
* @return 时间 格式:yyyyMMddHHmmss
*/
public String getDate(String year) {
return year + String.format("%02d%02d%02d%02d%02d",new Object[] { r.nextInt(12) + 1, r.nextInt(28) + 1, r.nextInt(24), r.nextInt(60), r.nextInt(60) });
}
}

执行ceateTable()方法时使用 hbase shell 命令查看 执行情况
Web界面的查看
插入数据后的情况


大数据HBase_04_01相关推荐

  1. hadoop,spark,scala,flink 大数据分布式系统汇总

    20220314 https://shimo.im/docs/YcPW8YY3T6dT86dV/read 尚硅谷大数据文档资料 iceberg相当于对hive的读写,starrocks相当于对mysq ...

  2. 大数据目标检测推理管道部署

    大数据目标检测推理管道部署 本文提供了一个用于对象检测的深度学习推理的概述. 自主车辆软件开发需要大规模的数据.计算和算法创新,这些都是gpu实现的.一组神经网络构成了感知和决策系统的基础.神经网络的 ...

  3. 客快物流大数据项目(四):大数据项目为什么使用Docker

    目录 大数据项目为什么使用Docker 一.场景一 二.场景二

  4. 2021年大数据ELK(二十八):制作Dashboard

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 制作Dashboard 一.点击第三个组件图标,并创建一个新的Dashboar ...

  5. 2021年大数据ELK(二十七):数据可视化(Visualize)

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 数据可视化(Visualize) 一.数据可视化的类型 二.以饼图展示404与 ...

  6. 2021年大数据ELK(二十六):探索数据(Discovery)

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 探索数据(Discovery) 一.使用探索数据功能 二.导入更多的Apach ...

  7. 2021年大数据ELK(二十五):添加Elasticsearch数据源

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 添加Elasticsearch数据源 一.Kibana索引模式 添加Elast ...

  8. 2021年大数据ELK(二十四):安装Kibana

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 安装Kibana 在Linux下安装Kibana,可以使用Elastic stack ...

  9. 2021年大数据ELK(二十三):Kibana简介

    全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. Kibana简介 通过上面的这张图就可以看到,Kibana可以用来展示丰富的图表. ...

最新文章

  1. K项目轶事之开工第一天
  2. SAP EWM - 其他主数据 - 承运方
  3. 分布式任务调度平台 XXL-JOB
  4. Dubbo的Zookeeper版本
  5. Dividing 多重背包 倍增DP
  6. hive 导出json格式 文件_Magicodes.IE在.NET Core中通过请求头导出多种格式文件
  7. git相关常用基本用法命令及分支操作指南命令
  8. 【Java】导入项目时,出现The project cannot be built until build path errors are resolved错误解决方法
  9. intellij idea 代码错误设置 Error 提示颜色修改
  10. ffmpeg实现mp4文件转h264文件
  11. 学会Java输入输出流,看这一篇就够了,建议收藏!
  12. dev、test和prod是什么意思?
  13. 手机投屏功能说明及开发代码
  14. 【Android显示系统初探】surface初相识
  15. 水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写程序,计算所有N位水仙花数。
  16. QT鼠标点击窗口外的部分使窗口隐藏
  17. 重磅!英伟达400亿英镑收购Arm,国产芯片怎么办?
  18. 移相全桥的分析与计算
  19. 【能力地图】芯片验证篇
  20. 宠物商城|外卖商城|服装商城(微信小程序)

热门文章

  1. 冬季好去处七彩蝴蝶园,温暖如春彩蝶纷飞
  2. mysql多表sumif_MySQL与EXCEL sum sumif sumifs 函数结合_品牌汇总_20161101
  3. FP-Tree频繁模式树算法
  4. LeetCode 881.救生艇
  5. 雅思阅读话题词汇-alluvial
  6. java获取汉字拼音_Java获取汉字对应的拼音(全拼或首字母)
  7. 1.一个整形数组的最大值
  8. OpenCV——硬币检测与计数的设计实现
  9. ucos 入门 --- 资料收集
  10. 项目管理之风险管理:如何系统化应对风险?