hive表,hive視圖,spark處理數據入mysql,shell獲取url數據下載json,Spark sql處理json,shell腳本執行kylin,azkaban任務調度

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會在最底層。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章