大数据平台开发——使用Java和Python调用Shell脚本

106 篇文章 15 订阅
15 篇文章 1 订阅

大数据平台开发——使用Java和Python调用Shell脚本

背景

在大数据平台开发中,经常会遇到需要调用Shell脚本的场景,倒不是说只能用Shell,毕竟大数据开发到头来一定是个语言无关的事情:

从Hive源码解读大数据开发为什么可以脱离SQL、Java、Scala:https://lizhiyong.blog.csdn.net/article/details/129742904

Shell能干的事情,Java和Python当然是一定可以干。但是可以不代表是最优的方式。

在这里插入图片描述

例如这种常见的情况,看起来就很紊乱。

由于Java微服务集群和大数据集群不太可能部署在相同的node上,也就导致了环境其实有很大的差异。

多数情况下,隔离的好处是利大于弊。比如大数据集群除了Flink,其它组件大多是用JDK1.8。而Flink为了使用ZGC这种更先进的GC,可能要用JDK11或者JDK17。Java后端微服务正在向JDK11平稳过渡,还有少一半JDK1.8,以及部分实在太过古老以至于无人敢动的JDK1.7应用。。。有的机器可能为了用上Free IPA、Ranger,有的机器可能要跑PySpark或者PyTorch,Python版本大概率也不同。大数据的集群一般还是多个。。。这种情况下,物理隔离后各种组件和应用大多都可以比较和谐融洽。

但是这么多机器,如果人员分工是按照大数据组/后端组这么分的,那就很容易出现甩锅的问题了。。。很可能大数据组的运维给机器配置的host和后端组的运维配置的host文件不一样。。。

还有一种情况就是Jar包的依赖冲突,例如我们的Tomcat和HBase还有Log4j出现过严重的冲突【没错,就是那个RSGroup硬件级资源隔离技术调研时遇到的】,光是排除依赖就折腾了有一两周。。。那么这种情况下,写能跑起来的Shell要比写能跑起来的Java容易很大,显然调用Shell就是个比排除依赖冲突再去调用API更好的主意。。。

有时候是成本问题。。。为了让Java后端服务器也可以调用命令去操作大数据集群而部署一套Cloudera Manager和Client显然是不划算的,一个node大概1w美刀/年的租金也不便宜,但是手动安装Client运维也大抵是不愿意这么做的。部署的服务变多后node宕掉了锅也不容易甩。。。

所以做大数据平台开发,也就躲不开调用Shell脚本,Shell脚本再去调用别的机器的Shell脚本这种事情了。。。

案例

Java

package com.zhiyong;

/**
 * @program: zhiyong_study
 * @description: 测试远程调用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("执行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执行完毕");
                pid.waitFor();
                System.out.println("shell执行完毕");
                exitValue = pid.exitValue();
                System.out.println("shell返回值:" + exitValue);
            }
            return exitValue;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return -1;

    }
}

可以使用这种比较简单的方式。把脚本放在本地服务器即可调用。我们使用这种方式去调用HBase shell,将输出重定向到log文件后再将log文件scp回来解析,从而获取到结果,和调用HBase的API效果是一致的。在Java后端组排除依赖的一两周时间里,让租户们提前体验了新功能。

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()

可以调用paramiko这个Python包,它可以远程调用别的机器的Shell。

这种方式我们最早用于集群任务迁移过程中的数据迁移及数据比对。由于领导阶级是Oracle数据库开发出身,对大数据一知半解,致使新老多套集群都叫nameservice1,这么搞无论如何:

USDP使用笔记(四)打通双集群HDFS实现跨nameservice访问:https://lizhiyong.blog.csdn.net/article/details/123436503

都是没办法打通跨nameservice域了。只能通过namenode的IP和8020端口来互相访问。但是HA模式下Active的master又是会变化的。。。

当然还有Kerberos认证的天坑一时半会儿也不太容易填。。。

于是我们的Shell脚本就可以放置在边缘节点,先从CDH5.16的老集群get需要的parquet文件到老集群某机器的本地,然后scp的方式传输到边缘节点,再从边缘节点scp给CDP7.1.5集群的某个节点,再执行put操作上传到指定的路径。虽然这是一种笨办法,但是在保障进度的特殊历史时期发挥了巨大作用。

总结

,然后scp的方式从边缘节点传输到边缘节点,再从边缘节点scp给CDP7.1.5集群的某个节点,再执行put操作上传到指定的路径。虽然这是一种笨办法,但是在保障进度的特殊历史时期发挥了巨大作用。

总结

大数据平台开发,由于跨服务器、多环境等问题,直接API调用的理想方式有时候是行不通的或者代价很大,这种情况就不一定要死磕API,可以考虑shell的方式去吊起别的集群的shell来执行所需的事项。。。

转载请注明出处:https://lizhiyong.blog.csdn.net/article/details/129919408
在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值