免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4772 | 回复: 0
打印 上一主题 下一主题

[HBase] HBase表设计及数据导入的一些思考 [复制链接]

论坛徽章:
6
CU大牛徽章
日期:2013-03-14 14:14:08CU大牛徽章
日期:2013-03-14 14:14:26CU大牛徽章
日期:2013-03-14 14:14:29处女座
日期:2014-04-21 11:51:59辰龙
日期:2014-05-12 09:15:10NBA常规赛纪念章
日期:2015-05-04 22:32:03
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-08-20 13:52 |只看该作者 |倒序浏览
最近公司业务要用到HBase,做了一些总结 求拍砖

1:查询需求
查询关键字:groupid,guid,onlycode,date。
(1)      guid分为guid1和guid2,二者同时存在于日志数据中,且需求要求只要有一个值满足条件,该行记录就应该被提取出来。等价于RDBMS中的OR原则。
(2)      guid与onlycode是互斥查询,只能取其一,其余查询条件是必选项。
2:设计原则
由于数据量大(每天10亿+),查询需求固定,故采用nosql数据库HBase。要求key直接命中。
由于存在OR的特殊需求和互斥查询,故采用了数据冗余机制和标志区分。具体行关键字如下所示:
1_groupid_guid_date:针对guid的查询,由于存在OR的关系,故原始数据中一行对应到HBase表中的两行,冗余了一份记录。
2_groupid_onlycode_date:针对onlycode的查询,冗余了一份记录。
以上设计可以满足需求,但存在以下问题
(1)      数据冗余了多份,从原始数据导入HBase的数据成倍增加,导入时间增长。
(2)      不易扩展,如果增加新的查询条件,数据就得重新冗余一份或者建立二级索引,表结构不整齐。
3:改进后的策略
原则:原始数据只存储一份,采用二级索引并且让数据和索引容易区分又不用分表
具体行关键字如下所示:
数据key为:D-文件split+incr,value为data
索引key为:I-1_groupid_guid_date或者2_groupid_onlycode_date,value为数据key中的key。
各个key都做了hash,下面导入数据部分详述。
数据key是唯一的,对应唯一的一行数据。
索引key则对应value版本。
这样设计之后,数据以D开头,索引以I开头,分别占据同一张表的上半区和下半区,不会混杂在一起,且以后新增查询关键字,对于历史数据只需重新遍历建立索引(这一步是不可避免的),新增数据直接录入即可,仍然保证数据只有一份。
4:数据导入优化
通常采用bulkload方式导入数据,其时间主要浪费在HFile的生成上,后边的mv过程并不占用时间。
生成HFile的采用的优化主要有以下几点:
(1)      压缩:
HFileOutputFormat需要设置压缩,map的output需要设置压缩。一方面减少了IO,另一方便也减少了网络传输(带宽对我们很珍贵)。
(2)      重写Reduce
默认的Reduce过程有个Treeset进行排序。这是个内存排序过程必须从实现过程中剔除。因为在我们的业务里,rowkey相同的记录有很多,没法直接实现内存排序(Reduce端的JVM默认内存200M)。其次从业务角度考虑,这个过程也可以省去。原因如下:Treeset是按照kv排序的(行关键字、列族、列名),由于我们只设计了一个列族(没必要多个),一个列(没必要多个,这个列包含了记录的详细信息,业务语义不详述了)。因此map执行完之后就是有序的,进入reduce端的行关键字都一样,对应的列族、列名都一样,只需要控制住时间戳,reduce端无需再排序,就可以实现输出结果的有序性。我们并不关心同一个rowkey下不同版本value的顺序。因此直接将结果写出即可。
(3)      预分区+hash
建表需要预分区,增加Reduce的数目。如果不采用预分区,则空表只有一个分区,默认只启动一个reduce。如何分区合理,需根据具体业务。通常都需要做hash操作,可以让数据更加均衡,某些情况下还能节省存储空间。Hash的合理性要和压缩相结合,使得分区均衡且容易压缩。我们的业务中,并没有对整个Key字段都做hash,而是排除了date字段,考虑到业务场景是离线数据批量导入,date是相同的。
(4)      具体参数设置参考网上的博客
关闭split,手动compact和balance等
(5)      多版本合并
结合上边的Reduce改进,我们将同一个rowkey的多个版本(需要多次测试寻找一个合理的值)合并到一起,这同时省去了多个key的存储空间。
(6)      版本影响
注意HBase的版本问题,在0.94.0版本基础上,最后的load过程并不是mv操作,而是copy,这样比较耗费时间,且占用网络带宽较多。0.94.6已经没有了这个问题,直接执行mv,相对于生成HFile的时间,这个时间忽略不计。源代码如下所示:
0.94.0:if(!srcFs.equals(fs))
0.94.6: if(!srcFs.getUri().equals(desFs.getUri()))
显而易见,equal的差别。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP