大數(shù)據(jù)平臺(tái)開發(fā)——使用Java和Python調(diào)用Shell腳本
背景
在大數(shù)據(jù)平臺(tái)開發(fā)中,經(jīng)常會(huì)遇到需要調(diào)用Shell腳本的場景,倒不是說只能用Shell,畢竟大數(shù)據(jù)開發(fā)到頭來一定是個(gè)語言無關(guān)的事情:
從Hive源碼解讀大數(shù)據(jù)開發(fā)為什么可以脫離SQL、Java、Scala:https://lizhiyong.blog.csdn.net/article/details/129742904
Shell能干的事情,Java和Python當(dāng)然是一定可以干。但是可以不代表是最優(yōu)的方式。
例如這種常見的情況,看起來就很紊亂。
由于Java微服務(wù)集群和大數(shù)據(jù)集群不太可能部署在相同的node上,也就導(dǎo)致了環(huán)境其實(shí)有很大的差異。
多數(shù)情況下,隔離的好處是利大于弊。比如大數(shù)據(jù)集群除了Flink,其它組件大多是用JDK1.8。而Flink為了使用ZGC這種更先進(jìn)的GC,可能要用JDK11或者JDK17。Java后端微服務(wù)正在向JDK11平穩(wěn)過渡,還有少一半JDK1.8,以及部分實(shí)在太過古老以至于無人敢動(dòng)的JDK1.7應(yīng)用。。。有的機(jī)器可能為了用上Free IPA、Ranger,有的機(jī)器可能要跑PySpark或者PyTorch,Python版本大概率也不同。大數(shù)據(jù)的集群一般還是多個(gè)。。。這種情況下,物理隔離后各種組件和應(yīng)用大多都可以比較和諧融洽。
但是這么多機(jī)器,如果人員分工是按照大數(shù)據(jù)組/后端組這么分的,那就很容易出現(xiàn)甩鍋的問題了。。。很可能大數(shù)據(jù)組的運(yùn)維給機(jī)器配置的host和后端組的運(yùn)維配置的host文件不一樣。。。
還有一種情況就是Jar包的依賴沖突,例如我們的Tomcat和HBase還有Log4j出現(xiàn)過嚴(yán)重的沖突【沒錯(cuò),就是那個(gè)RSGroup硬件級(jí)資源隔離技術(shù)調(diào)研時(shí)遇到的】,光是排除依賴就折騰了有一兩周。。。那么這種情況下,寫能跑起來的Shell要比寫能跑起來的Java容易很大,顯然調(diào)用Shell就是個(gè)比排除依賴沖突再去調(diào)用API更好的主意。。。
有時(shí)候是成本問題。。。為了讓Java后端服務(wù)器也可以調(diào)用命令去操作大數(shù)據(jù)集群而部署一套Cloudera Manager和Client顯然是不劃算的,一個(gè)node大概1w美刀/年的租金也不便宜,但是手動(dòng)安裝Client運(yùn)維也大抵是不愿意這么做的。部署的服務(wù)變多后node宕掉了鍋也不容易甩。。。
所以做大數(shù)據(jù)平臺(tái)開發(fā),也就躲不開調(diào)用Shell腳本,Shell腳本再去調(diào)用別的機(jī)器的Shell腳本這種事情了。。。
案例
Java
package com.zhiyong;
/**
* @program: zhiyong_study
* @description: 測(cè)試遠(yuǎn)程調(diào)用Shell
* @author: zhiyong
* @create: 2023-04-02 22:26
**/
public class TestShellDemo {
public static void main(String[] args) {
TestShellDemo demo = new TestShellDemo();
String cmd = "";
cmd = args[0];
int exeShResult = demo.exeSh(cmd);
System.out.println("exeShResult = " + exeShResult);
}
private int exeSh(String shellCommand) {
int Result = 0;
Process pid = null;
System.out.println("執(zhí)行Shell:" + shellCommand);
try {
String[] cmd = {"bin/sh", "-c", shellCommand};
pid = Runtime.getRuntime().exec(cmd);
int exitValue = 0;
System.out.println("pid的信息:" + pid.toString());
if (null!=pid){
System.out.println("等待shell執(zhí)行完畢");
pid.waitFor();
System.out.println("shell執(zhí)行完畢");
exitValue = pid.exitValue();
System.out.println("shell返回值:" + exitValue);
}
return exitValue;
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}
}
可以使用這種比較簡單的方式。把腳本放在本地服務(wù)器即可調(diào)用。我們使用這種方式去調(diào)用HBase shell,將輸出重定向到log文件后再將log文件scp回來解析,從而獲取到結(jié)果,和調(diào)用HBase的API效果是一致的。在Java后端組排除依賴的一兩周時(shí)間里,讓租戶們提前體驗(yàn)了新功能。
Python
#!/usr/bin/env python
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname='192.168.88.100',port=22,username="root",password="123456")
stdin,stdout,stderr = ssh.exec_command('echo "sh /root/shell/xxx.sh" | ssh -Tq root@192.168.88.50')
print(stdout.read().decode(encoding="utf-8"))
ssh.close()
可以調(diào)用paramiko
這個(gè)Python包,它可以遠(yuǎn)程調(diào)用別的機(jī)器的Shell。
這種方式我們最早用于集群任務(wù)遷移過程中的數(shù)據(jù)遷移及數(shù)據(jù)比對(duì)。由于領(lǐng)導(dǎo)階級(jí)是Oracle數(shù)據(jù)庫開發(fā)出身,對(duì)大數(shù)據(jù)一知半解,致使新老多套集群都叫nameservice1
,這么搞無論如何:
USDP使用筆記(四)打通雙集群HDFS實(shí)現(xiàn)跨nameservice訪問:https://lizhiyong.blog.csdn.net/article/details/123436503
都是沒辦法打通跨nameservice域了。只能通過namenode的IP和8020端口來互相訪問。但是HA模式下Active的master又是會(huì)變化的。。。
當(dāng)然還有Kerberos認(rèn)證的天坑一時(shí)半會(huì)兒也不太容易填。。。
于是我們的Shell腳本就可以放置在邊緣節(jié)點(diǎn),先從CDH5.16的老集群get需要的parquet文件到老集群某機(jī)器的本地,然后scp
的方式傳輸?shù)竭吘壒?jié)點(diǎn),再從邊緣節(jié)點(diǎn)scp給CDP7.1.5集群的某個(gè)節(jié)點(diǎn),再執(zhí)行put
操作上傳到指定的路徑。雖然這是一種笨辦法,但是在保障進(jìn)度的特殊歷史時(shí)期發(fā)揮了巨大作用。
總結(jié)
,然后scp
的方式從邊緣節(jié)點(diǎn)傳輸?shù)竭吘壒?jié)點(diǎn),再從邊緣節(jié)點(diǎn)scp給CDP7.1.5集群的某個(gè)節(jié)點(diǎn),再執(zhí)行put
操作上傳到指定的路徑。雖然這是一種笨辦法,但是在保障進(jìn)度的特殊歷史時(shí)期發(fā)揮了巨大作用。
總結(jié)
大數(shù)據(jù)平臺(tái)開發(fā),由于跨服務(wù)器、多環(huán)境等問題,直接API調(diào)用的理想方式有時(shí)候是行不通的或者代價(jià)很大,這種情況就不一定要死磕API,可以考慮shell的方式去吊起別的集群的shell來執(zhí)行所需的事項(xiàng)。。。文章來源:http://www.zghlxwxcb.cn/news/detail-406266.html
轉(zhuǎn)載請(qǐng)注明出處:https://lizhiyong.blog.csdn.net/article/details/129919408文章來源地址http://www.zghlxwxcb.cn/news/detail-406266.html
到了這里,關(guān)于大數(shù)據(jù)平臺(tái)開發(fā)——使用Java和Python調(diào)用Shell腳本的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!