分享

请问如果hbase表有某个列族有40个字段,怎么能提高写的速度

ohano_javaee 发表于 2015-2-12 17:07:28 [显示全部楼层] 回帖奖励 阅读模式 关闭右栏 8 82741
请教大神一个问题:
我们的hbase表有一个列族里有40个字段,发现每次写入时,是一个字段一个字段的写,性能很低下,经常阻塞。
请问有没有好的解决方案能让40个字段批量一次就能写入hbase呢?
谢谢

已有(8)人评论

跳转到指定楼层
stark_summer 发表于 2015-2-12 18:58:39

回帖奖励 +20 云币

“一个字段一个字段的写”?能给下核心代码看下么?
回复

使用道具 举报

s060403072 发表于 2015-2-12 19:06:23
回复

使用道具 举报

s060403072 发表于 2015-2-12 19:08:41
stark_summer 发表于 2015-2-12 18:58
“一个字段一个字段的写”?能给下核心代码看下么?

一个跟多个是一样的,参考这个hbase编程:Eclipse远程连接创建hbase表以及填充列与列数据




回复

使用道具 举报

ohano_javaee 发表于 2015-2-13 09:43:40
谢谢各位的回复,我先看一下
回复

使用道具 举报

ohano_javaee 发表于 2015-2-13 09:54:43
我现在不是要导入数据,是新增数据,所以bulkload好像满足不了吧
回复

使用道具 举报

desehawk 发表于 2015-2-13 11:48:31
ohano_javaee 发表于 2015-2-13 09:54
我现在不是要导入数据,是新增数据,所以bulkload好像满足不了吧


bulkload确实不太合适,可以采取下面方法:
 1. 避免region split
  不得不说,region split是提升写性能的一大障碍。减少region split次数可以从两方面入手。首先是预分配region。
  预分配region
  不在此重复region split的原理,请参见http://blog.sina.com.cn/s/blog_9cee0fd901018vu2.html。按数据量,row key的规则预先设计并分配好region,可以大幅降低region split的次数, 甚至不split。这点非常重要。
  适当提升hbase.hregion.max.filesize
  提升region的file容量也可以减少split的次数。具体的值需要按照你的数据量,region数量,row key分布等情况具体考量。一般来说,3~4G是不错的选择。


  2. 均匀分布每个Region Server的写压力
  之前也提到了RPC Handler的概念。好的Data Loader需要保证每个RPC Handlder都有活干,每个handler忙,但不至超载。注意region的压力不能过大,否则会导致反复重试,并伴有超时异常(可以提高超时的时间设置)。
  如何保证每个Region Server的压力均衡呢?这和region 数量,startKey设计, client数据插入顺序有关。
  一般来说,简单的数据插入程序应该是多线程实现。让每个线程负责一部分的row key范围,而row key范围又和region相关,所以可以在数据插入时,程序控制每个region的压力,不至于有些region闲着没事干。
  那么,如何设计row key呢?举个比较实际的例子,如果有张HBase表来记录每天某城市的通话记录, 常规思路下的row key是由电话号码 + yyyyMMddHHmmSS + ... 组成。按电话号码的规律来划分region。但是这样很容易导致数据插入不均匀(因为电话通话呈随机性)。但是,如果把电话号码倒序,数据在region层面的分布情况就大有改观。


  3. 分布式的数据插入程序
  HBase客户端在单节点上运行,即使使用多线程,也受限于单节点的硬件资源,写入速度不可能很快。典型的思路是将客户端部署在多个节点上运行,提高写的并发度。MapReduce是个很好的选择。使用MapReduce把写入程序分布到集群的各个节点上,并在每个mapper中运行多线程的插入程序。这样可以很好的提高写并发度。
  注意,不要使用reducer。mapper到reducer需要走网络,受限于集群带宽。其次,实际的应用场景一般是用户从关系型数据库中导出了文本类型的数据,然后希望能把导出的数据写到HBase里。在这种情况下,需要小心谨慎地设计和实现file split逻辑。


  4. HBase Client太慢?BulkLoad!
  请拿出HBase的API读读,HFileOutputFomart里有个叫configureIncrementalLoad的方法。API是这么介绍的:


  1. Configure a MapReduce Job to perform an incremental load into the given table. This
  2.   Inspects the table to configure a total order partitioner
  3.   Uploads the partitions file to the cluster and adds it to the DistributedCache
  4.   Sets the number of reduce tasks to match the current number of regions
  5.   Sets the output key/value class to match HFileOutputFormat's requirements
  6.   Sets the reducer up to perform the appropriate sorting (either KeyValueSortReducer or PutSortReducer)
  7.   The user should be sure to set the map output value class to either KeyValue or Put before running this function.
复制代码



  这是HBase提供的一种基于MapReduce的数据导入方案,完美地绕过了HBase Client(上一节的分布式插入方法也是用mapreduce实现的,不过本质上还是用hbase client来写数据)

  网上有不少文章叙述了使用命令行方式运行BulkLoad,比如
  但是,不得不说,实际生产环境上很难使用这种方式。毕竟源数据不可能直接用来写HBase。在数据迁移的过程中会涉及到数据清洗、整理归并等许多额外的工作。这显然不是命令行可以做到的事情。按照API的描述, 可行的方案是自定义一个Mapper在mapper中清洗数据,Mapper的输出value为HBase的Put类型,Reducer选用PutSortReducer。然后使用HFileOutputFormat#configureIncrementalLoad(Job, HTable);解决剩余工作。
  不过,这种实现也存在局限性。毕竟Mapper到Reducer比较吃网络。

 参考:hbase写入太慢,BulkLoad不太实用,该如何调优

回复

使用道具 举报

stark_summer 发表于 2015-2-13 18:47:40
回复

使用道具 举报

永无止进 发表于 2015-3-21 22:57:42
学习了,hbase
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条