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方法 ...
随机推荐
- hive -- 分区,分桶(创建,修改,删除)
hive -- 分区,分桶(创建,修改,删除) 分区: 静态创建分区: 1. 数据: john doe 10000.0 mary smith 8000.0 todd jones 7000.0 boss ...
- Python列表操作集合
对于python列表里元素的操作主要分为以下几个方面: 1.向列表里面加元素: 向python列表里面添加元素主要有三种方法: (1)append() append()对于列表的操作主要实现的是在特定 ...
- MSSQL转Mysql常用函数,语法等
MSSQL转Mysql常用 一.字段类型 MSSQL Mysql 备注 "nchar" "char()" 最大长度为255 "nvarchar&quo ...
- 004dayPython学习输入并输出用户名和密码
在python 2.7中,捕获用户输入用raw_input 一.捕获并打印用户名和密码 要求: 输入用户名和密码都可见 # -*- coding:utf-8 -*-userName = raw_inp ...
- L1-062 幸运彩票
彩票的号码有 6 位数字,若一张彩票的前 3 位上的数之和等于后 3 位上的数之和,则称这张彩票是幸运的.本题就请你判断给定的彩票是不是幸运的. 输入格式: 输入在第一行中给出一个正整数 N(≤ 10 ...
- MIME 参考手册
本文摘自http://www.w3school.com.cn/media/media_mimeref.asp MIME (Multipurpose Internet Mail Extensions) ...
- 【转】QT 添加外部库文件
转自:Qt 添加外部库文件 LIBS += D:\Code\Opengltest\OpenGL32.Lib D:\Code\Opengltest\GlU32.Lib # 直接加绝对路径 LIBS += ...
- 原生js实现下拉菜单
简单给两段代码: html和css部分: <style> .one li{ width:100px; height:30px; line-height:30px; background:u ...
- Window下,利用Anaconda2创建jupyter-notebook的python3环境方法
随着深度学习的火热,越来越多的人去学习和了解这门技术.而做算法的同学为了能够更快,更高效的写出相关的深度学习算法出来,需要比较方便的开发环境.今天主要介绍一下在jupyter notebook中,新增 ...
- react native获取组件高度,宽 度等
import React,{Component} from 'react'import { View, Text, Image, StyleSheet, TouchableHighlight, Tou ...