一、概述

  在实时应用之中,难免会遇到往NoSql数据如HBase中写入数据的情景。题主在工作中遇到如下情景,需要实时查询某个设备ID对应的账号ID数量。踩过的坑也挺多,举其中之一,如一开始选择使用NEO4J图数据库存储设备和账号的关系,当然也有其他的数据,最终构成一个复杂的图关系,但是这个图数据库免费版是单机安装(集群要收费),在实时写入和查询关系的时候,导致我们一台服务器内存和cpu损耗严重,为了保证Hadoop集群的稳定性,只好替换掉这个数据库,采用流行的HBase。本文就HBase的使用心得做如下记录。

二、解决方案

  1.rowkey设计:设备id是32位字母、数字组成的串,考虑到HBase长表扫描的查询最快,所以rowkey的设计方式为,设备ID+账号ID拼接而成,这样在扫描某个设备ID时会很快计算出条数。

2.HBase表设计:在创建表的时候采用预分区建表,因为这样的,如果知道hbase数据表的rowkey的分布情况,就可以在建表的时候对hbase进行region的预分区,这样做的好处是防止大数据量插入的热点问题,提高数据插入的效率。rowkey是字母或者数字开头,所以建表语句如下(数据量再大的时候还可以在细分分区):

create 'T_TEST', 'data', SPLITS => ['0', '1','2', '3','4', '5','6','7','8','9','a', 'b', 'c', 'd', 'e', 'f', 'g']

此处入坑:创建表的时候将HBase表映射到Hive外部表,语句如下。这样做是为了方便导入历史数据,但是Hive跑批将历史数据导入之后,从HBase查询已经导入的某一数据的时候,无法查询导数据,也无法通过API写入到HBase,这个问题很诡异,后来想了下Hive导入的数据编码和HBase的不同,于是重新将表删除,不采用映射表,直接使用Spark将历史数据导入,问题解决。

CREATE external TABLE tmp.H_T_TEST(key string ,num string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,data:num")
TBLPROPERTIES ("hbase.table.name" = "T_TEST");

3.设计好rowkey和表之后,我们就开始写Spark代码了。

此处入坑,我把HBase的连接池写在了和Spark的同一位置,这样会遇到一个问题,Spark程序运行的时候报HBaseConnection没有序列化,按照网上的做法,将对象加上 @transient注解,虽然不报错误,还是无法将数据写入到Hba之中。后来经过查找,找到了解决办法,将HBase的连接放到消息的循环之内,即一个分区建立一个HBase连接,代码如下。

def main(args: Array[String]): Unit = {
val sc: SparkContext = SparkUtil.createSparkContext(this.getClass.getSimpleName)
val ssc: StreamingContext = new StreamingContext(sc, Seconds(10))
val messages = SparkUtil.createDStreamFromKafka(
"T_TEST",
topicSet,
ssc)//创建消息接收器 messages.foreachRDD(rdd => {
rdd.foreachPartition(partitionRecords => {//循环分区
try {
val connection = HBaseUtil.getHbaseConn //获取HBase连接,分区创建一个连接,分区不跨节点,不需要序列化
partitionRecords.foreach(s => {
val data = JSON.parseObject(s._2)//将数据转化成JSON格式
val tableName = TableName.valueOf("T_TEST")
val table = connection.getTable(tableName)//获取表连接 val put = new Put(Bytes.toBytes(data.getString("id1") + "_" + data.getString("id2")))
put.addColumn(Bytes.toBytes("data"), Bytes.toBytes("num"), Bytes.toBytes("1")) Try(table.put(put)).getOrElse(table.close())//将数据写入HBase,若出错关闭table
table.close()//分区数据写入HBase后关闭连接
})
} catch {
case e: Exception => logger.error("写入HBase失败,{}", e.getMessage)
}
})
})
ssc.start()
ssc.awaitTermination() }

至此问题解决,数据正常,还没出现过问题,等待时间验证吧。

4.历史数据导入,在导入历史数据的时候,由于数据放在了Hive的两个不同表之中,一开始想要一次性读入,使用Spark SQL的dataframe,创建一个hivecontext,写HiveSQL将两个表结果执行union all操作,但是Spark程序报rpc错误。将两个表的结果分别查出,使用dataframe 的union all操作,也是不行,也是rpc错误,查了很多资料,还是没解决,莫名其妙的错误,后来两个表分开执行导入历史数据,问题不再出现,可能Spark还是不够成熟,总是遇到莫名其妙的问题。

三、总结

  在使用Hbase的时候要预分区。不要为了方便使用Hive外部映射表。HBase的连接池要放在分区循环开始的地方,不然创建很多的连接,会导致HBase垮掉。

Spark Streaming实时写入数据到HBase的更多相关文章

  1. Spark Streaming接收Kafka数据存储到Hbase

    Spark Streaming接收Kafka数据存储到Hbase fly spark hbase kafka 主要参考了这篇文章https://yq.aliyun.com/articles/60712 ...

  2. 【转】Spark Streaming 实时计算在甜橙金融监控系统中的应用及优化

    系统架构介绍 整个实时监控系统的架构是先由 Flume 收集服务器产生的日志 Log 和前端埋点数据, 然后实时把这些信息发送到 Kafka 分布式发布订阅消息系统,接着由 Spark Streami ...

  3. 【慕课网实战】Spark Streaming实时流处理项目实战笔记十之铭文升级版

    铭文一级: 第八章:Spark Streaming进阶与案例实战 updateStateByKey算子需求:统计到目前为止累积出现的单词的个数(需要保持住以前的状态) java.lang.Illega ...

  4. Spark练习之通过Spark Streaming实时计算wordcount程序

    Spark练习之通过Spark Streaming实时计算wordcount程序 Java版本 Scala版本 pom.xml Java版本 import org.apache.spark.Spark ...

  5. Spark Streaming实时计算框架介绍

    随着大数据的发展,人们对大数据的处理要求也越来越高,原有的批处理框架MapReduce适合离线计算,却无法满足实时性要求较高的业务,如实时推荐.用户行为分析等. Spark Streaming是建立在 ...

  6. 【Streaming】30分钟概览Spark Streaming 实时计算

    本文主要介绍四个问题: 什么是Spark Streaming实时计算? Spark实时计算原理流程是什么? Spark 2.X下一代实时计算框架Structured Streaming Spark S ...

  7. Spark Streaming揭秘 Day16 数据清理机制

    Spark Streaming揭秘 Day16 数据清理机制 今天主要来讲下Spark的数据清理机制,我们都知道,Spark是运行在jvm上的,虽然jvm本身就有对象的自动回收工作,但是,如果自己不进 ...

  8. 新闻网大数据实时分析可视化系统项目——19、Spark Streaming实时数据分析

    1.Spark Streaming功能介绍 1)定义 Spark Streaming is an extension of the core Spark API that enables scalab ...

  9. 通过Spark Streaming处理交易数据

    Apache Spark 是加州大学伯克利分校的 AMPLabs 开发的开源分布式轻量级通用计算框架. 由于 Spark 基于内存设计,使得它拥有比 Hadoop 更高的性能(极端情况下可以达到 10 ...

随机推荐

  1. 苹果App Store开发者帐户从申请,验证,到发布应用(1)

    app store为开发者提供四种类型的申请: 个人ios开发者计划$99/年 公司ios开发者计划$99/年 企业ios开发者计划$299/年 高校ios开发者计划免费 在这里主要介绍一下公司ios ...

  2. IOS开发-UI学习-delegate(代理)的使用,键盘消失

    代理是IOS开发中用到的一种设计模式.今天做了一个代理的小练习: 以下项目实现了两个页面之间的相互切换,并且在切换页面的时候完成了从一个页面往另一个页面的传值.从主页面往其他页面传值是容易的,但是反过 ...

  3. 安卓组件service

    [转]http://blog.csdn.net/ithomer/article/details/7364024 一. Service简介 Service是android 系统中的四大组件之一(Acti ...

  4. UVa 573 - The Snail

    题目大意:有一只蜗牛位于深一个深度为h米的井底,它白天向上爬u米,晚上向下滑d米,由于疲劳原因,蜗牛白天爬的高度会比上一天少f%(总是相对于第一天),如果白天爬的高度小于0,那么这天它就不再向上爬,问 ...

  5. nlpir分词器过期处理

    nlpir分词器的非商业授权期限只有1个月,到期之后使用分词器在创建实例时就会提示授权到期,解决方法如下: 在nlpir发明者张教授的github页面下载对应的授权证书,地址在这. 将下载的证书覆盖分 ...

  6. Sublime Text3 使用手册

    1.标签页切换:ctrl+tab 2.Sublime Text3的配色方案(Preferences——配色方案)我选白色方案是:Eiffel;深色方案我选:Monokai 3.左边资源栏:先ctrl+ ...

  7. 环信 之 iOS 客户端集成三:基础功能

    SDK中,大部分与网络有关的操作,都有三种方法: 同步方法 通过delegate回调的异步方法.要想能收到回调,必须要注册为:[[EaseMob sharedInstance].chatManager ...

  8. mysql常用博客论坛

    大神博客: starive的博客:http://blog.itpub.net/26435490/viewspace-1133659/ 北在南方的博客:http://blog.itpub.net/226 ...

  9. 会话Cookie及session的关系(Cookie & Session)

    会话Cookie及session的关系(Cookie & Session) 在通常的使用中,我们只知道session信息是存放在服务器端,而cookie是存放在客户端.但服务器如何使用sess ...

  10. Spring mvc系列一之 Spring mvc简单配置

    Spring mvc系列一之 Spring mvc简单配置-引用 Spring MVC做为SpringFrameWork的后续产品,Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块 ...