異構資料來源同步之資料同步 → datax 改造,有點意思

青石路發表於2024-05-20

開心一刻

去年在抖音裡談了個少婦,騙了我 9 萬

後來我發現了,她怕我報警

她把她表妹介紹給我

然後她表妹又騙了我 7 萬

異構資料來源同步之資料同步 → datax 改造,有點意思

DataX

DataX 是什麼,有什麼用,怎麼用

不做介紹,大家自行去官網(DataX)看,Gitee 上也有(DataX

不服氣嗎

你們別不服,我這是為了逼迫你們去自學,是為了你們好!

文件很詳細,也是開源的,我相信你們都能看懂,也能很快上手用起來

那這篇文章到此結束,大家各自去忙吧

但是等等,我想帶你們去改造改造datax

挺有意思的,我們慢慢往下看

去 Python

根據官方的 Quick Start

系統要求

是依賴 Python 來啟動的

$ cd  {YOUR_DATAX_HOME}/bin
$ python datax.py {YOUR_JOB.json}

如果要去掉 Python 依賴,你們會怎麼做?

是不是梳理清楚 datax.py 的程式碼邏輯就行了?

datax.py

這個程式碼不長,但是如果沒有一點 Python 底子,datax.py 是看不懂的

所以我們換個方式,去尋找我們需要的資訊就行了

DataX 的業務程式碼是 java 實現的,然後你們再往上看看 System Requirements

你們覺得該如何啟動 JVM 程序來執行 DataXjava 程式碼?

是不是隻能用 JDKjava 命令了?

所以我們直接在 datax.py 中搜尋 java 即可

你們會發現只有如下這一行表示 java 命令

ENGINE_COMMAND = "java -server ${jvm} %s -classpath %s  ${params} com.alibaba.datax.core.Engine -mode ${mode} -jobid ${jobid} -job ${job}" % (
    DEFAULT_PROPERTY_CONF, CLASS_PATH)

Python 中的 % 就相當於 java 中的 String.format 方法

python %

也就說,datax.py 是透過 java -server 命令來啟動 JVM 程序的

那麼我們是不是可以繞過 Python,直接在 cmd 呼叫 java -server 來啟動了?

java -server

這個命令還真不眼熟,因為我們接觸到的往往是 java -jar

我們用 java -h 看下 java 命令的說明

java -h

發現了什麼?

-serveroption 之一,與 -jar 並不是 非此即彼 的關係

所以不要去拿 java -serverjava -jar 做對比了,沒意義!!!

在Java中,JVM有兩種執行模式:客戶端模式和伺服器模式。這兩種模式是為了最佳化不同場景下的JVM效能而設計的。

伺服器模式:這種模式適用於長時間執行的應用程式,如Web伺服器或資料庫伺服器。伺服器模式下的JVM會進行更多的最佳化,以減少長時間執行的效能開銷。例如,它會進行更深入的即時編譯(JIT compilation),以提高程式碼的執行效率。

客戶端模式:預設情況下,JVM執行在客戶端模式。這種模式適用於較短時間執行的應用程式,如桌面應用或命令列工具。客戶端模式下的JVM會更快地啟動,但可能不如伺服器模式那樣高效。

使用-server選項啟動JVM時,您告訴JVM在伺服器模式下執行。這通常意味著JVM將使用更多的系統資源,但可以提供更好的效能,特別是在長時間執行的應用程式中

我們先下載 DataX 工具包

datax工具包

解壓之後,我的 DataX 的根目錄是:G:\datax-tool\datax

datax工具home目錄

我們不透過 datax.py 來啟動,而是直接在 cmd 下透過 java 命令來啟動

java -server -Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=G:\datax-tool\datax\log -Dfile.encoding=GBK -Dlogback.statusListenerClass=ch.qos.logback.core.status.NopStatusListener -Djava.security.egd=file:///dev/urandom -Ddatax.home=G:\datax-tool\datax -Dlogback.configurationFile=G:\datax-tool\datax\conf\logback.xml -classpath G:\datax-tool\datax\lib\* com.alibaba.datax.core.Engine -mode standalone -jobid -1 -job G:\datax-tool\datax\job\job.json

注意:上述 java 命令中的相關路徑需要替換成你們自己的路徑!

不出意外的話,會執行成功

java命令啟動

為什麼依賴 Python

如果你們去看了 DataX 工具包的目錄結構,或者 DataX 的原始碼

你們會發現 DataX 就是用 java 實現的,Python 僅僅只是作為一個啟動指令碼(另外兩個指令碼你們自己去研究)

啟動指令碼

僅僅為了一個啟動,而這個啟動又不是非 Python 不可,就引入了 Python 環境依賴,試問這合理嗎?

不合理

不要急著下結論,我們理智分析一波

DataX 正式投入使用的時候,會部署到什麼系統上,請你們大聲的告訴我

linux

不說全部,絕大部分是部署在 Linux 上,對此我相信你們都沒異議吧

那麼重點來了:目前主流的 Linux 系統,都自帶 Python !!!

也就是不用再額外的是安裝 Python,直接可以用,那為什麼不用呢?

那如果是部署在 Windows 上,而又不想安裝 Python,該如何啟動了?

如果你們還能問出這樣的問題,我只想給你們來上一槍

老子一槍崩了你

前面不是剛講嗎,在 cmd 直接用 java 命令來啟動 DataX 不就行了?

java 啟動 DataX

說的更詳細點,是透過 java 程式碼去啟動 DataX JVM 程序

我相信你們都會,直接上程式碼

private static final String DATAX_COMMAND = "java -server -Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=G:\\datax-tool\\datax\\log -Dfile.encoding=GBK -Dlogback.statusListenerClass=ch.qos.logback.core.status.NopStatusListener -Djava.security.egd=file:///dev/urandom -Ddatax.home=G:\\datax-tool\\datax -Dlogback.configurationFile=G:\\datax-tool\\datax\\conf\\logback.xml -classpath G:\\datax-tool\\datax\\lib\\* com.alibaba.datax.core.Engine -mode standalone -jobid -1 -job G:\\datax-tool\\datax\\job\\job.json";

public static void main(String[] args) {
	try {
		Process process = Runtime.getRuntime().exec(DATAX_COMMAND);
		// 等待命令執行完成
		int i = process.waitFor();
		if (i == 0) {
			System.out.println("job執行完成");
		} else {
			System.out.println("job執行失敗");
		}
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
}

是不是很簡單?

執行下,你會發現卡住了!!!

卡住

出師不利呀,要不放棄?

放棄

Runtime 物件呼叫 exec(cmd) 後,JVM 會啟動一個子程序,該程序會與 JVM 程序建立三個管道連線:標準輸入標準輸出標準錯誤流

假設子程序不斷在向標準輸出流和標準錯誤流寫資料,而 JVM 程序不讀取的話,當緩衝區滿之後將無法繼續寫入資料,最終造成阻塞在 waitfor()

所以改造下就好了

private static final String SYSTEM_ENCODING = System.getProperty("sun.jnu.encoding");
private static final String DATAX_COMMAND = "java -server -Xms1g -Xmx1g -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=G:\\datax-tool\\datax\\log -Dfile.encoding=GBK -Dlogback.statusListenerClass=ch.qos.logback.core.status.NopStatusListener -Djava.security.egd=file:///dev/urandom -Ddatax.home=G:\\datax-tool\\datax -Dlogback.configurationFile=G:\\datax-tool\\datax\\conf\\logback.xml -classpath G:\\datax-tool\\datax\\lib\\* com.alibaba.datax.core.Engine -mode standalone -jobid -1 -job G:\\datax-tool\\datax\\job\\job.json";

public static void main(String[] args) {
	try {
		Process process = Runtime.getRuntime().exec(DATAX_COMMAND);

		// 另啟執行緒讀取
		new Thread(() -> {
			try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), SYSTEM_ENCODING))) {
				String line;
				while ((line = reader.readLine()) != null) {
					System.out.println(line);
				}
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}).start();

		new Thread(() -> {
			try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), SYSTEM_ENCODING))) {
				String line;
				while ((line = errorReader.readLine()) != null) {
					System.out.println(line);
				}
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}).start();

		// 等待命令執行完成
		int i = process.waitFor();
		if (i == 0) {
			System.out.println("job執行完成");
		} else {
			System.out.println("job執行失敗");
		}
	} catch (Exception e) {
		throw new RuntimeException(e);
	}
}

還是比較簡單的吧,相信你們都能看懂

總結

  • DataX 是程序級別的,而 Job 下的 Task 是執行緒級別的

    image-20240519201433065

    為什麼 DataX 要實現成程序級別,而不是執行緒級別?

    小資料量的同步,實現方式往往很多

    但大資料量的同步,情況就不一樣了,那麼此時程序和執行緒的區別還大嗎

  • Linux 系統基本自帶 Python 環境,所以大家不要再糾結為什麼依賴 Python

    去掉 Python 依賴也很簡單,文中已有演示

  • DataX + datax-web 這個組合已經基本夠用

    datax-web 基於 XXL-JOB,基本滿足我們日常的排程要求了

相關文章