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. 微信和QQ内置浏览器为什么老是弹停止访问该网页,微信域名被屏蔽的解决办法

    近来很多商家开始重视域名防封的技术了,为什么呢,因为实在是封怕了.三天两头就得去换域名,换域名是小事,用户流失就是大事了,直接跟利益挂钩的.那么域名防封技术究竟有多重要呢?又该如何实现域名防封呢?下面 ...

  2. 20175212 《Java程序设计》第2周学习总结

    学号 20175212 <Java程序设计>第2周学习总结 教材学习内容总结 1.数据类型 此节介绍的数据类型与C中常用的相比仅多了Boolean(逻辑类型).byte(取值范围:[-12 ...

  3. wifi rate vs mode

  4. 微信或QQ屏蔽域名,爆红域名如何在微信打开,如何进行微信域名防封?

    近很多朋友都会遇到这个问题,为什么我的微信域名或者QQ域名怎么总是提示拦截呢?在这里跟大家说一下吧: 第一点:就是域名里面的内容违规或者诱导被举报而导致的拦截 第二点:就是被用户或者同行恶意举报而导致 ...

  5. HTML、CSS(小笔记)

    这是我自己在学习html.css时觉得要记的东西太多总结一些较为常用的标签. HTML <p></p>段落标签 <hn></hn>标题标签n数值为1~6 ...

  6. Divisor Subtraction

    Description You are given an integer number nn. The following algorithm is applied to it: if n=0, th ...

  7. luogu1706全排列

    #include<bits/stdc++.h> using namespace std; +]; +]; int search(int k); int print(); int n,num ...

  8. DBUtils——handler

    ArrayHandler: 把结果集中的第一行数据转成对象数组. ArrayListHandler: 把结果集中的每一行数据都转成一个对象数组,再存放到List中. BeanHandler: 将结果集 ...

  9. 关注Yumiot公众号,了解最新的物联网资讯

    Yumiot,专注于物联网行业,每天不定期推送最新的物联网行业新闻.详情请用微信搜索关注  yumiot  .

  10. 浅谈Vector、ArrayList、LinkedList

    下图是Collection的类继承图 从图中可以看出:Vector.ArrayList.LinkedList这三者都实现了List 接口.所有使用方式也很相似,主要区别在于实现方式的不同,所以对不同的 ...