HBase结合MapReduce批量导入

<IBM DB2>《DB2 官方监控脚本 2022版本》 DB2 监控脚本 阅读详情

Hbase是Hadoop生态体系配置的数据库,我们可以通过HTable api中的put方法向Hbase数据库中插入数据,但是由于put效率太低,不能批量插入大量的数据,文本将详细介绍如何通过MapReduce运算框架向Hbase数据库中导入数据。 
开篇先介绍业务场景:将电信手机上网日志中的数据导入到Hbase数据库中,将部分数据以及相应字段描述列出: 

è¿éåå¾çæè¿°

图片格式描述: 
è¿éåå¾çæè¿°
先介绍一个日期格式的转换:

public class TestDate
{
     public static void main(String[] args)
     {
         Date date = new Date();
         System.out.println(date);
         //用给定的模式和默认语言环境的日期格式符号构造 SimpleDateFormat
         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
         //将给定的 Date 格式化为日期/时间字符串
         String time = df.format(date);
         System.out.println(time);
     }
}
输出结果:
Thu Jun 02 10:34:52 CST 2016
2016-06-02 10:34:52


 public static void main(String[] args) throws ParseException
{
           String str = "30/May/2013:20:35:55 +0800";
           //构造一个日期格式转换器,匹配我们给定的时间
           SimpleDateFormat simple1 = new SimpleDateFormat("dd/MMM/yyyy:HH:mm:ss", Locale.ENGLISH);
           //将其转换为我们熟悉的时间格式
           Date date = simple1.parse(str);
           System.out.println(date);

} 

输出结果:
Thu May 30 20:35:55 CST 2013


linux--shell中常用的日期格式化输出:
[root@hadoop80 local]# date
Thu Jun  2 10:39:14 PDT 2016
[root@hadoop80 local]# date +%Y-%m-%d-%H-%M-%S
2016-06-02-10-39-15

在Java当中,我们经常利用SimpledateFormat这个类将给定的日期转化成指定的格式。


**接下来在归纳一下Hbase结合MapReduce批量导入数据的时候,在代码当中应该注意的事项:**
①MyReducer类继承的是TableReduce类,而不在是MapReduce中常用的Reducer类
②<k3,v3>的数值类型没有什么用,通常将k3的数值类型设置为NullWritable即可
③只设置map函数的输出类型,不在设置reduce函数的输出类型,因为②的原因
④指定对输出文件格式化处理的类改为TableOutputFormat,而不在是TextOutputFormat
⑤输出文件的路径改为指定的表名,在Configuration中进行设定,而不在是path的方式
⑥如果想过jar包的方式运行程序,需要job.setJarByClass(……)。
接下来将贴出我在编程的时候第一次写出的业务代码:当然遇到了很多的问题。


 

package IT01;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat;
import org.apache.hadoop.hbase.mapreduce.TableReducer;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.partition.HashPartitioner;
public class HbaseApp
{
     public static String path1 = "hdfs://hadoop80:9000/FlowData.txt";
     public static void main(String[] args) throws Exception
     {
           Configuration conf = new Configuration();  //也可以用HBaseConfiguration类
           conf.set("hbase.rootdir","hdfs://hadoop80:9000/hbase");
           conf.set("hbase.zookeeper.quorum","hadoop80");
           conf.set(TableOutputFormat.OUTPUT_TABLE,"wlan_log");//在这里需要指定表的名字:相当于输出文件的路径
           conf.set("dfs.socket.timeout","2000");

           Job job = new Job(conf,"HbaseApp");
           //job.setJarByClass(HbaseImport.class);  //是否打jar包运行
           FileInputFormat.setInputPaths(job, new Path(path1));
           job.setInputFormatClass(TextInputFormat.class);
           job.setMapperClass(MyMapper.class);
           job.setMapOutputKeyClass(Text.class);
           job.setMapOutputValueClass(Text.class);

           job.setNumReduceTasks(1);
           job.setPartitionerClass(HashPartitioner.class);

           job.setReducerClass(MyReducer.class);
//         job.setOutputKeyClass(Text.class);
//         job.setOutputValueClass(NullWritable.class);
           job.setOutputFormatClass(TableOutputFormat.class);//不在是TextOutputFormat
//         FileOutputFormat.setOutputPath(job, new Path(path2));
           job.waitForCompletion(true);
     }
     public static class MyMapper extends Mapper<LongWritable, Text, Text, Text>
     {
            protected void map(LongWritable k1, Text v1,Context context)throws IOException, InterruptedException
            {
                  String[] splited = v1.toString().split("\t");
                  String reportTime = splited[0];
                  String msisdn = splited[1];
                  Date date = new Date(Long.parseLong(reportTime));
                  String time = DateConvert.dateParse(date);
                  String rowkey = msisdn+":"+time;//获取到行健
                  context.write(new Text(rowkey),new Text(v1.toString())); //将行健rowkey和对应的记录进行输出    
            }
     }
     public static class MyReducer extends TableReducer<Text, Text, NullWritable>
     {
            protected void reduce(Text k2, Iterable<Text> v2s,Context context)throws IOException, InterruptedException
            {
                  for (Text v2 : v2s)
                 {
                     String[] splited = v2.toString().split("\t");
                     /**添加记录的时候需要指定行健、列族、列名、数值***/
                     Put put = new Put(k2.toString().getBytes());
                     put.add("cf".getBytes(),"reportTime".getBytes(), splited[0].getBytes());
                     put.add("cf".getBytes(),"msisdn".getBytes(), splited[1].getBytes());
                     put.add("cf".getBytes(),"apmac1".getBytes(), splited[2].getBytes());
                     put.add("cf".getBytes(),"apmac2".getBytes(), splited[3].getBytes());
                     put.add("cf".getBytes(),"host".getBytes(), splited[4].getBytes());
                     put.add("cf".getBytes(),"sitetype".getBytes(), splited[5].getBytes());
                     put.add("cf".getBytes(),"upPackNum".getBytes(), splited[6].getBytes());
                     put.add("cf".getBytes(),"downPackNum".getBytes(), splited[7].getBytes());
                     put.add("cf".getBytes(),"upPayLoad".getBytes(), splited[8].getBytes());
                     put.add("cf".getBytes(),"downPayLoad".getBytes(), splited[9].getBytes());
                     put.add("cf".getBytes(),"httpstatus".getBytes(), splited[10].getBytes());
                     context.write(NullWritable.get(),put);
                 }       
            }
     }
}
class DateConvert
{
    public static String dateParse(Date  date)
    {
         SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");//构造一个日期解析器
         return df.format(date); 
    }
}


程序运行完之后:显示如下异常NumberFormatException 
 è¿éåå¾çæè¿°
显示的是数字格式异常, 于是我在map函数当中又加了一个throws NumberFormatException

           

 protected void map(LongWritable k1, Text v1,Context context)throws IOException, InterruptedException,NumberFormatException
            {
                  String[] splited = v1.toString().split("\t");
                  String reportTime = splited[0];
                  String msisdn = splited[1];
                  Date date = new Date(Long.parseLong(reportTime));
                  String time = DateConvert.dateParse(date);
                  String rowkey = msisdn+":"+time;//获取到行健
                  context.write(new Text(rowkey),new Text(v1.toString()));      
            }


但是这样我发现也不对,因为当我追踪Mapp这个类的源代码时,我发现父类的map方法并没有抛出NumberFormatException这个异常,根据子类重写方法抛出异常的范围不能大于父类被重写方法抛出异常的范围,我又将上面这段代码用try——catch这种异常处理方式进行处理:

protected void map(LongWritable k1, Text v1,Context context)throws IOException, InterruptedException
            {
                  try
                  {
                      String[] splited = v1.toString().split("\t");
                      String reportTime = splited[0];
                      String msisdn = splited[1];
                      Date date = new Date(Long.parseLong(reportTime));
                      String time = DateConvert.dateParse(date);
                      String rowkey = msisdn+":"+time;//获取到行健
                      context.write(new Text(rowkey),new Text(v1.toString()));      
                  }catch(Exception e)
                  {
                      Counter counter = context.getCounter("NumberExceptionNum", "num");
                      counter.increment(1L);
                  }
            }


当我将代码改成这样的时候,此时程序并没有显示抛出NumberFormatException这个异常,说明异常得到了处理,但是当我去查看Hbase数据的时候,发现HDFS中的日志数据并没有导入到Hbase数据库中,于是我又查看了一下MapReduce的运行日志: 
è¿éåå¾çæè¿°
也就是我的22行数据在map函数中当中并没有输出,这个问题就匪夷所思了,为什么22行数据都会抛出数字格式异常呢,而且都没有输出,于是我想到可能是SimpleDateFormat这个类的问题,于是我又开始各种百度,发现网上很多文章都是批判这个类的,最终终于找到了问题的解决方案,用trim()这个方法去除字符串前后的空格即可。

protected void map(LongWritable k1, Text v1,Context context)throws IOException, InterruptedException
            {
                  try
                  {
                      String[] splited = v1.toString().split("\t");
                      String reportTime = splited[0].trim();
                      String msisdn = splited[1].trim();
                      Date date = new Date(Long.parseLong(reportTime));
                      String time = DateConvert.dateParse(date);
                      String rowkey = msisdn+":"+time;//获取到行健
                      context.write(new Text(rowkey),new Text(v1.toString()));      
                  }catch(Exception e)
                  {
                      Counter counter = context.getCounter("NumberExceptionNum", "num");
                      counter.increment(1L);
                  }
            }


于是我又开始运行程序,但是当我运行完之后,从MapReduce的计数器当中,我发现第一条数据文本并没有导入:因为数字格式异常的这个原因估计在运行过程中被终止了。下面是计数器的显示: 
 è¿éåå¾çæè¿°
于是我又想到了一个解决方案,将第一条数据多复制一条即可,然后重写将数据上传到HDFS中。 
此时在一次 运行程序,显示正确,此时数据也全部导入到Hbase数据库中。 
 è¿éåå¾çæè¿°
Hbase中数据查看核实: 
 è¿éåå¾çæè¿°
将HDFS中的数据通过MapReduce导入到Hbase数据库时,总结如下:

è¿éåå¾çæè¿°  
核心步骤:先将数据文件上传到HDFS,然后用MapReduce进行处理,将处理后的数据插入到 hbase中 
注意事项: 
1>子类重写方法抛出异常的范围不能大于父类被重写方法抛出异常的范围 
2>用trim()这个方法可以去除字符串前后的空格,换行符。 
3>既然第一条数据总是显示数字格式异常,将第一条数据复制为2份即可。 
4>在处理数据的时候尽量用制表符,而不要用”\t”(血的教训!)。 
5>数据在使用的时候一定要记得去除掉末尾的空行(不然你就蓝瘦香菇吧!)。 
6>有的时候数字数据(或者数据本身)可能会造成莫名其妙的问题!

--------------------- 
作者:安静的技术控 
来源:优快云 
原文:https://blog.youkuaiyun.com/a2011480169/article/details/51405727 
版权声明:本文为博主原创文章,转载请附上博文链接!

NSGA-II 多目标优化 —— 理论、案例与交互式 GUI 实现 本文详细介绍了 NSGA-II 多目标优化算法的基本原理、数学模型和实现流程。从非支配排序、拥挤距离计算到遗传操作,NSGA-II 通过对种群进行分层和排序,能够有效求解多目标优化问题,获得 Pareto 前沿解集。通过机械结构优化、资源分配和控制参数调优等典型案例,我们展示了 NSGA-II 在实际工程中的广泛应用。为帮助工程师和研究者更直观地理解算法求解过程,本文提供了基于 Python 与 PyQt6 的交互式 GUI 演示系统代码示例。 阅读详情

相关推荐

OpenEuler22.03 LTS下Zabbix7.0监控系统的容器化部署避坑指南(含Docker-Compose完整配置)

本文详细介绍了在OpenEuler22.03 LTS操作系统上容器化部署Zabbix7.0监控系统的完整流程,包括Docker引擎配置、Docker-Compose编排、网络模式选择及性能调优等关键步骤。针对OpenEuler环境下的特殊问题提供了解决方案,帮助用户高效搭建稳定可靠的监控系统。

python9snake的博客 267

hbase 结合MapReduce 批量导入

hbase 结合MapReduce 批量导入

XD_122 1670

基于PWM的汽车仪表步进电机微步驱动优化实践

本文深入探讨了基于PWM的微步驱动技术,用于优化汽车仪表步进电机的运行性能。通过将传统的分步驱动升级为PWM微步细分驱动,利用正弦/余弦查表法合成旋转磁场,有效消除了指针抖动与噪声,实现了指针的平滑、精准运动。文章以STM32和VID2905电机为例,提供了详细的硬件连接、代码实现及高级优化技巧,为提升汽车仪表体验提供了实用方案。

weixin_29169505的博客 510

HBase数据导入的几种操作

数据导入有如下几种方式: 1.利用HBase提供的ImportTsv将csv文件导入到HBase 2.利用HBase提供的completebulkload将数据导入到HBase 3.利用HBase提供的Import将数据导入到HBase利用ImportTsv将csv文件导入到HBase命令:格式:hbase [类] [分隔符] [行键,列族] [表] [导入文件] bin/hbase org

吃果冻不吐果冻皮 1万+

深入Linux内核:PTP硬件时间戳(HW Timestamp)是如何炼成的?

本文深入探讨了Linux内核中PTP硬件时间戳(HW Timestamp)的实现原理与实战应用。通过分析IEEE 1588协议在网络时间同步中的关键作用,详细解析了硬件时间戳在Linux内核中的架构设计、驱动开发及性能优化技巧,帮助开发者实现纳秒级精度的时间同步。

weixin_30727835的博客 650

ELK - CentOS7 安装 elasticsearch 7.17.5

elk elasticsearch 安装

qq_19783793的博客 1461

离线备份hbase数据

1. Export/Import(导入导出) hdfs常用命令: http://www.cnblogs.com/gaopeng527/p/4314215.html 1) 导出     通过Export导出数据到目标集群的hdfs,再在目标集群执行import导入数据,Export支持指定开始时间和结束时间,因此可以做增量备份,Export工具参数如下: 可见,在导出时可以指定versio...

十色花的博客 996

电磁炉线圈加热仿真全流程:用Ansys Maxwell分析涡流效应与热损耗

本文详细介绍了使用Ansys Maxwell进行电磁炉线圈加热仿真的全流程。通过构建2D轴对称涡流场模型,深入分析了高频下的涡流效应、趋肤效应与热损耗分布,为优化线圈设计、提升加热效率与均匀性提供了量化依据和实用指南。

sss66的博客 963

HBase数据迁移(备份)常见方式总结以及演示(集成MapReduce)

HBase数据迁移 通常我们的数据来自logs以及RDBMS中,在有些时候,我们需要进行数据迁移,比如,将RDBMS中数据进行备份迁移到HBase中存储或者将一些文件迁移到HBase中,常见的HBase的数据迁移有以上几种方式: 使用Put API来插入数据 使用Bulk Load方式迁移海量数据(下面会详解以及演示) 编写MapReduce程序进行数据迁移 使用Sqoop等工具从RDBMS...

不清不慎的博客 1252

mysql9.0windows安装

将这里的位置修改为你刚刚创建并复制data目录的地址即可,win11的系统使用vscode修改之后,会让你确认开启更高权限以进行保存,比较方便,window10不需要确认,修改后可以直接保存。:在修改之前,最好将下图文件进行备份,将原始的文件保存好一份,以防更改了配置之后,导致mysql服务报错,无法启动,备份好的话直接将有问题的配置文件给替换就可以,无需重新安装一次mySql。双击下载的msi文件进行安装。安装有问题的,可以直接进行卸载,新本的mySql会将注册表中的数据自动进行清除,还是很方便的。

m0_74824123的博客 6444

双目深度相机--10.双目视觉的主要步骤讲解分析

双目视觉技术通过模拟人眼原理,利用两个相机从不同视角采集图像,实现三维坐标计算。其核心流程包括:1)系统标定,消除相机畸变并建立坐标映射关系;2)图像同步采集与预处理;3)立体匹配,寻找左右图像对应点;4)基于视差图的深度计算;5)三维重建生成点云或网格模型;6)结果应用如目标测距、三维建模等。关键技术难点在于精确标定和准确匹配,这两步直接影响最终深度计算的精度。该技术广泛应用于自动驾驶、工业检测、VR等领域,实现了从二维图像到三维空间的精准转换。

AIoT深度探索者 | 嵌入式系统架构师 深耕物联网(IoT)与人工智能(AI)融合技术,聚焦​​边缘计算、图像开发、低功耗通信协议​​,致力于智能硬件,关注我获取最新技术文章信息与海量资源~ 624

Hbase的MapReduce(Hbase权威指南)+ BulkLoad导入HBase

目录 Hbase权威指南第7张与MapReduce集成 预测执行和版本介绍 Hbase与MapReduce集成 例7.1MapReduce作业从一个文件中读取数据并写入Hbase表 MapReduce生成HFile文件,再使用BulkLoad导入HBase中 Hbase权威指南第7张与MapReduce集成 预测执行和版本介绍 2.5.2.9. 预测执行 (...

u012447842的博客 860

如何使用 Claude Code 搜索 SAP note

当然,Claude Code 自己仍然要有一种合法可用的模型访问方式,例如 Claude 订阅、Anthropic API 或公司配置的模型提供方式,这和 Browser Extension 是两个问题。因为 Claude Code 已经是完整的 MCP Host,而 Microsoft Playwright MCP 又已经明确支持现有 Chrome Session,两者拼起来在技术架构上完全成立。Microsoft Playwright MCP 默认可以创建持久化浏览器 Profile。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 62

HBASE结合MapReduce批量导入

HBASE结合MapReduce批量导入

chbxw 1247

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

HBase结合MapReduce批量导入(HDFS中的数据导入到HBase)

HBase结合MapReduce批量导入 1 package hbase; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 import org.apache.hadoop.conf.Configuration; 7 import org.apache.hadoop.hbas...

weixin_34059951的博客 232

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Hadoop之——HBASE结合MapReduce批量导入数据

废话不多说,直接上代码,你懂得 package hbase; import java.text.SimpleDateFormat; import java.util.Date; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.Put; import org.apache.ha

冰河的专栏 5547

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Hbase结合MapReduce批量导入数据

public class HbaseMR { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.set("hbase.zookeeper.quorum", "192.168.1.182"); conf.set(TableO

ukakasu的博客 510

Hbase结合MapReduce的批量导入

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33860528的博客 96

用Python玩转滴答清单:手把手教你调用未公开的网页版API(附完整代码)

本文详细介绍了如何使用Python调用滴答清单(TickTick)未公开的网页版API,实现任务管理的自动化。从环境准备、认证机制到核心API功能实现,手把手教你构建自动化工作流系统,提升任务管理效率。适用于需要与滴答清单深度集成的开发者。

weixin_33709590的博客 344

HBase BulkLoad 导入大量数据

HBase常用写入数据方式 1、使用MapReduce作业中的TableOutputformat类 //context.write(new ImmutableBytesWritable(Bytes.toBytes(rowkey)), put) 2、使用客户端API //table.put(put) 然而,这些方法并不总是最有效的方法。 BulkLoad bulkload方式...

没有格子衬衫的程序员 2943
上一篇: 分布式存储入库过程本质上是建索引过程
下一篇: Hbase Bulk Loading与HBase API方式分析和对比
千淘万漉
博客等级 码龄10年 115粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值