作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处

大家都知道用mapreduce或者spark写入已知的hbase中的表时,直接在mapreduce或者spark的driver class中声明如下代码

job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, tablename);

随后mapreduce在mapper或者reducer中直接context写入即可,而spark则是构造好包含Put的PairRDDFunctions后saveAsHadoopDataset即可.

而经常会碰到一些要求是根据输入数据,处理后需要写入hbase多个表或者表名是未知的,需要按照数据中某个字段来构造表名写入hbase.

由于表名未知,所以不能设置TableOutputFormat.OUTPUT_TABLE,那么这种要求也容易实现,分别总结mapreduce和spark的实现方法(其实到最后会发现殊途同归)

一.MapReduce写入Hbase多表

在MR的main方法中加入如下代码即可

job.setOutputFormatClass(MultiTableOutputFormat.class);

随后就可以在mapper或者reducer的context中根据相关字段构造表名和put写入多个hbase表.

二.Spark写入Hbase多表

这里直接用我测试过的spark streaming程序写入多个hbase表,上代码

object SparkStreamingWriteToHbase {
def main(args: Array[String]): Unit = {
var masterUrl = "yarn-client"
if (args.length > 0) {
masterUrl = args(0)
}
val conf = new SparkConf().setAppName("Write to several tables of Hbase").setMaster(masterUrl) val ssc = new StreamingContext(conf, Seconds(5)) val topics = Set("app_events") val brokers = PropertiesUtil.getValue("BROKER_ADDRESS") val kafkaParams = Map[String, String](
"metadata.broker.list" -> brokers, "serializer.class" -> "kafka.serializer.StringEncoder") val hbaseTableSuffix = "_clickcounts" val hConf = HBaseConfiguration.create()
val zookeeper = PropertiesUtil.getValue("ZOOKEEPER_ADDRESS")
hConf.set(HConstants.ZOOKEEPER_QUORUM, zookeeper) val jobConf = new JobConf(hConf, this.getClass) val kafkaDStreams = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topics) val appUserClicks = kafkaDStreams.flatMap(rdd => {
val data = JSONObject.fromObject(rdd._2)
Some(data)
}).map{jsonLine =>
val key = jsonLine.getString("appId") + "_" + jsonLine.getString("uid")
val value = jsonLine.getString("click_count")
(key, value)
} val result = appUserClicks.map { item =>
val rowKey = item._1
val value = item._2
convertToHbasePut(rowKey, value, hbaseTableSuffix)
} result.foreachRDD { rdd =>
rdd.saveAsNewAPIHadoopFile("", classOf[ImmutableBytesWritable], classOf[Put], classOf[MultiTableOutputFormat], jobConf)
} ssc.start()
ssc.awaitTermination()
} def convertToHbasePut(key: String, value: String, tableNameSuffix: String): (ImmutableBytesWritable, Put) = {
val rowKey = key
val tableName = rowKey.split("_")(0) + tableNameSuffix
val put = new Put(Bytes.toBytes(rowKey))
put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("count"), Bytes.toBytes(value))
(new ImmutableBytesWritable(Bytes.toBytes(tableName)), put)
} }

简单描述下,这里spark streaming中处理的是从kafka中读取的json数据,其中的appId字段用来构造tablename区分写入不同的hbase table.最后以saveAsNewAPIHadoopFile把rdd写入hbase表

进入saveAsNewAPIHadoopFile会发现其实和mapreduce的配置没什么区别,如下

def saveAsNewAPIHadoopFile(
path: String,
keyClass: Class[_],
valueClass: Class[_],
outputFormatClass: Class[_ <: NewOutputFormat[_, _]],
conf: Configuration = self.context.hadoopConfiguration)
{
// Rename this as hadoopConf internally to avoid shadowing (see SPARK-2038).
val hadoopConf = conf
val job = new NewAPIHadoopJob(hadoopConf)
job.setOutputKeyClass(keyClass)
job.setOutputValueClass(valueClass)
job.setOutputFormatClass(outputFormatClass)
job.getConfiguration.set("mapred.output.dir", path)
saveAsNewAPIHadoopDataset(job.getConfiguration)
}

这个方法的参数分别是ouput path,这里写入hbase,传入为空即可,其他参数outputKeyClass,outputValueClass,outputFormatClass,jobconf

这里的outputFormatClass确保一定是MultiTableOutputFormat来保证写入多表,对了,这里说明一点,确保你要写入的hbase表首先被create了。

MapReduce和Spark写入Hbase多表总结的更多相关文章

  1. Spark写入HBase(Bulk方式)

    在使用Spark时经常需要把数据落入HBase中,如果使用普通的Java API,写入会速度很慢.还好Spark提供了Bulk写入方式的接口.那么Bulk写入与普通写入相比有什么优势呢? BulkLo ...

  2. spark读写hbase性能对比

    一.spark写入hbase hbase client以put方式封装数据,并支持逐条或批量插入.spark中内置saveAsHadoopDataset和saveAsNewAPIHadoopDatas ...

  3. spark 操作hbase

    HBase经过七年发展,终于在今年2月底,发布了 1.0.0 版本.这个版本提供了一些让人激动的功能,并且,在不牺牲稳定性的前提下,引入了新的API.虽然 1.0.0 兼容旧版本的 API,不过还是应 ...

  4. spark 对hbase 操作

    本文将分两部分介绍,第一部分讲解使用 HBase 新版 API 进行 CRUD 基本操作:第二部分讲解如何将 Spark 内的 RDDs 写入 HBase 的表中,反之,HBase 中的表又是如何以 ...

  5. spark运算结果写入hbase及优化

    在Spark中利用map-reduce或者spark sql分析了数据之后,我们需要将结果写入外部文件系统. 本文,以向Hbase中写数据,为例,说一下,Spark怎么向Hbase中写数据. 首先,需 ...

  6. 大数据学习day34---spark14------1 redis的事务(pipeline)测试 ,2. 利用redis的pipeline实现数据统计的exactlyonce ,3 SparkStreaming中数据写入Hbase实现ExactlyOnce, 4.Spark StandAlone的执行模式,5 spark on yarn

    1 redis的事务(pipeline)测试 Redis本身对数据进行操作,单条命令是原子性的,但事务不保证原子性,且没有回滚.事务中任何命令执行失败,其余的命令仍会被执行,将Redis的多个操作放到 ...

  7. spark 写入数据到Geomesa(Hbase)

    package com.grady.geomesa import org.apache.spark.sql.jts.PointUDT import org.apache.spark.sql.types ...

  8. Spark DataFrame写入HBase的常用方式

    Spark是目前最流行的分布式计算框架,而HBase则是在HDFS之上的列式分布式存储引擎,基于Spark做离线或者实时计算,数据结果保存在HBase中是目前很流行的做法.例如用户画像.单品画像.推荐 ...

  9. 使用spark将内存中的数据写入到hive表中

    使用spark将内存中的数据写入到hive表中 hive-site.xml <?xml version="1.0" encoding="UTF-8" st ...

随机推荐

  1. 继电器是如何成为CPU的(1)

    继电器是如何成为CPU的(1) ——<穿越计算机的迷雾>整理和总结 究竟是如何设计的电路,具有计算和控制的智力? 这一点也不高深.本系列文章从初中学的最简单的电路图说起,看看能不能从最初的 ...

  2. KMP算法求解

    // KMP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespac ...

  3. 深入理解CSS中的margin负值

    前面的话 margin属性在实际中非常常用,也是平时踩坑较多的地方.margin折叠部分相信不少人都因为这样那样的原因中过招.margin负值也是很常用的功能,很多特殊的布局方法都依赖于它.它看似简单 ...

  4. 使用HTML5的cavas实现的一个画板

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-e ...

  5. iOS 后台处理

    iOS 后台处理的常见用途 1.进入后台时候删除资源:应用处于挂起状态的时候所占用的资源越少,该应用被iOS终止的风险就越低.通过从内存中清理那些易于重新创建的资源,可以增加应用驻留内存的机会,因此可 ...

  6. AFN解析器里的坑

    AFN框架是用来用来发送网络请求的,它的好处是可以自动给你解析JSON数据,还可以发送带参数的请求AFN框架还可以监测当前的网络状态,还支持HTTPS请求,分别对用的类为AFNetworkReacha ...

  7. SQL 提示介绍 hash/merge/concat union

    查询提示一直是个很有争议的东西,因为他影响了sql server 自己选择执行计划.很多人在问是否应该使用查询提示的时候一般会被告知慎用或不要使用...但是个人认为善用提示在不修改语句的条件下,是常用 ...

  8. Android快乐贪吃蛇游戏实战项目开发教程-01项目概述与目录

    一.项目简介 贪吃蛇是一个很经典的游戏,也很适合用来学习.本教程将和大家一起做一个Android版的贪吃蛇游戏. 我已经将做好的案例上传到了应用宝,无病毒.无广告,大家可以放心下载下来把玩一下.应用宝 ...

  9. 【python之路3】if 语句

    1.if语句用法(if....else....) #!/usr/bin/env python # -*- coding:utf-8 -*- my_name = raw_input("plea ...

  10. mono -图片处理

    这篇文章中您将了解到以下内容 保存Bitmap WebClient文件上传 向服务端传递数据 保存Bitmap 做移动端开发,图片上传下载是最普通的需求了. 在mono for android中按照资 ...