Spark读HBase写MySQL
1 Spark读HBase
Spark读HBase黑名单数据,过滤出当日新增userid,并与mysql黑名单表内userid去重后,写入mysql。
def main(args: Array[String]): Unit = {
@volatile var broadcastMysqlUserids: Broadcast[Array[String]] = null
val today = args(0)
val sourceHBaseTable = PropertiesUtil.getProperty("anticheat.blacklist.hbase.tbale")
val sinkMysqlTable = PropertiesUtil.getProperty("anticheat.blacklist.mysql.dbtable")
val zookeeper = PropertiesUtil.getProperty("anticheat.blacklist.zookeeper.quorum")
val zkport = PropertiesUtil.getProperty("anticheat.blacklist.zookeeper.port")
val znode = PropertiesUtil.getProperty("anticheat.blacklist.zookeeper.znode")
//创建SparkSession
val sparkconf = new SparkConf().setAppName("").set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
val sc = new SparkContext(sparkconf)
val spark = AnticheatUtil.SparkSessionSingleton.getInstance(sc.getConf)
//配置hbase参数
val conf = HBaseConfiguration.create
conf.set("hbase.zookeeper.quorum", zookeeper)
conf.set("hbase.zookeeper.property.clientPort", zkport)
conf.set("zookeeper.znode.parent", znode)
conf.set(TableInputFormat.INPUT_TABLE, sourceHBaseTable)
// 从数据源获取数据
val hbaseRDD = sc.newAPIHadoopRDD(conf,classOf[TableInputFormat],classOf[ImmutableBytesWritable],classOf[Result])
//读取mysql表,并将mysql表中的userid广播出去,用于去重
broadcastMysqlUserids = get_mysql_user_blacklist(spark,sinkMysqlTable)
//获取当日新增userid数据组装成与mysql表结构一致的对象rdd
val records_userid_rdd = get_new_blacklist_rdd(hbaseRDD,today,broadcastMysqlUserids)
//将当日新增userid数据存入mysql
save_blacklist_to_mysql(records_userid_rdd,today,spark,sinkMysqlTable)
}
2 Spark读MySQL表广播出去
/**
* Spark读Mysql用户黑名单表,将黑名单中所有userid赋予广播变量
* @param spark
* @return
*/
def get_mysql_user_blacklist(spark: SparkSession,table :String) :Broadcast[Array[String]] = {
@volatile var broadcastMysqlUserids: Broadcast[Array[String]] = null
val url = PropertiesUtil.getProperty("anticheat.blacklist.mysql.url")
val user = PropertiesUtil.getProperty("anticheat.blacklist.mysql.user")
val password = PropertiesUtil.getProperty("anticheat.blacklist.mysql.password")
import spark.implicits._
val mysql_userids_rdd = spark.sqlContext.read
.format("jdbc")
.option("url",url)
.option("dbtable",table)
.option("user",user)
.option("password",password)
.load()
.map(record => {
val userid = record.getString(0)
userid
})
if(broadcastMysqlUserids !=null){
broadcastMysqlUserids.unpersist()
}
broadcastMysqlUserids = spark.sparkContext.broadcast(mysql_userids_rdd.collect())
println(s"broadcastMysqlUserids.size= ${broadcastMysqlUserids.value.size}")
broadcastMysqlUserids
}
3 构建黑名单数据对象rdd
/**
* 构建新增userid数据写入mysql
* @param hbaseRDD
* @param today
* @return
*/
def get_new_blacklist_rdd(hbaseRDD: RDD[(ImmutableBytesWritable, Result)],today: String,broadcastMysqlUserids: Broadcast[Array[String]]): RDD[BlackList] = {
val records_userid_rdd : RDD[BlackList] = hbaseRDD.filter(line =>{
//过滤出当日新增userid
var flag = false //默认非当日新增
val userid = Bytes.toString(line._2.getRow)
val dt = Bytes.toString(line._2.getValue(Bytes.toBytes("user"), Bytes.toBytes("dt")))
val did_dt = Bytes.toString(line._2.getValue(Bytes.toBytes("user"), Bytes.toBytes("did_dt")))
/* 判断为当日新增userid同时需满足三个条件:
1. 用户维度加入时间dt=today
2. 或者用户维度加入时间dt=null 且设备维度加入时间did_dt=today
3. 并且不在mysql黑名单表中
*/
if(today.equals(dt) || (dt==null && today.equals(did_dt))){
//broadcastMysqlUserids.value.search(userid).isInstanceOf[InsertionPoint]调用scala 二分查找函数,注意此函数找到返回false
if(broadcastMysqlUserids.value.search(userid).isInstanceOf[InsertionPoint]){
//以上三个条件全满足,表示为当日新增,flag 赋值为 true
flag = true
}
}
flag
}).map(record =>{
//获取新增用户userid,加入黑名单时间设为today,其余字段设为默认值
val userid = Bytes.toString(record._2.getRow)
val day = Integer.parseInt(today)
BlackList(userid,day,null,0,"system")
})
records_userid_rdd
}
case class BlackList(userid: String, dt: Int, update_time: Timestamp,delete_flag: Int,operator : String)
4 Spark写MySQL
/**
* 将userid黑名单数据写入mysql
* @param blacklist_rdd
* @param today
* @param spark
*/
def save_blacklist_to_mysql(blacklist_rdd: RDD[BlackList],today: String,spark: SparkSession,table :String): Unit ={
val url = PropertiesUtil.getProperty("anticheat.blacklist.mysql.url")
val user = PropertiesUtil.getProperty("anticheat.blacklist.mysql.user")
val password = PropertiesUtil.getProperty("anticheat.blacklist.mysql.password")
import spark.implicits._
val records_userid_dataset = blacklist_rdd.toDS()
records_userid_dataset.write
.format("jdbc")
.option("url",url)
.option("dbtable",table)
.option("user",user)
.option("password",password)
.mode(SaveMode.Append)
.save()
}
5 注意问题
数据存入Mysql注意事项
尽量先设置好存储模式
默认为SaveMode.ErrorIfExists模式,该模式下,如果数据库中已经存在该表,则会直接报异常,导致数据不能存入数据库.另外三种模式如下:
SaveMode.Append 如果表已经存在,则追加在该表中;若该表不存在,则会先创建表,再插入数据;
SaveMode.Overwrite 重写模式,其实质是先将已有的表及其数据全都删除,再重新创建该表,最后插入新的数据;
SaveMode.Ignore 若表不存在,则创建表,并存入数据;在表存在的情况下,直接跳过数据的存储,不会报错。

Spark读HBase写MySQL的更多相关文章
- spark读文件写mysql(java版)
package org.langtong.sparkdemo; import com.fasterxml.jackson.databind.ObjectMapper; import org.apach ...
- IDEA中Spark读Hbase中的数据
import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.io.ImmutableBytesWr ...
- IDEA中 Spark 读Hbase 报错处理:
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] // :: ERROR RecoverableZooKeepe ...
- Spark读Hbase优化 --手动划分region提高并行数
一. Hbase的region 我们先简单介绍下Hbase的架构和Hbase的region: 从物理集群的角度看,Hbase集群中,由一个Hmaster管理多个HRegionServer,其中每个HR ...
- Spark 读 Hbase
package com.grady import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.c ...
- spark读文件写入mysql(scala版本)
package com.zjlantone.hive import java.util.Properties import com.zjlantone.hive.SparkOperaterHive.s ...
- 用MapReduce读HBase写MongoDB样例
1.版本信息: Hadoop版本:2.7.1 HBase版本:1.2.1 MongDB版本:3.4.14 2.HBase表名及数据: 3.Maven依赖: <dependency> < ...
- spark sql读hbase
项目背景 spark sql读hbase据说官网如今在写,但还没稳定,所以我基于hbase-rdd这个项目进行了一个封装,当中会区分是否为2进制,假设是就在配置文件里指定为#b,如long#b,还实用 ...
- Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作
Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作 1.sparkstreaming实时写入Hbase(saveAsNewAPIHadoopDataset方法 ...
随机推荐
- 当你的layui表格要做全选+删除功能【兼容ie8】
<!-- 全选 --> <div class="choose"> <input type="checkbox" id=" ...
- js判重
1.两个数组,取出不重复的部分 var arr=[1,2,3]; var arr1=[1,2]; vat tmp=[]; for(let i in arr1){ if(!(arr.includes(a ...
- Linux上文件恢复工具
文件恢复工具extundelete官网:http://extundelete.sourceforge.net/ 使用方法,在页面里找到download,下载源码安装包:extundelete-0.2. ...
- 运用jieba库 寻找高频词
一.准备 1.首先 先用cmd 安装 jieba库,输入 pip install jieba 2.其次 本次要用到wordcloud库和 matplotlib库,也在cmd输入pip install ...
- C# MethodInvoker委托的使用
一.MethodInvoker是什么? MethodInvoker 表示一个委托,该委托可以执行托管代码中声明为void且不接受任何参数的任何方法.在对控件的 invoke 方法进行调用时或需要一个简 ...
- linux常用命令 命令管道符
多命令顺序执行 多命令顺序执行 多命令执行符 格式 作用 : 命令1:命令2 多个命令顺序执行,命令之间没有任何逻辑联系 && 命令1&&命令2 逻辑与 当命令1正确执 ...
- freemarker导出word档
1.word另存为xml:2.xml文件后缀名改成ftl:3.编写完整json字符串备用:4.修改ftl中动态字段为json中对应字段名:5.编写java代码自动生成word文件:(注意:换行用< ...
- c迭代器与生成器
一:迭代器 1.什么是迭代? 1.重复 2.下一次重复是基于上一次的结果 # l=['a','b','c','d'] # count= # while count < len(l): # p ...
- devexpress—WPF
https://docs.devexpress.com/WPF/7875/index Ocelot 资源汇总 https://www.cnblogs.com/shanyou/p/10363360.ht ...
- MySQL · 性能优化· 5.7.6 InnoDB page flush 优化
在这篇文中,我们已经详细介绍了Oracle MySQL以及社区分支最新的对InnoDB page flush的优化.在最近release的5.7.6版本中又有了进一步的改进.主要包括以下几点修改 修改 ...