前言
学习过程中的笔记,给踩坑的同学做个参考,笔记已经过去很久了,如有问题请留言。。
一、基础知识
- HBase是一个构建在HDFS上的分布式列存储系统,主要用于海量非结构化数据存储。
- 依靠横向扩展,通过不断增加廉价的商用服务器,来增加计算和存储能力
- HBase是一个分布式的、面向列的开源数据库
- 表由行和列组成,列划分为多个列族/列簇(column family)
- RowKey:是Byte array,是表中每条记录的“主键”,方便快速查找,Rowkey的设计非常重要。
- Column Family:列族,拥有一个名称(string),包含一个或者多个相关列
- Column:属于某一个columnfamily,familyName:columnName,每条记录可动态添加
- HBase 数据访问形式
- get:指定rowkey获取一行数据
- scan:指定StartRow和StopRow获取范围内数据
- 全表扫描:扫描整个HBase表
-
HBase 表结构
二、特征
- BigTable:一个表可以有数十亿行和百万个列
- 面向列:面向列族的存储和权限控制
- 稀疏:空(null)列不占用存储空间,表可以设计的非常稀疏
- 数据单一性:存储的是byte
三、存储原理
- Hbase中一个表被划分了很多个Region,它可以动态扩展,保证整个系统的负载均衡。
- 让一个Region达了上限的时候,就会自动拆分二个相等的Region。(原理就是Hbase中的split和compaction,Region-split 分裂 ,split会使Server有一段时间的停顿)
- 每个Region
- 每个Region由一个RegionServer管理,一个RegionServer可以管理多个Region。
- RgionServer管理100-1000个region比较合适。 Region的大小一般在1-20GB
四、Rowkey 设计原则
- 长度原则
- Rowkey最大长度为64kb,设计的时候越短越好,最好是不要超过16个字节
- 数据的持久化文件HFile是按照key/value的形式存储的,Rowkey过长会影响HFile的存储效率
- Rowkey过长,会占用更多的内存,内存的有效利用率会变低,影响查询效率
- 散列原则
- HBase 按照升序排序,如果同一类型的数据(如时间)在一起,在查询的时候,大量的client会直接访问集群的一个或极少数的节点,如果超出了该节点的最大承受能力会导致性能下降甚至region不可用
- 数据存储的时候不要按照时间戳存储,最好是在高位存储随机数(可以定义个固定的函数,这样方便重新构建完整的Rowkey)
- 唯一原则
- Rowkey设计必须保证唯一性
五、HBase 表设计建议
- 列族名尽可能的小,因为存储时,每列都会带上列族名,过长的列族名会浪费更多的存储空间。可以选择牺牲可读性,比如设置一到两个字符作为列族名
- 列名尽可能的小
- 不要在一个表里定义太多的column family。最好是只定义一个column family
- 预分区+随机散列,让数据均匀分布在集群中,避免热点问题的发生,能够充分发挥分布式系统的性能
六、HBase shell
1. 创建表
> create 'NewsHK', {NAME=>'news'}, {NAME=>'visit'}
> create 'news_rowkey_record', {NAME=>'rowkey_info'}
2.查看所有表
> list
3.查看表描述
> describe 'NewsHK'
4. scan浏览表中数据
> scan 'NewsHK'
5.删除一个列族:需要先将表disable,否则无法进行操作
> disable 'NewsHK'
> is_enabled 'NewsHK' #查看下是否成功
> alter 'NewsHK',{NAME=>'visit',METHOD=>'delete'}
> enable 'NewsHK'
6.插入记录
> put 'NewsHK','rowkey001','news:title','value'
> put 'NewsHK','rowkey001','news:text','value'
7.get 获取数据
根据rowkey获取一行数据
> get 'NewsHK','rowkey001‘
获取某rowkey的一个列族的数据
> get 'NewsHK','rowkey001','news'
获取rowkey的一个列族的某个字段
> get 'NewsHK','rowkey001','news:title'
通过timestamp来获取两个版本的数据
> get 'NewsHK','rowkey001',{COLUMN=>'news:title',TIMESTAMP=>1471282238461}
8. scan的形式获取数据
> scan 'NewsStream',{LIMIT=>1,REVERSED=>true}
> scan 'NewsStream',{LIMIT=>1,STARTROW=>'2017-04-16',ENDROW=>'2017-04-17'}
> scan 'puc_weibo',{LIMIT=>10,STARTROW=>'2017-01-01',COLUMN=>'weiboinfo:sentiment'}
9. 更新数据,直接覆盖即可,如果字段不存在会新增字段,所以注意大小写,否则容易出现脏数据
> put 'NewsHK','rowkey001','news:title' ,'value1'
10. 查询表中有多少行
> count 'NewsHK'
11. 删除整行
> deleteall 'NewsHK','rowkey001'
12. 删除字段
> delete 'NewsHK','rowkey001','news:title'
13.将整张表清空:
> truncate 'NewsHK'
14.删除表
> disable 'NewsHK'
> drop 'NewsHK'