[PostgreSQL, Data Engineering] pg_obfuscator — обфускатор для postgres с сохранением распределения данных (на основе clickhouse obfuscator)

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
07-Апр-2021 14:32

ВведениеВ конце прошлого года мы завершили один из самых интересных и необычных проектов, которыми нам приходилось заниматься. Наш клиент - klara.com - коммуникационная телемедицинская платформа, упрощающая взаимодействие пациентов с врачами в США, столкнулась со стремительным ростом на волне пандемии 2020 года. Одним из вызовов на которые пришлось отвечать инженерам klara.com в это непростое время стало автоматизированное нагрузочное тестирование, способное обнаружить проблемы с производительностью до того как они проявят себя в production среде.Задача построения пайплайна нагрузочного тестирования выглядела достаточно изолированной для того, чтобы ее можно было выделить в отдельный проект и отдать на реализацию нашей команде.Постановка задачи выглядела так: спроектировать и реализовать пайплайн нагрузочного тестирования таким образом, чтобы его можно было легко поддерживать силами QA-инженеров, использовать как часть CI/CD процессов компании, расширять по необходимости и иметь возможность реализовать различные сценарии нагрузочного тестирования. Критерием успешности проекта стала точная реализация одного из кейса по производительности из production в среде нагрузочного тестирования с помощью инструментов, которые мы разработали.Технологическая платформаОсновные языки программирования в команде - Ruby, JS. В качестве основного хранилища klara.com использует Postgres. Безопасность персональных данных пациентов (PHI - Protected Health Information) является ключевым аспектом бизнеса klara.com. Для обеспечения надежного хранения и обработки данных платформа использует HIPPA совместимую SaaS платформу - Aptible. Aptible покупает ресурсы у AWS, поэтому для дальнейшего описания будет достаточно считать Aptible сильно урезанной и зарегулированной версией AWS. Для максимально корректной реализации нагрузочного тестирования нам нужна среда максимально похожая на production среду. Идеально, если идентичными будут: серверный парк, структура и объем данных, версии кода, структура и объем трафика. Очевидно также, что сделать все перечисленное абсолютно идентичным за разумное время и бюджет не реально и всегда приходится принимать некие допущения.В этой статье я расскажу как мы готовили данные для нагрузочного тестирования.Чтобы воспроизвести похожее поведение приложения во время тестов нам нужно иметь максимально похожую на production базу данных с точки зрения объема данных и их распределения. Из-за того, что klara хранит в том числе персональные данные, нам понадобится обфускация базы. Дополнительное условие - скорость работы обфускатора, хотелось бы быстро.Обзор решенийСейчас существует несколько инструментов для решения этой задачи в postgres, мы провели краткий сравнительный анализ, который приведен ниже:postgresql_anonymizer+ Самое популярное по количеству звезд на github решение из имеющихся + Очень много функций для разных типов данных с разными стратегиями, которые можно применять точечно для выбранных полей (https://postgresql-anonymizer.readthedocs.io/en/lat...ing_functions/)+ Можно выгружать сразу в *.sql дамп- Нужно устанавливать как расширение рядом с бд- Для каждого поля нужно прописывать security labels с масками- Маски работают только с одной схемой- Нет данных по производительностиЭто решение мы не рассматривали из-за того, что оно должно устанавливаться как расширение, запихивать, что-то в production - так себе идея.triki+ Заявлена высокая скорость работы (1.4гб mysql dump 17sec)+ Много типов данных + можно определить свои (форк + правки т.к. кристал руби-френдли язык)+ Можно выгрузить конфигурацию всей схемы для дальнейшей настройки обфускатора (таблицы-поля)+ Не требуется никаких правок в исходной бд, только настроить коннект+ Выгружает в *.sql дампВыглядело неплохим вариантом, удобный деплой, понятный нам и заказчику язык, очевидный недостаток - не понятно как сохраняется распределение данных.pgdump-obfuscator (форк)+ есть возможность задавать параметры полей через cli (только в форке)- нет информации о производительности- обновлялся 8 лет назадclickhouse-obfuscator+ Заявлена высокая скорость работы (в докладе говорилось, что 1тб данных обфусцирован за 1.5 дня)- Написан на C++ (нашей команде сложно вносить изменения)- Принимает только csv-формат- Нет внятной документации (только статья на Хабре)Высокая скорость, сохранение распределения данных после обфускации, поддержка большой компанией и комьюнити - по этим причинам мы выбрали обфускатор от clickhouse.pg_obfuscatorК сожалению для нашей задачи, clickhouse obfuscator не поддерживал прямое подключение к postgresql. Поэтому нам пришлось написать утилиту, которая решает задачу обфускации postgresql с учетом всей специфики работы именно с этой базой. Исходный код доступен по адресу.Утилита представляет собой wrapper над psql client и clickhouse obfuscator и реализует следующую функциональность
  • выгрузка схемы базы с сохранением внешних ключей и проверок ссылочной целостности 
  • исключение из обфускации таблиц, полей таблиц
  • использование предопределенных шаблонов для генерации фейковых значений для полей
  • маппинг типов данных postgres на типы данных clickhouse
  • генерацию конфигурации со значениями по умолчанию
Из-за специфики работы clickhouse-obfuscator утилита требует дискового пространства для работы равного двойному размеру базы данных. Поставляется в виде docker image и доступна по адресу.В настоящий момент есть ограничения, которые следует иметь в виду: 
  • утилита поддерживает только базовые типы postgres и не поддерживает вложенные: hstore, json, jsonb
  • несмотря на автоматическую генерацию конфига, для первого запуска он нуждается в правках
  • объем docker image составляет почти 700Mb
В рамках поставленной задачи мы наблюдали следующие скоростные характеристики: тестовая база 10Гб обфусцировалась за 40 минут, продуктовая в 50 Гб - 6..8 часов. Чем обусловлена нелинейность работы мы не выясняли.Ниже я продемонстрирую работу c pg_obfuscator на примере работы с devrimgunduz/pagila: PostgreSQL Sample Database.ДемоРазвернем контейнер с postgres и создадим в нем 2 базы для демонстрации:
docker run --rm --name=db -e POSTGRES_PASSWORD=password -p5432:5432 postgres
docker exec -i db psql -U postgres postgres -c 'create database pagila;'
docker exec -i db psql -U postgres postgres -c 'create database pagila_o;'
Посмотрим IP-адрес базы - он понадобится для работы обфускатора:docker inspect db | grep IPAdd            "SecondaryIPAddresses": null,            "IPAddress": "172.17.0.2"И зальем в контейнер скрипты из проекта pagila:
cd /tmp
git clone git@github.com:devrimgunduz/pagila.git
docker exec -i db psql -U postgres pagila < /tmp/pagila/pagila-schema.sql
docker exec -i db psql -U postgres pagila < /tmp/pagila/pagila-data.sql
Убедимся, что там появились данные:docker exec -i db psql -U postgres pagila -c 'select     a.first_name, a.last_name, f.film_id, f.title, f.description from film f join film_actor fa on f.film_id = fa.film_id join actor a on a.actor_id=fa.actor_id where f.film_id = 7;'
first_name | last_name | film_id |      title      |                                    description
------------+-----------+---------+-----------------+-----------------------------------------------------------------------------------
 JIM        | MOSTEL    |       7 | AIRPLANE SIERRA | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat
 RICHARD    | PENN      |       7 | AIRPLANE SIERRA | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat
 OPRAH      | KILMER    |       7 | AIRPLANE SIERRA | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat
 MENA       | HOPPER    |       7 | AIRPLANE SIERRA | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat
 MICHAEL    | BOLGER    |       7 | AIRPLANE SIERRA | A Touching Saga of a Hunter And a Butler who must Discover a Butler in A Jet Boat
(5 rows)
 База для экспериментов готова. Теперь расчехлим pg_obfuscator, принципиальным моментом является монтирования тома для конфига, чтобы иметь возможность его потом поправить.
mkdir /tmp/config
docker run -it --rm -v /tmp/config:/opt/pg_obfuscator/config pg_obfuscator sh
Дальше команды выполняются в шелле обфускатора, если не сказано другого:
bundle exec ruby pg_obfuscator.rb  --configure --source-db-host 172.17.0.2 --source-db-port 5432 --source-db-name pagila --source-db-user postgres --source-db-password password
.......
I, [2021-04-02T08:47:54.682868 #9]  INFO -- : Processed 20 tables
I, [2021-04-02T08:47:54.683243 #9]  INFO -- : Check config before run export tables and obfuscation!
I, [2021-04-02T08:47:54.696328 #9]  INFO -- : Config saved to: config/config.yml
Обфускатор говорит, что нужно проверить конфиг и внести необходимые изменения. Конфиг для 20 таблиц получился около 400 строк, секции, которые нуждаются в правках отмечены - need_fix: true. Для того, чтобы вам было легче повторить я выложил исправленный конфиг сюда.Для демонстрации генерации фейковых данных посмотрим на секцию в таблице actor:
last_name:
  db_data_type: text
  not_null: true
  obfuscator_data_type: String
  fake_data:
    type: pattern
    value: "%{first_name}SON"
В качестве фамилии мы используем имя и постфикс SON.Выполним последовательно экспорт схемы, данных, обфускацию и заливку полученных данных в базу pagila_o
ruby pg_obfuscator.rb --export-schema --source-db-host 172.17.0.2 --source-db-port 5432 --source-db-name pagila --source-db-user postgres --source-db-password password
ruby pg_obfuscator.rb --export-tables --source-db-host 172.17.0.2 --source-db-port 5432 --source-db-name pagila --source-db-user postgres --source-db-password password
bundle exec ruby pg_obfuscator.rb --obfuscate
ruby pg_obfuscator.rb --import --target-db-host 172.17.0.2 --target-db-port 5432 --target-db-name pagila_o --target-db-user postgres --target-db-password password
и выйдя из контейнера с обфускатором посмотрим на результат
docker exec -i db psql -U postgres pagila_o -c 'select   a.first_name, a.last_name, f.film_id, f.title, f.description from film f join film_actor fa on f.film_id = fa.film_id join actor a on a.actor_id=fa.actor_id where f.film_id = 7;'
 first_name | last_name | film_id |   title   |                                                      description
------------+-----------+---------+-----------+------------------------------------------------------------------------------------------------------------------------
 SA         | SASON     |       7 | ROON SUIT | A Amazing Display of a Database Administ And a Dog And a Database a Pastry Chef And a Car And a Manned Mine Shark Tank
 RURA       | RURASON   |       7 | ROON SUIT | A Amazing Display of a Database Administ And a Dog And a Database a Pastry Chef And a Car And a Manned Mine Shark Tank
 BER        | BERSON    |       7 | ROON SUIT | A Amazing Display of a Database Administ And a Dog And a Database a Pastry Chef And a Car And a Manned Mine Shark Tank
 CA         | CASON     |       7 | ROON SUIT | A Amazing Display of a Database Administ And a Dog And a Database a Pastry Chef And a Car And a Manned Mine Shark Tank
 MER        | MERSON    |       7 | ROON SUIT | A Amazing Display of a Database Administ And a Dog And a Database a Pastry Chef And a Car And a Manned Mine Shark Tank
(5 rows)
Видим, что last_name сформирован фейкером, описание обфусцировано, ссылочная целостность сохранена.На этом все, мы надеемся, что утилита будет полезна сообществу, будем рады видеть пулреквесты.Благодарим команду clickhouse obfuscator за отличный продукт!
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_postgresql, #_data_engineering, #_obfuskatsija (обфускация), #_postgresql, #_postgres, #_postgresql, #_data_engineering
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 20:08
Часовой пояс: UTC + 5