HBase学习笔记

HBase基础命令

(和hive,cassandra不同,不能使用 use namespace 进入命名空间,建不建区别貌似不大)
创建命名空间:
create_namespace 'my_ns'

删除命名空间:
drop_namespace 'my_ns'

更改命名空间:
alter_namespace 'my_ns', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}

创建表:
create 'table name','column family'
例子:
create 'my_ns:my_table', 'fam'
create 'emp', 'personal data', 'professional data'

描述表:
describe 'table name'

列出表:
list
list 'table_name_prefix.*'

更改表:
添加一个新的列族:
alter 'table_name', NAME => 'family_name'

修改单元最大数目:
alter 't1', NAME => 'f1', VERSIONS => 5

删除列族:
alter ‘ table name ’, ‘delete’ => ‘ column family ’

删除表:
删除一个表之前必须先将其禁用。
disable 'emp'
drop 'emp'

插入数据:
put 'table name','row1','colfamily:colname','value'
例子:
put 'emp','1','personal data:name','raju'
put 'emp','1','personal data:city','hyderabad'

更新数据:(实质是直接插入,相同行列直接覆盖)
put 'table name','row','Column family:column name','new value'
例子:
put 'emp','row1','personal:city','Delhi'

扫描数据(扫描所有行):
scan 'table name'

读取数据:
读取一行数据:
get ’table name’,’row1’
例子:
get 'emp', '1'

读取一列数据:
get 'table name', ‘rowid’, {COLUMN => ‘column family:column name ’}
例子:
get 'emp', 'row1', {COLUMN=>'personal:name'}

更多查询数据方式:https://blog.youkuaiyun.com/kehan_c/article/details/95453746

在一个表中删除特定列:
delete 'table name','row','column name','time stamp'
例子:
delete 'emp', '1', 'personal data:city',

删除一行数据(删除表的所有单元格):
deleteall 'table name','row'
例子:
deleteall 'emp','1'

hbase shell执行文本命令

sample_commands.txt 文本内容:
create ‘test’, ‘cf’
list ‘test’
put ‘test’, ‘row1’, ‘cf:a’, ‘value1’
put ‘test’, ‘row2’, ‘cf:b’, ‘value2’
put ‘test’, ‘row3’, ‘cf:c’, ‘value3’
put ‘test’, ‘row4’, ‘cf:d’, ‘value4’
scan ‘test’
get ‘test’, ‘row1’
disable ‘test’
enable ‘test’

可通过以下命令来执行命令脚本:
./hbase shell ./sample_commands.txt

shell的特殊技巧

put 'test', 'row1', 'cf:a', 'value1'
可以写成
test.put 'row1', 'cf:a', 'value1'
同样适用于其他命令,如
t.scan
t.describe
t.disable
t.drop

对于已创建的表,可以使用get_table方法将它分配给一个变量,如
tab = get_table 't'
然后就可以使用tab.scan,tab.put ‘r1’ ,‘f’, ‘v’ 等命令了

建表的注意事项(Table Schema Rules Of Thumb):

1、目标区域(region)大小在10到50 GB之间。
2、目标是细胞(cell)不大于10 MB,或50 MB,如果你使用mob。否则,请考虑将单元格数据存储在HDFS中,并在HBase中存储指向该数据的指针。
3、一个典型的模式每个表有1到3个列族。不应该设计HBase表来模拟RDBMS表。
4、对于包含1或2列族的表,大约50-100个区域(region)是一个不错的数字。请记住,区域是列族的连续段。
5、保持你的列名尽可能的简短。列名存储为每个值(忽略前缀编码)。它们不应该像典型的RDBMS那样是自记录和描述性的。
6、如果您正在存储基于时间的机器数据或日志信息,而行键基于设备ID或服务ID加上时间,那么您可能会得到这样一种模式:旧的数据区域永远不会在特定的年龄之外有额外的写操作。在这种情况下,您将得到少量活动区域和大量没有新写的旧区域。对于这些情况,您可以容忍更多的区域,因为您的资源消耗仅由活动区域驱动。
7、如果只有一个列族忙于写操作,那么只有该列族才能容纳内存。在分配资源时要注意写模式。

自己总结:
1、列族数量要尽可能的少,最好不要超过3个;
2、列族数量尽可能是一个,只有当你需要读取不同的列范围时,才引入第二个(例如,每次只查询一个列族数据,不经常同时查询两个列族的数据);
3、一个表中存在多个列族,注意列族的行数,如果一个列族只有10行,一个100万行,那扫描10行的这个列族的效率会很低;
4、版本version尽可能不要设置的太高。它代表着存储的历史数据的数量,多余的数据才会被清除。

行键设计

1、因为行键是按照字母自动排序的,相关的数据可能会在一个region里,如果大量的读写某个或部分节点的数据,可能会造成节点的堵塞。
a)Salting。就是加随机前缀,这样分布就散开了,这种方式有利于写数据,但在读数据时,要计算去掉随机前缀,不利于读数据。
b)Hashing。和上面差不多,区别是这个前缀有规律,读数据的时候好计算,可以考虑使用。
c)Reversing the Key。直接反转行键,把最容易变化的部分放到开头,这可以有效的随机分布行键,且不怎么影响读数据,但是牺牲了行键自带的排序功能。真遇到阻塞了,这个还是很推荐使用的。

2、单调递增的行键设置是不好的,某些情况下影响写速度。因此不要使用时间戳或者1、2、3作为行键,如果非要使用时间戳,在时间戳前面加上其他的例如类型等不会一直变的字段,如key1-timestamp。

3、行键和列族名尽可能的短一点,不然会降低效率。(原理是行键和列族名作为必须存储的数据,在每行数据都存在,为了随机访问其保存在HFile中的索引值会很大,会占用大块的内存。压缩的话也会占据很大的索引)
列族名尽可能的短小,但是行键要注意,在短小的同时不能影响正常的get和scan查询。

4、反转时间戳。[key][reverse_timestamp]这种形式挺不错的,先按key排序,再按时间戳倒序。
reverse_timestamp = Long.MAX_VALUE – timestamp

5、行键是不可变的。除非删除后再插入新数据。所以导数据的时候搞清楚行键对不对。

6、如果某些列的访问频率比其他列高,则创建多个列族来将经常访问的列与很少访问的列分开。这提高了性能,因为HBase只读取查询中指定的列族。
7、对于结构化对象,不要使用JSON,它不是很紧凑。使用protobuf、Avro、msgpack或BSON等格式。
8、考虑在存储前使用快速LZ变体压缩数据,以减少延迟和I/O成本。
9、

行键设计实例:

与mysql、hive、cassandra不同,hbase的行键很重要,作为检索工具,它的设置与其它的数据库显著不同,它不能很好地支持join操作,因此对行键设计的要求极高。
行键的具体设计要根据实际的数据情况来设计。

日志数据和序列化数据:
a)时间引导
[bucket][timestamp][hostname][log-event]
其中,long bucket = timestamp % numBuckets;

b)主机引导
[hostname][log-event][timestamp]

c)可变长度行键和定长行键
hbase的行键如果设计成定长的会更好,如果想把变长的行键转换为定长的行键,可以使用MD5加密或者数字替换的方法。

[MD5 hash of hostname] = 16 bytes
[MD5 hash of event-type] = 16 bytes
[timestamp] = 8 bytes

数字替换是使用hbase的counter功能。

客户订单模型(Customer/Order):
订单(order)的行键可以设置为:
[customer number][order number]
在hbase中最好使用定长的行键,因此可以使用md5或者数字替换转换一下:

[MD5 of customer number] = 16 bytes
[MD5 of order number] = 16 bytes
或者
[substituted long for customer number] = 8 bytes
[MD5 of order number] = 16 bytes

关系型数据库一般会建立几张表来保存订单数据,例如order、ShippingLocation、LineItem 等,但hbase没有join能力,来回查找信息很麻烦,所以有时候会把所有的信息整合到一张表里,例如这个例子里,可以把行键设置为
[order-rowkey] [LINE record type] [line item number]
其中订单详情列(LineItem )应该包含很多东西,可以作为列族中的一列,也可以直接保存成一个不规范的数据,例如json形式的数据,但这样解析起来很麻烦,hbase不好直接读取内部信息。

高表和宽表:
高表就是行多,列少,宽表相反,每行数据都存储了很多数据,这两种消耗的存储空间基本没有差别,个人感觉宽表挺好,前提是不要扫描返回行的所有cell,每次只读取一部分数据。

Time To Live (TTL)

ColumnFamilies 可以设置 秒 级别的ttl,时间一到立刻清除数据,刚添加的也删除。
cell 可以设置 毫秒 级别的ttl,但是数据留存时间不会超过所属列族的ttl。

Bulk Loading(最有效的导数据方式)

最直接的导数据方式有 通过client调用API 或者 执行mapreduce作业使用TableOutputFormat 类,但最有效的还是直接将数据写成HFile文件,然后直接提交集群读取。这种方式就是 Bulk Load。

使用Bulk Load的两个步骤:
1、数据准备。通过mapreduce作业准备数据,HFileOutputFormat2自带了一个很有效的功能configureIncrementalLoad(),它可以根据当前表的region分区界限自动设置TotalOrderPartitioner。HFileOutputFormat2这种输出格式以HBase的内部存储格式写出数据(Hfile),可以非常有效地将数据加载到集群中。

2、数据加载。可以使用importtsv的importtsv.bulk.output选项,它可以将数据导入到正在运行的集群中。这个命令行工具遍历准备好的数据文件,每个文件都确定文件所属的区域region。然后,它与采用HFile的适当的RegionServer联系,将其移动到存储目录中,并使数据对客户机可用。如果在数据准备的时候(过程中)region边界发生了变化,该工具会自动调整数据的分片,保证数据的正确加载,但是该功能效率不高,所以在加载数据时,要注意降低数据准备(第一个步骤)的延迟,或者尽量避免多作业同时写数据。

或者通过mapreduce作业使用HFileOutputFormat达到相同的目标。

进阶
如果还不满足importtsv的效率,可以深入研究ImportTsv.java并检查javadoc来获取HFileOutputFormat(HFile的输出格式)。
导入步骤也可以以编程的形式实现,可以研究一下LoadIncrementalHFiles 类。

Hbase工具

Canary 测试工具:
canary-test -help 来查看帮助
如果不输入参数,默认以 region模式 来获取集群每个region的一行

ImportTsv 导入工具:
通过put导入

$ bin/hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns=a,b,c <tablename> <hdfs-inputdir>

为批量加载(bulk-loading)生成存储文件(storeFile)

$ bin/hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.columns=a,b,c -Dimporttsv.bulk.output=hdfs://storefile-outputdir <tablename> <hdfs-data-inputdir>

这些文件可以通过completebulkload加载到Hbase中。

警告:如果准备了大量的数据想通过bulk loading导入到Hbase中,需要确定目标Hbase已经进行了预分区。

CompleteBulkLoad 加载工具:
一般和ImportTsv 一起使用,用于将storeFile加载到表中。

RowCounter 计数工具:
RowCounter是一个用来计算表的行数的mapreduce程序
RowCounter每个单元格只计算一个版本version。

CellCounter 计数工具:
它统计了表的更细粒度的统计信息。如:
表中总行数。
所有行上的列族(cf)总数。
所有行的限定符(cf:qualifier)总数。
每个CF的总发生率。
每个限定符的总出现次数。
每个限定符的版本总数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值