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的更多相关文章

  1. spark读文件写mysql(java版)

    package org.langtong.sparkdemo; import com.fasterxml.jackson.databind.ObjectMapper; import org.apach ...

  2. IDEA中Spark读Hbase中的数据

    import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.io.ImmutableBytesWr ...

  3. IDEA中 Spark 读Hbase 报错处理:

    SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory] // :: ERROR RecoverableZooKeepe ...

  4. Spark读Hbase优化 --手动划分region提高并行数

    一. Hbase的region 我们先简单介绍下Hbase的架构和Hbase的region: 从物理集群的角度看,Hbase集群中,由一个Hmaster管理多个HRegionServer,其中每个HR ...

  5. Spark 读 Hbase

    package com.grady import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.c ...

  6. spark读文件写入mysql(scala版本)

    package com.zjlantone.hive import java.util.Properties import com.zjlantone.hive.SparkOperaterHive.s ...

  7. 用MapReduce读HBase写MongoDB样例

    1.版本信息: Hadoop版本:2.7.1 HBase版本:1.2.1 MongDB版本:3.4.14 2.HBase表名及数据: 3.Maven依赖: <dependency> < ...

  8. spark sql读hbase

    项目背景 spark sql读hbase据说官网如今在写,但还没稳定,所以我基于hbase-rdd这个项目进行了一个封装,当中会区分是否为2进制,假设是就在配置文件里指定为#b,如long#b,还实用 ...

  9. Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作

    Spark-读写HBase,SparkStreaming操作,Spark的HBase相关操作 1.sparkstreaming实时写入Hbase(saveAsNewAPIHadoopDataset方法 ...

随机推荐

  1. 学号 20175212 《Java程序设计》第3周学习总结

    学号 20175212 <Java程序设计>第3周学习总结 教材学习内容总结 一. Java--面向对象语言 核心内容为对象,一切围绕着对象.以下为三个重要性质: 封装性:将数据和对数据的 ...

  2. PDF 补丁丁 0.6.0.3355 版发布(修复阅读模式、书签缩放的问题)

    PDF补丁丁的新版本修复了染色阅读模式失效.编辑器书签缩放比例调整在某些场合下失败的问题.

  3. eclipse光标变粗解决方法

    如上图,光标变成黑块好像没那么顺眼,原因是我们不小心按到了insert键造成的,再按一下insert键就OK了,如果delete和insert是一个键那么就用FN键+delete/insert键就可以 ...

  4. React 的坑

    MemoryRouter 会缓存组件,导致有时候 componentDidMount 不会执行

  5. 开发一个简单的chrome插件-解析本地markdown文件

    准备软件环境 1. 软件环境 首先,需要使用到的软件和工具环境如下: 一个最新的chrome浏览器 编辑器vscode 2. 使用的js库 代码高亮库:prismjs https://prismjs. ...

  6. How to convert Word table into Excel using OpenXML

    原文出处:https://code.msdn.microsoft.com/How-to-convert-Word-table-0cb4c9c3 class Program { static void ...

  7. String.split()方法

    如果用“(”作为分隔的话,必须是如下写法,String.split("\\("),这样才能正确的分隔开,不能用String.split("("); 如果用“)” ...

  8. 对低开销的静态组件使用v-once

    <body> <div id="app"> <terms-of-service></terms-of-service> </d ...

  9. Mysql 存储过程查询结果赋值到变量的方法

    drop table if exists test_tbl; create table test_tbl (name varchar(20), status int(2)); insert into ...

  10. vim详解

    vim介绍: 1.vim是vi的升级版本 2.vim是带有颜色显示的 3.vim三个模式:一般模式.编辑模式.命令模式 最小化模式下默认是没有安装vim的: [root@linux-xl ~]# yu ...