【DataX】生产环境搭建DataX集群案例

【DataX】生产环境搭建DataX集群案例

【一】环境搭建

【1】服务器说明

后端:10.238.168.161

前端(含nginx):10.238.168.96

datax集群(3台):10.238.168.62、10.238.168.106、10.238.168.173

【2】用户密码管理

(1)nginx使用nginx用户

bash 复制代码
# 新增nginx用户组和用户,并创建/home/nginx专属目录
groupadd nginx && useradd -g nginx nginx -d /home/nginx

# 设置nginx用户的密码,俩次输入
passwd nginx 

(2)datax集群使用datax用户

bash 复制代码
# 新增datax用户组和用户,并创建/home/datax专属目录
groupadd datax && useradd -g datax datax -d /home/datax

# 设置datax用户的密码,俩次输入
passwd datax 

(3)前端后端使用damp用户

bash 复制代码
# 新增damp用户组和用户,并创建/home/damp专属目录
groupadd damp && useradd -g damp damp -d /home/damp

# 设置damp用户的密码,俩次输入
passwd damp 

(4)如果用户密码忘了

Linux 无法直接查看明文密码!

哪怕你是 root,系统里存放的永远是密码哈希(加密字符串),不保存原始明文密码

使用root用户,可以直接重置普通用户密码(不需要知道旧密码),执行后直接输入新密码即可,不用旧密码。

bash 复制代码
passwd zhangsan

【3】DataX安装启动

下载安装包

bash 复制代码
mkdir /home/datax/dgs_middleware_upload
#传输"datax.zip"文件到"/home/datax/dgs_middleware_upload"

# 解压文件
cd /home/datax/dgs_middleware_upload && unzip datax.zip

# 移动文件
mv datax ../.

测试验证

bash 复制代码
python /home/datax/datax/bin/datax.py /home/datax/datax/job/job.json

出现如下内容,则表明安装成功

......

2021-10-12 21:51:12.335 job-0 INFO JobContainer -

任务启动时刻 : 2021-10-12 21:51:02

任务结束时刻 : 2021-10-12 21:51:12

任务总计耗时 : 10s

任务平均流量 : 253.91KB/s

记录写入速度 : 10000rec/s

读出记录总数 : 100000

读写失败总数 : 0

【二】DataX集群搭建

【1】配置后端到nginx的ssh免密

(1)后端服务器生成生成SSH密钥对

bash 复制代码
cd ~/.ssh/ 
ssh-keygen -t rsa
#一直回车

一路按回车键,生成客户机秘钥对

在当前后端服务器,我们可以看到在家目录自动创建一个隐藏文件夹 .ssh,并且生成两个文件,分别是私钥文件 id_rsa 和公钥文件 id_rsa.pub 。

powershell 复制代码
ls /root/.ssh

(2)复制公钥到nginx服务器

使用ssh-copy-id传公钥,ssh + Tab键发现有ssh-copy-id命令

powershell 复制代码
# 自动将公钥复制到目标服务器
ssh-copy-id username@serverB_IP

# 指定端口
ssh-copy-id -p 2222 username@serverB_IP

# 指定特定密钥文件
ssh-copy-id -i ~/.ssh/id_rsa_serverB username@serverB_IP

案例:

在客户机键入下面的命令,在应答的位置输入 yes,接着输入远程机的密码,之后就可以免密码登录

powershell 复制代码
ssh-copy-id nginx@10.238.168.96

在远程前端服务器10.238.168.96,我们会发现,同样在用户家目录创建了一个隐藏文件夹 .ssh,这个目录下面多了一个文件 authorized_keys,这就是刚才传过来的公钥,这样下次客户机远程过来,就不用再输入密码,这种方式在集群中用得比较多。

(3)验证

执行下面命令,不需要再输入密码就代表免密成功

bash 复制代码
ssh nginx@10.238.168.96

【2】配置后端到datax集群的ssh免密

(1)nginx服务器生成生成SSH密钥对

同上

(2)复制公钥到datax服务器

同上

【3】配置nginx负载均衡datax集群

bash 复制代码
vim /home/nginx/nginx_home/conf/nginx.conf

# 新增以下内容
stream {
	upstream datax_cluster {
		server 10.238.168.62:22;
		server 10.238.168.106:22;
		server 10.238.168.173:22;
	}
	server {
		listen 20144;	# Nginx本机监听TCP端口20144
		proxy_pass datax_cluster;	# 所有访问 20144 的 TCP 连接,转发给 upstream 集群
	}

}

重载 nginx:nginx -s reload

防火墙放行:Nginx 机器入站 20144,Nginx 出站访问三台 DataX 22 端口

重要前提:三台 DataX 服务器ssh 账号、密码 / 密钥完全一致

【4】后端通过nginx轮训datax集群

(1)nacos配置datax的相关信息

1-nginx的ip地址

2-nginx转发datax的监控端口20144

3-datax服务器的账号密码

  1. Nginx stream{} 四层代理 只转发 TCP 数据包,完全不参与 SSH 协议交互、不处理认证
  2. SSH 握手、账号密码校验,是Java 程序 ↔ 最终 DataX 服务器之间完成;
  3. Nginx 只是 "透明管道",自身不需要、也不会使用这组账号密码。

(2)后端代码

java 复制代码
public static SshExecResult execCommand(String command) {
    // 1. 创建SSH会话,连接配置中的主机(Nginx跳板地址:20144)
    Session session = JschUtil.openSession(config.getHost(), config.getPort(), config.getUserName(), config.getPassWd(), 60 * 60 * 1000);
    SshExecResult result = null;
    try {
        FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
        // 2. 【关键】第一条SSH命令:hostname -I | awk '{print $1}'
        String ipResult = JschUtil.exec(session, "hostname -I | awk '{print $1}'", StandardCharsets.UTF_8, new FastByteArrayOutputStream());
        log.info(StrUtil.format("datax服务ip:{}", ipResult));

        // 3. 执行传入的业务command命令
        String execResult = JschUtil.exec(session, command, StandardCharsets.UTF_8, outputStream);
        // 4. 获取stderr错误输出
        String errorMsg = outputStream.toString();

        // 5. 封装返回对象
        result = new SshExecResult();
        result.setNomarlMsg(execResult);
        result.setErrorMsg(errorMsg);
    } catch (Exception e) {
        log.error("操作异常:{}", e.getMessage(), e);
    } finally {
        // 6. 强制关闭ssh会话,释放连接
        if (session != null) {
            session.disconnect();
        }
    }
    return result;
}

(1)建立 SSH Session

java 复制代码
Session session = JschUtil.openSession(config.getHost(), config.getPort(), config.getUserName(), config.getPassWd(), 60 * 60 * 1000);
  • config.getHost() / getPort() = Nginx 跳板 IP + 20144 端口
  • 使用 JSch(Java SSH 客户端) 创建 SSH 会话,超时 1 小时
  • ⚠️ 这里连接的是 Nginx 四层代理,不是直连 DataX 机器

(2)执行探测命令(核心目的)

java 复制代码
String ipResult = JschUtil.exec(session, "hostname -I | awk '{print $1}'", ...);

命令含义:

bash 复制代码
hostname -I      # 输出本机所有内网IP(不带127.0.0.1)
awk '{print $1}' # 取第一个IP地址

为什么要执行这一条?

因为 Nginx 做了 SSH 负载均衡,程序只知道跳板地址,不知道当前这次连接落到三台 DataX 节点中的哪一台

通过登录进去执行 hostname,拿到真实后端 DataX 服务器内网 IP,打印日志用于追踪问题。

(3)执行业务命令

java 复制代码
String execResult = JschUtil.exec(session, command, StandardCharsets.UTF_8, outputStream);
  • command:上层传入需要在 DataX 节点执行的 shell 指令
  • outputStream 用来捕获标准错误 stderr

【三】流程总结

bash 复制代码
Java程序
    ↓ SSH连接 NginxIP:20144
    ↓ Nginx stream四层负载均衡,随机转发到 62/106/173 的22端口,不做身份校验
    ↓ Nginx转发TCP流 → 轮询后端DataX机器:22端口
DataX节点(被选中机器)
    ↓ 代码先执行 hostname -I 获取被选中的DataX本机真实IP并打印日志
    ↓ 再执行业务shell命令
    ↓ 返回输出结果
Java代码 finally关闭SSH连接
相关推荐
丈剑走天涯2 小时前
JVM(十) JDK8 CMS (Concurrent Mark Sweep)
jvm
c238562 小时前
把 C++ 内存分配拆透:new 与 malloc 的三层血缘
开发语言·c++·算法
好好沉淀2 小时前
@NotBlank(message = “{xxx}“) 注解中花括号的含义
java
fīɡЙtīиɡ ℡2 小时前
内存泄漏产生的原因
java·spring·servlet
moonsims3 小时前
星闪在跨域无人化系统作用
开发语言·php
码智社3 小时前
Java实现RSA密钥生成、加密解密、加签验签
java
wear工程师4 小时前
ThreadLocal 在线程池里为什么会串数据:别只会答内存泄漏
java·后端
Iruoyaoxh4 小时前
栈和队列~
java·开发语言
审小匠OpenCPAi4 小时前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计