В конце прошлого года мы завершили один из самых интересных и необычных проектов, которыми нам приходилось заниматься.  Наш клиент - 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/latest/masking_functions/) + Можно выгружать сразу в *.sql дамп - Нужно устанавливать как расширение рядом с бд - Для каждого поля нужно прописывать security labels с масками - Маски работают только с одной схемой - Нет данных по производительности Это решение мы не рассматривали из-за того, что оно должно устанавливаться как расширение, запихивать, что-то в production - так себе идея. triki + Заявлена высокая скорость работы (1.4гб mysql dump 17sec) + Много типов данных + можно определить свои (форк + правки т.к. кристал руби-френдли язык) + Можно выгрузить конфигурацию всей схемы для дальнейшей настройки обфускатора (таблицы-поля) + Не требуется никаких правок в исходной бд, только настроить коннект + Выгружает в *.sql дамп Выглядело неплохим вариантом, удобный деплой, понятный нам и заказчику язык, очевидный недостаток - не понятно как сохраняется распределение данных. pgdump-obfuscator (форк) + есть возможность задавать параметры полей через cli (только в форке) - нет информации о производительности - обновлялся 8 лет назад clickhouse-obfuscator + Заявлена высокая скорость работы (в докладе говорилось, что 1тб данных обфусцирован за 1.5 дня) - Написан на C++ (нашей команде сложно вносить изменения) - Принимает только csv-формат - Нет внятной документации (только статья на Хабре) Высокая скорость, сохранение распределения данных после обфускации, поддержка большой компанией и комьюнити - по этим причинам мы выбрали обфускатор от clickhouse. К сожалению для нашей задачи, 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 базы для демонстрации: Посмотрим IP-адрес базы - он понадобится для работы обфускатора: docker inspect db | grep IPAdd             "SecondaryIPAddresses": null,             "IPAddress": "172.17.0.2" И зальем в контейнер скрипты из проекта pagila: Убедимся, что там появились данные: 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;'  База для экспериментов готова. Теперь расчехлим pg_obfuscator, принципиальным моментом является монтирования тома для конфига, чтобы иметь возможность его потом поправить. Дальше команды выполняются в шелле обфускатора, если не сказано другого: Обфускатор говорит, что нужно проверить конфиг и внести необходимые изменения. Конфиг для 20 таблиц получился около 400 строк, секции, которые нуждаются в правках отмечены - need_fix: true. Для того, чтобы вам было легче повторить я выложил исправленный конфиг сюда. Для демонстрации генерации фейковых данных посмотрим на секцию в таблице actor: В качестве фамилии мы используем имя и постфикс SON. Выполним последовательно экспорт схемы, данных, обфускацию и заливку полученных данных в базу pagila_o и выйдя из контейнера с обфускатором посмотрим на результат Видим, что last_name сформирован фейкером, описание обфусцировано, ссылочная целостность сохранена. На этом все, мы надеемся, что утилита будет полезна сообществу, будем рады видеть пулреквесты. Благодарим команду clickhouse obfuscator за отличный продукт!