Memantau proses ETL dalam gudang data kecil

Ramai orang menggunakan alat khusus untuk membuat rutin untuk mengekstrak, mengubah dan memuatkan data ke dalam pangkalan data hubungan. Proses alat direkodkan, ralat direkodkan.

Sekiranya berlaku ralat, log mengandungi maklumat bahawa alat itu gagal menyelesaikan tugas dan modul mana (selalunya java) berhenti di mana. Baris terakhir mungkin mengandungi ralat pangkalan data, seperti pelanggaran kunci unik jadual.

Untuk menjawab persoalan tentang peranan yang dimainkan oleh maklumat ralat ETL, saya mengklasifikasikan semua masalah yang berlaku sejak dua tahun lalu dalam repositori yang agak besar.

Memantau proses ETL dalam gudang data kecil

Ralat pangkalan data termasuk seperti: ruang tidak mencukupi, sambungan terputus, sesi digantung, dsb.

Ralat logik termasuk pelanggaran kekunci jadual, objek tidak sah, kekurangan akses kepada objek, dsb.
Penjadual mungkin tidak dilancarkan tepat pada masanya, mungkin membeku, dsb.

Kesilapan mudah tidak memerlukan banyak masa untuk diperbetulkan. ETL yang baik boleh mengendalikan kebanyakannya sendiri.

Ralat kompleks menjadikannya perlu untuk membuka dan menyemak prosedur pengendalian data dan meneroka sumber data. Selalunya membawa kepada keperluan untuk menguji perubahan dan menggunakan.

Jadi, separuh daripada semua masalah berkaitan dengan pangkalan data. 48% daripada semua ralat adalah ralat mudah.
Satu pertiga daripada semua masalah berkaitan dengan perubahan dalam logik atau model storan; lebih separuh daripada ralat ini adalah kompleks.

Dan kurang daripada satu perempat daripada semua masalah berkaitan dengan penjadual tugas, 18% daripadanya adalah ralat mudah.

Secara keseluruhan, 22% daripada semua ralat yang berlaku adalah rumit dan memerlukan perhatian dan masa yang paling banyak untuk membetulkannya. Ia berlaku kira-kira sekali seminggu. Sedangkan kesilapan mudah berlaku hampir setiap hari.

Jelas sekali, pemantauan proses ETL akan berkesan apabila lokasi ralat ditunjukkan dalam log setepat mungkin dan masa yang minimum diperlukan untuk mencari punca masalah.

Pemantauan yang berkesan

Apakah yang saya mahu lihat dalam proses pemantauan ETL?

Memantau proses ETL dalam gudang data kecil
Mula pada - apabila saya mula bekerja,
Sumber - sumber data,
Lapisan - tahap storan yang dimuatkan,
Nama Kerja ETL ialah prosedur pemuatan yang terdiri daripada banyak langkah kecil,
Nombor Langkah β€” nombor langkah yang sedang dilaksanakan,
Baris Terjejas - berapa banyak data yang telah diproses,
Tempoh saat - berapa lama masa yang diperlukan untuk dilaksanakan,
Status - sama ada semuanya baik atau tidak: OK, ERROR, RUNNING, HANGS
Mesej β€” mesej terakhir yang berjaya atau penerangan ralat.

Berdasarkan status rekod, anda boleh menghantar e-mel. surat kepada peserta lain. Sekiranya tidak ada kesilapan, maka surat tidak diperlukan.

Dengan cara ini, sekiranya berlaku ralat, lokasi kejadian ditunjukkan dengan jelas.

Kadang-kadang ia berlaku bahawa alat pemantauan itu sendiri tidak berfungsi. Dalam kes ini, adalah mungkin untuk memanggil paparan (pandangan) secara langsung dalam pangkalan data, berdasarkan laporan yang dibina.

Jadual pemantauan ETL

Untuk melaksanakan pemantauan proses ETL, satu jadual dan satu paparan sudah memadai.

Untuk melakukan ini, anda boleh kembali ke simpanan kecil anda sendiri dan buat prototaip dalam pangkalan data sqlite.

jadual DDL

CREATE TABLE UTL_JOB_STATUS (
/* Table for logging of job execution log. Important that the job has the steps ETL_START and ETL_END or ETL_ERROR */
  UTL_JOB_STATUS_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  SID               INTEGER NOT NULL DEFAULT -1, /* Session Identificator. Unique for every Run of job */
  LOG_DT            INTEGER NOT NULL DEFAULT 0,  /* Date time */
  LOG_D             INTEGER NOT NULL DEFAULT 0,  /* Date */
  JOB_NAME          TEXT NOT NULL DEFAULT 'N/A', /* Job name like JOB_STG2DM_GEO */
  STEP_NAME         TEXT NOT NULL DEFAULT 'N/A', /* ETL_START, ... , ETL_END/ETL_ERROR */
  STEP_DESCR        TEXT,                        /* Description of task or error message */
  UNIQUE (SID, JOB_NAME, STEP_NAME)
);
INSERT INTO UTL_JOB_STATUS (UTL_JOB_STATUS_ID) VALUES (-1);

Lihat/laporkan DDL

CREATE VIEW IF NOT EXISTS UTL_JOB_STATUS_V
AS /* Content: Package Execution Log for last 3 Months. */
WITH SRC AS (
  SELECT LOG_D,
    LOG_DT,
    UTL_JOB_STATUS_ID,
    SID,
	CASE WHEN INSTR(JOB_NAME, 'FTP') THEN 'TRANSFER' /* file transfer */
	     WHEN INSTR(JOB_NAME, 'STG') THEN 'STAGE' /* stage */
	     WHEN INSTR(JOB_NAME, 'CLS') THEN 'CLEANSING' /* cleansing */
	     WHEN INSTR(JOB_NAME, 'DIM') THEN 'DIMENSION' /* dimension */
	     WHEN INSTR(JOB_NAME, 'FCT') THEN 'FACT' /* fact */
		 WHEN INSTR(JOB_NAME, 'ETL') THEN 'STAGE-MART' /* data mart */
	     WHEN INSTR(JOB_NAME, 'RPT') THEN 'REPORT' /* report */
	     ELSE 'N/A' END AS LAYER,
	CASE WHEN INSTR(JOB_NAME, 'ACCESS') THEN 'ACCESS LOG' /* source */
	     WHEN INSTR(JOB_NAME, 'MASTER') THEN 'MASTER DATA' /* source */
	     WHEN INSTR(JOB_NAME, 'AD-HOC') THEN 'AD-HOC' /* source */
	     ELSE 'N/A' END AS SOURCE,
    JOB_NAME,
    STEP_NAME,
    CASE WHEN STEP_NAME='ETL_START' THEN 1 ELSE 0 END AS START_FLAG,
    CASE WHEN STEP_NAME='ETL_END' THEN 1 ELSE 0 END AS END_FLAG,
    CASE WHEN STEP_NAME='ETL_ERROR' THEN 1 ELSE 0 END AS ERROR_FLAG,
    STEP_NAME || ' : ' || STEP_DESCR AS STEP_LOG,
	SUBSTR( SUBSTR(STEP_DESCR, INSTR(STEP_DESCR, '***')+4), 1, INSTR(SUBSTR(STEP_DESCR, INSTR(STEP_DESCR, '***')+4), '***')-2 ) AS AFFECTED_ROWS
  FROM UTL_JOB_STATUS
  WHERE datetime(LOG_D, 'unixepoch') >= date('now', 'start of month', '-3 month')
)
SELECT JB.SID,
  JB.MIN_LOG_DT AS START_DT,
  strftime('%d.%m.%Y %H:%M', datetime(JB.MIN_LOG_DT, 'unixepoch')) AS LOG_DT,
  JB.SOURCE,
  JB.LAYER,
  JB.JOB_NAME,
  CASE
  WHEN JB.ERROR_FLAG = 1 THEN 'ERROR'
  WHEN JB.ERROR_FLAG = 0 AND JB.END_FLAG = 0 AND strftime('%s','now') - JB.MIN_LOG_DT > 0.5*60*60 THEN 'HANGS' /* half an hour */
  WHEN JB.ERROR_FLAG = 0 AND JB.END_FLAG = 0 THEN 'RUNNING'
  ELSE 'OK'
  END AS STATUS,
  ERR.STEP_LOG     AS STEP_LOG,
  JB.CNT           AS STEP_CNT,
  JB.AFFECTED_ROWS AS AFFECTED_ROWS,
  strftime('%d.%m.%Y %H:%M', datetime(JB.MIN_LOG_DT, 'unixepoch')) AS JOB_START_DT,
  strftime('%d.%m.%Y %H:%M', datetime(JB.MAX_LOG_DT, 'unixepoch')) AS JOB_END_DT,
  JB.MAX_LOG_DT - JB.MIN_LOG_DT AS JOB_DURATION_SEC
FROM
  ( SELECT SID, SOURCE, LAYER, JOB_NAME,
           MAX(UTL_JOB_STATUS_ID) AS UTL_JOB_STATUS_ID,
           MAX(START_FLAG)       AS START_FLAG,
           MAX(END_FLAG)         AS END_FLAG,
           MAX(ERROR_FLAG)       AS ERROR_FLAG,
           MIN(LOG_DT)           AS MIN_LOG_DT,
           MAX(LOG_DT)           AS MAX_LOG_DT,
           SUM(1)                AS CNT,
           SUM(IFNULL(AFFECTED_ROWS, 0)) AS AFFECTED_ROWS
    FROM SRC
    GROUP BY SID, SOURCE, LAYER, JOB_NAME
  ) JB,
  ( SELECT UTL_JOB_STATUS_ID, SID, JOB_NAME, STEP_LOG
    FROM SRC
    WHERE 1 = 1
  ) ERR
WHERE 1 = 1
  AND JB.SID = ERR.SID
  AND JB.JOB_NAME = ERR.JOB_NAME
  AND JB.UTL_JOB_STATUS_ID = ERR.UTL_JOB_STATUS_ID
ORDER BY JB.MIN_LOG_DT DESC, JB.SID DESC, JB.SOURCE;

SQL Memeriksa keupayaan untuk mendapatkan nombor sesi baharu

SELECT SUM (
  CASE WHEN start_job.JOB_NAME IS NOT NULL AND end_job.JOB_NAME IS NULL /* existed job finished */
	    AND NOT ( 'y' = 'n' ) /* force restart PARAMETER */
       THEN 1 ELSE 0
  END ) AS IS_RUNNING
  FROM
    ( SELECT 1 AS dummy FROM UTL_JOB_STATUS WHERE sid = -1) d_job
  LEFT OUTER JOIN
    ( SELECT JOB_NAME, SID, 1 AS dummy
      FROM UTL_JOB_STATUS
      WHERE JOB_NAME = 'RPT_ACCESS_LOG' /* job name PARAMETER */
	    AND STEP_NAME = 'ETL_START'
      GROUP BY JOB_NAME, SID
    ) start_job /* starts */
  ON d_job.dummy = start_job.dummy
  LEFT OUTER JOIN
    ( SELECT JOB_NAME, SID
      FROM UTL_JOB_STATUS
      WHERE JOB_NAME = 'RPT_ACCESS_LOG'  /* job name PARAMETER */
	    AND STEP_NAME in ('ETL_END', 'ETL_ERROR') /* stop status */
      GROUP BY JOB_NAME, SID
    ) end_job /* ends */
  ON start_job.JOB_NAME = end_job.JOB_NAME
     AND start_job.SID = end_job.SID

Ciri-ciri Jadual:

  • permulaan dan akhir prosedur pemprosesan data mesti disertakan dengan langkah-langkah ETL_START dan ETL_END
  • sekiranya berlaku ralat, langkah ETL_ERROR hendaklah dibuat dengan penerangannya
  • jumlah data yang diproses harus diserlahkan, contohnya, dengan asterisk
  • prosedur yang sama boleh dimulakan pada masa yang sama dengan parameter force_restart=y; tanpa itu, nombor sesi dikeluarkan hanya kepada prosedur yang lengkap
  • dalam mod biasa adalah mustahil untuk menjalankan prosedur pemprosesan data yang sama secara selari

Operasi yang diperlukan untuk bekerja dengan jadual adalah seperti berikut:

  • mendapatkan nombor sesi prosedur ETL yang dilancarkan
  • memasukkan catatan log ke dalam jadual
  • mendapatkan rekod kejayaan terakhir prosedur ETL

Dalam pangkalan data seperti Oracle atau Postgres, operasi ini boleh dilaksanakan dengan fungsi terbina dalam. sqlite memerlukan mekanisme luaran dan dalam kes ini ia prototaip dalam PHP.

Output

Oleh itu, pelaporan ralat dalam alat pemprosesan data memainkan peranan yang sangat penting. Tetapi mereka tidak boleh dipanggil optimum untuk mencari punca masalah dengan cepat. Apabila bilangan prosedur menghampiri seratus, pemantauan proses bertukar menjadi projek yang kompleks.

Artikel tersebut memberikan contoh penyelesaian yang mungkin untuk masalah dalam bentuk prototaip. Keseluruhan prototaip repositori kecil tersedia dalam gitlab Utiliti SQLite PHP ETL.

Sumber: www.habr.com

Tambah komen