
以前的定時任務(wù)都是使用 for循環(huán)加 sleep ,這種偽裝的定時任務(wù) 有很大的局限性,為了 更好的使用數(shù)據(jù)流傳輸 到 hdfs,我們在不借助工具的前提下 使用 scp expect hadoop 等多個linux非原生的 命令組合的腳本 完成了 數(shù)據(jù)的傳輸,當然為了實現(xiàn)自動化傳輸 ,必須借助 linux的 crontab 定時任務(wù) 組件命令 在執(zhí)行腳本,
腳本的執(zhí)行有 按天 執(zhí)行 按小時執(zhí)行 ,未來也會有按周或者 按月執(zhí)行的。
在使用crontab 我也遇到了一些問題,當然這些問題 有crontab自身的小bug,和對 crontab應用不熟悉造成的,做一個小的流水賬記錄一下
1.定時任務(wù) 是和 linux的用戶綁定的,root 設(shè)置的定時任務(wù) 只有 root 用戶才可以執(zhí)行設(shè)置和切換到root 用戶才能查看,其他用戶設(shè)置的定時任務(wù)也只有本用戶自己可以執(zhí)行設(shè)置和查看,要使用哪個用戶執(zhí)行 要心中有數(shù) ,使用 crontab -e ,設(shè)置定時任務(wù)
2.使用定時任務(wù)要執(zhí)行的腳本 需要 修改其權(quán)限,使之 有權(quán)限執(zhí)行腳本
chmod 777 *.sh
3.首先 crontab 的配置文件 /etc/crontab 的環(huán)境變量 和 root 用戶下/etc/profile 、 普通用戶 下 ~/.bashrc不共通的,這也是造成 為什么在shell 中直接執(zhí)行沒有問題,但是到crontab 就無法執(zhí)行 或根本沒有執(zhí)行,或者執(zhí)行出錯,比如 就 scp expect hadoop 這些命令 crontab 的環(huán)境變量是沒有的,不可能識別,為了 被識別 可以通過兩種方式
1.全局修改 全局生效 在 crontab的配置文件 把 環(huán)境變量補充到和 /etc/profile 、 普通用戶 下 ~/.bashrc 一致的PATH 變量,一般 缺少 /usr/local/bin /usr/local/sbin ,然后把 一些 特殊的 命令 比如 scp 和except 找到他們的執(zhí)行全路徑
which scp
which except
把得到的全路徑 以 alias 形式 寫入到 /etc/crontab中 即可
比如 scp=/usr/bin/scp
這樣就可以執(zhí)行 scp 命令
- 局部修改 局部起效 ,把要執(zhí)行的 命令的全路徑在 你要執(zhí)行的腳本中 做一下聲明 ,就可以直接使用 ,比如
聲明:
HADOOP=/usr/local/hadoop/bin/hadoop
我在使用時 就是
$HADOOP fs -put ./* /pathdir
4.另外就是 定時任務(wù)設(shè)定的時間,以前總聽 大家講按天 執(zhí)行 腳本的定時任務(wù)都是設(shè)置在后半夜 凌晨兩三點的,這樣做能盡可能的不影響線上業(yè)務(wù) ,得到的信息可能也是比較容易計算 的不會多少。可是我剛開始也這么做了,結(jié)果沒有拿到數(shù)據(jù),我不知道為什么,還以為是腳本沒被執(zhí)行或者執(zhí)行錯誤,但最后通過觀察 源文件目錄的生成時間原來是下午一點多,當然非??尚?,人家都沒有生成 ,我能捉到了才怪呢,所以這個腳本的執(zhí)行時間 一定是受源文件的生成時間有關(guān)的,一定是在源文件生成之后完整后才可以抓取,這樣一來 執(zhí)行的時間也是考究的,不一定非要后半夜 ,折中一下選擇更合適的時間
5.存儲和刪除
我們的定時任務(wù)這期主要是中轉(zhuǎn)數(shù)據(jù),數(shù)據(jù)量 每天大概有600G 左右,有時候需要修補數(shù)據(jù),每天產(chǎn)生的數(shù)據(jù)就更多了,我們在中轉(zhuǎn)機器上掛載了 一個2T 的硬盤,按道理裝兩天的肯定夠,不過還是經(jīng)常能碰到 數(shù)據(jù)傳輸?shù)臅r候,磁盤就剩20G了,稍微不注意,磁盤被占滿,數(shù)據(jù)傳輸被阻塞 ,使用scp 是不支持中斷傳輸?shù)模瑪?shù)據(jù)流 最煩的就是傳了一半半半兒的,修補數(shù)據(jù)使用 通配符 或者正則匹配都多多少少有點小麻煩,很多人推薦使用 rsync 傳輸 ,支持中斷和 update 覆蓋,存儲是限量的,所以 必要的定時刪除也是必要的,刪除的時機也很重要,比如按天分類目錄的,我們在前一天的日志 傳輸完整 數(shù)據(jù)完整性驗證后 并上傳到 目的地 完成相應的存儲和計算任務(wù) 后,并 新一天的數(shù)據(jù)開始正常傳輸后的一到兩個小時內(nèi) 刪除即可,這是整體一口氣刪除,當然這個時候 可能 部分數(shù)據(jù)會占用一天的磁盤時間,假如我們是按小時傳輸 驗證的,也完全可以在每小時 傳輸驗證后的 十分鐘內(nèi)刪除 掉上一個時間段的中轉(zhuǎn)數(shù)據(jù),這樣做的節(jié)省磁盤空間 ,缺點是出現(xiàn)異常 修補數(shù)據(jù)可能需要重新從源機器傳輸,另外 rm -rf file 刪除大文件也是一個非常耗時的,耗 cpu 的,600G 的數(shù)據(jù)一口氣刪完 ,對于8核16G的 centos 來說可能也需要 20分鐘。
6.打印日志 ,
當 把 寫腳本 設(shè)置定時任務(wù)走一遍 ,突然發(fā)現(xiàn) 好像 正常的日志流工具也是這么操作的,算是更加熟悉了 ,在我們在執(zhí)行腳本時 有時候 甚至大部分不在電腦前 半夜凌晨三點還在睡覺,所以追蹤track 定時任務(wù)的執(zhí)行情況很重要 ,有了這些日志才可能在出現(xiàn)異常是及時捕獲到,可以悠閑滴 喝著拿鐵 查看監(jiān)控,最簡單的 就是
echo "$Date( "%y%m%d %H:%M:%S") track message " >> data.log
對于異常 信息 當然更需要被捕獲
這樣清晰明了 ,我在定位問題的關(guān)鍵節(jié)省了很多功夫,排除了很多障礙物
7 數(shù)據(jù)完整性驗證
數(shù)據(jù)在傳輸?shù)倪^程中就必然會遭遇到 數(shù)據(jù)的丟失和失敗,比如 就剛才的 磁盤滿了,傳輸阻塞,某些文件傳輸?shù)揭话刖捅?咔嚓掉了,假如你沒有驗證就把他當成完整數(shù)據(jù)來處理,帶來的損失可能非常大,首先數(shù)據(jù)完整性是一個工程性的話題,一你要盡最大努力保證 數(shù)據(jù)傳輸?shù)姆€(wěn)定和可靠,我們使用except >>eof 確保 讀原始數(shù)據(jù)讀完,然后在傳輸?shù)?目的地后 通過簡單的 wc -l 比對行數(shù) 或者 文件字節(jié)大小 du -h ./file ,如果時間充?;蛘咝阅?高亢,我們還可以通過MD5 或者其他 算法 驗證文件中途是否遭遇被篡改,數(shù)據(jù)完整性驗證后 通過一個 標志性 success.log空文件 作為 目錄驗證通過的標志。
8 郵件監(jiān)控和報警
作為某些leader 他總有各種強迫癥,希望可以喝著咖啡 查收郵件 來確認工作的進度,在我們 批量的定時任務(wù)執(zhí)行后 數(shù)據(jù)驗證成功 ,按道理 為了安撫領(lǐng)導的小情緒,我們只有按照一定的套路來讓他放心,就是數(shù)據(jù)最后的狀態(tài)信息郵件發(fā)給他,email的中文
前一行 是醒目的 紅色 success 或者 黑色的failed ,剩下的從 傳輸日志中抓取到的日志信息,讓他看個夠,最好是夠喝一杯星巴克的時間,還有大部分為了數(shù)據(jù)安全,沒有公網(wǎng)只有 內(nèi)網(wǎng),這個郵件服務(wù)還是需要中轉(zhuǎn)一下,挺頭痛的。
9.定時任務(wù)隊列
在我們執(zhí)行定時任務(wù)是 ,有時候不單單是一個定時任務(wù),可能是很多,比如 我昨天就還開始了 17個定時任務(wù),我們的建議是 定時任務(wù) 要有高內(nèi)聚 低耦合的意識,同一個流程的盡量寫在一個腳本里 ,這樣也可以做一些類似數(shù)據(jù)庫事務(wù)的處理,不是一個流程 的盡量在不同的腳本中,防止一個流程任務(wù)的失敗 影響到其他任務(wù)。
當然 任務(wù)的開啟就像是打印機的打印流程,先來后到總是有的, 按小時執(zhí)行的 我們盡量安排在 一個時刻內(nèi)的05到-45之間,因為 一個任務(wù)不可能是立馬執(zhí)行結(jié)束的,需要一些時間,太早了怕是元數(shù)據(jù)沒有,太晚了,會影響到下一個時刻的定時任務(wù),我們能做到的就是盡量在一個時刻內(nèi)解決掉本時刻的所有任務(wù),不要拖累下一個時刻,不然累積就是一個大問題 ,造成越來越多的任務(wù)延后執(zhí)行,甚至宕機。
10后臺進程
我們的任務(wù)
11.腳本管理
剛才說了 我一天就開了17個定時任務(wù),大致寫了20個腳本,如果腳本很散亂,可能不便于管理,假如哪天不小心刪除了,想死的心 和想殺人的怒火,哎,好吧我收斂一下。。。
我的建議是 有一個專門的目錄 比如 scripts 做腳本管理,腳本的命名最好也是有規(guī)律的,可以一目了然之意的。做好腳本的備份和 gitlab的版本控制
12 修補數(shù)據(jù) 和 流程管理 維護
剛才也說了 數(shù)據(jù)有時候就像我們的褲子,修修補補又三年,數(shù)據(jù)丟失 傳輸失敗,肯定要修補一下,怎么修補 和我們的數(shù)據(jù)文件定義有很大關(guān)系,比如我們的源數(shù)據(jù)是按小時 按機器生成的,我們在修補的時候直接修補丟失時刻的數(shù)據(jù)即可,但是千萬不要刻舟求劍。
另外 一臺中轉(zhuǎn)機器一天800G 數(shù)據(jù)的傳輸,肯定要使用內(nèi)網(wǎng)傳輸,大數(shù)據(jù)量對于單臺機器來說 占用相當大的帶寬 ,也會造成一些 延時操作 等等問題。我們還要錯開傳輸?shù)母叻迤?br>
13 半夜23點之痛
這個主要是針對我們按小時生成的元數(shù)據(jù),我們一般都是延后一個小時去抓取上一個時刻的數(shù)據(jù),比如8點十分去抓取 七點一個小時的元數(shù)據(jù) ,這個延后一小時會有一定的影響,比如 到了凌晨12點 在linux就是00時刻,就是第二天了,但是我們還要去抓取 上一天的23點的數(shù)據(jù), 有時候我腦子就錯亂了,這個時候就需要 針對 23點做一個 if處理 ,通過教訓,為了最小化腳本的代碼,有些 腳本 的中出現(xiàn)的 數(shù)值 字符串 一定要 變量話,這樣在流程管理中 會節(jié)省很大功夫,也不容易出錯
14 壓縮和解壓之痛
gzip 壓縮可以達到 八倍,在加上tarball ,其實能夠很好的處理數(shù)據(jù),但是 解壓時間超級長,比如說 tarball 是 10G ,解壓后 100G ,這個解壓過程其實有半個小時左右,很長很嚇人,我們本想使用snappy ,但是在linux上操作還有點問題,我們的原始數(shù)據(jù)是隔天打包,大前天打包 ,昨天的不壓縮,所以只能爭取盡快在沒壓縮之前傳輸,另外 爭取 使用snappy 更好 更快。