For-each node melakukan iterasi terhadap result set hulu, seperti daftar nama file atau partisi, lalu mengeksekusi subtask yang sama untuk setiap elemen. Pendekatan ini menghilangkan kebutuhan membuat tugas secara manual satu per satu dan memungkinkan alur kerja yang dinamis serta otomatis.
Kasus penggunaan
For-each node memungkinkan eksekusi berparameter ketika Anda perlu menerapkan logika analisis atau pemrosesan yang sama pada berbagai unit bisnis, lini produk, atau item konfigurasi. Misalnya, jika perusahaan Anda memiliki beberapa lini produk dan Anda perlu menghasilkan laporan harian terpisah untuk masing-masing, logika pemrosesannya identik; hanya data target yang berbeda.
Seperti halnya loop for dalam bahasa pemrograman, for-each node melakukan iterasi terhadap daftar—misalnya nama tabel, nama partisi, atau nama file—dan mengeksekusi sub-alur kerja yang telah ditentukan untuk setiap item.
Catatan penggunaan
Persyaratan versi: Hanya tersedia di DataWorks Edisi Standar dan versi yang lebih baru.
Izin: Akun RAM Anda harus ditambahkan ke workspace target dan diberi peran developer atau administrator workspace. Untuk informasi selengkapnya, lihat Add members to a workspace.
Cara kerja
For-each node bertindak sebagai wadah yang membungkus sub-alur kerja yang dapat dikustomisasi, yang dikenal sebagai loop body. Cara kerjanya sebagai berikut:
-
Masukan data: For-each node bergantung pada assignment node hulu atau node lain yang dapat ditetapkan (seperti node EMR Hive). Node ini mengambil result set berformat array dengan mengikat parameter
loopDataArray. -
Eksekusi loop: Saat node dimulai, ia melakukan iterasi terhadap setiap elemen dalam result set secara berurutan. Untuk setiap elemen, loop body dieksekusi sepenuhnya satu kali, dari node
Starthingga nodeEnd.CatatanNode Start dan End tidak dapat diedit. Keduanya hanya menandai awal dan akhir loop body.
-
Transfer data: Selama setiap iterasi, nilai elemen saat ini diteruskan ke node di dalam loop body melalui built-in variables. Node bisnis internal menggunakan
${dag.foreach.current}untuk mengakses item data yang sedang diproses.
Parameter bawaan
Variabel dalam format ${...} merupakan sintaks templat khusus DataWorks. DataWorks langsung mengurai parameter ini dan menggantinya dengan nilai aktual sebelum eksekusi.
Node di dalam loop body for-each dapat menggunakan built-in variables berikut untuk mengakses status dan data loop:
|
Parameter bawaan |
Deskripsi |
Analogi loop |
|
|
Result set lengkap yang diteruskan dari assignment node hulu. |
Pertimbangkan kode loop for berikut:
|
|
|
Item data yang sedang diproses pada iterasi saat ini. |
|
|
|
Offset loop saat ini (diindeks mulai dari 0). |
|
|
|
Hitungan perulangan saat ini (indeks dimulai dari 1). |
Jika output hulu berupa array dua dimensi, seperti hasil kueri SQL, Anda juga dapat menggunakan sintaks berikut untuk mengakses nilai tertentu:
|
Parameter lainnya |
Deskripsi |
|
|
Mendapatkan string dengan memisahkan elemen baris data saat ini (array satu dimensi) menggunakan koma |
|
|
Item ke- |
|
|
Data dari baris ke- For-each node saat ini tidak mendukung loop bersarang. Contoh ini hanya untuk demonstrasi pengambilan nilai. |
Batasan
-
Mekanisme eksekusi: Loop mendukung serial execution maupun parallel execution. Anda dapat memilih eksekusi parallel jika iterasi saling independen.
-
Batas jumlah loop: Jumlah maksimum loop default adalah 128, yang dapat ditingkatkan hingga 1024.
-
Batasan debugging: Anda tidak dapat menjalankan for-each node secara langsung di Data Studio. Anda harus deploy tugas tersebut, lalu mengujinya di Operation Center menggunakan fitur smoke testing.
-
Batasan eksekusi: For-each node tidak dapat dijalankan secara terisolasi. Ini mencakup smoke testing, backfill, dan eksekusi manual.
-
Kontrol alur dalam loop body: Jika Anda menggunakan branch node di dalam loop body for-each, pastikan semua cabang akhirnya menyatu pada satu merge node sebelum terhubung ke node
End. Hal ini menjamin integritas logis loop body. -
Batasan rerun: Setelah node di-deploy, rerun otomatis saat gagal dilanjutkan dari titik kegagalan. Namun, rerun manual akan memicu rerun lengkap seluruh for-each node.
Prosedur
Prosedur ini menggunakan assignment node sebagai node hulu dan node Shell di dalam loop body untuk mencetak hasilnya. Prosedur ini memandu Anda melalui konfigurasi tugas for-each yang lengkap:
-
Siapkan data hulu (konfigurasikan assignment node)
Buat dan konfigurasikan assignment node untuk menyediakan result set yang dapat diiterasi bagi for-each node hilir.
-
Di alur kerja, buat assignment node (misalnya,
assign) dan letakkan di hulu for-each node. -
Klik ganda assignment node dan pilih lingkungan Python 2. Misalnya, gunakan
Python 2untuk menghasilkan array dengan empat elemen:Node ini mengeluarkan [10,20,30,40] ke node hilir dengan secara otomatis membagi baris output terakhir menjadi array pada setiap koma.
print "10,20,30,40" -
Assignment node secara otomatis menghasilkan parameter output bernama
outputs, yang merepresentasikan result set-nya. -
Save assignment node.
-
-
Konfigurasikan for-each node untuk mengonsumsi data
Konfigurasikan for-each node agar menerima data hulu dan menggunakannya di dalam loop body-nya.
-
Klik ganda for-each node untuk membuka canvas internalnya.
-
Di panel Scheduling di sebelah kanan, temukan parameter
loopDataArraydi bawah Scheduling Parameters dan klik Bind.Pilih parameter outputs dari node assign untuk membuat binding. Setelah binding selesai, nilai parameter loopDataArray mencerminkan status binding-nya.
-
Di kotak dialog yang muncul, atur Value Source ke assignment node hulu (
assign) dan pilih parameteroutputs-nya. Tindakan ini secara otomatis membuat dependensi antara kedua node. -
Di for-each loop body, klik Create Internal Node dan buat node
Shell.Dalam skenario nyata, Anda dapat mengonfigurasi jenis node apa pun.
-
Klik ganda node Shell baru dan gunakan built-in variables dalam kode untuk mengambil dan mencetak informasi tentang loop:
#!/bin/bash # Gunakan ${dag.loopTimes} untuk mendapatkan jumlah loop saat ini echo "Current loop number is: ${dag.loopTimes}" # Gunakan ${dag.foreach.current} untuk mendapatkan item data iterasi saat ini echo "Current item is: ${dag.foreach.current}" -
(Opsional) Di panel Scheduling Settings di sebelah kanan, konfigurasikan properti di bawah Scheduling Policy.
-
Maximum Number of Loops: Nilai default adalah 128, dan maksimum adalah 1024.
PentingParameter ini menentukan jumlah maksimum iterasi untuk loop body. Jika jumlah item data hulu besar, tingkatkan nilai ini agar semua item diproses.
-
Execute Policy: Pilih Serial untuk contoh ini.
-
Serial: Menjalankan iterasi secara berurutan.
-
Parallel: Menjalankan iterasi loop secara konkuren untuk meningkatkan efisiensi tugas. Dalam mode Parallel, jika satu iterasi gagal, iterasi lain tidak terpengaruh. Penjadwal berusaha menjalankan semua iterasi hingga selesai. Konkurensi default adalah 5, dan maksimum adalah 20.
-
-
-
Save node Shell.
-
-
Deploy, jalankan, dan verifikasi
Deploy alur kerja ke Operation Center untuk eksekusi dan verifikasi hasil for-each node.
-
Kembali ke canvas alur kerja utama dan klik tombol Deploy di toolbar untuk memublikasikan seluruh alur kerja.
-
Buka dan lakukan smoke test pada alur kerja target.
PentingJangan lakukan smoke test pada for-each node secara individual. Karena for-each node bergantung pada output assignment node hulu, Anda harus memulai pengujian dari assignment node untuk memastikan alur data lengkap.
-
Setelah test instance berhasil dijalankan, temukan instans for-each node di daftar, buka, lalu klik kanan dan pilih View Internal Nodes.
-
Di tampilan node internal, periksa instans node Shell yang dihasilkan oleh setiap loop. Buka running log salah satu instans untuk melihat output iterasi tersebut dan verifikasi bahwa outputnya benar.
Panel kiri menunjukkan bahwa keempat iterasi loop telah selesai. Running log untuk iterasi keempat mengeluarkan
Current loop number is: 4danCurrent item is: 40, serta perintah Shell keluar dengan kode 0, yang menunjukkan eksekusi berhasil.
-
Selain menggunakan assignment node tradisional sebagai node hulu, for-each node juga mendukung pencapaian efek iterasi yang sama melalui fitur assignment parameter dari node SQL hulu. Untuk jenis node yang mendukung assignment parameter—seperti EMR Hive, Hologres SQL, EMR Spark SQL, AnalyticDB for PostgreSQL, ClickHouse SQL, dan MySQL—Anda dapat menambahkan assignment parameter di bagian Node Context Parameters > Output Parameters of This Node.
Kasus penggunaan: Memproses format data berbeda
Skenario 1: Memproses array satu dimensi
-
keluaran node penugasan: 2025-11-01, 2025-11-02, 2025-11-03
-
Jumlah iterasi: 3
-
Saat iterasi kedua:
-
Nilai
${dag.foreach.current}adalah2025-11-02. -
Nilai
${dag.loopTimes}adalah2.
-
Skenario 2: Memproses array dua dimensi
-
Output assignment node (MaxCompute SQL):
+-----+----------+ | id | city | +-----+----------+ | 101 | beijing | | 102 | shanghai | +-----+----------+ -
Jumlah iterasi: 2
-
Saat iterasi kedua:
-
Nilai
${dag.foreach.current}adalah102,shanghai. -
Nilai
${dag.loopTimes}adalah2. -
Nilai
${dag.foreach.current[0]}adalah102. -
Nilai
${dag.foreach.current[1]}adalahshanghai.
-
Skenario: Memproses data tabel partisi secara batch lintas beberapa lini bisnis
Contoh ini menunjukkan cara menggunakan assignment node dan for-each node untuk memproses data perilaku pengguna secara batch lintas beberapa lini bisnis, mengotomatiskan pemrosesan data dengan satu set logika yang melayani banyak lini produk.
Latar belakang
Asumsikan Anda adalah insinyur pengembangan data di perusahaan internet terpadu, bertanggung jawab memproses data dari tiga lini bisnis inti: e-dagang (ecom), keuangan (finance), dan logistik (logistics), dengan kemungkinan penambahan lebih banyak di masa depan. Anda perlu menjalankan logika agregasi yang sama pada log perilaku pengguna dari ketiga lini bisnis ini setiap hari untuk menghitung jumlah tayangan halaman harian (PV) per pengguna dan menyimpan hasilnya di tabel agregat terpadu.
Tabel sumber hulu (lapisan DWD):
dwd_user_behavior_ecom_d: Tabel perilaku pengguna e-dagang.dwd_user_behavior_finance_d: Tabel perilaku pengguna keuangan.dwd_user_behavior_logistics_d: Tabel perilaku pengguna logistik.dwd_user_behavior_${business_line}_d: Tabel perilaku pengguna untuk lini bisnis potensial lainnya di masa depan.Tabel-tabel ini memiliki skema yang sama dan dipartisi berdasarkan hari (
dt).
Tabel target hilir (lapisan DWS):
dws_user_summary_d: Tabel agregat pengguna.Tabel ini dipartisi ganda berdasarkan lini bisnis (
biz_line) dan hari (dt) untuk menyimpan hasil agregasi dari semua lini bisnis secara terpadu.
Membuat tugas terpisah untuk setiap lini bisnis mengakibatkan biaya maintenance tinggi dan rentan kesalahan. Dengan for-each node, Anda hanya perlu memelihara satu set logika pemrosesan, dan sistem secara otomatis melakukan iterasi melalui semua lini bisnis untuk menyelesaikan komputasi.
Penyiapan data
Pertama, buat tabel sampel dan masukkan data uji (menggunakan tanggal bisnis 20251010 sebagai contoh).
Kaitkan sumber daya komputasi dengan workspace.
Buka Data Studio untuk pengembangan data dan buat node MaxCompute SQL.
Buat tabel sumber (lapisan DWD): Tambahkan kode berikut ke node MaxCompute SQL dan jalankan.
-- Tabel perilaku pengguna e-dagang CREATE TABLE IF NOT EXISTS dwd_user_behavior_ecom_d ( user_id STRING COMMENT 'User ID', action_type STRING COMMENT 'Action type', event_time BIGINT COMMENT 'Event timestamp in milliseconds (Unix)' ) COMMENT 'E-commerce user behavior log detail table' PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd'); INSERT OVERWRITE TABLE dwd_user_behavior_ecom_d PARTITION (dt='20251010') VALUES ('user001', 'click', 1760004060000), -- 2025-10-10 10:01:00.000 ('user002', 'browse', 1760004150000), -- 2025-10-10 10:02:30.000 ('user001', 'add_to_cart', 1760004300000); -- 2025-10-10 10:05:00.000 -- Verifikasi tabel perilaku pengguna e-dagang berhasil dibuat SELECT * FROM dwd_user_behavior_ecom_d where dt='20251010'; -- Tabel perilaku pengguna keuangan CREATE TABLE IF NOT EXISTS dwd_user_behavior_finance_d ( user_id STRING COMMENT 'User ID', action_type STRING COMMENT 'Action type', event_time BIGINT COMMENT 'Event timestamp in milliseconds (Unix)' ) COMMENT 'Finance user behavior log detail table' PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd'); INSERT OVERWRITE TABLE dwd_user_behavior_finance_d PARTITION (dt='20251010') VALUES ('user003', 'open_app', 1760020200000), -- 2025-10-10 14:30:00.000 ('user003', 'transfer', 1760020215000), -- 2025-10-10 14:30:15.000 ('user003', 'check_balance', 1760020245000), -- 2025-10-10 14:30:45.000 ('user004', 'open_app', 1760020300000); -- 2025-10-10 14:31:40.000 -- Verifikasi tabel perilaku pengguna keuangan berhasil dibuat SELECT * FROM dwd_user_behavior_finance_d where dt='20251010'; -- Tabel perilaku pengguna logistik CREATE TABLE IF NOT EXISTS dwd_user_behavior_logistics_d ( user_id STRING COMMENT 'User ID', action_type STRING COMMENT 'Action type', event_time BIGINT COMMENT 'Event timestamp in milliseconds (Unix)' ) COMMENT 'Logistics user behavior log detail table' PARTITIONED BY (dt STRING COMMENT 'Date partition, format yyyymmdd'); INSERT OVERWRITE TABLE dwd_user_behavior_logistics_d PARTITION (dt='20251010') VALUES ('user001', 'check_status', 1760032800000), -- 2025-10-10 18:00:00.000 ('user005', 'schedule_pickup', 1760032920000); -- 2025-10-10 18:02:00.000 -- Verifikasi tabel perilaku pengguna logistik berhasil dibuat SELECT * FROM dwd_user_behavior_logistics_d where dt='20251010';Buat tabel target (lapisan DWS): Tambahkan kode berikut ke node MaxCompute SQL dan jalankan.
CREATE TABLE IF NOT EXISTS dws_user_summary_d ( user_id STRING COMMENT 'User ID', pv BIGINT COMMENT 'Daily activity count' ) COMMENT 'User daily activity summary table' PARTITIONED BY ( dt STRING COMMENT 'Date partition, format yyyymmdd', biz_line STRING COMMENT 'Business line partition, e.g. ecom, finance, logistics' );PentingJika workspace menggunakan mode standar, Anda perlu mendeploy node ini ke lingkungan produksi dan melakukan backfill data.
Implementasi alur kerja
Buat alur kerja. Di bagian Scheduling Parameters di sisi kanan, atur parameter penjadwalan bizdate ke hari sebelumnya:
$[yyyymmdd-1].Di alur kerja, buat assignment node bernama get_biz_list dan tulis kode berikut dalam MaxCompute SQL. Node ini mengeluarkan daftar lini bisnis yang akan diproses:
-- Output semua lini bisnis yang akan diproses SELECT 'ecom' AS biz_line UNION ALL SELECT 'finance' AS biz_line UNION ALL SELECT 'logistics' AS biz_line;Konfigurasikan for-each node
Kembali ke halaman alur kerja dan buat node for-each hilir untuk assignment node get_biz_list.
Buka halaman pengaturan for-each node. Di bagian di bawah schedule settings di sisi kanan, ikat parameter loopDataArray ke outputs node get_biz_list.
Di loop body for-each node, klik Create Internal Node dan buat node MaxCompute SQL. Tulis logika pemrosesan di dalam loop body.
CatatanSkrip ini digerakkan oleh for-each node dan dieksekusi sekali untuk setiap lini bisnis.
Variabel bawaan ${dag.foreach.current} secara dinamis diganti dengan nama lini bisnis saat ini pada setiap iterasi. Nilai iterasi yang diharapkan adalah: 'ecom', 'finance', 'logistics'.
SET odps.sql.allow.dynamic.partition=true; INSERT OVERWRITE TABLE dws_user_summary_d PARTITION (dt='${bizdate}', biz_line) SELECT user_id, COUNT(*) AS pv, '${dag.foreach.current}' AS biz_line FROM dwd_user_behavior_${dag.foreach.current}_d WHERE dt = '${bizdate}' GROUP BY user_id;
Tambahkan node verifikasi
Kembali ke alur kerja. Klik Create Downstream pada for-each node untuk membuat node MaxCompute SQL dan tambahkan kode berikut.
SELECT * FROM dws_user_summary_d WHERE dt='20251010' ORDER BY biz_line, user_id;
Penyebaran dan hasil
Deploy alur kerja ke lingkungan produksi. Buka halaman di Operation Center. Temukan alur kerja target dan lakukan smoke testing dengan tanggal bisnis diatur ke '20251010'.
Setelah eksekusi selesai, lihat log waktu proses di test instance. Output yang diharapkan dari node terakhir adalah sebagai berikut:
user_id | pv | dt | biz_line |
user001 | 2 | 20251010 | ecom |
user002 | 1 | 20251010 | ecom |
user003 | 3 | 20251010 | finance |
user004 | 1 | 20251010 | finance |
user001 | 1 | 20251010 | logistics |
user005 | 1 | 20251010 | logistics |
Keunggulan
Skalabilitas tinggi: Untuk menambahkan lini bisnis baru, cukup tambahkan satu baris SQL di assignment node tanpa mengubah logika pemrosesan.
Maintenance mudah: Semua lini bisnis berbagi satu set logika pemrosesan. Satu modifikasi berlaku untuk semuanya.
FAQ
-
Q: Mengapa saya tidak bisa menjalankan for-each node secara langsung di Data Studio untuk mengujinya?
A: Ini sesuai desain. Node tersebut memerlukan lingkungan penjadwalan lengkap untuk menyelesaikan node context dan dependensinya, sehingga tidak mendukung eksekusi langsung di Data Studio. Anda harus deploy tugas ke Operation Center dan mengujinya menggunakan backfill atau memicu eksekusi terjadwal.
-
Q: Mengapa smoke test pada for-each node individual gagal atau tidak melakukan apa-apa?
A: Data loop untuk for-each node berasal dari parameter input
loopDataArray, yang harus bound ke parameteroutputsdari assignment node hulu. Jika Anda menjalankan for-each node sendirian, node tersebut akan gagal atau dilewati karena tidak menerima result set input. -
Q: Mengapa loop saya hanya berjalan sekali?
A: Hal ini biasanya terjadi karena output dari assignment node hulu diurai sebagai satu elemen tunggal. Periksa output Anda:
-
1. Apakah berupa string tunggal tanpa pembatas?
-
2. Jika Anda ingin melakukan iterasi atas beberapa item, pastikan item-item tersebut dipisahkan dengan koma (
,). Misalnya,'item1,item2,item3'menghasilkan tiga loop, sedangkan'item1 item2 item3'hanya menghasilkan satu loop.
-