[PostgreSQL, Data Engineering] pg_obfuscator — обфускатор для postgres с сохранением распределения данных (на основе clickhouse obfuscator)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
ВведениеВ конце прошлого года мы завершили один из самых интересных и необычных проектов, которыми нам приходилось заниматься. Наш клиент - 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] Автоматический failover базы данных Moodle в PostgreSQL с помощью ClusterControl (перевод)
- [Конференции, Data Engineering] Опыт разработки и внедрения систем данных в data-driven компаниях
- [Информационная безопасность, PostgreSQL, Администрирование баз данных] Обеспечение безопасности базы данных PostgreSQL (перевод)
- [PostgreSQL] Postgresso 30
- [Python, Программирование, Учебный процесс в IT, Data Engineering] Из филолога в Python-разработчики: как переучиться и чего ждать от новой профессии
- [MySQL, PostgreSQL, SQL, Microsoft SQL Server] DataGrip 2021.1: Редактирование прав, контекстные шаблоны, предсказуемая навигация и не только
- [PostgreSQL, SQL, SQLite, Kotlin] Kotlite и Kotgres: генераторы SQL и JDBC кода на Kotlin для Sqlite и Postgresql
- [PostgreSQL, C] Рецепты PostgreSQL: асинхронные уведомления в… реплике!?
- [.NET, C#, Разработка под Windows] Делаем откаты БД в msi. История про создание резервных копий и удаление БД в WixSharp
- [Big Data, Хранилища данных, Data Engineering] Мультитул для управления Хранилищем Данных — кейс Wheely + dbt
Теги для поиска: #_postgresql, #_data_engineering, #_obfuskatsija (обфускация), #_postgresql, #_postgres, #_postgresql, #_data_engineering
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:59
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
ВведениеВ конце прошлого года мы завершили один из самых интересных и необычных проектов, которыми нам приходилось заниматься. Наш клиент - 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 и реализует следующую функциональность
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;' 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 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) 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 last_name:
db_data_type: text not_null: true obfuscator_data_type: String fake_data: type: pattern value: "%{first_name}SON" 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) =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:59
Часовой пояс: UTC + 5