MapReduce和Spark写入Hbase多表总结
作者: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多表总结的更多相关文章
- Spark写入HBase(Bulk方式)
在使用Spark时经常需要把数据落入HBase中,如果使用普通的Java API,写入会速度很慢.还好Spark提供了Bulk写入方式的接口.那么Bulk写入与普通写入相比有什么优势呢? BulkLo ...
- spark读写hbase性能对比
一.spark写入hbase hbase client以put方式封装数据,并支持逐条或批量插入.spark中内置saveAsHadoopDataset和saveAsNewAPIHadoopDatas ...
- spark 操作hbase
HBase经过七年发展,终于在今年2月底,发布了 1.0.0 版本.这个版本提供了一些让人激动的功能,并且,在不牺牲稳定性的前提下,引入了新的API.虽然 1.0.0 兼容旧版本的 API,不过还是应 ...
- spark 对hbase 操作
本文将分两部分介绍,第一部分讲解使用 HBase 新版 API 进行 CRUD 基本操作:第二部分讲解如何将 Spark 内的 RDDs 写入 HBase 的表中,反之,HBase 中的表又是如何以 ...
- spark运算结果写入hbase及优化
在Spark中利用map-reduce或者spark sql分析了数据之后,我们需要将结果写入外部文件系统. 本文,以向Hbase中写数据,为例,说一下,Spark怎么向Hbase中写数据. 首先,需 ...
- 大数据学习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的多个操作放到 ...
- spark 写入数据到Geomesa(Hbase)
package com.grady.geomesa import org.apache.spark.sql.jts.PointUDT import org.apache.spark.sql.types ...
- Spark DataFrame写入HBase的常用方式
Spark是目前最流行的分布式计算框架,而HBase则是在HDFS之上的列式分布式存储引擎,基于Spark做离线或者实时计算,数据结果保存在HBase中是目前很流行的做法.例如用户画像.单品画像.推荐 ...
- 使用spark将内存中的数据写入到hive表中
使用spark将内存中的数据写入到hive表中 hive-site.xml <?xml version="1.0" encoding="UTF-8" st ...
随机推荐
- PHP以接口方式实现多重继承(完全模拟)--学习笔记
1.UML类图: 2.PHP代码: <?php /** * Created by PhpStorm. * User: andy * Date: 16-11-23 * Time: 下午7:57 ...
- 立即执行函数表达式(IIFE)
原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...
- Go结构体实现类似成员函数机制
Go语言结构体成员能否是函数,从而实现类似类的成员函数的机制呢?答案是肯定的. package main import "fmt" type stru struct { testf ...
- MySQL 系列(三)你不知道的 视图、触发器、存储过程、函数、事务、索引、语句
第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...
- CSS 3学习——transform 2D转换
首先声明一点,transform属性不为none的元素是它的定位子元素(绝对定位和固定定位)的包含块,而且对内创建一个新的层叠上下文. 注意:可以通过 transform-box 属性指定元素的那个盒 ...
- 通过AngularJS实现前端与后台的数据对接(一)——预备工作篇
最近,笔者在做一个项目:使用AngularJS,从而实现前端与后台的数据对接.笔者这是第一次做前端与后台的数据对接的工作,因此遇到了许多问题.笔者在这些问题中,总结了一些如何实现前端与后台的数据对接的 ...
- 超全面的.NET GDI+图形图像编程教程
本篇主题内容是.NET GDI+图形图像编程系列的教程,不要被这个滚动条吓到,为了查找方便,我没有分开写,上面加了目录了,而且很多都是源码和图片~ (*^_^*) 本人也为了学习深刻,另一方面也是为了 ...
- 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)
今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...
- echo命令
linux的echo命令, 在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的, 因此有必要了解下echo的用法echo命令的功能是在显示器上显示一段文字,一般起到一个提示的 ...
- HTPC家庭娱乐和XBOX未来发展畅想<另:创业工作机会>
微软中国在上海举办新闻发布会,正式宣布Xbox One将于9月23日在中国开始销售,定价3699元起.这款早在2001年就发布的电视游戏机终于在经历了14年的等待后,进军中国大陆市场.此次Xbox O ...