1 Spark獲取json數據,並將json數據存hive庫
hive表建立Demo
--如果存在hive表,直接刪除這個hive表。
drop table if EXISTS tb_trade_info;
--創建hive表(第一次全量,後續增量)
CREATE TABLE IF NOT EXISTS tb_trade_info (
salesmanId VARCHAR(40) comment '發展業務員Id',
salesmanName VARCHAR(20) comment '發展店鋪的業務員名稱',
createDate bigint comment '交易訂單創建天,時間格式爲yyyyMMdd的integer值,分區時間'
)
partitioned by(pt_createDate integer comment '創建天,時間格式爲yyyyMMdd的integer值,分區時間')
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
hive視圖建立Demo
--- 交易客單價對應的視圖(第一次全量,後續增量)
DROP VIEW IF EXISTS trade_info_view;
CREATE VIEW IF NOT EXISTS trade_info_view
(
shopRegTime COMMENT '商戶註冊時間',
levelOne COMMENT '客單價 <10元',
pt_createDate COMMENT '創建天,時間格式爲yyyyMMdd的integer值,分區時間'
) COMMENT '客單價視圖'
AS
select
shopRegTime,
(case when (balanceFee + payFee) < 10.0 then 1 else 0 end) as levelOne,
pt_createDate
from
tb_trade_info;
按照某個字段分組降序,獲取最開始的第一條的hive視圖demo
-- 廣告主,流量主對應的 按照廣告發布時間進行控制
DROP VIEW IF EXISTS advert_flowofmain_view;
CREATE VIEW IF NOT EXISTS advert_flowofmain_view
(
shopId COMMENT '店鋪Id,主鍵唯一',
action COMMENT '動作類型:10,發佈廣告,20:流量任務(流量主)'
) COMMENT '廣告主、流量主數量統計視圖'
AS
select
t.shopId,
t.action
from
(
select
shopId,
action,
ROW_NUMBER() OVER(PARTITION BY advertId ORDER BY actionTime desc) AS rn
FROM
table_name
) t
where t.rn=1;
代碼示例:
import java.util.Date
import xxx.xxx.bigdata.common.utils.DateUtils
import org.apache.spark.sql.SparkSession
object TradeDataClean {
// def main(args: Array[String]): Unit = {
// val conf = new SparkConf().setAppName("TradeDataClean").setMaster("local")
// val sc = new SparkContext(conf)
// val input = sc.textFile("hdfs://bigdata1:9000/bplan/data-center/alitradelist.log.2018-06-21")
//
// input.collect().foreach(
// x => {
// println(x);
// val json = JSON.parseObject(x)
// println("====value====")
// println(json)
// println(json.getString("agentId"))
// }
// )
//
// sc.stop()
// }
/**
* 如果有參數,直接返回參數中的值,如果沒有默認是前一天的時間
* @param args :系統運行參數
* @param pattern :時間格式
* @return
*/
// def gainDayByArgsOrSysCreate(args: Array[String],pattern: String):String = {
// //如果有參數,直接返回參數中的值,如果沒有默認是前一天的時間
// if(args.length > 1) {
// args(1)
// } else {
// val previousDay = DateUtils.addOrMinusDay(new Date(), -1);
// DateUtils.dateFormat(previousDay, "yyyy-MM-dd");
// }
// }
/**
* args(0) :要處理的json文件路徑
* @param args
*/
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("TradeDataClean")
//.master("local[*]")
.config("spark.sql.warehouse.dir","/user/hive/warehouse")
//爲解決:Use the CROSS JOIN syntax to allow cartesian products between these relations
//.config("spark.sql.crossJoin.enabled",true)
//.config("spark.sql.warehouse.dir","hdfs://bigdata1:9000/user/hive/warehouse")
.enableHiveSupport()
.getOrCreate();
//val previousDayStr = gainDayByArgsOrSysCreate(args,"yyyy-MM-dd")
//val df = spark.read.json("/bplan/data-center/tradeInfo/"+ previousDayStr +"/tradeInfo.json")
val df = spark.read.json(args(0))
//val df = spark.read.json("hdfs://bigdata1:9000/xxx/xxx/xxxx")
spark.sql("use data_center")
df.createOrReplaceTempView("tb_trade_info_temp");
val previousDay = DateUtils.addOrMinusDay(new Date(), -1)
//val tmepRdd = rs.rdd.saveAsTextFile("hdfs://bigdata1:9000/bplan/data-center/temp.txt")
val pt_createDate = DateUtils.dateFormat(previousDay, "yyyyMMdd");
spark.sql("INSERT INTO TABLE tb_trade_info partition(pt_createDate=" + pt_createDate + ") " +
"SELECT " +
" ttit.agentId as agentId, " +
" from_unixtime(ttit.payTimeUnix,'yyyyMMdd') as createDate " +
"FROM " +
" tb_sys_industry si, " +
" tb_shop ts," +
" tb_trade_info_temp ttit " +
"WHERE " +
" si.category_id = ts.industryId " +
" and ts.shopId = ttit.shopId" +
" and ts.storeType != 10");
spark.stop()
}
}
spark處理數據入mysql數據庫:
package xxx.shop
import java.sql.{Connection, DriverManager, PreparedStatement}
import xxxx.common.utils.snowflake.SnowflakeUtils
import org.apache.spark.sql.SparkSession
object ShopExtDataClean {
// /**
// * 如果有參數,直接返回參數中的值,如果沒有默認是前一天的時間
// * @param args :系統運行參數
// * @param pattern :時間格式
// * @return
// */
// def gainDayByArgsOrSysCreate(args: Array[String],pattern: String):String = {
// //如果有參數,直接返回參數中的值,如果沒有默認是前一天的時間
// if(args.length > 1) {
// args(1)
// } else {
// val previousDay = DateUtils.addOrMinusDay(new Date(), -1);
// DateUtils.dateFormat(previousDay, "yyyy-MM-dd");
// }
// }
/**
* args(0) :json數據
* args(1) :mysql的ip地址
* args(2) :mysql數據庫的端口號
* args(3) :mysql數據庫用戶
* args(4) :mysql數據庫密碼
*
* @param args
*/
def main(args: Array[String]): Unit = {
val spark = SparkSession
.builder()
.appName("ShopDataClean")
//.master("local[*]")
.config("spark.sql.warehouse.dir", "/user/hive/warehouse")
.enableHiveSupport()
.getOrCreate();
// val previousDayStr = gainDayByArgsOrSysCreate(args,"yyyy-MM-dd")
//val df = spark.read.json("/bplan/data-center/shop/" + previousDayStr + "/shop.json");
val df = spark.read.json(args(0));
spark.sql("use data_center");
df.createOrReplaceTempView("shop_ext_temp")
val df2 = spark.sql("SELECT " +
" st.areaName as areaName, " +
" st.areaCode as areaCode, " +
" st.agentId as agentId, " +
" st.agentName as agentName, " +
" st.rootCategoryId as rootCategoryId, " +
" st.parentCategoryId as parentCategoryId, " +
" st.industryId as industryId, " +
" st.industryName as industryName, " +
" set.shopId as shopId, " +
" set.businessType as businessType, " +
" set.addTime as addTime, " +
" set.num as num " +
"FROM " +
" shop_ext_temp set left join tb_shop st " +
"ON " +
" set.shopId = st.shopId and st.storeType in(1, 20)")
//" set.shopId = st.shopId and st.storeType = 1 or st.storeType = 20")
// val previousDay = DateUtils.addOrMinusDay(new Date(), -1);
// //將臨時的數據存入到實際的tb_shop表中
// val pt_createDate = DateUtils.dateFormat(previousDay, "yyyyMMdd")
var conn: Connection = null;
var ps: PreparedStatement = null;
val sql = s"insert into tb_shop_ext(" +
s"id," +
s"area_name," +
s"area_code," +
s"agent_id," +
s"agent_name," +
s"root_category_id," +
s"parent_category_id," +
s"industry_id," +
s"industry_name," +
s"shop_id," +
s"business_type," +
s"add_time," +
s"num) " +
s"values (?,?,?,?,?,?,?,?,?,?,?,?,?)"
try {
Class.forName("com.mysql.jdbc.Driver")
conn = DriverManager.getConnection(s"jdbc:mysql://" + args(1) + ":" + args(2) + "/data_center", args(3), args(4))
ps = conn.prepareStatement(sql)
//關閉自動提交,即開啓事務
conn.setAutoCommit(false)
var i = 1;
df2.collect().foreach(
x => {
ps.setLong(1, SnowflakeUtils.getId)
ps.setString(2, x.get(0).toString)
ps.setString(3, x.get(1).toString)
ps.setString(4, x.get(2).toString)
ps.setString(5, x.get(3).toString)
ps.setString(6, x.get(4).toString)
ps.setString(7, x.get(5).toString)
ps.setString(8, x.get(6).toString)
ps.setString(9, x.get(7).toString)
ps.setString(10, x.get(8).toString)
ps.setInt(11, x.get(9).toString.toInt)
ps.setLong(12, x.get(10).toString.toLong)
ps.setInt(13, x.get(11).toString.toInt)
ps.addBatch()
i += 1;
if (i % 500 == 0) {
ps.executeBatch()
}
}
)
//最後不足500條的,直接執行批量更新操作
ps.executeBatch()
ps.close()
//執行完後,手動提交事務
conn.commit()
//再把自動提交打開
conn.setAutoCommit(true)
} catch {
case e: Exception => {
//先打印出異常
e.printStackTrace()
try {
//發生異常,事務回滾
if (conn != null && !conn.isClosed) {
conn.rollback()
conn.setAutoCommit(true)
}
} catch {
case ex: Exception => ex.printStackTrace()
}
}
} finally {
if (ps != null) {
try {
ps.close()
} catch {
//下面兩行等價 case e : Exception => e.printStackTrace()
//case e : ClassNotFoundException => e.printStackTrace()
//case e : SQLException => e.printStackTrace()
case e: Exception => e.printStackTrace()
}
}
if (conn != null) {
try {
conn.close()
} catch {
case ex: Exception => ex.printStackTrace()
}
}
}
spark.stop();
//程序正常退出
System.exit(0)
}
}
2 Shell腳本中下載json數據
自己定義的env的腳本:
env.sh
#!/bin/bash
#定義接口請求url地址
export webUrl='http://xxx/xxx/xxx/xxxx'
export backUpWebUrl='http://xxxx/xxxx/xxxx/xxxx'
#echo ${webUrl}
#設置默認的數據類型,默認下載全量數據
export dataType="full"
#昨天時間(時間格式類:2018-10-24)
export yesterday=`date --date='1 days ago' +%Y-%m-%d`
export today=`date +%Y-%m-%d`
#1周前數據(用於保留7天數據)
export aweekAgo=`date --date='7 days ago' +%Y-%m-%d`
export aweekAgoFolder=
#echo $yesterday
#oss中json的位置
export ossUrl="https://ossurl"
#當前路徑
export current=$PWD
#Spark運行所需的參數配置等信息
export sparkArgs="--jars /xxxx/apache-phoenix-4.14.1-HBase-1.4-bin/phoenix-spark-4.14.1-HBase-1.4.jar,/xxx/apache-phoenix-4.14.1-HBase-1.4-bin/phoenix-4.14.1-HBase-1.4-client.jar --master spark://xxxx:7077 --executor-memory 2g --total-executor-cores 6 --class "
#Spark程序所在位置
export programPrefixPath="/xxxx/program"
#kylin的參數
export kylinUserInfo="--user ADMIN:KYLIN"
export kylinCubeUrl="http://xxxx:7070/kylin/api/cubes/"
export kylinJobsUrl="http://xxxx:7070/kylin/api/jobs/"
export startTime="2015-01-01 00:00"
export startTimeTimeStamp=`date -d "$startTime" +%s`
export startTimeTimeStampMs=$(($startTimeTimeStamp * 1000))
export endTime=`date +%Y-%m-%d -d "+1days"`
export endTimeTimeStamp=`date -d "$endTime" +%s`
#將時間戳編程毫秒值
export endTimeTimeStampMs=$(($endTimeTimeStamp * 1000))
#phoenix對應的ZkUrl
#export phoenixZkUrl="jdbc:phoenix:ip地址:2181"
#########################################################
#3、訂單交易數據請求參數(第一次全量,後續增量)
#請求地址:curl -d "dataName=tradeInfo&dataType=full&dataTime=2018-10-23" http://xxxxx/oss/selectList
export tradeInfoArgs="dataName=tradeInfo&dataType=" #$dataType"&dataTime="$yesterday
#json的url信息存儲的文件路徑
export tradeInfoJsonUrls=$current/tmpfile/tradeInfoJsonUrls
#json的url存儲位置前綴
export tradeInfoJsonUrlPrefix=$current/tmpfile/tradeInfoJsonUrlPrefix
export tradeAnalyzeCubeName="tb_trade_analyze_cube"
export tradeCollectMoneyCubeName="tb_trade_collect_money_cube"
#用於存儲是否下載了的變量文件
export tradeInfoVariableFile=$current/tmpfile/tradeInfoVariableFile
#!/bin/bash
source /etc/profile
#求結果中的url路徑長度,如果是4,表示這裏的值是一個控制了(下面這兩行是等效的)
#urlLength=`echo ${urlInfo} |jq '.data.urls[1]' | awk '{print length($0)}'`
#urlLength=$(echo ${urlInfo} |jq '.data.urls[1]' | awk '{print length($0)}')
#echo $urlLength
#引用公共文件中定義的參數變量
source $PWD/env.sh
#定義變量
urlInfo=
#定義嘗試次數
retryTimes=1
#json數據所在的文件目錄(相對於腳本所在的相對路徑)
urlPrefix=
#Json數據文件存放的實際目錄
fileFolder=
#最新的數據下載位置
newUrlArgs=
#傳遞變量存儲的路徑的位置,返回當前當前數據類型
function resetArgs() {
#如果文件存在,讀取相應的數據類型
if [[ `ls $tradeInfoVariableFile | grep tradeInfoVariableFile | grep -v grep` != "" ]];then
#存在這個文件的時候,返回存儲在文件中的這個類型的值
#獲取數據類型,然後讀取出文件中dataType的值,將dataType=變成空值
dataType=`cat $tradeInfoVariableFile | grep dataType | sed 's/dataType=//g'`
newUrlArgs=$tradeInfoArgs$dataType"&dataTime="$yesterday
#並返回dataType
#return $dataType
else
mkdir -p $current/tmpfile
cd $current/tmpfile
#不存在這個文件的時候,返回0,並創建這個文件,將變量的類型的值寫入到文件中
#將數據類型寫入進去,表示後續都是按照增量的方式進行計算
echo "dataType=increment" > $tradeInfoVariableFile
newUrlArgs=$tradeInfoArgs"full&dataTime="$yesterday
#return "full"
fi
}
#獲取代理商和區域的數據json url地址信息
function getUrlInfo() {
resetArgs
echo $newUrlArgs
#獲取代理商的地址信息
urlInfo=`curl -d $newUrlArgs $webUrl`
}
#獲取url參數
#返回值
#1:請求url的結果爲200,且成功做了相關操作
#0:請求url的結果不爲爲200
function getUrlsArray() {
code=$(echo ${urlInfo} |jq '.code')
if [[ "$code" = 200 ]];then
echo "狀態碼爲200"
mkdir -p $current/tmpfile
#刪除上次生成的臨時的json url地址
rm -rf $tradeInfoJsonUrls
rm -rf $tradeInfoJsonUrlPrefix
touch $tradeInfoJsonUrls
touch $tradeInfoJsonUrlPrefix
dataInfo=$(echo ${urlInfo} |jq '.data')
if [[ $dataInfo == "" ]];then
return 1
fi
#獲取url的前綴
echo "===============開始獲取 json url 路徑前綴==========================="
echo ${urlInfo} |jq '.data.urlPrefix' > $tradeInfoJsonUrlPrefix
sed -i 's/"//g' $tradeInfoJsonUrlPrefix
echo "===============獲取 json url 路徑前綴結束==========================="
echo "===============開始獲取 json url ==================================="
#do while方式獲取url的列表,然後把結果存入新的數組中
#定義數組的角標
index=0
while :
do
#獲取url
url=$(echo ${urlInfo} |jq '.data.urls['$index']')
#查看字符串中是否有指定字符串
hasBplan=$(echo $url | grep "bplan/data-center")
#如果url中有bplan/data-center這樣的表示,將這些url存入到臨時文件中
if [[ "$hasBplan" != "" ]]
then
echo $url >> $tradeInfoJsonUrls
index=`expr $index + 1`
else
break
fi
done
#將文本中的所有的字符串中的引號去除掉
sed -i 's/"//g' $tradeInfoJsonUrls
echo "===============獲取 json url 成功==================================="
#如果最終成功,返回1
return 1
else
#如果沒有得到url的值,返回0,表示失敗
webUrl=$backUpWebUrl
return 0
fi
}
#如果獲取url的過程失敗,則一直失敗重試,直到程序被處理好了
function getUrlRetry() {
while :
do
echo "開始執行第${retryTimes}次任務,結果如下:"
#調用方法
getUrlInfo
getUrlsArray
#判斷本地執行是否成功
if [[ $? = 1 ]];then
echo "第${retryTimes}次執行之後,處理json數據成功了,接着處理後續任務"
break
else
echo "第${retryTimes}次執行程序失敗,休眠5分鐘後再次重試,知道144次之後停止"
#重試144次,即144 * 5 = 720min (半天)
if [[ "$retryTimes" -eq 144 ]];then
echo "已經執行了${retryTimes}次,程序達到預定次數,後續停止執行"
break
else
retryTimes=`expr $retryTimes + 1`
#休眠5分鐘
sleep 5m
#再次執行這個函數
fi
fi
#爲了讓打印的日誌顯示好看一些,空3行
echo ""
echo ""
echo ""
done
}
#1、獲取Json文件相對腳本的文件目錄(相對路徑)
#2、獲取Json數據文件在磁盤上的絕對路徑
function getJsonFolderPath() {
#查看指定文件是否存在
urlPrefix=`cat $tradeInfoJsonUrlPrefix`
#數據文件所在位置
fileFolder=$current$urlPrefix
}
#下載Json文件
function downloadJsons() {
#獲取到url路徑前綴
echo "開始下載Json文件"
#urlPrefix=`cat $tradeInfoJsonUrlPrefix`
#echo $current$urlPrefix
#最終下載的文件存放位置在下面
#fileFolder=$current$urlPrefix
getJsonFolderPath
if [[ $urlPrefix == "" ]];then
echo "當天沒有數據文件,直接返回"
return 0;
fi
mkdir -p $fileFolder
#刪除指定目錄下的文件,然後刪除
rm -rf $fileFolder/*
#進入$current$urlPrefix,開始循環下載json文件
cd $fileFolder
#開始循環文件,然後下載文件
for line in `cat $tradeInfoJsonUrls`
do
jsonOssPath=$ossUrl$line
echo $jsonOssPath
wget $jsonOssPath
echo "文件路徑:"$current$line
newPath=`echo $line |sed 's/_//g'`
mv $current$line $current$newPath
done
#修改替換文件中文件名稱
sed -i 's/_//g' $tradeInfoJsonUrls
echo "下載json文件結束"
}
#上傳json文件到HDFS中
function putJsonFile2Hdfs() {
#上傳數據文件到HDFS中
cd $current
getJsonFolderPath
if [[ $urlPrefix == "" ]];then
echo "當天沒有數據文件,直接返回"
return 0;
fi
echo "hdfs中的文件路徑"
echo $urlPrefix
hdfs dfs -rm -r $urlPrefix
hdfs dfs -mkdir -p $urlPrefix
#下面是上傳文件到hdfs中
for line in `cat $tradeInfoJsonUrls`
do
echo $current$line
#將文件上傳到指定的目錄中
hdfs dfs -put $current$line $urlPrefix
#上傳完成之後,刪除留在本地的Json文件
rm -rf $current$line
done
echo "上傳json文件到HDFS中完成"
}
#獲取數據json文件路徑,前綴等信息
getUrlRetry
#下載json數據到指定目錄
downloadJsons
#上傳數據文件到HDFS中
putJsonFile2Hdfs
#清理Linux系統中不用的垃圾暫用的內存
sync
echo 3 > /proc/sys/vm/drop_caches
3、Shell腳本中執行Spark程序
#!/bin/bash
source /etc/profile
#求結果中的url路徑長度,如果是4,表示這裏的值是一個控制了(下面這兩行是等效的)
#urlLength=`echo ${urlInfo} |jq '.data.urls[1]' | awk '{print length($0)}'`
#urlLength=$(echo ${urlInfo} |jq '.data.urls[1]' | awk '{print length($0)}')
#echo $urlLength
#引用公共文件中定義的參數變量
source $PWD/env.sh
#json數據所在的文件目錄(相對於腳本所在的相對路徑)
urlPrefix=
#Json數據文件存放的實際目錄
fileFolder=
#1、獲取Json文件相對腳本的文件目錄(相對路徑)
#2、獲取Json數據文件在磁盤上的絕對路徑
function getJsonFolderPath() {
#查看指定文件是否存在
urlPrefix=`cat $tradeInfoJsonUrlPrefix`
#數據文件所在位置
fileFolder=$current$urlPrefix
}
#是否執行過初始化程序了的控制邏輯
function isInited() {
#如果文件存在,讀取相應的數據類型
if [[ `ls $tradeInfoVariableFile | grep tradeInfoVariableFile | grep -v grep` != "" ]];then
dataType=`cat $tradeInfoVariableFile | grep sparkInited | sed 's/sparkInited=//g'`
#如果沒有,說明這個Spark程序還沒有初始化過
if [[ $dataType == "" ]];then
echo -e "\n" >> $tradeInfoVariableFile
echo "sparkInited=inited" >> $tradeInfoVariableFile
return 0;
else
return 1;
fi
else
mkdir -p $current/tmpfile
cd $current/tmpfile
#如果沒有這個文件,則是在這個文件中添加
echo "sparkInited=inited" > $tradeInfoVariableFile
return 0;
fi
}
function mergeFiles() {
#上傳數據文件到HDFS中
cd $current
getJsonFolderPath
isInited
if [[ $? == 1 ]];then
echo "開始合併小文件爲大文件"
hdfs dfs -getmerge $urlPrefix $PWD/tradeInfo
#刪除$urlPrefix 下的文件
hdfs dfs -rm $urlPrefix/*
#將文件上傳到指定的位置
hdfs dfs -put $PWD/tradeInfo $urlPrefix
echo $urlPrefix"tradeInfo" > $tradeInfoJsonUrls
echo "文件合併完成,並且已經將新文件路徑寫入文件"
rm -rf $PWD/tradeInfo
echo "刪除存儲在本地的文件"
fi
}
#Spark處理
function sparkHandler() {
#上傳數據文件到HDFS中
cd $current
getJsonFolderPath
if [[ $urlPrefix == "" ]];then
echo "當天沒有數據文件,直接返回"
return 0;
fi
isInited
if [[ $? == 0 ]];then
#由於是全量數據,在處理之前,刪除hive庫中的所有數據
echo '開始drop hive中的tb_trade_info表'
hive -e "
use data_center;
drop table if EXISTS tb_trade_info;
CREATE TABLE IF NOT EXISTS tb_trade_info (
createDate bigint comment '交易訂單創建天,時間格式爲yyyyMMdd的integer值,分區時間'
)
partitioned by(pt_createDate integer comment '創建天,時間格式爲yyyyMMdd的integer值,分區時間')
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
"
echo 'drop hive中的tb_trade_info表 完成'
fi
#下面是上傳文件到hdfs中
for line in `cat $tradeInfoJsonUrls`
do
#執行Spark程序來
echo $line
cd $SPARK_HOME
bin/spark-submit $sparkArgs xxx.xxx.xxx.xxx.xxx.TradeDataClean $programPrefixPath/trade-info/trade-info-1.0.1-SNAPSHOT.jar $line
done
echo "完成執行Spark程序"
}
mergeFiles
#上傳數據文件到HDFS中
sparkHandler
#清理Linux系統中不用的垃圾暫用的內存
sync
echo 3 > /proc/sys/vm/drop_caches
4 Shell腳本中執行kylin restapi讓kylin任務執行
env.sh 內容:
#!/bin/bash
#kylin的參數
export kylinUserInfo="--user ADMIN:KYLIN"
export kylinCubeUrl="http://xxx:7070/kylin/api/cubes/"
export kylinJobsUrl="http://xxxx:7070/kylin/api/jobs/"
export startTime="2015-01-01 00:00"
export startTimeTimeStamp=`date -d "$startTime" +%s`
export startTimeTimeStampMs=$(($startTimeTimeStamp * 1000))
export endTime=`date +%Y-%m-%d -d "+1days"`
export endTimeTimeStamp=`date -d "$endTime" +%s`
#將時間戳編程毫秒值
export endTimeTimeStampMs=$(($endTimeTimeStamp * 1000))
export tradeInfoArgs="dataName=tradeInfo&dataType=" #$dataType"&dataTime="$yesterday
#json的url信息存儲的文件路徑
export tradeInfoJsonUrls=$current/tmpfile/tradeInfoJsonUrls
#json的url存儲位置前綴
export tradeInfoJsonUrlPrefix=$current/tmpfile/tradeInfoJsonUrlPrefix
export tradeAnalyzeCubeName="xxxx"
export tradeCollectMoneyCubeName="xxxx"
#用於存儲是否下載了的變量文件
export tradeInfoVariableFile=$current/tmpfile/tradeInfoVariableFile
#!/bin/bash
source /etc/profile
#引用公共文件中定義的參數變量
source $PWD/env.sh
jobId=
#是否執行過初始化程序了的控制邏輯
function isInited() {
#如果文件存在,讀取相應的數據類型
if [[ `ls $tradeInfoVariableFile | grep tradeInfoVariableFile | grep -v grep` != "" ]];then
dataType=`cat $tradeInfoVariableFile | grep kylinTradeAnalyzeCubeInited | sed 's/kylinTradeAnalyzeCubeInited=//g'`
#如果沒有,說明這個Spark程序還沒有初始化過
if [[ $dataType == "" ]];then
echo -e "\n" >> $tradeInfoVariableFile
echo "kylinTradeAnalyzeCubeInited=inited" >> $tradeInfoVariableFile
return 0;
else
return 1;
fi
else
mkdir -p $current/tmpfile
cd $current/tmpfile
#如果沒有這個文件,則是在這個文件中添加
echo "kylinTradeAnalyzeCubeInited=inited" > $tradeInfoVariableFile
return 0;
fi
}
#Spark處理
function kylinHandler() {
isInited
if [[ $? == 0 ]];then
#上傳數據文件到HDFS中
cd $current
#1、Disable Cube
curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/disable
echo ""
echo ""
#2、Purge Cube
curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/purge
echo ""
echo ""
#3、Enable Cube
curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/enable
echo ""
echo ""
#4、Build cube
cubeBuildInfo=`curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" -d '{ "startTime":'$startTimeTimeStampMs',"endTime":'$endTimeTimeStampMs', "buildType": "BUILD"}' $kylinCubeUrl$tradeAnalyzeCubeName/build`
echo ""
echo ""
else
cubeBuildInfo=`curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" -d '{"endTime":'$endTimeTimeStampMs', "buildType": "BUILD"}' $kylinCubeUrl$tradeAnalyzeCubeName/rebuild`
echo ""
echo ""
fi
echo "cube build的狀態結果:"
echo $cubeBuildInfo
echo ""
echo ""
#查看是否build好了,如果build好了,發現last_build_time變成了build的最後時間了。
jobId=$(echo $cubeBuildInfo |jq '.uuid')
echo $jobId > $jobId
sed -i 's/"//g' $jobId
realJobId=`cat $jobId`
echo $realJobId
rm -rf $jobId
echo ""
echo ""
while :
do
sleep 1m
cubeJobInfo=`curl -X GET --user ADMIN:KYLIN $kylinJobsUrl$realJobId`
echo "獲取cube job運行的狀態"
echo $cubeJobInfo
echo ""
echo ""
jobStatus=$(echo $cubeJobInfo | jq ".job_status")
echo "jobStatus"
echo $jobStatus > $realJobId
sed -i 's/"//g' $realJobId
realJobStatus=`cat $realJobId`
echo "$realJobStatus"
echo ""
if [[ $realJobStatus == "NEW" ]];then
echo "kylin cube build job status:NEW; sleep 1m;"
elif [[ $realJobStatus == "PENDING" ]];then
echo "kylin cube build job status:PENDING; sleep 1m;"
elif [[ $realJobStatus == "RUNNING" ]];then
echo "kylin cube build job status:RUNNING; sleep 1m;"
elif [[ $realJobStatus == "STOPPED" ]];then
echo "kylin cube build job status:STOPPED"
#如果stop了,停掉kylin腳本的運行
break;
elif [[ $realJobStatus == "FINISHED" ]];then
echo "kylin cube build job status:FINISHED"
break;
elif [[ $realJobStatus == "ERROR" ]];then
echo "kylin cube build job status:ERROR"
break;
elif [[ $realJobStatus == "DISCARDED" ]];then
echo "kylin cube build job status:DISCARDED"
break;
else
echo "kylin cube build job status:OTHER UNKNOWN STATUS"
break;
fi
done
#刪除文件
rm -rf $realJobId
}
#上傳數據文件到HDFS中
kylinHandler
#清理Linux系統中不用的垃圾暫用的內存
sync
echo 3 > /proc/sys/vm/drop_caches
5 編寫Azkaban的job
目的:編寫一個類似下面圖能夠並行執行任務,串行往下執行任務,最終到一個結束任務。
最頂層的一個job腳本
#jsonHandler-all.job
type=command
command=sh /xxx/jsonHandler-all.sh
對於下面一行並行的任務,其中的一個的寫法如下:
#sparkHandler-advertiserFlowofmain
type=command
dependencies=sparkHandler-shop
command=sh /xxxx/sparkHandler-advertiserFlowofmain.sh
注意上面的dependencies,這種寫法之後,在上面的那種圖中,這個job上只有一個sparkHandler-shop相關的任務
對於最底層的那個任務,需要依賴上面的多個任務的名稱,類似如下:
#sparkHandler-tradeInfo
type=command
dependencies=sparkHandler-couponCard,sparkHandler-memberCard
command=sh /data/workspace/bplan-data-center-job/sparkHandler-tradeInfo.sh
這個寫完之後,在sparkHandler-tradeInfo的上面就會存在2個任務job,分別是:sparkHandler-couponCard,sparkHandler-memberCard。sparkHandler-tradeInfo會在最底層。