Semuanya dimulai dengan fakta bahwa kita dihadapkan dengan kebutuhan untuk dengan cepat dan benar membentuk struktur EDWEX, JSON, DDL dan kemudian menggulungnya pada kontur yang berbeda dari basis data relasional. Dengan kontur, maksud saya singkatan yang semua orang tahu - DEV, TST, UAT, PRD.

Pada saat itu, kami melakukan hampir semuanya secara manual: kami menghasilkan DDL, dan mengumpulkan edwex dan json berdasarkan metadata dari database Oracle. Ada banyak parameter input. Jika Anda melewatkan satu, Anda akan salah membentuk entitas. Dan karena seluruh proses pembentukan konsisten dan berkelanjutan, kesalahan hanya akan terdeteksi di bagian paling akhir. Tentang bagaimana kita semua otomatis dan mengatasi kesalahan, baca di bawah potongan.
Sedikit tentang infrastruktur
Sebelum kita mengisi data dalam tabel database relasional, kita perlu menerimanya dari sumber - dalam format apa pun, misalnya, di Excel. Data dari sumber menggunakan mekanisme in-house diangkut ke Hadoop (Data Lake). Hive telah menginstal add-on Hive - dengan bantuannya kita dapat melihat konten file menggunakan sintaks seperti SQL.
Untuk mentransfer data di Danau Data dalam bentuk tabel, kita perlu json, yang dibentuk berdasarkan metadata. Untuk mem-parsing data dalam format Excel, kita perlu membuat file EDWEX. File EDWEX (EDW_EXTRACTOR) adalah seperangkat artefak yang berisi set tabel dengan nama, serta set bidang untuk masing-masing tabel ini, yang dibentuk berdasarkan metadata. Bergantung pada versi model dan ID sumber, set bidang bervariasi. Pembentukan DDL diperlukan untuk membuat tabel sendiri dalam database Hive di tingkat data operasional dan dalam database Greenplum di tingkat data terperinci dan agregat. Artinya, data terutama ditransfer ke Hive, jika perlu, disaring dan ditransfer ke Greenplum untuk manipulasi data selanjutnya dan membuat etalase toko berdasarkan itu.
Contoh artefak Edwexpak - berisi seperangkat tabel
data - berisi sekumpulan bidang
pack.edwex:
1 Table_1 User Table_1 bid between to_char($fromdt,'yyyymm') and to_char($actualdt,'yyyymm') 2 Table_2 User Table_2 curbid between to_char($fromdt,'yyyymm') and to_char($actualdt,'yyyymm') 3 Table_3 User Table_3 bid between to_char($fromdt,'yyyymm') and to_char($actualdt,'yyyymm')
data.edwex:
1 1 CHARGE_ID NUMBER 38 0 1 2 SVC_ID NUMBER 38 0 1 3 VND_ID NUMBER 38 0 1 4 PRICE NUMBER 38 5 1 5 QUANTITY NUMBER 38 5 1 6 BASE NUMBER 38 5 1 7 TAX NUMBER 38 5 1 8 TOTAL NUMBER 38 5 1 9 TAX_RATE NUMBER 38 5 1 10 TAX_IN VARCHAR 1 1 11 CHARGE_KIND VARCHAR 3 1 12 PRIVILEGE_ID NUMBER 38 0 1 13 CHARGE_REF_ID NUMBER 38 0 1 14 EBID NUMBER 38 0 1 15 INVOICE_ID NUMBER 38 0 1 16 ZERO_STATE_ID NUMBER 38 0 1 17 USER_ID NUMBER 38 0 1 18 BID NUMBER 38 0 1 19 QUANTITY_REAL NUMBER 38 5 2 1 CURBID NUMBER 38 0 2 2 USER_ID NUMBER 38 0 2 3 VND_ID NUMBER 38 0 2 4 APPBID NUMBER 38 0 2 5 SVC_ID NUMBER 38 0 2 6 DEBT NUMBER 38 5 2 7 INSTDEBT NUMBER 38 5 3 1 INVOICE_ID NUMBER 38 0 3 2 INVOICE_DATE DATE 3 3 INVOICE_NUM VARCHAR 64 3 4 INVOICE_NUM_N NUMBER 38 5 3 5 BASE NUMBER 38 5 3 6 TAX NUMBER 38 5 3 7 TOTAL NUMBER 38 5 3 8 PREPAID VARCHAR 1 3 9 EXPLICIT VARCHAR 1 3 10 VND_ID NUMBER 38 0 3 11 ADV_PAYMENT_ID NUMBER 38 0 3 12 MDBID NUMBER 38 0 3 13 BID NUMBER 38 0 3 14 USER_ID NUMBER 38 0 3 15 ZERO_STATE_ID NUMBER 38 0 3 16 ACTIVE_SUM NUMBER 38 5 3 17 SPLIT_VND NUMBER 38 5 3 18 PRECREATED VARCHAR 1
Contoh artefak Json Table.json: { "metadata": [ { "colOrder":"1", "name":"charge_id", "dataType":"DECIMAL", "precision":"0", "requied":"true", "keyFile":"" }, { "colOrder":"2", "name":"svc_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"3", "name":"vnd_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"4", "name":"price", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"5", "name":"quantity", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"6", "name":"base", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"7", "name":"tax", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"8", "name":"total", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"9", "name":"tax_rate", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"10", "name":"tax_in", "dataType":"STRING", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"11", "name":"charge_kind", "dataType":"STRING", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"12", "name":"privilege_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"13", "name":"charge_ref_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"14", "name":"ebid", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"15", "name":"invoice_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"16", "name":"zero_state_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"17", "name":"user_id", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"18", "name":"bid", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" }, { "colOrder":"19", "name":"quantity_real", "dataType":"DECIMAL", "precision":"0", "requied":"false", "keyFile":"" } ], "ctlPath":" ctl", "errPath":" ", "inPath":" hdfs", "outSchema":" ", "outTable":" ", "isPartitioned":" ", "sourceId":"id " }
Contoh Artefak DDLubah skema tabel.GP_000001_TABLE ganti nama menjadi Z_GP_000001_TABLE_20180807;
buat skema tabel.GP_000001_TABLE
(
`charge_id` DECIMAL (38.0),
`svc_id` DECIMAL (38.0),
`vnd_id` DECIMAL (38.0),
`price` DECIMAL (38.5),
`Kuantitas` DECIMAL (38.5),
`base` DECIMAL (38.5),
`pajak` DECIMAL (38.5),
`total` DECIMAL (38.5),
`tax_rate` DECIMAL (38.5),
`tax_in` STRING,
`charge_kind` STRING,
`privilege_id` DECIMAL (38.0),
`charge_ref_id` DECIMAL (38.0),
`ebid` DECIMAL (38.0),
`invoice_id` DECIMAL (38.0),
`zero_state_id` DECIMAL (38,0),
`user_id` DECIMAL (38.0),
`bid` DECIMAL (38.0),
`quantity_real` DECIMAL (38.5),
`load_dttm` TIMESTAMP,
`src_id` SMALLINT,
`package_id` BIGINT,
`wf_run_id` BIGINT,
`md5` STRING
)
BENTUK FORMAT BIDANG YANG DITETAPKAN DIAKHIRI OLEH '\ t'
DIIMPOR SEBAGAI INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOKASI 'cara untuk membentuk dalam HDFS'
TBLPROPERTIES ('auto.purge' = 'true', 'transient_lastDlastDdlTime' = '1489060201');
masukkan ke dalam skema.GP_000001_TABLE (`charge_id`,
`svc_id`,
`vnd_id`,
`harga`,
`kuantitas`,
`base`,
`pajak`,
`total`,
`tax_rate`,
`tax_in`,
`charge_kind`,
`privilege_id`,
`charge_ref_id`,
`ebid`,
`invoice_id`,
`zero_state_id`,
`user_id`,
menawar
`quantity_real`,
`load_dttm`,
`src_id`,
package_id
`wf_run_id`,
`md5`)
pilih `charge_id`,
`svc_id`,
`vnd_id`,
`harga`,
`kuantitas`,
`base`,
`pajak`,
`total`,
`tax_rate`,
`tax_in`,
`charge_kind`,
`privilege_id`,
`charge_ref_id`,
`ebid`,
`invoice_id`,
`zero_state_id`,
`user_id`,
menawar
`quantity_real`,
load_dttm,
src_id
package_id,
wf_run_id,
md5 dari scheme.Z_GP_000001_TABLE_20180807;
ubah skema tabel.GP_000001_TABLE ganti nama menjadi Z_GP_000001_TABLE_20180807;
buat skema tabel.GP_000001_TABLE
(
`charge_id` DECIMAL (38.0),
`svc_id` DECIMAL (38.0),
`vnd_id` DECIMAL (38.0),
`price` DECIMAL (38.5),
`Kuantitas` DECIMAL (38.5),
`base` DECIMAL (38.5),
`pajak` DECIMAL (38.5),
`total` DECIMAL (38.5),
`tax_rate` DECIMAL (38.5),
`tax_in` STRING,
`charge_kind` STRING,
`privilege_id` DECIMAL (38.0),
`charge_ref_id` DECIMAL (38.0),
`ebid` DECIMAL (38.0),
`invoice_id` DECIMAL (38.0),
`zero_state_id` DECIMAL (38,0),
`user_id` DECIMAL (38.0),
`bid` DECIMAL (38.0),
`quantity_real` DECIMAL (38.5),
`load_dttm` TIMESTAMP,
`src_id` SMALLINT,
`package_id` BIGINT,
`wf_run_id` BIGINT,
`md5` STRING
)
BENTUK FORMAT BIDANG YANG DITETAPKAN DIAKHIR OLEH '\ t'
DIIMPOR SEBAGAI INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOKASI 'cara untuk membentuk dalam HDFS'
TBLPROPERTIES ('auto.purge' = 'true', 'transient_lastDlastDdlTime' = '1489060201');
masukkan ke dalam skema.GP_000001_CPA_CHARGE (`charge_id`,
`svc_id`,
`vnd_id`,
`harga`,
`kuantitas`,
`base`,
`pajak`,
`total`,
`tax_rate`,
`tax_in`,
`charge_kind`,
`privilege_id`,
`charge_ref_id`,
`ebid`,
`invoice_id`,
`zero_state_id`,
`user_id`,
menawar
`quantity_real`,
`load_dttm`,
`src_id`,
package_id
`wf_run_id`,
`md5`)
pilih `charge_id`,
`svc_id`,
`vnd_id`,
`harga`,
`kuantitas`,
`base`,
`pajak`,
`total`,
`tax_rate`,
`tax_in`,
`charge_kind`,
`privilege_id`,
`charge_ref_id`,
`ebid`,
`invoice_id`,
`zero_state_id`,
`user_id`,
menawar
`quantity_real`,
load_dttm,
src_id
package_id,
wf_run_id,
md5 dari scheme.Z_GP_000001_TABLE_20180807;
Cara mengotomatisasi
Untuk mengatasi masalah, kami menggunakan:
- Jenkins - sebagai orkestra dan alat untuk mengimplementasikan proses CI.
- Python - ini mengimplementasikan fungsi dan unit test.
- SQL - untuk mengakses database metadata.
- Script Shell - untuk menyalin artefak antara direktori dan membuat skrip dalam proyek multijob yang berjalan di server Jenkins.
Untuk memulainya, kami awalnya bekerja dengan sejumlah besar sumber, oleh karena itu, menggunakan skrip Shell sebagai parameter awal, kami meneruskan ID sumber untuk fungsi SQL untuk mengidentifikasi mereka. Fungsi SQL yang dihasilkan selanjutnya akan secara otomatis dieksekusi di database metadata. Berdasarkan metadata yang tersedia, fungsi-fungsi ini membentuk file dengan daftar fungsi SQL baru untuk masing-masing tabel sumber sehingga kita selanjutnya dapat memanggil mereka dalam program yang dapat dieksekusi. Hasil dari eksekusi fungsi-fungsi yang dihasilkan adalah transfer nilai-nilai DDL, JSON atau EDWEX ke parameter output.
Di sinilah Python terhubung, dengan semua fungsi yang dapat dieksekusi dan tes unit ditulis. Sebelum memulai salah satu modul untuk menggulung artefak menggunakan unit test, transfer parameter yang benar diperiksa untuk menjalankan skrip python. Pengujian tidak hanya memeriksa kebenaran parameter input, tetapi juga keberadaannya dalam modul metadata, ukuran file yang dibuat, dan tanggal pembuatannya. Tes juga memantau jumlah artefak baru yang dibuat dan jumlah artefak yang ada. Jadi kami mengoptimalkan penggunaan sumber daya server, karena kami hanya mengambil file baru untuk bergulir dan tidak menginstal ulang model yang ada lagi.
Dan hanya setelah berhasil melewati semua pemeriksaan adalah program python dieksekusi yang menciptakan artefak yang diperlukan dan menguraikan hasilnya ke dalam folder proyek yang diperlukan di server. Python tidak hanya mengarahkan file json yang dihasilkan ke direktori, tetapi juga membentuk struktur ke dalam Data Lake sehingga data dimuat dengan benar. Ketika menghasilkan artefak DDL, mereka tidak hanya disimpan untuk analisis dan penggunaan kembali nanti, tetapi juga dapat segera diinstal dalam database menggunakan model dan struktur baru yang ditentukan dalam modul metadata. Ini memungkinkan Anda membuat ratusan tabel dalam waktu singkat tanpa melibatkan tenaga kerja manual.
Dan di mana Jenkins di sini?
Jenkins masuk ketika perlu untuk mengelola semua proses ini secara visual menggunakan antarmuka.
Alat ini dipilih karena:
- sepenuhnya mencakup kebutuhan untuk otomatisasi perakitan dan pemasangan
- memungkinkan Anda merancang mekanisme untuk merakit artefak dengan penerapan proses pengujian mandiri
- memungkinkan Anda mengelola peluncuran pekerjaan dan memantau eksekusi dengan mudah ke orang yang jauh dari pemrograman
- memungkinkan Anda untuk mengonfigurasi mekanisme pencatatan sedemikian rupa sehingga hasil eksekusi akan dapat dipahami oleh siapa pun di tim. Masalah dalam majelis akan diindikasikan secara eksplisit atau proses akan selesai dengan sukses.
Untuk menyelesaikan tugas, kami telah membuat beberapa proyek multijob. Jenis proyek ini telah digunakan, karena dapat bekerja secara paralel dengan pekerjaan lain dalam satu permulaan. Setiap pekerjaan bertanggung jawab atas implementasi blok fungsionalitasnya. Jadi kami mengganti proses berurutan untuk mendapatkan artefak dengan yang paralel otonom. Semuanya dimulai secara terpisah: pembentukan EDWEX, JSON, DDL, pembentukan struktur dalam HIVE, pemasangan struktur tabel dalam database. Kami menganalisis hasilnya pada berbagai tahap pembentukan artefak dan melanjutkan untuk meluncurkan tindakan selanjutnya jika berhasil.
Bagian Jenkins diimplementasikan tanpa banyak trik. Parameter
String atau
Run dikirim ke input untuk memulai kode python. Parameter
String adalah jendela untuk memasukkan nilai tipe str sebelum memulai. Parameter
run dapat ditransfer dengan cepat ke pekerjaan lain untuk dieksekusi, untuk ini cukup hanya untuk menunjukkan dari proyek mana perlu untuk mengambil variabel yang diterima. Juga, sebuah node dilewatkan sebagai parameter terpisah untuk eksekusi. Di sini, partisi menjadi runtime pada DEV, TST, UAT, PRD baru saja diimplementasikan. Pekerjaan terpisah digunakan untuk mentransfer file EDWEX yang diterima ke SVN dengan nomor revisi agar dapat melacak versi struktur yang diubah.
Contoh antarmuka dalam Jenkins:

Hasil dari pelaksanaan pekerjaan adalah pembuatan dan pemasangan artefak yang diperlukan, transfernya ke SVN dan pembentukan laporan HTML yang menampilkan keberhasilan lulus uji unit dan hasil perakitan dan pemasangan artefak. Pekerjaan dapat dijalankan secara individual dengan tangan Anda, atau dalam mode otomatis, setelah sebelumnya membangun rantai eksekusi.
Arsitektur mekanisme pemasangan dan pemasanganUntuk meringkas
Banyak pekerjaan telah dilakukan untuk mengotomatisasi pembentukan artefak. Sebelumnya, Anda harus memanjat ke server secara manual, menjalankan skrip shell, lalu mempelajari dan mengedit data untuk waktu yang lama dengan tangan Anda. Sekarang cukup klik pada tombol start, tentukan ID sistem sumber, nomor model dan loop eksekusi. Dengan bantuan Jenkins, adalah mungkin untuk menyusun dan memecah seluruh perakitan dan mekanisme pemasangan artefak menjadi tahap-tahap independen. Pemeriksaan yang diperlukan ditambahkan sebelum memulai pembentukan artefak dan integrasi mereka. Artefak yang diterima secara otomatis ditransfer ke SVN, yang menyederhanakan pekerjaan dengan tim analis sistem dan pemodel data yang terkait. Cek diterapkan untuk menghindari peluncuran formasi artefak yang menganggur dan mengkonfirmasi kebenarannya.
Hasilnya, kami mengurangi proses perakitan dan pemasangan artefak model yang memakan waktu dari beberapa jam menjadi beberapa menit. Dan yang paling penting, mereka menghilangkan terjadinya kesalahan karena faktor manusia, yang pasti muncul dalam proses rutin yang kompleks.