- 浏览: 595890 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (669)
- oracle (36)
- java (98)
- spring (48)
- UML (2)
- hibernate (10)
- tomcat (7)
- 高性能 (11)
- mysql (25)
- sql (19)
- web (42)
- 数据库设计 (4)
- Nio (6)
- Netty (8)
- Excel (3)
- File (4)
- AOP (1)
- Jetty (1)
- Log4J (4)
- 链表 (1)
- Spring Junit4 (3)
- Autowired Resource (0)
- Jackson (1)
- Javascript (58)
- Spring Cache (2)
- Spring - CXF (2)
- Spring Inject (2)
- 汉字拼音 (3)
- 代理模式 (3)
- Spring事务 (4)
- ActiveMQ (6)
- XML (3)
- Cglib (2)
- Activiti (15)
- 附件问题 (1)
- javaMail (1)
- Thread (19)
- 算法 (6)
- 正则表达式 (3)
- 国际化 (2)
- Json (3)
- EJB (3)
- Struts2 (1)
- Maven (7)
- Mybatis (7)
- Redis (8)
- DWR (1)
- Lucene (2)
- Linux (73)
- 杂谈 (2)
- CSS (13)
- Linux服务篇 (3)
- Kettle (9)
- android (81)
- protocol (2)
- EasyUI (6)
- nginx (2)
- zookeeper (6)
- Hadoop (41)
- cache (7)
- shiro (3)
- HBase (12)
- Hive (8)
- Spark (15)
- Scala (16)
- YARN (3)
- Kafka (5)
- Sqoop (2)
- Pig (3)
- Vue (6)
- sprint boot (19)
- dubbo (2)
- mongodb (2)
最新评论
Hbase里的数据量一般都小不了,因此MapReduce跟Hbase就成了天然的好搭档。
1.ZK授权表
首先一点来说,Hbase是强依赖于ZK的。博主所在的team,就经常出现ZK连接数太多被打爆然后Hbase挂了的情况。一般在访问Hbase表之前,需要通过访问ZK得到授权:
2.thrift对象转化
本例中操作的对象为XX表,Column Family为”P”, Qualifer 为”P”与”C”,里面对应的value都是thrift对象。其中”P”对应的thrift对象为:
“C”对应的thrift对象为:
这个时候我们就需要经常将Bytes转化为thrift对象,通用的方法为:
3.Map阶段读取Hbase里的数据
在Map阶段对Hbase表扫描,得出数据
4.run方法里配置相关驱动
run方法里需要配置一些相关的参数,保证任务的顺利进行。
其中, TableMapReduceUtil.addDependencyJars 方法添加了完成任务一些必要的类。
5.完整的代码
TableMapReduceUtil.initTableMapperJob把HBase表中的数据注入到Mapper中
然后将代码打包,提交到集群上运行对应的shell脚本即可。
转自:http://www.tuicool.com/articles/u6z6Nvb
1.ZK授权表
首先一点来说,Hbase是强依赖于ZK的。博主所在的team,就经常出现ZK连接数太多被打爆然后Hbase挂了的情况。一般在访问Hbase表之前,需要通过访问ZK得到授权:
/** * 为hbase表授权。 * * @param tableConfigKey 任意一个字符串。 * @param tableName 需要授权的表名, scan涉及到的表不需要额外授权。 * @param job 相关job。 * @throws IOException */ public static void initAuthentication(String tableConfigKey, String tableName, Job job) throws IOException { Configuration peerConf = job.getConfiguration(); peerConf.set(tableConfigKey, tableName); ZKUtil.applyClusterKeyToConf(peerConf, tableName); if (User.isHBaseSecurityEnabled(peerConf)) { LOGGER.info("Obtaining remote user authentication token with table:{}", tableName); try { User.getCurrent().obtainAuthTokenForJob(peerConf, job); } catch (InterruptedException ex) { LOGGER.info("Interrupted obtaining remote user authentication token"); LOGGER.error("Obtained remote user authentication token with table:{}, error:\n", tableName, ex); Thread.interrupted(); } LOGGER.info("Obtained remote user authentication token with table:{}", tableName); } }
2.thrift对象转化
本例中操作的对象为XX表,Column Family为”P”, Qualifer 为”P”与”C”,里面对应的value都是thrift对象。其中”P”对应的thrift对象为:
struct UserProfile { 1: optional byte sex; 2: optional i32 age; 3: optional string phoneBrand; 4: optional string locationProvince; }
“C”对应的thrift对象为:
struct UserClickInfo { 1: required i32 totolAck; 2: required i32 totalClick; 3: optional map<i64, map<string, i32>> ackClick; }
这个时候我们就需要经常将Bytes转化为thrift对象,通用的方法为:
/** * convert byte array to thrift object. * * @param <T> type of thrift object. * @param thriftObj an thrift object. * @return byte array if convert succeeded, <code>null</code> if convert failed. * @throws TException */ public static final <T extends TBase<T, ?>> T convertBytesToThriftObject(byte[] raw, T thriftObj) throws TException { if (ArrayUtils.isEmpty(raw)) { return null; } Validate.notNull(thriftObj, "thriftObj"); TDeserializer serializer = new TDeserializer(new TBinaryProtocol.Factory()); serializer.deserialize(thriftObj, raw); return thriftObj; }
3.Map阶段读取Hbase里的数据
在Map阶段对Hbase表扫描,得出数据
//输出的KV均为Text static class ReadMapper extends TableMapper<Text,Text> { @Override protected void map(ImmutableBytesWritable key, Result res, Context context) throws IOException,InterruptedException{ String uuid = StringUtils.reverse(Bytes.toString(key.copyBytes())); if (res == null || res.isEmpty()) return; res.getFamilyMap(USER_FEATURE_COLUMN_FAMILY); for(KeyValue kv:res.list()) { String qualifier = Bytes.toString(kv.getQualifier()); //String qualifier = kv.getKeyString(); if(qualifier.equals("P")) { try { UserProfile userProfile = new UserProfile(); convertBytesToThriftObject(kv.getValue(), userProfile); String profileRes = userProfile.getAge() + "," + userProfile.getSex() + "," + userProfile.getPhoneBrand() + "," + userProfile.getLocationProvince(); context.write(new Text(uuid),new Text(profileRes)); } catch (Exception ex) {} } else if(qualifier.equals("C")) { UserClickInfo userClickInfo = new UserClickInfo(); try { convertBytesToThriftObject(kv.getValue(), userClickInfo); Map<Long,Map<String,Integer>> resMap = userClickInfo.getAckClick(); for(Map.Entry<Long,Map<String,Integer>> entry:resMap.entrySet()) { String appid = String.valueOf(entry.getKey()); int click = entry.getValue().get("click"); int ack = entry.getValue().get("ack"); String all = appid + "," + String.valueOf(click) + "," + String.valueOf(ack); context.write(new Text(uuid),new Text(all)); } int allClick = userClickInfo.getTotalClick(); int allAck = userClickInfo.getTotolAck(); String allNum = "999," + String.valueOf(allClick) + "," + String.valueOf(allAck); context.write(new Text(uuid),new Text(allNum)); } catch (Exception ex) {} } } } }
4.run方法里配置相关驱动
run方法里需要配置一些相关的参数,保证任务的顺利进行。
其中, TableMapReduceUtil.addDependencyJars 方法添加了完成任务一些必要的类。
public int run(String[] args) throws Exception{ Configuration conf = HBaseConfiguration.create(); Job job = Job.getInstance(conf,"read_data_from_hbase"); job.setJarByClass(ReadDataFromHbase.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); job.setReducerClass(ReadReducer.class); job.setSpeculativeExecution(false); TableMapReduceUtil.addDependencyJars(job.getConfiguration(),StringUtils.class, TimeUtils.class, Util.class, CompressionCodec.class, TStructDescriptor.class, ObjectMapper.class, CompressionCodecName.class, BytesInput.class); Scan scan = new Scan(); //对整个CF扫描 scan.addFamily(USER_FEATURE_COLUMN_FAMILY); String table = "XXX"; initAuthentication(table,table,job); TableMapReduceUtil.initTableMapperJob(table, scan, ReadMapper.class, Text.class, Text.class, job); String output = ""; FileSystem.get(job.getConfiguration()).delete(new Path(output), true); FileOutputFormat.setOutputPath(job,new Path(output)); return job.waitForCompletion(true) ? 0 : 1; }
5.完整的代码
TableMapReduceUtil.initTableMapperJob把HBase表中的数据注入到Mapper中
package com.xiaomi.xmpush.mr_job_and_tools.task; import com.twitter.elephantbird.thrift.TStructDescriptor; import XXX.XXX.XXX.XXX.common.util.TimeUtils; import XXX.XXX.XXX.thrift.UserClickInfo; import XXX.XXX.XXX.thrift.UserProfile; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.Validate; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; import org.apache.hadoop.hbase.mapreduce.TableMapper; import org.apache.hadoop.hbase.security.User; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.zookeeper.ZKUtil; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Reducer; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; import org.apache.parquet.bytes.BytesInput; import org.apache.parquet.format.CompressionCodec; import org.apache.parquet.format.Util; import org.apache.parquet.hadoop.metadata.CompressionCodecName; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import shaded.parquet.org.codehaus.jackson.map.ObjectMapper; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by WangLei on 17-3-13. */ public class ReadDataFromHbase extends Configured implements Tool{ private static final Logger LOGGER = LoggerFactory.getLogger(ReadDataFromHbase.class); public static final byte[] USER_FEATURE_COLUMN_FAMILY = Bytes.toBytes("P"); /** * convert byte array to thrift object. * * @param <T> type of thrift object. * @param thriftObj an thrift object. * @return byte array if convert succeeded, <code>null</code> if convert failed. * @throws TException */ public static final <T extends TBase<T, ?>> T convertBytesToThriftObject(byte[] raw, T thriftObj) throws TException { if (ArrayUtils.isEmpty(raw)) { return null; } Validate.notNull(thriftObj, "thriftObj"); TDeserializer serializer = new TDeserializer(new TBinaryProtocol.Factory()); serializer.deserialize(thriftObj, raw); return thriftObj; } /** * 为hbase表授权。 * * @param tableConfigKey 任意一个字符串。 * @param tableName 需要授权的表名, scan涉及到的表不需要额外授权。 * @param job 相关job。 * @throws IOException */ public static void initAuthentication(String tableConfigKey, String tableName, Job job) throws IOException { Configuration peerConf = job.getConfiguration(); peerConf.set(tableConfigKey, tableName); ZKUtil.applyClusterKeyToConf(peerConf, tableName); if (User.isHBaseSecurityEnabled(peerConf)) { LOGGER.info("Obtaining remote user authentication token with table:{}", tableName); try { User.getCurrent().obtainAuthTokenForJob(peerConf, job); } catch (InterruptedException ex) { LOGGER.info("Interrupted obtaining remote user authentication token"); LOGGER.error("Obtained remote user authentication token with table:{}, error:\n", tableName, ex); Thread.interrupted(); } LOGGER.info("Obtained remote user authentication token with table:{}", tableName); } } static class ReadMapper extends TableMapper<Text,Text> { @Override protected void map(ImmutableBytesWritable key, Result res, Context context) throws IOException,InterruptedException{ String uuid = StringUtils.reverse(Bytes.toString(key.copyBytes())); if (res == null || res.isEmpty()) return; res.getFamilyMap(USER_FEATURE_COLUMN_FAMILY); for(KeyValue kv:res.list()) { String qualifier = Bytes.toString(kv.getQualifier()); //String qualifier = kv.getKeyString(); if(qualifier.equals("P")) { try { UserProfile userProfile = new UserProfile(); convertBytesToThriftObject(kv.getValue(), userProfile); String profileRes = userProfile.getAge() + "," + userProfile.getSex() + "," + userProfile.getPhoneBrand() + "," + userProfile.getLocationProvince(); context.write(new Text(uuid),new Text(profileRes)); } catch (Exception ex) {} } else if(qualifier.equals("C")) { UserClickInfo userClickInfo = new UserClickInfo(); try { convertBytesToThriftObject(kv.getValue(), userClickInfo); Map<Long,Map<String,Integer>> resMap = userClickInfo.getAckClick(); for(Map.Entry<Long,Map<String,Integer>> entry:resMap.entrySet()) { String appid = String.valueOf(entry.getKey()); int click = entry.getValue().get("click"); int ack = entry.getValue().get("ack"); String all = appid + "," + String.valueOf(click) + "," + String.valueOf(ack); context.write(new Text(uuid),new Text(all)); } int allClick = userClickInfo.getTotalClick(); int allAck = userClickInfo.getTotolAck(); String allNum = "999," + String.valueOf(allClick) + "," + String.valueOf(allAck); context.write(new Text(uuid),new Text(allNum)); } catch (Exception ex) {} } } } } static class ReadReducer extends Reducer<Text,Text,Text,Text> { @Override protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException,InterruptedException{ List<String> resultList = new ArrayList<String>(); for(Text each:values) { resultList.add(each.toString()); } String res = StringUtils.join(resultList,":"); context.write(key,new Text(res)); } } @Override public int run(String[] args) throws Exception{ Configuration conf = HBaseConfiguration.create(); Job job = Job.getInstance(conf,"read_data_from_hbase"); job.setJarByClass(ReadDataFromHbase.class); job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); job.setReducerClass(ReadReducer.class); job.setSpeculativeExecution(false); TableMapReduceUtil.addDependencyJars(job.getConfiguration(),StringUtils.class, TimeUtils.class, Util.class, CompressionCodec.class, TStructDescriptor.class, ObjectMapper.class, CompressionCodecName.class, BytesInput.class); Scan scan = new Scan(); //对整个CF扫描 scan.addFamily(USER_FEATURE_COLUMN_FAMILY); String table = "XXX"; initAuthentication(table,table,job); TableMapReduceUtil.initTableMapperJob(table, scan, ReadMapper.class, Text.class, Text.class, job); String output = ""; FileSystem.get(job.getConfiguration()).delete(new Path(output), true); FileOutputFormat.setOutputPath(job,new Path(output)); return job.waitForCompletion(true) ? 0 : 1; } public static void main(String[] args) throws Exception{ System.exit(ToolRunner.run(new ReadDataFromHbase(),args)); } }
然后将代码打包,提交到集群上运行对应的shell脚本即可。
转自:http://www.tuicool.com/articles/u6z6Nvb
发表评论
文章已被作者锁定,不允许评论。
-
Hadoop namenode的fsimage与editlog详解
2017-05-19 10:04 1176Namenode主要维护两个文件,一个是fsimage,一个是 ... -
Hadoop HBase建表时预分区(region)的方法学习
2017-05-15 11:18 1188如果知道Hbase数据表的key的分布情况,就可以在建表的时候 ... -
Hadoop HBase行健(rowkey)设计原则学习
2017-05-15 10:34 1123Hbase是三维有序存储的,通过rowkey(行键),colu ... -
Hadoop HBase中split原理学习
2017-05-12 13:38 2269在Hbase中split是一个很重 ... -
Hadoop HBase中Compaction原理学习
2017-05-12 10:34 993HBase Compaction策略 RegionServer ... -
Hadoop HBase性能优化学习
2017-05-12 09:15 684一、调整参数 入门级的调优可以从调整参数开始。投入小,回报快 ... -
Hadoop 分布式文件系统学习
2017-05-10 15:34 498一. 分布式文件系统 分布式文件系统,在整个分布式系统体系中处 ... -
Hadoop MapReduce处理wordcount代码分析
2017-04-28 14:25 590package org.apache.hadoop.exa ... -
Hadoop YARN完全分布式配置学习
2017-04-26 10:27 571版本及配置简介 Java: J ... -
Hadoop YARN各个组件和流程的学习
2017-04-24 19:04 646一、基本组成结构 * 集 ... -
Hadoop YARN(Yet Another Resource Negotiator)详细解析
2017-04-24 18:30 1152带有 MapReduce 的 Apache Had ... -
Hive 注意事项与扩展特性
2017-04-06 19:31 7441. 使用HIVE注意点 字符集 Hadoop和Hive都 ... -
Hive 元数据和QL基本操作学习整理
2017-04-06 14:36 1016Hive元数据库 Hive将元数据存储在RDBMS 中,一般常 ... -
Hive 文件压缩存储格式(STORED AS)
2017-04-06 09:35 2298Hive文件存储格式包括以下几类: 1.TEXTFILE ... -
Hive SQL自带函数总结
2017-04-05 19:25 1138字符串长度函数:length ... -
Hive 连接查询操作(不支持IN查询)
2017-04-05 19:16 716CREATE EXTERNAL TABLE IF NOT ... -
Hive优化学习(join ,group by,in)
2017-04-05 18:48 1813一、join优化 Join ... -
Hive 基础知识学习(语法)
2017-04-05 15:51 895一.Hive 简介 Hive是基于 Hadoop 分布式文件 ... -
Hive 架构与基本语法(OLAP)
2017-04-05 15:16 1241Hive 是什么 Hive是建立在Hadoop上的数据仓库基础 ... -
Hadoop MapReduce将HDFS文本数据导入HBase
2017-03-24 11:13 1219HBase本身提供了很多种数据导入的方式,通常有两种常用方式: ...
相关推荐
■ Hadoop系统的安装和操作管理 ■ 大数据分布式文件系统HDFS ■ Hadoop MapReduce并行编程模型、框架与编程接口 ■ 分布式数据表HBase ■ 分布式数据仓库Hive ■ Intel Hadoop系统优化与功能增强 ■ MapReduce 基础...
《HBase权威指南》是一本深入探讨分布式列式数据库HBase的专业书籍,其代码范例存放在名为“hbase-book-master.zip”的压缩包中。这个压缩包是专门为那些无法直接访问互联网的学习者准备的,旨在提供一个离线环境下...
- **气象数据集分析**:使用一个具体的气象数据集作为例子,展示了如何使用Hadoop进行数据分析,包括使用Unix工具进行初步处理,然后利用Hadoop MapReduce完成进一步的数据分析。 - **分布化**:介绍MapReduce如何...
Hadoop分布式系统通过集群的方式运行,能够处理大量数据,并允许用户通过Hadoop的MapReduce编程范例创建并执行应用程序。Hadoop系统包含以下几个核心组件: 1. Hadoop分布式文件系统(HDFS):HDFS是一个高度容错性...
【描述】:本文档提供了2019年关于Hadoop的开题报告的范例,适合指导进行Hadoop相关研究的学生进行开题报告的撰写。 【标签】:“互联网” 【内容摘要】: Hadoop是一个开源框架,主要解决海量数据的存储和处理...
分布式系统是计算机科学中的一个重要领域,它涉及到多个独立计算节点通过网络...通过深入学习和理解这些原理和范例,读者可以更好地设计和构建可扩展、健壮的分布式系统,以适应不断增长的业务需求和复杂的技术环境。
一种越来越受欢迎的大数据处理范例是MapReduce编程,其中处理过程由Map操作和Reduce操作指定。但是,MapReduce对于大型的、不变的输入数据在网络上反复传输的情况,处理迭代应用的效果不佳,因此对于大量的图处理...