`
lookqlp
  • 浏览: 346183 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

hello hbase

阅读更多
前言
近半年本人主要在倒腾数据,遇到海量数据去重的难题,曾经尝试过各种hivesql,然而随着数据量逐渐增大,处理耗时也越来越长,各种方案一一破产。2012年11月份提过使用HBase唯一主键的方案,随即做了相关预研(参看hive&hbase解决方案测评)。该方案由于HBase转化成hive表性能问题而搁浅。但在测评报告最后的总结中提到:或许我们可以选择数据“冷热”、以及部分字段切表来优化。

2013年3月,我们在业务上做了调整,通过部分字段来区分数据的“冷热”,从此希望的烟火重新燃起……

表设计
为区分数据的“冷热”,我们采用分表方式,即冷数据A和热数据B存储于HBase的不同表,另外每天增量数据的冷数据C也有一张表来存储。相对而言,B、C两张表数据量不大,顶多上千万条记录,A才是可能成为海量(TB、PB级别)的数据表。3张表的设计缺点是增量数据导入时业务复杂,需要经过多次判断。

导入
数据导入HBase及hive时遇到了几个问题,一一道来。

数据在数量级别上分两种,一种是初始化大数据量数据,另一种是常态化增量小数据量数据。两种数据导入HBase时需要采取不同的策略。

初始化数据
我们有3亿+的初始化数据,对于海量数据存储大吞吐量写入的HBase来说是小case(根据各种测评得出的结论)。原先采用MapRedue按行读取hdfs文件数据,直接put至HBase表中方式。该方式是很普遍很通用的方式,按理说应该能顺利进行,但在我们真正运行时却超级缓慢。这里我们忽视了几个重要的问题:
1.我们数据有40+个字段,而HBase导入测评字段数少。
2.HBase表没有预先创建分区,数据在插入过程中HBase会不停的执行split操作。
3.HBase的单个regionserver适合存储几个region?
网上有不少HBase数据导入调优的资料,海量数据导入最优的一种方式是将数据转化成HBase认知的HFile形式。该方式可以通过MapReduce输出HFile

job.setOutputFormatClass(HFileOutputFormat.class);
HFileOutputFormat.configureIncrementalLoad(job, new HTable(conf, hbase_table_name));
HFileOutputFormat.setOutputPath(job, new Path(outpath));
然后通过LoadIncrementalHFiles

Configuration HBASE_CONFIG = new Configuration();
conf = HBaseConfiguration.create(HBASE_CONFIG);
SchemaMetrics.configureGlobally(conf);
String[] params = new GenericOptionsParser(conf, args).getRemainingArgs();
if (params.length != 2) {
    System.err.println("Usage: LoadHFileToHBase <hdfs_path> <hbase_table>");
    System.exit(-1);
}
LoadIncrementalHFiles loader = new LoadIncrementalHFiles(conf);
HTable ht=new HTable(conf,params[1]);
ht.setAutoFlush(false);
loader.doBulkLoad(new Path(params[0]), ht);
load至HBase表中。需要注意的点有:HBase表需要预创建region,不然在转化HFile时只有一个reduce(有几个region就有几个reduce,如何预创建分区见下一节),导致转化超慢;如此也会想到,在做HFile转化时,HBase表在做其他导入操作或者说有split操作,会导致后续的load也会超级慢,所以我们在做MapReduce HFile的转化时,HBase表最好不要有任何写入操作。
那这种方式能顺利进行吗?我们预创建表region数1000和100分别做了测试,在load数据时,都会报超时的异样(很抱歉,异常信息未记录),真是痛不欲生,花了很长时间没有解决此问题。
随即,我们又回到原导入方式,预先创建了region测试,速度上有点点提升,效率上本人着实觉得不合理,一个map运行很长时间。分析一下,map按行获取数据,转化成put对象后,执行导入,各种调优参数也调了批量导入也试过了,就是不见速度上有提升。为啥?很可能是在连接HBase时耗时,该MapRecude采用内置连接HBase的方式即:

conf.set(TableOutputFormat.OUTPUT_TABLE, hbase_table_name);
job.setOutputFormatClass(TableOutputFormat.class);
接着,本人不采用内置连接方式

protected void setup(Context context) throws IOException, InterruptedException {
    String table_name = context.getConfiguration().get("table_name").trim();
    if (StringUtils.isNotBlank(table_name)) {
        tablename = table_name;
        ht = new HTable(context.getConfiguration(), tablename);
        ht.setAutoFlush(false);
        ht.setWriteBufferSize(5*1024*1024);
        putlist = new ArrayList<Put>();
    }
}
......
protected void cleanup(Context context) throws IOException, InterruptedException {
    if (putlist.size() != 0){
        ht.put(putlist);
        putlist.clear();
    }
    ht.close();
}
立马map执行速度快了n倍,终于告了一段落。至于为何MapReduce内置连接HBase会慢,需查看源码,待研究。
常态化数据
由于常态化数据小,所以相应表采用普通的创建即可。HBase至HBase表操作采用org.apache.hadoop.hbase.mapreduce.CopyTable方式,HBase表至hive表采用MapReduce方式。
RowKey设计
使用HBase做存储,RowKey设计是最最关键的一部分。HBase查询数据方式有三种:

根据RowKey(高效)
根据RowKey区间(高效)
采用scan(转化成MapReduce低效,不满足实时性)
可见好的RowKey直接影响查询速率(此处未考虑secondary indexes)。

在数据导入过程中,需要预先创建region,也就是需要划分RowKey段。我们设计RowKey是数字型,对已有的初始化数据RowKey化分了1000份,经过测试,HBase会出现死节点情况,一个regionserver多少个region才合适呢?官方给出的答案是:

http://hbase.apache.org/book.html,2.5.2.6.1.how many regions per regions。

根据我们的实际情况,目前hadoop9个节点,4个regionserver。将1000份减少到100份,并根据数据量的大小,每个region设置成6G

public static boolean createTable(String tableName, String family, byte[][] splits) throws IOException {
    HBaseAdmin admin = new HBaseAdmin(conf);
    try {
        if (admin.tableExists(tableName)) {
            System.out.println("table already exists!");
        } else {
            HTableDescriptor tableDesc = new HTableDescriptor(tableName);
            tableDesc.addFamily(new HColumnDescriptor(family));
            tableDesc.setMaxFileSize(new Long("6442450900"));
            admin.createTable(tableDesc, splits);
            return true;
        }
        return false;
    } catch (TableExistsException e) {
        return false;
    }
}
public static byte[][] getHexSplits(String[] regions) {
    int numRegions = regions.length;
    byte[][] splits = new byte[numRegions - 1][];
    for (int i = 0; i < numRegions - 1; i++) {
        BigInteger key = new BigInteger(regions[i], 16);
        byte[] b = String.format("%016x", key).getBytes();
        splits[i] = b;
    }
    return splits;
}
应用总结
适合TB级别数据,将会增长到TB级别数据。
很高的写吞吐量,瞬间写入量大。
可通过rowkey访问数据,hbase rowkey访问数据最高效。
列可扩展。
结构化、半结构化数据。
无交叉表、连接表、多层索引、事务操作的数据模型。
遗留的问题
secondary indexesCCHADOOP-95 - hbase secondary indexes - OPEN ,0.94版本没有此功能,期待后续版本提供类似select * from table where anycell="XXX"的功能,目前国内有公司在应用层实现创建索引表,在应用层实现索引查询功能。
load HFile时超时的异样
表设计中,热数据表和增量冷数据表数据小,也采用了HBase存储。可通过关系型数据做中间存储替换,或者将3张表合并成一张大表替换(前提索引问题解决)。
分享到:
评论
2 楼 lookqlp 2014-08-04  
di1984HIT 写道
谢谢,您写的很好啊,你的rowkey是基于什么创建的。?

根据不同的业务场景,rowkey方式都不一样,所以业务依赖性挺强的
1 楼 di1984HIT 2014-06-18  
谢谢,您写的很好啊,你的rowkey是基于什么创建的。?

相关推荐

    AMWU-大数据一:hello HBase (HBase1.03伪单机版本安装,Windows7 JAVA远程调用

    HBase AMWU-大数据一:hello HBase (HBase1.03伪单机版本安装,Windows7 JAVA远程调用)

    Hello HBase

    ### HBase概述 HBase是一种基于Hadoop框架的分布式、可扩展的大数据存储系统,它提供了类似Bigtable的功能,能够实现在Hadoop和HDFS之上构建高性能、高可靠性的列式存储数据库。作为一种NoSQL数据库,HBase适用于...

    Hadoop原理与技术Hbase的基本操作

    上机实操,熟悉指令操作Hbase和java代码操作Hbase 二、实验环境 Windows 10 VMware Workstation Pro虚拟机 Hadoop环境 Jdk1.8 三、实验内容 1:指令操作Hbase (1):start-all.sh,启动所有进程 (2):start-hbase.sh...

    Hbase 的shell基本操作

    - 向test表中的row1行,cf1列族下的greet列中插入字符串'hello':`put 'test', 'row1', 'cf1:greet', 'hello'`。 每个列族可以包含多个列,列名由列族名和列限定符组成,中间使用冒号分隔。 6. 获取特定行的数据...

    hbase java api 访问 增加修改删除(一)

    append.addColumn(Bytes.toBytes("cf3"), Bytes.toBytes("message"), Bytes.toBytes("Hello, ")); Result appendedResult = table.append(append); ``` 以上就是HBase Java API进行增加、修改和删除操作的基本用法...

    hbase 理论基础教程

    例如,a:cf1:bar:***:7和a:cf1:foo:***:hello都遵循这种格式。 在物理模型方面,HBase的一张表由一个或多个Hregion组成,记录之间按照RowKey的字典序排列。Region按大小分割,每个表一开始只有一个region,随着数据...

    【免费下载】HBase分布式数据库实验

    【HBase 分布式数据库实验】是一份详细指导如何在实验环境中操作和管理HBase的教程,适合于学习大数据技术的人员。实验手册涵盖了HBase的基础知识、数据管理和集群管理等多个方面,旨在通过实践帮助读者深入理解...

    HiveHelloWorld.java

    Hive的HelloWorld程序 链接hbase,搜索字段输出

    Apache-Phoenix使用文档-英文1

    Apache Phoenix 是一个高性能的关系型数据库层,专门为Apache HBase设计,允许用户通过SQL查询和管理HBase中的数据。Phoenix利用JDBC驱动程序将SQL查询转换为HBase的原生操作,提高了查询性能,尤其适用于大数据分析...

    apache h-base 权威指南

    HBASE 权威指南 ... “Hello! This is AWS. Whatever you are running, please turn it off!”). They were looking for an alternative. The Google Bigta‐ ble paper1 had just been published.

    Hello World半成品.pptx

    ### Hello World半成品.pptx 知识点总结 #### 一、华为云数据中心与挖掘设计总体方案概览 **1.1 商业挑战与需求** - **商业挑战:** - 面对日益增长的数据量和业务复杂度,企业需要更高效地管理和利用数据资源,...

    出现Exception in threadmain java.lang.NoClassDefFoundError的各种可能情况.doc

    例如,如果公共类名为`HelloWorld`,那么源文件名也必须是`HelloWorld.java`。如果文件名与类名不符,编译器可能能够成功编译,但运行时会因为找不到正确的类定义而抛出`NoClassDefFoundError`。 ### 解决方法: ...

    高级软件人才培训专家-Hadoop课程资料-1-第一章 - Hello大数据&分布式

    ### 高级软件人才培训专家-Hadoop课程资料-1-第一章 - Hello大数据&分布式 #### 知识点概览 1. **数据的概念与价值** - 数据的基本定义及其在现代社会中的重要性。 - 数据如何影响现实生活的具体案例。 2. **...

    hello-kafka-stream-testing:在HBaseHadoop或其他数据提取管道中测试基于Kafka的应用程序或微服务(例如ReadWrite)的最简单方法

    Kafka测试Hello World示例 此使用开放源代码库进行声明式样式测试。 可以克隆和运行多种口味的。 运行测试之前,请确保启动 。 让我们学习自动测试Kafka应用程序的最简单,最有效的方法。 在以下情况下特别有用: ...

    用maven搭建spring MVC环境,详细易懂

    在类中,我们添加一个 HelloWorld 方法,用于处理请求和响应。 资源目录结构 在 Maven 项目中,我们需要创建一个正确的目录结构。我们需要创建一个 src/main/java 文件夹,用于存放代码,然后创建一个 test 文件夹...

    史上最全的大数据面试题,大数据开发者必看.pdf

    `udf`函数用于自定义处理逻辑,这里注册了一个简单的将字符串前缀"hello"的方法。 3. Hive: - Hive是基于Hadoop的数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供SQL接口进行查询。 - 内部表和...

    Hadoop深度实战

    - **第一个HelloWorld程序** - 编写一个简单的WordCount程序,了解MapReduce的基本流程。 - **一个单表关联的例子** - 实现一个简单的数据处理任务,如两个表的关联操作。 #### 四、在Linux上安装Hive - **目的*...

    BigDataProject:这是我的大数据类项目

    环境安装与Hello-World DEMO 核心环境搭建 ---依赖[0] ---依赖[1] ---依赖[1] ---依赖[3] spark探索 本节均依赖[3]或[4]。 生态环境搭建 MySQL搭建 MySQL 8.0环境搭建 Hive与HBASE HBASE分布式环境搭建 Hive环境搭建...

Global site tag (gtag.js) - Google Analytics