spark-streaming任務提交遇到的坑
一、背景
基本所有公司互聯網公司都會有離線和實時任務,達到實時的目的手段據個人了解有storm、spark-streaming、flink。今天來探討一下spark-streaming任務的開發到上線過程中遇到的問題。
公司領導最近提了一個實時展示用戶、產品各方面統計數據的需求,對於數據埋點需要有一套針對性的計劃。因此需要我們大數據平臺對數據進行實時接收、清洗、導入....的內容。詳細內容不再介紹。下面介紹在開發中spark on yarn遇到的坑。
二、代碼坑
1.maven項目中,resource目錄是一個classpath目錄,配置文件所在地
通過ConfigFactory.load("application.properties")來獲取
logger = LoggerFactory.getLogger(this.getClass)來獲取logger
2.case class樣例類
特點有:不用new;toString漂亮;實現了hashcode和equal;可用case匹配;默認可序列化等
所以如果只是用來保存一個具有多個屬性的對象,那再好不過了
3.結果批量插入batch
conn.setAutoCommit(false)
一個循環ps.addBatch()
一個ps.executeBatch()
conn.commit()
註意,insert update delete操作不能用executeQuery(),只能是select是query
4.數據庫連接池
雖然設置上都差不多,但是實現上還需要更加格式化的代碼,每次調用,都是先獲取連接池,再獲取connection
5.StreamingContext中含有SparkContext函數來獲取sc,所以不用再去創建sc
但是需要註意,在整個spark代碼中無論是sc還是ssc還是sqlContext都不能調用.stop()方法,不然會中值進程
註意:別忘了調用ssc.start()
6.動態創建對象
Class.forName().newInstance().asInstanceOf[]通過這種方式可以有選擇的創建對應的類的對象
7.rdd.collect()
返回的是一個數組Array,註意:rdd的lazy性質
8.@volatile
該註解表示該變量的修改代碼不能被進行執行順序優化,以及修改引用即時性,但是不保證同步安全性。同步的三個特性保證兩個,安全性實際上並不需要,因為@volatile的目的是我修改你即時查看,並不是多線程多並發的共同修改
9.Option[Type]
功能太強大,Option的子類有Some()和None,表示盡可能返回給你你想要的,如果存在那麽結果就在Some(....)中的....。...就是結果,如果不存在就返回None,所以很多時候的用法是匹配:
def show(x: Option[String]) = x match {
case Some(s) => s
case None => "?"
}
存在的話怎麽樣,不存在的話怎麽樣
11.正則方法
"""(\d+\.\d+\.\d+\.\d+).*?logger.php\?(.*?) HTTP.*""".r,用””.r表示正則對象
也可以用 new Regex(....)的方法
有方法如下findAllIn;findFirstIn;findPrefixOf;replaceFirstIn,replaceAllIn.
我想說的是另外一個關於分組的問題()
python中是.group(index)
scala中是直接val regexobject(變量1,變量2,...) = “字符串”
其中變量1 2就是正則中()所包含的分組
val logRegex(ip, query) = logStr這個例子就是吧logStr用logRegex匹配,把(\d+\.\d+\.\d+\.\d+)作為ip變量的值,把(.*?)作為query變量的值。,一口氣定義並初始化兩個變量
三、分布式任務的坑
1.簽名問題
引入的各種包存在簽名,當submit執行的時候會不信任!!!,所以需要刪除jar包中的文件zip -d ***.jar ‘META-INF/*DSA‘ ‘META-INF/*.RSA‘ ‘META-INF/*SF‘
2.讀取文件問題
在程序中除了配置文件還有一個文件用來把ip解析成城市信息,但是每次提交上去之後發現讀取這個文件失敗,根本找不到這個文件,但是jar包中確實是存在的!!!
這就是一個分布式運行的問題,如果在本地沒問題,放在classpath中或者絕對路徑都可以,此時說一下到底那些代碼是是appmaster中執行,那些代碼在worker中執行。
appmaster:main中開始到rdd操作之前
worker:從rdd操作開始到結束
可以看出,我們最好是把需要共享的信息在rdd操作之前讀入然後傳入rdd的應用函數參數中
3.數據共享、變量共享
當然這個問題的根本原因還是appmaster和worker的分布式運行原因。
問題一:object和class的問題,object是一個靜態的東西,可以人為object在每臺機器上都是一個對象,而且各不相同!一定要註意,但是如果我們在appmaster中創建一個class的對象,在worker中調用這個對象的屬性,那麽這個屬性不是多個,而是唯一的一個!!!!!!!!!!!!!!!!!!!!!!!!!!!
所以我們不能通過在object中定義大家都需要的變量!
問題二:序列化問題。當我使用class來共享數據以及變量的時候,報錯task can not seriablzable.........,問題在於serializable的class條件是類中的類變量都是可以序列化的!!!!請自行檢查。
本文僅僅是列出了出現的問題以及解決辦法,具體問題的詳細解析後續文章中介紹。
參考鏈接:
https://www.cnblogs.com/dolphin0520/p/3920373.html
spark-streaming任務提交遇到的坑