company_banner

Тестирование хранилищ данных

    Публикуется от имени IvanovAleksey.



    В интернете мало информации по тестированию Data Warehouse.
    Можно найти общие требования: полнота данных, качество и т.п.
    Но нигде нет описания организации процесса, и какими проверками можно покрыть эти требования.
    В этой статье постараюсь рассказать: как мы тестируем Хранилище данных в "Тинькофф Банк".


    Наш Data Warehouse


    Сначала коротко опишу наше Хранилище.
    Процессы загрузки и обработки данных реализованы в виде джобов. Джобы запускаются на планировщике обычно ночью, когда никто не использует внешние системы (нагрузка на них минимальна), и после закрытия бизнес дня.
    Структура базы — это множество таблиц разного объема (от нескольких строк до 3 млрд. и более), с разным количеством колонок (от 1 до 200), с историчностью и без неё. Размер базы около 35Тб.
    Используются внешние источники данных: Oracle, CSV/XLS файлы, MySql, Informix, BIN файлы, CDH – Cloudera(Hadoop). Выгружаем данные во внешние системы также через Oracle, SAS таблицы и в виде CSV/XLS файлов.
    Объекты хранилища (описание баз, джобов, таблиц, вьюх и т.п.) разрабатываются в SAS Data Integration Studio и хранятся на SAS сервере в виде метаданных. Физически таблицы находятся в базах Greenplum и SAS.
    Для запуска джобов, по метаданным генерируется код и переносится на деплоймент сервер. После чего они могут быть запущены на планировщике.
    Изменения на среды, переносятся в виде пакетов, состоящих из метаданных и скриптов (на создание/правку физики, данных). Для удобства переноса разработчиками была написана специальная программа «Авторелиз».
    Для ручного запуска джобов есть веб портал. Там же можно увидеть запущенные планировщики и статусы работающих на них джобов.


    Подробнее можно почитать в наших предыдущих статьях

    Объекты тестирования


    Любая доработка DWH представляет собой создание/изменение физики и метаданных таблиц и джобов. Либо это корректировка скриптами уже загруженных данных.
    Например, создается новая витрина. В пакете будут метаданные нового джоба и таргета и скрипт на создание физики новой таблицы в базе данных.
    Таким образом, объект тестирования – это измененный/созданный по задаче джоб, данные в его целевой таблице и данные в целевых таблицах зависимых джобов (если они есть).


    Уровни и виды тестирования


    Наш тестовый контур полностью повторяет продуктивный: тоже железо, те же данные, того же объема, загружаются и обрабатываются с помощью таких же процессов. Учитывая эту особенность, а также то, что задачи разрабатываются, когда в источниках уже есть все необходимые данные, можно без потери качества сократить объем проверок.
    Нагрузочное тестирование (Performance testing) и тестирование на больших объемах данных (Volume testing) проводим только при переносе задачи на тест: проверяем время работы джоба, нагрузку на стенд(например, с помощью Grafana) и объем ворков (не буду эти проверки подробно описывать в этой статье).
    На системном уровне работа джобов и качество данных проверяется автоматически. За джобами следит сам ночной планировщик и скрипт контроля объемов ворков. А данные после загрузки, проверяются с помощью Data Quality Daemon (о нем ниже). Если что-то не так с данными, ответственным приходят письма с ошибками.
    Из «белого ящика» смотрим только правильное указание среды (были ошибки с хардкодом схем test и dev). В будущем планируется проверять это автоматом, при публикации пакета разработчиком.
    Основными у нас являются функциональное тестирование («черный ящик») и проверка регрессии, на уровнях: компонентов и интеграции.
    С учетом определенных в предыдущем абзаце объектов тестирования, полный набор проверок выглядит так:


    • Модульное тестирование. Проверяем сам новый/измененный джоб и данные в его целевой таблице.
      Функциональное тестирование: строим прототип и сравниваем со значениями в новых/измененных колонках целевых таблиц.
      Регрессионное тестирование: выполняем сравнение с бекапом, незатронутые доработкой данные, должны совпадать.
    • Интеграционное тестирование. Проверяем качество данных на выходе зависимых джобов (в которые не вносились изменения) и во внешних системах.
      Функциональное тестирование: качество затронутых доработкой данных должно соответствовать ТЗ.
      Регрессионное тестирование: качество незатронутых доработкой данных, не должно изменится.

    Под «сравнением с бекапом» имеется в виду сверка результатов работы новой и предыдущей версии джоба. То есть старый и новый джоб запускаются на одинаковых данных. И сравниваются их целевые таблицы.
    «Прототип» — набор данных, собранный по ТЗ, и который должен быть в витрине после доработки. Это может быть макет либо полностью новой таблицы, либо только изменившихся колонок в старой таблице.
    В зависимости от задачи, некоторые из этих проверок могут быть избыточными. Определив типы доработки, можно избавится от избыточных проверок и сократить время тестирования.


    Виды изменений и проверки


    Проект Data Warehouse в банке постоянно развивается – создаются новые витрины, дорабатываются старые, оптимизируются процессы загрузки. Но в действительности все задачи можно разделить на четыре группы со своим достаточным набором тестов:


    1. Технические.
      Оптимизация, миграция и т.п. – то есть задачи, где алгоритм не меняется. И данные в целевой таблице тоже не должны измениться.
      Достаточно выполнить проверку регрессии: сравнить таргет измененного джоба с бекапом. Зависимые джобы можно не проверять, т.к. если таргет совпадает с бекапом – зависимый джоб его так же обработает.
    2. Изменение старого функционала.
      Меняется алгоритм, фильтры (меняется кол-во строк), добавляются новые поля, источники. То есть, меняется набор данных в целевой таблице.
      Необходимо выполнить все проверки: сравнить данные в целевой таблице измененного джоба с бекапом и прототипом, проверить качество данных в целевых таблицах зависимых джобов и внешних системах.
    3. Разработка новых витрин.
      Создаются новые таблицы и джобы, которые их загружают.
      Выполняем только функциональное тестирование: сверяем целевые таблицы с прототипами.
      Если выгрузка идет во внешнюю систему, дополнительно проверяем интеграцию — смотрим, как во внешней системе отображаются загруженные данные.
    4. Правка данных.
      Удаление дублей, старых записей, исправление версионности, проставление корректных значений.
      Проверка этих изменений довольно сложная и описать её в двух предложениях не получится. Подробно расскажу в следующей статье

    Если в рамках проекта/задачи присутствуют сразу несколько видов изменений, то в тестовый набор берем проверки по каждому из них.


    Этих проверок достаточно, чтобы гарантировать соответствие требований и результатов разработки в большинстве задач.


    Блиц проверки


    Построение прототипа и выполнение сравнения может занять много времени (зависит от производительности среды и объема данных). Мы столкнулись с этой проблемой, когда тестовый контур был слабее продуктивного. Чтобы не потерять зря время на сравнении и сразу выловить критичные дефекты, использовались быстрые проверки.
    Подходят для любого типа задач и выполняются перед началом тестирования:


    • Задача пришла на тест и джоб отрабатывает (да, это иногда забывают проверить)
    • Не должно быть null и дублей по ключу (если в ТЗ не указано обратное). Версионность таблицы должна быть соблюдена.
    • По новым полям приходят данные: select count(new_field) from table1 должно быть больше 0.
    • Новые записи загружаются в таблицу: сравниваем кол-во записей в бекапе и таргете.

    Если они завершились неудачно – можно сразу вернуть задачу в разработку/завести дефект Critical.


    Инструменты


    Основные действия во время тестирования: накат задач на тест, сравнение таблиц.
    Как уже говорил, для переноса используется собственная разработка, программа «Авторелиз». Что позволяет сэкономить время и избежать ошибок при ручном переносе.


    Работа программы выглядит примерно так:


    • Снимаются бекапы физики таблиц и метаданных измененных объектов.
    • Выполняются скрипты, которые должны выполниться до импорта новых метаданных
    • Импорт метаданных.
    • Выполняются скрипты, которые должны выполниться после импорта метаданных и перед запуском джобов на планировщике.
    • Деплой джобов и запуск на планировщике.
    • Выполняются скрипты, которые должны выполниться после завершения работы джоба.

    Запускается через консоль. На вход подается номер задачи, имя среды и дополнительные параметры (например, делать паузу после каждого шага).


    Для сравнения таблиц (таргет с прототипом/бекапом) используется макрос, который сверяет значения в строках по указанному ключу и сопоставляет заполняемость полей.
    На вход макросу передаются имена таблиц и ключ сравнения.
    Пример результата работы:


    Количество расхождений по колонкам. Сами расхождения смотрите в difference.


    Obs column_name differ_base_to_comp
    1 column_1 0
    2 column_2 20
    3 column_3 0

    Количество расхождений в группировках по _cd и _flg полях.


    Obs column_name column_group base_groups compare_groups diff base_group_pct compare_group_pct diff_group_pct
    1 column_2 A 18743 63 18680 0.0021 0.0024 -0.0003
    2 column_2 B 4451740 17756 4433984 0.4897 0.6877 -0.1980
    3 column_2 C 4619311 7813 4611498 0.5082 0.3026 0.2056
    4 column_2 null 191 188 3 0.0000 0.0073 -0.0073

    Для проверки качества данных используется макрос профайлинга. Который считает кол-во и процент записей с null по каждой колонке, дубли и null по ключу, строк в группировке по флагам и значениям, min/max/avg по суммам в столбцах.
    На вход подается название таблицы и ключ.
    На выходе получаем отчет, с табличками по каждому из расчетов.
    Пример:


    Количество миссингов по колонкам.


    Obs column_name base_nulls nulls_pct
    1 column_1 0 0.00
    2 column_2 0 0.00
    3 column_3 7 0.03
    4 column_4 0 0.00
    5 column_5 0 0.00

    Так же есть макрос для сравнения профайлингов двух таблиц между собой (или с таблицей на продуктиве). Принцип работы тот же: выполняются профайлинги для каждой таблицы, и полученные результаты сравниваются.
    Отчет на выходе похож на обычный профайлинг, только с данными по двум таблицам.


    Контроль качества данных


    Для контроля качества данных во всем хранилище используется самописный Data Quality Daemon (DQD), который проверяет все таблицы на соответствие правилам, составленными аналитиками и специалистами отдела контроля качества данных.
    DQD представляет собой процесс, который каждые 10 минут находит обновившиеся таблицы и выполняет заданные SQL запросы. Результаты сравнивает с эталонными показателями (предустановленные значения) и рассылает отчет с отклонениями.
    Пример отчета:


    Constraint Definition SQL Script Corrupted Rows Cnt
    test_schema.table1 / Unique Entity Key [id] select sum(cnt) as cnt from ( select 0 as cnt union all select 1 as cnt from test_schema.table1 group by id having count(*) > 1 union all select 1 as cnt from test_schema.table1 where not ((id ) is not null) ) sq 15

    Оформление тест кейсов


    В нашем банке тестирование живет в Zephyr (надстройка Jira). Сами задачи на доработку оформляются как тикеты в Jira, а тест кейсы и тестраны в Zephyr.
    Попробовав несколько вариантов, остановились на том, что заводим по кейсу на каждый измененный, в рамках задачи, джоб. Кейс называем: «<номер задачи в jira>: <имя джоба>». И линкуем к тикету.
    Основные преимущества такого подхода:


    1. в задаче видно покрытие кейсами (какие джобы будут проверяться)
    2. можно легко посчитать процент run/pass/failed
    3. простой поиск по имени джоба возвращает все написанные кейсы, их статус, кто и когда написал, выполнял и по какой задаче.
    4. опять же, из названия кейса, можно узнать номер задачи на доработку. А открыв его перейти в неё по линку.

    Заключение


    Тестирование DWH — непростой процесс со своей спецификой. Если придерживаться классической методологии, то он получается весьма громоздким.
    Наш подход позволяет тестировать быстро (в среднем один тестировщик делает задачу за три дня) и при этом количество пропущенных ошибок сведено к нулю. За полгода более 400 задач были выведены на продуктив.
    Останавливаться на достигнутом не собираемся. Следующая цель — автоматизация большинства проверок.

    • +9
    • 15,8k
    • 6
    Tinkoff.ru
    395,85
    IT’s Tinkoff.ru — просто о сложном
    Поделиться публикацией

    Комментарии 6

      0
      подскажите, а выражение «where not ((id ) is not null) )» написано так с какой-то целью?
        0
        Для универсализации. DQD может использовать этот запрос так же для таблиц с составным ключом, просто подставив их на меcто «id».
        То есть
        where not ((id, id2, id3, start_dttm… ) is not null)
        выдаст записи, у которых хотя бы одно из перечисленных полей — null
        +1
        А вы не смотрели готовые системы для Data Quality? Чем не угодили, что используете свой велосипед?
          0
          Смотрели, но не нашли ничего, чтобы удовлетворило нашим требованиям: простота, скорость, гибкость, настраиваемость.
          У DQD всё это есть… и он дешевле :)
            0
            Не планируете про него рассказать?
              0
              Да, в одной из следующих статей.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

        Самое читаемое