ProHoster > Blog > διαχείριση > Εργαλείο δημιουργίας δεδομένων ή αυτό που είναι κοινό μεταξύ του Data Warehouse και του Smoothie
Εργαλείο δημιουργίας δεδομένων ή αυτό που είναι κοινό μεταξύ του Data Warehouse και του Smoothie
Με ποιες αρχές χτίζεται μια ιδανική αποθήκη δεδομένων;
Επικεντρωθείτε στην επιχειρηματική αξία και τα αναλυτικά στοιχεία απουσία κωδικού λέβητα. Διαχείριση του DWH ως βάσης κωδικών: έκδοση εκδόσεων, αναθεώρηση, αυτοματοποιημένη δοκιμή και CI. Αρθρωτό, επεκτάσιμο, ανοιχτού κώδικα και κοινότητα. Φιλική προς τον χρήστη τεκμηρίωση και οπτικοποίηση εξαρτήσεων (Data Lineage).
Περισσότερα για όλα αυτά και για τον ρόλο του DBT στο οικοσύστημα Big Data & Analytics - Welcome to cat.
Γεια σε όλους
Ο Artemy Kozyr είναι σε επαφή. Για περισσότερα από 5 χρόνια εργάζομαι με αποθήκες δεδομένων, χτίζοντας ETL/ELT, καθώς και ανάλυση δεδομένων και οπτικοποίηση. Αυτή τη στιγμή εργάζομαι σε Wheely, διδάσκω στο OTUS σε ένα μάθημα Μηχανικός δεδομένων, και σήμερα θέλω να μοιραστώ μαζί σας ένα άρθρο που έγραψα εν όψει της έναρξης νέες εγγραφές για το μάθημα.
Σύντομη ανασκόπηση
Το πλαίσιο DBT αφορά το T στο ακρωνύμιο ELT (Extract - Transform - Load).
Με την εμφάνιση τέτοιων παραγωγικών και επεκτάσιμων αναλυτικών βάσεων δεδομένων όπως οι BigQuery, Redshift, Snowflake, δεν υπήρχε νόημα να κάνουμε μετασχηματισμούς εκτός της Αποθήκης Δεδομένων.
Το DBT δεν πραγματοποιεί λήψη δεδομένων από πηγές, αλλά παρέχει εξαιρετικές ευκαιρίες για εργασία με δεδομένα που έχουν ήδη φορτωθεί στον Αποθηκευτικό χώρο (σε Εσωτερική ή Εξωτερική αποθήκευση).
Ο κύριος σκοπός του DBT είναι να πάρει τον κώδικα, να τον μεταγλωττίσει σε SQL, να εκτελέσει τις εντολές με τη σωστή σειρά στο Repository.
Δομή έργου DBT
Το έργο αποτελείται από καταλόγους και αρχεία μόνο 2 τύπων:
Μοντέλο (.sql) - μια μονάδα μετασχηματισμού που εκφράζεται με ένα ερώτημα SELECT
Ο χρήστης προετοιμάζει τον κωδικό μοντέλου σε οποιοδήποτε βολικό IDE
Χρησιμοποιώντας το CLI, εκκινούνται μοντέλα, το DBT μεταγλωττίζει τον κώδικα μοντέλου σε SQL
Ο μεταγλωττισμένος κώδικας SQL εκτελείται στο Storage σε μια δεδομένη ακολουθία (γραφική παράσταση)
Δείτε πώς μπορεί να μοιάζει η εκτέλεση από το CLI:
Όλα είναι ΕΠΙΛΟΓΗ
Αυτό είναι ένα χαρακτηριστικό γνώρισμα του πλαισίου Data Build Tool. Με άλλα λόγια, το DBT αφαιρεί όλο τον κώδικα που σχετίζεται με την υλοποίηση των ερωτήσεών σας στο Store (παραλλαγές από τις εντολές CREATE, INSERT, UPDATE, DELETE ALTER, GRANT, ...).
Οποιοδήποτε μοντέλο περιλαμβάνει τη σύνταξη ενός ερωτήματος SELECT που ορίζει το σύνολο δεδομένων που προκύπτει.
Σε αυτήν την περίπτωση, η λογική μετασχηματισμού μπορεί να είναι πολυεπίπεδη και να ενοποιεί δεδομένα από πολλά άλλα μοντέλα. Ένα παράδειγμα μοντέλου που θα δημιουργήσει μια έκθεση παραγγελιών (f_orders):
{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}
with orders as (
select * from {{ ref('stg_orders') }}
),
order_payments as (
select * from {{ ref('order_payments') }}
),
final as (
select
orders.order_id,
orders.customer_id,
orders.order_date,
orders.status,
{% for payment_method in payment_methods -%}
order_payments.{{payment_method}}_amount,
{% endfor -%}
order_payments.total_amount as amount
from orders
left join order_payments using (order_id)
)
select * from final
Τι ενδιαφέροντα πράγματα μπορούμε να δούμε εδώ;
Πρώτον: Χρησιμοποιείται CTE (Κοινές εκφράσεις πίνακα) - για την οργάνωση και κατανόηση κώδικα που περιέχει πολλούς μετασχηματισμούς και επιχειρηματική λογική
Δεύτερον: Ο κώδικας μοντέλου είναι ένα μείγμα SQL και γλώσσας Jinja (γλώσσα προτύπου).
Το παράδειγμα χρησιμοποιεί έναν βρόχο for για να δημιουργήσετε το ποσό για κάθε τρόπο πληρωμής που καθορίζεται στην έκφραση σειρά. Χρησιμοποιείται επίσης η λειτουργία σχ — τη δυνατότητα αναφοράς άλλων μοντέλων εντός του κώδικα:
Κατά τη σύνταξη σχ θα μετατραπεί σε δείκτη προορισμού σε πίνακα ή προβολή στο χώρο αποθήκευσης
σχ σας επιτρέπει να δημιουργήσετε ένα γράφημα εξάρτησης μοντέλου
Ακριβώς Jinja προσθέτει σχεδόν απεριόριστες δυνατότητες στο DBT. Τα πιο συχνά χρησιμοποιούμενα είναι:
Δηλώσεις If / else - δηλώσεις κλάδου
Για βρόχους
Μεταβλητές
Μακροεντολή - δημιουργία μακροεντολών
Υλοποίηση: Πίνακας, Προβολή, Αύξουσα
Η στρατηγική υλοποίησης είναι μια προσέγγιση σύμφωνα με την οποία το προκύπτον σύνολο δεδομένων μοντέλου θα αποθηκευτεί στο Storage.
Βασικά είναι:
Πίνακας - φυσικός πίνακας στο Storage
Προβολή - προβολή, εικονικός πίνακας στο Storage
Υπάρχουν επίσης πιο σύνθετες στρατηγικές υλοποίησης:
Αυξητική - αυξητική φόρτωση (μεγάλων πινάκων δεδομένων). προστίθενται νέες γραμμές, ενημερώνονται οι αλλαγμένες γραμμές, διαγράφονται οι διαγραμμένες γραμμές
Εφήμερο - το μοντέλο δεν υλοποιείται άμεσα, αλλά συμμετέχει ως CTE σε άλλα μοντέλα
Οποιεσδήποτε άλλες στρατηγικές μπορείτε να προσθέσετε μόνοι σας
Εκτός από τις στρατηγικές υλοποίησης, υπάρχουν ευκαιρίες για βελτιστοποίηση για συγκεκριμένους Αποθηκευτικούς χώρους, για παράδειγμα:
Προς το παρόν υποστηρίζονται οι παρακάτω αποθηκευτικοί χώροι:
Postgres
Redshift
BigQuery
Νιφάδα χιονιού
Presto (μερικώς)
Spark (μερικώς)
Microsoft SQL Server (προσαρμογέας κοινότητας)
Ας βελτιώσουμε το μοντέλο μας:
Ας κάνουμε τη γέμισή του σταδιακή (Incremental)
Ας προσθέσουμε πλήκτρα τμηματοποίησης και ταξινόμησης για το Redshift
-- Конфигурация модели:
-- Инкрементальное наполнение, уникальный ключ для обновления записей (unique_key)
-- Ключ сегментации (dist), ключ сортировки (sort)
{{
config(
materialized='incremental',
unique_key='order_id',
dist="customer_id",
sort="order_date"
)
}}
{% set payment_methods = ['credit_card', 'coupon', 'bank_transfer', 'gift_card'] %}
with orders as (
select * from {{ ref('stg_orders') }}
where 1=1
{% if is_incremental() -%}
-- Этот фильтр будет применен только для инкрементального запуска
and order_date >= (select max(order_date) from {{ this }})
{%- endif %}
),
order_payments as (
select * from {{ ref('order_payments') }}
),
final as (
select
orders.order_id,
orders.customer_id,
orders.order_date,
orders.status,
{% for payment_method in payment_methods -%}
order_payments.{{payment_method}}_amount,
{% endfor -%}
order_payments.total_amount as amount
from orders
left join order_payments using (order_id)
)
select * from final
Γράφημα εξάρτησης μοντέλου
Είναι επίσης ένα δέντρο εξάρτησης. Είναι επίσης γνωστό ως DAG (Directed Acyclic Graph).
Το DBT δημιουργεί ένα γράφημα με βάση τη διαμόρφωση όλων των μοντέλων έργων, ή μάλλον, τις συνδέσεις ref() εντός μοντέλων με άλλα μοντέλα. Έχοντας ένα γράφημα σας επιτρέπει να κάνετε τα ακόλουθα πράγματα:
Εκτέλεση μοντέλων με τη σωστή σειρά
Παραλληλισμός σχηματισμού βιτρίνας
Εκτέλεση αυθαίρετου υπογράφου
Παράδειγμα οπτικοποίησης γραφήματος:
Κάθε κόμβος του γραφήματος είναι ένα μοντέλο· οι άκρες του γραφήματος καθορίζονται από την έκφραση ref.
Ποιότητα Δεδομένων και Τεκμηρίωση
Εκτός από τη διαμόρφωση των ίδιων των μοντέλων, το DBT σάς επιτρέπει να δοκιμάσετε έναν αριθμό υποθέσεων (βεβαιώσεων) σχετικά με το προκύπτον σύνολο δεδομένων, όπως:
Οχι κενό
Μοναδική
Ακεραιότητα αναφοράς - ακεραιότητα αναφοράς (για παράδειγμα, το customer_id στον πίνακα παραγγελιών αντιστοιχεί στο αναγνωριστικό στον πίνακα πελατών)
Αντιστοίχιση της λίστας των αποδεκτών τιμών
Είναι δυνατό να προσθέσετε τις δικές σας δοκιμές (προσαρμοσμένες δοκιμές δεδομένων), όπως, για παράδειγμα, % απόκλιση εσόδων με δείκτες από μια ημέρα, μια εβδομάδα, έναν μήνα πριν. Οποιαδήποτε υπόθεση που διατυπώνεται ως ερώτημα SQL μπορεί να γίνει δοκιμή.
Με αυτόν τον τρόπο, μπορείτε να εντοπίσετε ανεπιθύμητες αποκλίσεις και σφάλματα στα δεδομένα στα παράθυρα της Αποθήκης.
Όσον αφορά την τεκμηρίωση, το DBT παρέχει μηχανισμούς για την προσθήκη, την έκδοση και τη διανομή μεταδεδομένων και σχολίων σε επίπεδα μοντέλου και ακόμη και χαρακτηριστικών.
Δείτε πώς φαίνεται η προσθήκη δοκιμών και τεκμηρίωσης σε επίπεδο αρχείου διαμόρφωσης:
- name: fct_orders
description: This table has basic information about orders, as well as some derived facts based on payments
columns:
- name: order_id
tests:
- unique # проверка на уникальность значений
- not_null # проверка на наличие null
description: This is a unique identifier for an order
- name: customer_id
description: Foreign key to the customers table
tests:
- not_null
- relationships: # проверка ссылочной целостности
to: ref('dim_customers')
field: customer_id
- name: order_date
description: Date (UTC) that the order was placed
- name: status
description: '{{ doc("orders_status") }}'
tests:
- accepted_values: # проверка на допустимые значения
values: ['placed', 'shipped', 'completed', 'return_pending', 'returned']
Και εδώ είναι πώς φαίνεται αυτή η τεκμηρίωση στον ιστότοπο που δημιουργήθηκε:
Μακροεντολές και Ενότητες
Ο σκοπός του DBT δεν είναι τόσο να γίνει ένα σύνολο σεναρίων SQL, αλλά να παρέχει στους χρήστες ένα ισχυρό και πλούσιο σε χαρακτηριστικά μέσα για τη δημιουργία των δικών τους μετασχηματισμών και τη διανομή αυτών των λειτουργικών μονάδων.
Οι μακροεντολές είναι σύνολα κατασκευών και εκφράσεων που μπορούν να κληθούν ως συναρτήσεις μέσα σε μοντέλα. Οι μακροεντολές σάς επιτρέπουν να επαναχρησιμοποιείτε SQL μεταξύ μοντέλων και έργων σύμφωνα με την αρχή μηχανικής DRY (Don't Repeat Yourself).
Παράδειγμα μακροεντολής:
{% macro rename_category(column_name) %}
case
when {{ column_name }} ilike '%osx%' then 'osx'
when {{ column_name }} ilike '%android%' then 'android'
when {{ column_name }} ilike '%ios%' then 'ios'
else 'other'
end as renamed_product
{% endmacro %}
Και η χρήση του:
{% set column_name = 'product' %}
select
product,
{{ rename_category(column_name) }} -- вызов макроса
from my_table
Το DBT συνοδεύεται από έναν διαχειριστή πακέτων που επιτρέπει στους χρήστες να δημοσιεύουν και να επαναχρησιμοποιούν μεμονωμένες μονάδες και μακροεντολές.
Αυτό σημαίνει ότι μπορείτε να φορτώσετε και να χρησιμοποιήσετε βιβλιοθήκες όπως:
dbt_utils: εργασία με Date/Time, Surrogate Keys, Schema tests, Pivot/Unpivot και άλλα
Μπορείτε να βρείτε μια πλήρη λίστα πακέτων στη διεύθυνση dbt hub.
Ακόμα περισσότερα χαρακτηριστικά
Εδώ θα περιγράψω μερικά άλλα ενδιαφέροντα χαρακτηριστικά και υλοποιήσεις που χρησιμοποιούμε η ομάδα και εγώ για να δημιουργήσουμε μια αποθήκη δεδομένων στο Wheely.
Διαχωρισμός περιβαλλόντων χρόνου εκτέλεσης DEV - TEST - PROD
Ακόμη και μέσα στο ίδιο σύμπλεγμα DWH (μέσα σε διαφορετικά σχήματα). Για παράδειγμα, χρησιμοποιώντας την ακόλουθη έκφραση:
with source as (
select * from {{ source('salesforce', 'users') }}
where 1=1
{%- if target.name in ['dev', 'test', 'ci'] -%}
where timestamp >= dateadd(day, -3, current_date)
{%- endif -%}
)
Αυτός ο κώδικας λέει κυριολεκτικά: για περιβάλλοντα dev, δοκιμή, ci λήψη δεδομένων μόνο για τις τελευταίες 3 ημέρες και όχι περισσότερες. Δηλαδή, η εκτέλεση σε αυτά τα περιβάλλοντα θα είναι πολύ πιο γρήγορη και θα απαιτεί λιγότερους πόρους. Όταν τρέχετε σε περιβάλλον κέντρο η κατάσταση του φίλτρου θα αγνοηθεί.
Υλοποίηση με εναλλακτική κωδικοποίηση στήλης
Το Redshift είναι ένα στήλες DBMS που σας επιτρέπει να ορίσετε αλγόριθμους συμπίεσης δεδομένων για κάθε μεμονωμένη στήλη. Η επιλογή βέλτιστων αλγορίθμων μπορεί να μειώσει το χώρο στο δίσκο κατά 20-50%.
Macro redshift.compress_table θα εκτελέσει την εντολή ANALYZE COMPRESSION, θα δημιουργήσει έναν νέο πίνακα με τους προτεινόμενους αλγόριθμους κωδικοποίησης στηλών, τα καθορισμένα κλειδιά τμηματοποίησης (dist_key) και τα κλειδιά ταξινόμησης (sort_key), θα μεταφέρει τα δεδομένα σε αυτόν και, εάν χρειάζεται, θα διαγράψει το παλιό αντίγραφο.
Μπορείτε να προσαρτήσετε άγκιστρα σε κάθε εκτέλεση του μοντέλου, τα οποία θα εκτελεστούν πριν από την εκκίνηση ή αμέσως μετά την ολοκλήρωση της δημιουργίας του μοντέλου:
Η ενότητα καταγραφής θα σας επιτρέψει να καταγράψετε όλα τα απαραίτητα μεταδεδομένα σε έναν ξεχωριστό πίνακα, ο οποίος μπορεί στη συνέχεια να χρησιμοποιηθεί για τον έλεγχο και την ανάλυση των σημείων συμφόρησης.
Έτσι φαίνεται ο πίνακας εργαλείων με βάση τα δεδομένα καταγραφής στο Looker:
Αυτοματοποίηση Συντήρησης Αποθήκευσης
Εάν χρησιμοποιείτε ορισμένες επεκτάσεις της λειτουργικότητας του χρησιμοποιούμενου Αποθετηρίου, όπως το UDF (Συναρτήσεις που καθορίζονται από τον χρήστη), τότε η έκδοση αυτών των λειτουργιών, ο έλεγχος πρόσβασης και η αυτοματοποιημένη κυκλοφορία νέων εκδόσεων είναι πολύ βολικό να κάνετε στο DBT.
Χρησιμοποιούμε το UDF στην Python για τον υπολογισμό των κατακερματισμών, των τομέων email και της αποκωδικοποίησης μάσκας bit.
Ένα παράδειγμα μακροεντολής που δημιουργεί ένα UDF σε οποιοδήποτε περιβάλλον εκτέλεσης (dev, test, prod):
{% macro create_udf() -%}
{% set sql %}
CREATE OR REPLACE FUNCTION {{ target.schema }}.f_sha256(mes "varchar")
RETURNS varchar
LANGUAGE plpythonu
STABLE
AS $$
import hashlib
return hashlib.sha256(mes).hexdigest()
$$
;
{% endset %}
{% set table = run_query(sql) %}
{%- endmacro %}
Στη Wheely χρησιμοποιούμε το Amazon Redshift, το οποίο βασίζεται στην PostgreSQL. Για το Redshift, είναι σημαντικό να συλλέγετε τακτικά στατιστικά στοιχεία σε πίνακες και να ελευθερώνετε χώρο στο δίσκο - τις εντολές ANALYZE και VACUUM, αντίστοιχα.
Για να γίνει αυτό, οι εντολές από τη μακροεντολή redshift_maintenance εκτελούνται κάθε βράδυ:
{% macro redshift_maintenance() %}
{% set vacuumable_tables=run_query(vacuumable_tables_sql) %}
{% for row in vacuumable_tables %}
{% set message_prefix=loop.index ~ " of " ~ loop.length %}
{%- set relation_to_vacuum = adapter.get_relation(
database=row['table_database'],
schema=row['table_schema'],
identifier=row['table_name']
) -%}
{% do run_query("commit") %}
{% if relation_to_vacuum %}
{% set start=modules.datetime.datetime.now() %}
{{ dbt_utils.log_info(message_prefix ~ " Vacuuming " ~ relation_to_vacuum) }}
{% do run_query("VACUUM " ~ relation_to_vacuum ~ " BOOST") %}
{{ dbt_utils.log_info(message_prefix ~ " Analyzing " ~ relation_to_vacuum) }}
{% do run_query("ANALYZE " ~ relation_to_vacuum) %}
{% set end=modules.datetime.datetime.now() %}
{% set total_seconds = (end - start).total_seconds() | round(2) %}
{{ dbt_utils.log_info(message_prefix ~ " Finished " ~ relation_to_vacuum ~ " in " ~ total_seconds ~ "s") }}
{% else %}
{{ dbt_utils.log_info(message_prefix ~ ' Skipping relation "' ~ row.values() | join ('"."') ~ '" as it does not exist') }}
{% endif %}
{% endfor %}
{% endmacro %}
DBT Cloud
Είναι δυνατή η χρήση του DBT ως υπηρεσία (Managed Service). Περιλαμβάνεται:
Web IDE για την ανάπτυξη έργων και μοντέλων
Διαμόρφωση και προγραμματισμός εργασιών
Απλή και βολική πρόσβαση στα κούτσουρα
Ιστοσελίδα με τεκμηρίωση του έργου σας
Σύνδεση CI (Συνεχής Ενοποίηση)
Συμπέρασμα
Η προετοιμασία και η κατανάλωση DWH γίνεται τόσο ευχάριστη και ωφέλιμη όσο η κατανάλωση ενός smoothie. Το DBT αποτελείται από Jinja, επεκτάσεις χρήστη (modules), έναν μεταγλωττιστή, έναν εκτελεστή και έναν διαχειριστή πακέτων. Συνδυάζοντας αυτά τα στοιχεία αποκτάτε ένα πλήρες περιβάλλον εργασίας για την αποθήκη δεδομένων σας. Δεν υπάρχει σχεδόν καλύτερος τρόπος διαχείρισης του μετασχηματισμού στο DWH σήμερα.
Οι πεποιθήσεις που ακολουθούν οι προγραμματιστές του DBT διατυπώνονται ως εξής:
Ο κώδικας, όχι το GUI, είναι η καλύτερη αφαίρεση για την έκφραση περίπλοκης αναλυτικής λογικής
Η εργασία με δεδομένα θα πρέπει να προσαρμόζει τις βέλτιστες πρακτικές στη μηχανική λογισμικού (Software Engineering)
Η υποδομή κρίσιμων δεδομένων θα πρέπει να ελέγχεται από την κοινότητα των χρηστών ως λογισμικό ανοιχτού κώδικα
Όχι μόνο τα εργαλεία ανάλυσης, αλλά και ο κώδικας θα γίνονται όλο και περισσότερο ιδιοκτησία της κοινότητας ανοιχτού κώδικα
Αυτές οι βασικές πεποιθήσεις έχουν δημιουργήσει ένα προϊόν που χρησιμοποιείται από περισσότερες από 850 εταιρείες σήμερα και αποτελούν τη βάση πολλών συναρπαστικών επεκτάσεων που θα δημιουργηθούν στο μέλλον.
Εκτός από το DBT και το Data Warehousing, ως μέρος του μαθήματος Data Engineer στην πλατφόρμα OTUS, οι συνάδελφοί μου και εγώ διδάσκουμε μαθήματα για μια σειρά από άλλα σχετικά και σύγχρονα θέματα:
Αρχιτεκτονικές Έννοιες για Εφαρμογές Μεγάλων Δεδομένων
Εξασκηθείτε με το Spark και το Spark Streaming
Διερεύνηση μεθόδων και εργαλείων για τη φόρτωση πηγών δεδομένων
Κατασκευή αναλυτικών βιτρινών στο DWH
Έννοιες NoSQL: HBase, Cassandra, ElasticSearch
Αρχές παρακολούθησης και ενορχήστρωσης
Τελικό έργο: συναρμολόγηση όλων των δεξιοτήτων υπό την υποστήριξη καθοδήγησης