Amazon Redshift: новое хранилище данных на петабайты
Компания Amazon выкатила принципиально новый сервис Redshift для хранения баз данных размером от нескольких сотен гигабайт до многих петабайт. Продукт нацелен на корпоративных заказчиков, которых сдерживает ограничение в 1 терабайт традиционной RDS, при этом хотят пользоваться привычными SQL-приложениями и гарантировать мгновенную доступность данных.
Кластер Redshift поднимается в пару щелчков мыши из административной панели AWS. Стоимость хранения данных здесь сравнима с обычным S3 и зависит от типа кластера и тарифного плана. Например, на трёхлетнем плане она составляет $999 за терабайт в год.
Пользователям Redshift предлагается два типа серверов для кластера: XL и 8XL.
High Storage Extra Large (XL) DW Node
- CPU: 2 виртуальных ядра
- ECU: 4.4
- Память: 15 GiB
- Диски: 3 HDD with 2 TB of local attached storage
- Сеть: средняя
- Скорость I/O с диском: средняя
- API: dw.hs1.xlarge
High Storage Eight Extra Large (8XL) DW
- CPU: 16 virtual cores
- ECU: 35
- Память: 120 GiB
- Диски: 24 HDD с 16 TB локального пространства
- Сеть: 10 Gigabit Ethernet
- Скорость I/O с диском: очень высокая
- API: dw.hs1.8xlarge

В тот же день компания Google тоже снизила цены на 20% на хранение данных в Google Cloud Platform, и объявила о запуске нового сервиса по дешёвому долговременному хранению архивов Durable Reduced Availability Storage, по типу AWS Glacier.

- хранилище данных
- data warehouse
- Amazon Redshift
- AWS
- Amazon S3
- Google Cloud
- снижение цен
Amazon Redshift и традиционные хранилища данных
За последние 12 лет облачная экосистема Amazon пережила поразительный рост. К 2020 году Amazon Web Services (AWS) зарегистрировала выручку в размере 44 миллиардов долларов, что вдвое превышает совокупный доход двух ее ключевых конкурентов в сфере облачных технологий: Google Cloud и Microsoft Azure. AWS Redshift – главный двигатель этого роста.
Облачное хранилище данных AWS Redshift, один из флагманских продуктов Amazon, кардинально меняет правила игры в отрасли. От непревзойденной производительности до неограниченной масштабируемости – число корпоративных клиентов, использующих Redshift, увеличивается с каждым днем. В этой статье мы рассмотрим мир Redshift, его мощные функции и почему так много компаний выбирают Redshift для хранения своих данных и аналитики.
Что такое AWS Redshift?
AWS Redshift – это облачный сервис для хранения данных петабайтного масштаба, одно из решений экосистемы данных Amazon. Платформа, основанная на PostgreSQL, интегрируется с большинством сторонних приложений за счет применения драйверов ODBC и JDBC.
Redshift обеспечивает невероятно высокую производительность за счет использования двух ключевых архитектурных элементов: столбчатого хранилища данных и массивно-параллельной обработки. В 2012 году Amazon инвестировал в поставщика хранилищ данных, ParAccel (сейчас куплен Actian), и использовал свою технологию параллельной обработки в Redshift. Решение быстро стало неотъемлемой частью ландшафта аналитики больших данных благодаря своей способности выполнять запросы на основе SQL в больших базах данных, в которых есть смесь структурированных, неструктурированных и полуструктурированных данных.
За последние пять лет Redshift стал одним из ведущих облачных решений благодаря своей непревзойденной способности предоставлять организациям бизнес-аналитику.
Чем Redshift превосходит традиционные хранилища данных?
Традиционно компании сталкивались с рядом проблем при настройке хранилищ данных. Во-первых, организация таких центров на территории компании дорогая и на ее запуск уйдут месяцы. Этот фактор требовал от руководства твердой бюджетной и стратегической уверенности. Во-вторых, через несколько месяцев или лет объем данных неизменно увеличивался, а это означало, что компаниям приходилось выбирать между инвестированием в новое оборудование или терпимостью к низкой производительности.
Облачное решение Redshift помогает компаниям решить эти проблемы. Создание кластера из консоли AWS занимает считанные минуты. Прием данных в Redshift выполняется простой командой COPY из Amazon S3 (Simple Storage Service) или DynamoDB. Кроме того, масштабируемая архитектура Redshift позволяет компаниям размещать динамический запрос на масштабирование инфраструктуры вверх или вниз по мере изменения требований.
Поскольку кластеры серверов полностью управляются AWS, Redshift избавляет нас от рутинных задач по администрированию баз данных. Сложные задачи, такие как шифрование данных, решаются легко с помощью встроенных функций безопасности Redshift. Платформа также выполняет непрерывное резервное копирование данных, устраняя риск потери данных или необходимость планирования оборудования для резервного копирования.
Учитывая, что Redshift является экономичным, надежным, масштабируемым и быстродействующим решением, компании, естественно, склоняются к такому варианту хранилища данных как услуги (DWaaS).
AWS Redshift – что под капотом?
Основная причина того, что Redshift стала одним из самых популярных решений для облачных хранилищ данных – это архитектурные элементы, лежащие в его основе. AWS фокусируется на постоянных инновациях, добавляя новые функции и предлагая расширения продуктов. Давайте рассмотрим несколько особенностей дизайна Redshift, которые изменили способ получения бизнес-информации.
Хранение данных в столбцах
Традиционные реляционные базы данных используют хранилище на основе строк. Это идеально подходит для тех случаев, когда применяются простые запросы и нужно обновлять определенные строки, например, в приложениях CRM и ERP.
База данных на основе строк будет хранить данные в таблице 1 в таком виде:
тут блог

Общественные обязательства интроверта.
Сообщения на ИТ тематику, но не обязательно.
О Redshift
О ClickHouse я уже рассказывал. А о Redshift как-то позабыл. Вспомнил, когда пришлось рассказывать о них на конференции. Здесь — краткий пересказ.
Redshift — это аналитическая база данных, живущая в облаке AWS. Это проприетарная БД. Вы не можете её запустить где-то локально в Докере. Только в Амазоне.
Redshift — не оригинальная разработка Амазона. Это продукт компании ParAccel. Они лет шесть пилили свою уникальную аналитическую БД на основе PostgreSQL 8. И в 2011 году выпустили ParAccel Analytic Database. В 2012 этот продукт адаптировал Амазон под своё облако. В публичную эксплуатацию Redshift вышел в начале 2013. А мы на проекте начали его использовать в начале 2020. Redshift к этому моменту явно был зрелым продуктом.
Я думал, ClickHouse значительно моложе. Но нет, он моложе лишь на годик. ClickHouse использовался в Яндекс.Метрике уже в 2012.
Redshift, как и ClickHouse, — колоночная СУБД. То есть она хранит данные не по строкам, как тот же Postgres, а по колонкам. В результате, так как в одной колонке присутствуют однородные данные, данные получается эффективно сжимать при хранении на диске. Очень эффективно. В частности, этим колоночные БД хороши.
Redshift — распределённая БД. Кластер Redshift состоит из нескольких узлов, расположенных в одном регионе AWS. На каждом узле запущено несколько слайсов (slices) — процессов БД. Как правило, по числу ядер CPU.

Redshift, как и ClickHouse, — поддерживает SQL. Слава богу, никакой поддержки конкретных стандартов SQL не декларируется. И правильно, SQL в этих колоночных БД весьма специфичный.
Redshift позиционируется как БД для операционной аналитики в реальном времени. Того, что называется OLAP (Online analytical processing) и BI (Business intelligence). Куча данных забивается в большую БД с поддержкой SQL. Аналитик эти данные как-то вертит. А потом всё грохается. Очень похоже на типичный юзкейс для Redshift.
Redshift поддерживает SQL. И этот SQL на 70% совпадает с SQL PostgreSQL 8. Что неудивительно.
В Redshift есть транзакции. С единственным уровнем изоляции serializable . Сделано это через read-write lock на уровне таблиц. Что, с одной стороны, — хорошо. Потому что это действительно честные транзакции. А с другой стороны — плохо. Ибо порождает серьёзные проблемы с производительностью конкурентных запросов. Даже сам уровень конкурентности в кластере Redshift (размер очереди транзакций) не может превышать пятидесяти.
В ClickHouse, напомню, вообще нет транзакций. Все асинхронно и eventually. Также в ClickHouse нет честных (с немедленным эффектом) UPDATE и DELETE . Впрочем, существующего ALTER DELETE вполне достаточно, чтобы удовлетворить GDPR.
На вход в Redshift у нас на проекте поступают данные из бид-реквестов OpenRTB. Метка времени, айдишники, цены, множители. Порядка 19 колонок сейчас. Плюс ещё разнообразные уведомления, которые вставляются в ещё 11 таблиц. Порядка 300 тысяч запросов в минуту.
В ClickHouse, на другом проекте, мы складываем DNS запросы. Их на порядок меньше — порядка 30 тысяч в минуту.
Из Redshiftа мы извлекаем в основном отчёты. Сколько всего, в штуках и в деньгах, было потрачено. С группировкой по разным параметрам и временным интервалам. Тут встречаются джойны с несколькими другими таблицами. Чтобы прилепить сюда и курсы валют, и наличие разных уведомлений. И ещё извлекаем немного статистики по входящим запросам, например, общий размер аудитории. Ну и делаем совершенно произвольные запросы в Redshift для проверки соответствия данных в разных системах. RTB — это есть взаимодействие множества разных систем. И часто нужно сверять данные.
В итоге мы в Redshift имеем, в той самой большой таблице с бид-реквестами, больше 7 миллиардов записей. И то, мы храним данные лишь где-то за последний месяц. Это порядка 370 гигабайт на диске. Всё это умещается в кластер из 4 не самых больших узлов типа dc2.large , с 2 vCPU и 15 гигабайтами памяти на борту каждого. И стоит это удовольствие порядка $850 в месяц. Недёшево.
ClickHouse другого проекта на обычных виртуалках умещается на 6 узлах о 8 гигабайтах памяти на каждом. За $240 в месяц. И это за 195 гигабайт живых данных. За полгода. В два раза меньше данных за в три раза меньше денег. Тоже недёшево.
Типы данных. В Redshift они обычные SQLные, унаследованные от PostgreSQL. Даже какой-то GEOMETRY завезли. А вот ARRAY почему-то нет. Из-за отсутствия ARRAY нам приходится хранить чуть больше строк, чем можно было бы.
ClickHouse на типы данных побогаче. Тут совершенно не следуют SQL традиции, в том числе и в их наименовании. Есть enumы. Есть сложные типы, вроде тех же массивов, кортежей и даже что-то типа объектов (вложенные типы вроде мапы). Из целочисленных мне нравится UInt256 . Буду мутить с блокчейнами, буду его использовать. Ибо в Ethereum везде сплошной uint256 .
Redshift и ClickHouse умеют здорово сжимать данные. Это одно из важных преимуществ колоночных БД. Из универсальных поддерживаются весьма эффективные и модерновые алгоритмы сжатия: LZO и ZSTD. В ClickHouse можно задать уровень сжатия.
Гораздо более интересны специализированные алгоритмы. BYTEDICT превращает строки в enumы, которых в Redshift нет. Если у вас не более 256 уникальных значений, на каждую запись будет отведён лишь один байт. Плюс словарь значений, конечно же. MOSTLY8 , MOSTLY16 , MOSTLY32 хранит целочисленные значения более короткими числами, чем предусмотрено в обычном SQL от Postgres.
Плохо то, что по умолчанию Redshift предлагает вовсе не самые оптимальные алгоритмы сжатия. Вероятно, потому, что новые алгоритмы добавлялись позднее, и они не хотели ломать обратную совместимость. И даже ANALYZE COMPRESSION недостаточно вникает в структуру данных, и тоже предлагает не самый лучший вариант.
На практике лучше всего сжимает ZSTD , и строки, и вещественные числа. Для целых чисел, в зависимости от диапазона значений, стоит выбрать какой-нибудь MOSTLY* . Для строк, которые на самом деле enum, обязательно выбирайте BYTEDICT . И да, sort key сжимать нельзя.
В Redshift тщательно выбирайте алгоритм сжатия сразу при создании таблицы. Поменять его потом может оказаться не так уж и просто. В худшем случае придётся создавать, копировать и переименовывать колонки.
Собственно, о sort key. Во всех колоночных БД нет привычных индексов, которые можно почти в любой момент создать по любым колонкам. Есть лишь два ключа. DISTSTYLE/DISTKEY в Redshift, и аналогичный по смыслу PARTITION BY в ClickHouse — отвечают за физическое распределение записей. И SORTKEY и ORDER BY — ключ сортировки.
DISTSTYLE в Redshift отвечает за то, как строки будут распределяться между узлами кластера (точнее, слайсами). AUTO — БД сама решит (не надо так делать). EVEN — строки будут размазаны псевдослучайно-равномерно. ALL — данная таблица будет присутствовать на каждом узле кластера, что может быть полезно для небольших таблиц-справочников. KEY — распределение по DISTKEY , явно выбранной колонке. Строки с одинаковыми значениями в этой колонке будут располагаться в одном слайсе. Это полезно для эффективного джойна по этой колонке.
К сожалению, DISTKEY может указывать лишь на одну колонку. Если такой удобной колонки, по которой можно всё джойнить, у вас нет, придётся довольствоваться DISTSTYLE EVEN .
PARTITION BY в ClickHouse хоть и похож по сути, имеет совершенно другой смысл. Это выражение, по которому записи в таблице будут объединяться в партиции. На каждом узле кластера. Произвольное выражение, но в первых версиях ClickHouse ключ партицирования всегда неявно соответствовал toYYYYMM(eventDate) , то есть год и месяц колонки типа Date . Партиции в ClickHouse можно очень быстро отцепить, удалить, перенести на другой узел и прицепить там.
Ключ сортировки в обеих БД это именно что ключ сортировки. Данные на диске будут отсортированы именно по этому ключу. Этот ключ может быть составным, из нескольких колонок. Соответственно, поиск по любому префиксу этого ключа будет значительно быстрее. Поэтому ключ сортировки крайне желательно включать в условие WHERE любого запроса. Иначе БД будет вынуждена просканировать всю таблицу, что, очевидно, медленнее. Впрочем, помните, что это колоночная БД. Чем меньше колонок участвует в запросе, тем быстрее. Просканировать одну колонку, в общем-то, не так уж и долго.
В ClickHouse, кроме того, индекс по ключу сортировки — разреженный. Это значит, что в индексе хранится адрес не каждой строки, а, допустим, каждой восьмитысячной строки. Это значительно уменьшает размер самого индекса. Но снижает эффективность запросов, которым нужно извлечь лишь несколько строк.
О, внешние БД. К Redshift и ClickHouse можно подключать внешние таблицы или даже целые базы данных. Из PostgreSQL или MySQL. Или даже из произвольных БД, доступных через JDBC или ODBC, в случае ClickHouse. И к этим внешним таблицам можно будет делать джойны. Может быть очень удобно хранить там длинные справочники, например.
Redshift, кроме того, может делать запросы напрямую к файлам, которые хранятся в S3. Это называется Redshift Spectrum. Это могут быть как «простые текстовые» файлы, типа CSV, так и более сложные форматы вроде JSON, или даже специальные форматы, хранящие данные в колонках, такие как Parquet. То есть вы просто складываете правильные файлы правильным образом в S3, а потом делаете SQL запросы по ним из Redshift.
А ещё Redshift может загружать и выгружать данные в/из кучи разных источников. Это делается командами COPY (загрузка) и UNLOAD (выгрузка). Можно загружать/выгружать из того же S3, из DynamoDB, из EMR (Elastic Map Reduce, то есть из разных хадупов), и даже с удалённого сервера по SSH.
А в ClickHouse есть словари. Это наборы ключей и связанных значений, которые хранятся (как правило) в памяти узлов и могут загружаться и обновляться из внешних источников. Опять-таки, идеальное решение для справочников (не сильно больших).
И Redshift, и ClickHouse — распределённые системы. А значит, они могут масштабироваться.
В Redshift всё сводится к изменению размеров и характеристик кластера. А сам кластер всегда живёт в одном регионе AWS. Можно менять количество и размеры узлов, а также управлять размером хранилища.
В простейшем случае кластер Redshift может состоять из одного узла. Впрочем, даже самый маленький узелочек будем вам стоить $160 в месяц. В single-node кластере действительно лишь один инстанс. Тут нет лидера. Несколько другая архитектура получается. Поэтому добавить ещё узлов без простоя не получится.
А в multi-node кластере, помимо узлов, которые хранят и обрабатывают данные, появляется ещё leader node. Через него проходят все запросы, и он ещё высчитывает некоторые финальные агрегаты.
Узлы можно выбирать разных размеров. И есть ещё два разных типа. DC2 узлы хранят данные исключительно на локальных SSD дисках. Больше узлов — больше места для данных в кластере. А RA3 узлы могут прозрачно вытеснять данные во внешнее хранилище. Снова S3. В этом случае объём хранилища почти не ограничен. А вы платите столько, сколько храните.
В ClickHouse всё ближе к NoSQL. Здесь кластер — это шарды реплик. Данные разбиваются на шарды. Причём Кликхаусу почти пофигу, как вы разбиваете данные. Можно просто прямо вставлять в тот шард, куда удобнее, например, ближе географически. Когда будут делаться запросы, всё равно будут опрошены все шарды. А сами шарды могут быть разных размеров и производительности. Только вот время выполнения запроса будет определяться скоростью самого медленного шарда.
А сами шарды могут состоять из нескольких реплик. Причём наличие реплик ускоряет и чтение, и запись. Поскольку репликация асинхронная, а писать можно в любую реплику. Другие реплики просто рано или поздно подсосут себе отсутствующие данные.
Redshift для общения по сети использует протокол PostgreSQL 8. Поэтому все инструменты работы с Postgres могут к нему подключиться (но не все они будут одинаково полезны в отношении Redshift).
У ClickHouse есть аж два сетевых протокола. Свой бинарный протокол, который используется для общения узлов кластера между собой, а также в родном CLI клиенте clickhouse-client . И HTTP протокол. Запросы можно засылать прямо curl ом.
JDBC драйвер. К Redshift можно подключиться и Postgres драйвером. Только последние версии этого драйвера ругаются ворнингами, что PostgreSQL 8 — это слишком старая версия сервера, которая скоро перестанет поддерживаться.
А ещё у Redshift есть свои JDBC драйвера. Аж двух версий. Версии 1.x крайне не рекомендую к использованию. Они глючат. А версии 2.x — открыты, и проблем с ними не замечено.
У ClickHouse свой JDBC драйвер. Он, почему-то, подключается через HTTP. Он работает.
Материализованные представления. Они есть и там и там. Нам они очень понравилось в ClickHouse. Потому что там их можно использовать вместе со -State агрегатными функциями и движком AggregatingMergeTree. В результате у вас получаются автоматически обновляемые агрегаты, сворачивающие исходные данные в несколько раз. При этом сами исходные данные можно потом и удалить (когда партиция заполнится).
В Redshift materialized views самые обычные. И их нужно руками обновлять командой REFRESH MATERIALIZED VIEW .
Самое интересное. Как вставлять 300k строк в минуту. В Redshift пришлось знатно помучиться.
Мама же учила вас всегда использовать prepared statement? Ну хотя бы для того, чтобы избежать SQL инъекций. Так вот, у разработчиков Redshift, ну или как минимум у разработчиков её JDBC драйвера, были другие мамы. Использовать PreparedStatement для быстрой вставки в Redshift у вас не получится. Не знаю почему, но каждый INSERT через PreparedStatement занимает не менее двух секунд. И батчи не помогают. Так что забываем про правильную вставку.
Рекомендуемый способ быстрой вставки в Redshift — это multi-row insert. Это когда в одном выражении INSERT вы указываете сразу много строк для вставки. Как-то так: INSERT INTO. VALUES (. ), (. ), . . Такую строку придётся собрать самостоятельно. И она может быть длиной до 16 мегабайт. Да, пришлось сделать это руками. Хорошо, что во входных данных нет произвольного пользовательского ввода, только цифры да айдишники, можно надеяться, что примитивного экранирования будет достаточно.
Но даже этого недостаточно для 300k вставок в минуту. Ещё более рекомендуемый способ — делать COPY из S3. То есть вы буквально пишете в S3 файлы. Например, |-separated, с разделителем в виде символа «|». Такой формат предполагает Redshift по умолчанию. Файлов должно быть больше, чем слайсов в кластере Redshift. А потом делаете COPY . И эта единственная команда COPY за те же самые две секунды всасывает все эти данные. Магия. Они называют это массивно-параллельной обработкой. Каждый слайс обрабатывает часть всех файлов. Именно поэтому файлов должно быть много.
Да, это очень странно. Но да, через S3 уже можно вставить 300k записей в минуту.
Хотя мы уже думаем, что, раз уж эти данные уже есть в S3, и, на самом деле, эти данные нужны не сильно часто, они не входят в те постоянные отчёты, что делают пользователи, может, пусть они и лежат в S3. А запросы, если понадобится, можно делать и через Redshift Spectrum.
В ClickHouse проблем со вставкой нет. Батчи JDBC, и PreparedStatement работают прекрасно. Рекомендуются батчи не менее 1000 строк и вставка не чаще раза в секунду.
Конечно, остаётся проблема того, как этот самый батч создать. Его же надо где-то накопить. В памяти, в очереди. Где-то надо. И, как всегда, есть риск либо потерять какой-нибудь кусок данных, либо вставить более одного раза.
SQL в Redshift скучен. Самый обычный SQL. Хотя вполне нормально поддерживаются common table expression (CTE). Те самые запросы с WITH . Это радует.
А в ClickHouse есть несколько уникальных плюшек. Можно считать агрегаты не по всем строкам, а по некоторому подмножеству строк, приближённые агрегаты, с помощью SAMPLE . Можно оптимизировать выполнение запроса, сначала анализируя только колонки с условиями выборки, а лишь затем извлекая данные из остальных колонок, с помощью PREWHERE . Можно сразу формировать строку «итого» при группировке, с помощью WITH TOTALS .
В ClickHouse встроено громадное количество всяких разных интересных функций агрегации. Разнообразные квантили, стандартные отклонения и прочие прелести на радость статистикам.
Redshift из коробки не выходит за рамки обычных для SQL агрегатов. Но тут можно писать UDF (user defined functions). На SQL или Python. Или даже запускаемые на Lambda. Также можно писать хранимые процедуры на PL/pgSQL. Интересно, существуют ли библиотеки статистических функций, чтобы хоть чуть-чуть приблизиться к ClickHouse?
Ну и, наконец, проблемы.
Не используйте JDBC драйвер для Redshift версии 1.x. У нас он приводил к зависаниям на пару минут при каждом открытии подключения к Redshift. Только при запуске внутри AWS. Только если в classpath при этом присутствовал и драйвер PostgreSQL. Этот же драйвер периодически вызывал странные ошибки в DataGrip. То колонки с таймстампами не отображаются. То вообще не получается стянуть схему БД. С драйвером версии 2.x проблем не замечено.
С конкурентностью у Redshift всё плохо. Транзакции сделаны через блокировку на уровне таблиц. А это значит, что те самые вставки кучи строк и тяжёлые выборки по одним и тем же таблицам нужно делать в один поток. Серьёзно, мы пытались вставлять и делать выборки в несколько потоков. В лучшем случае это нисколько не ускоряет их выполнение. В худшем случае можно словить дедлоки. Которые в худшем случае лечатся ребутом кластера. Вроде как можно поиграть с очередями запросов. Но что-то я сомневаюсь, что это как-то существенно изменит ситуацию.
У ClickHouse, кстати, всё в точности наоборот. Все операции асинхронны. Параллельная вставка лишь увеличивает (до определённого момента) общую производительность. Конкуренция идёт, как обычно, за CPU, память и дисковый ввод-вывод. Пока всего этого хватает, параллельные запросы друг другу не мешают. Но нет транзакций.
Redshift может внезапно сожрать весь диск. Как я понимаю, каждый подзапрос на самом деле создаёт временную таблицу, куда записываются результаты подзапроса. На диск. Если вы будете неаккуратны, попытаетесь извлечь слишком много строк, или слишком много колонок, в слишком большом количестве подзапросов. То вы легко случайно за несколько минут сможете занять места в два раза больше, чем у вас уже хранится в кластере. И всё. Пока операции не отменятся из-за нехватки места на диске, и это самое место не освободится, весь кластер будет стоять колом.
Redshift хоть и поддерживает SQL, но не все комбинации, которые можно выразить в SQL, в нём допустимы. Например, он очень не любит подзапросы в сочетании с внешними соединениями. Или просто слишком большое количество подзапросов. Вы просто пишете запрос, слегка его усложняете, и получаете красивую ошибку, которая объясняет ничего: [0A000] ERROR: This type of correlated subquery pattern is not supported yet .
Ситуация усугубляется ещё тем, что вы не можете поднять Redshift где-нибудь локально в Докере. Для локальных экспериментов предлагают использовать PostgreSQL. Ну так хитрый запрос без проблем выполняется в Postgres. А вот в Redshift, внезапно, отказывается работать.
Между тем, ClickHouse без проблем можно запустить локально. Open source и всё такое. Запускаете один узел в Docker, и вперёд.
Ну и последняя мелочь. В Redshift нет и намёка на разнообразные collation. Есть лишь два: CASE_SENSITIVE и CASE_INSENSITIVE . Что бы это ни значило. Опять вопиющее расхождение с PostgreSQL.
С ClickHouse проблем было меньше. Больше всего доставлял ZooKeeper. Он нужен для работы реплик. В нём узлы кластера хранят информацию о том, какой узел какие куски данных содержит. И какие, соответственно, нужно скопировать. ZooKeeper — это часть Hadoop, написан на Java. И, если его неправильно приготовить, он будет падать, глючить и жрать диск своими снапшотами и логами.
А ещё ClickHouse не поддерживается популярными инструментами управления миграциями БД. Видимо, потому, что в ClickHouse нет транзакций, и эти инструменты не могут надёжно сохранить метаданные о миграциях в самом ClickHouse. Впрочем, на практике схемы в ClickHouse меняются очень редко. Не сильно сложно руками держать несколько идемпотентных SQL скриптов для воссоздания схемы БД с нуля.
Ну и ClickHouse, к сожалению, ещё не поддерживается как managed сервис в популярных среди западных заказчиков облаках. Он есть только в Yandex.Cloud. Только из-за этого мы не смогли воткнуть ClickHouse в тот самый проект, куда воткнули Redshift. Заказчик настаивал на максимальном использовании managed сервисов в AWS.
На самом деле, Redshift и ClickHouse действительно очень похожи. Оба могут хранить очень много данных. Оба очень эффективно сжимают эти данные на диске. Оба позволяют быстро вставлять много строк.
Разница есть в транзакциях. В Redshift они строго serializable. В ClickHouse их нет. В конкурентности. Redshift, из-за блокировок на уровне таблиц, очень не любит конкурентные запросы на одни и те же таблицы. И в скорости ответа. От Redshift очень сложно добиться ответа быстрее, чем через пару секунд. А ClickHouse вполне может отвечать за сотню-другую миллисекунд.
Ну и подход к масштабируемости у них разный. Redshift хоть и может вырасти до большого кластера из десятков узлов, всё равно будет жить лишь в одном регионе. Его типичный вариант использования — загрузить много данных, чтобы их повертеть аналитиком в одиночестве.
А с ClickHouse можно построить географически распределённый кластер. Можно добиться локальности данных — иметь узел кластера в том регионе, где данные генерируются, для быстрой вставки.
P.P.S. Извините, что почти нет картинок. Но и в официальных документациях их тоже почти нет 🙁
Аналитический движок Amazon Redshift + преимущества Облака

На связи Артемий Козырь из команды Аналитики, и я продолжаю знакомить вас с Wheely. В этом выпуске:
- Основы гибких кластерных вычислений
- Колоночное хранение и компрессия данных
- Вместо индексов: ключи сегментации и сортировки
- Управление доступами, правами, ресурсами
- Интеграция с S3 или Даталейк на ровном месте
Все аналитические решения Wheely так или иначе строятся на основе Хранилища Данных, движком которого выступает продукт с кодовым названием Redshift от провайдера облачных сервисов Amazon. Но почему именно этот продукт?
Эту публикацию я бы охарактеризовал как базовую и основополагающую. Сложные механизмы и принципы работы системы скрыты от бизнес-пользователей, но именно они лежат в основе производительного и современного решения. Постараюсь внести ясность и подчеркнуть для вас ключевые особенности.
Кластерные вычисления как основа архитектуры
Кластер состоит из leader node (координатор) и набора compute node (вычислительный узел). Координатор играет роль связующего звена между кластером и пользовательскими приложениями, генерирует планы запросов, управляет коммуникацией. Вычислительные узлы — рабочие лошадки, на которых выполняется основная часть расчетов.

Redshift обеспечивает параллельную обработку данных на кластере машин
Этот принцип широко известен как MPP (massively parallel processing, массово-параллельная архитектура). Не лишним будет упомянуть и другие популярные СУБД, использующие подобные принципы: BigQuery, Vertica, Greenplum, Teradata, Azure SQL DW.
Каждая compute node обладает набором выделенных ресурсов: CPU, memory, disk, которые определяются типом виртуальной машины.

Сегодня в Wheely мы используем 8 узлов типа dc2.large, что в сумме составляет 16 vCPU, 120 GiB памяти, 1.3 TB объем диска. Кто-то может справедливо заметить, что это не такие уж и огромные объемы данных, на что я бы возразил: суть не в объеме, а в том, какие результаты и пользу вы можете выжать из этих данных.
Не могут не радовать элементы гибкости и эластичности (elasticity), в целом присущие облачным сервисам. С ростом бизнеса и потребности в аналитике несколько раз без особого труда производилось расширение кластера: увеличивалось количество узлов (resize), осуществлялся переход на новое поколение виртуальных машин (node upgrade).

Concurrency Scaling позволит поднять временный кластер для того чтобы справиться с пиковой нагрузкой
В моменты пиковых нагрузок производительность на стабильном уровне может поддержать функция concurrency scaling, которая автоматически добавляет вычислительные мощности в виде временных compute nodes, которые «гасятся» после спада нагрузки.
Колоночное хранение и компрессия данных
В противовес классическим операционным СУБД (PostgreSQL, MySQL, SQL Server), хранящим данные в строковом формате (row-oriented storage), Redshift использует все преимущества колоночного хранения (column-oriented storage). Блоки на диске заполняются данными одной колонки, и каждая колонка хранится отдельно от любой другой.
Это дает несколько неоспоримых преимуществ для аналитических нагрузок. Прежде всего для операций проекции (запросе каких-то конкретных колонок). Представьте себе широкую таблицу фактов из 100+ колонок; для формирования результата запроса нам из них понадобятся только 5. При колоночном хранении мы с диска прочтем ровно 5 запрашиваемых колонок. При строковом хранении пришлось бы читать все 100+ колонок и потом отбросить бОльшую часть, что в разы увеличивает интенсивность I/O и нагрузку на диск.

Колоночное хранение организовывает в блоки данные одной колонки (не строки!)
Во-вторых, будучи однородными, данные одной колонки весьма успешно поддаются сжатию (compression). Объясняя на пальцах, нет необходимости хранить наименование тарифа (Business, First, Luxe) для каждой поездки. Достаточно сделать одну запись и указать, на какое количество строк будет распространяться это значение: . Эффект становится особенно заметен, когда количество строк исчисляется сотнями тысяч и миллионами. На деле всё несколько сложнее: кодеков (алгоритмов) сжатия около десятка, и у каждого есть свои особенности и лучшие сценарии для применения.

Однако при должном усердии можно добиться еще более значительного сжатия, чем дефолтные кодеки, выбранные Amazon Redshift. Чуть подробнее этот вопрос я раскрывал в публикации Compressing Redshift columnar data even further with proper encodings.

Пересмотр алгоритмов сжатия данных позволил сэкономить 21% дискового пространства
Ключи сегментации и сортировки вместо индексов
В Redshift вторичные поисковые структуры данных (индексы) в привычном понимании (B-Tree, Bitmap) отсутствуют. Здесь они просто не нужны, и вот почему:
Тонкая настройка позволяет задать принцип, по которому строки будут распределены между узлами кластера: равномерное (EVEN), копия на каждом (ALL), или по ключу (KEY). Эта конфигурация носит название тип сегментации (distribution style).

3 типа распределения каждой строки данных в кластере: KEY, ALL, EVEN
А уже данные в блоках на каждом узле можно физически хранить в заданном порядке, то есть отсортированными. На ум приходит сортировка, например, по монотонно возрастающему идентификатору. Конфигурация, использующая один и тот же атрибут в distribution key, sort key обеспечит использование самого оптимального типа соединения таблиц — SORT MERGE JOIN:
ORDER BY request_id:
Смотрите на это как на конструкцию ORDER BY в SQL-запросе, сохраняющую порядок в таблице на диске. При этом задействованы могут быть несколько колонок — тогда это уже составной ключ (compound sort key).
ORDER BY city, date, product_name:
В дополнение, есть еще такой очень хитрый вид сортировки как Interleaved sort key, который дает одинаковый вес любой из колонок (или их комбинации) в ключе сортировки. Он отлично подходит к витринам данных, для которых нет одного заранее известного паттерна доступа.
INTERLEAVED SORT BY completed_ts_loc, city, country, service_group, is_airport, is_wheely_journey:
Вкупе с колоночным хранением данных это дает поразительные результаты с точки зрения производительности и использования ресурсов.
Разграничение прав доступа и ресурсных квот
На мой взгляд, это один из фундаментальных вопросов, напрямую влияющий на безопасностью и работоспособность кластера:
- любой пользователь принадлежит к группе с четким скоупом прав
- все запросы разбиваются на категории и обрабатываются с различным приоритетом
Структура лучше хаоса. Концептуально можно сделать так:
- Бизнес-пользователи смотрят только на витрины данных
- Аналитики видят стейдж и промежуточные таблицы
- Инженеры видят сырые данные и метаданные
- Админ видит их всех 🙂
Amazon Redshift является форком широко известной PostgreSQL и поэтому синтаксис многим покажется знакомым:
Упрощенная версия конфигурации групп и прав доступа:
---------------------- -- USER MANAGEMENT --- ---------------------- CREATE USER etl WITH PASSWORD '' ; CREATE USER hevo WITH PASSWORD '' ; CREATE USER dbt WITH PASSWORD '' ; CREATE USER da WITH PASSWORD '' ; CREATE USER nb WITH PASSWORD '' ; CREATE USER looker WITH PASSWORD '' SYSLOG ACCESS UNRESTRICTED ; CREATE USER ar WITH PASSWORD '' ; CREATE USER ak WITH PASSWORD '' ; ------------------------- --- SCHEMA MANAGEMENT --- ------------------------- CREATE SCHEMA IF NOT EXISTS hevo AUTHORIZATION hevo ; CREATE SCHEMA IF NOT EXISTS ext AUTHORIZATION etl ; CREATE SCHEMA IF NOT EXISTS flatten AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS staging AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS intermediate AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS analytics AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS ad_hoc AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS meta AUTHORIZATION dbt ; CREATE SCHEMA IF NOT EXISTS looker_scratch AUTHORIZATION looker ; ----------------------- -- GROUP MANAGEMENT --- ----------------------- CREATE GROUP etl WITH USER etl, hevo ; CREATE GROUP dbt WITH USER dbt ; CREATE GROUP analytics WITH USER da, nb ; CREATE GROUP bi WITH USER looker ; CREATE GROUP business_users WITH USER ar, ak ; ---------------------------- -- PRIVILEGES MANAGEMENT --- ---------------------------- -- GROUP etl GRANT USAGE ON SCHEMA hevo, staging, flatten, analytics, intermediate TO GROUP etl ; -- GROUP dbt GRANT USAGE ON SCHEMA hevo, snapshots TO GROUP dbt ; GRANT USAGE, CREATE ON SCHEMA ext TO GROUP dbt ; GRANT SELECT ON ALL tables IN SCHEMA hevo TO GROUP dbt ; GRANT ALL PRIVILEGES ON ALL tables IN SCHEMA meta, ext, snapshots TO GROUP dbt ; ALTER DEFAULT PRIVILEGES FOR USER hevo IN SCHEMA hevo GRANT SELECT ON tables TO GROUP dbt ; ALTER DEFAULT PRIVILEGES FOR USER etl IN SCHEMA ext GRANT ALL PRIVILEGES ON tables TO GROUP dbt ; -- GROUP analytics GRANT USAGE ON SCHEMA hevo, ext, flatten, staging, intermediate, restricted, analytics, meta TO GROUP analytics ; GRANT USAGE, CREATE ON SCHEMA ad_hoc TO GROUP analytics ; GRANT SELECT ON ALL tables IN SCHEMA hevo, ext, flatten, staging, intermediate, restricted, analytics, meta TO GROUP analytics ; GRANT ALL PRIVILEGES ON ALL tables IN SCHEMA ad_hoc TO GROUP analytics ; ALTER DEFAULT PRIVILEGES FOR USER dbt IN SCHEMA flatten, staging, intermediate, restricted, analytics, meta GRANT SELECT ON tables TO GROUP analytics ; ALTER DEFAULT PRIVILEGES FOR USER dbt IN SCHEMA ad_hoc GRANT ALL PRIVILEGES ON tables TO GROUP analytics ; -- GROUP bi GRANT USAGE ON SCHEMA analytics, meta, ad_hoc, snapshots TO GROUP bi ; GRANT SELECT ON ALL tables IN SCHEMA analytics, meta, ad_hoc TO GROUP bi ; ALTER DEFAULT PRIVILEGES FOR USER dbt IN SCHEMA analytics, meta, ad_hoc GRANT SELECT ON tables TO GROUP bi ; -- GROUP business users GRANT USAGE ON SCHEMA analytics TO GROUP business_users ; GRANT USAGE, CREATE ON SCHEMA ad_hoc TO GROUP business_users ; GRANT SELECT ON ALL tables IN SCHEMA analytics TO GROUP business_users ; GRANT ALL PRIVILEGES ON ALL tables IN SCHEMA ad_hoc TO GROUP business_users ; ALTER DEFAULT PRIVILEGES FOR USER dbt IN SCHEMA analytics GRANT SELECT ON tables TO GROUP business_users ;
У Amazon Redshift очень неплохие настройки automatic workload management (WLM), т.е. автоматическое управление параллелизмом запросов и выделением ресурсов. Но на каком-то моменте и его усилия достигают предела. Redshift просто не может знать всё о специфике вашей нагрузки:
- Периодичность и время запуска ELT
- Приоритетные часы для BI и Ad-hoc
- Какие запросы можно “отстреливать” и почему
- Наиболее важные запросы, которые точно должны завершаться

Конфигурация очередей (WLM) позволяет гибко управлять нагрузкой на кластер
Однако это уже тема отдельной публикации, и потенциально я могу сделать подробный доклад по разграничению прав доступа и тонкой настройки очередей.
Отдельно хочется упомянуть про short-query acceleration. Amazon Redshift гордится использованием ML-алгоритмов для предсказания времени выполнения запросов, и короткие (~ до 30 сек.) пропускает впереди тех, что будут выполняться долго. В любом случае, после включении этой фичи у кластера Wheely как будто открылось второе дыхание, а BI здорово ускорился.
Data Lake ближе чем вы можете представить
Что там с возможностью устроить Даталейк на ровном месте? Она есть! Вместе с расширением Redshift Spectrum кластер приобретает новые возможности:
- В виде SQL DDL описывать внешние источники данных (файлы в S3)
- Выполнять запросы к таким данным: доступны проекции (SELECT), фильтры (WHERE), соединения наборов данных (JOINs), вставка (INSERT)
- Работать с вложенными и полу-структурированными данными: JSON, ORC, PARQUET
Всё это напоминает широко известные EXTERNAL TABLE в _Hive. _И по сути так оно и есть: под капотом используется именно Hive Metastore.

Благодаря Spectrum в Redshift доступен широкий набор популярных форматов данных
В Wheely мы нашли несколько применений Spectrum:
1. Data Quality Pipeline
Каждый день при помощи S3 и Spectrum выполняется кросс-сверка операционной базы данных (MongoDB) и Хранилища (Redshift). Чуть подробнее я описывал это в публикации Кто ответит за качество аналитики: QA для Хранилища Данных, и с тех пор даже есть значительные усовершенствования.
2. Архивирование холодных данных в S3
Холодные данные сроком давности >3 лет мы выгружаем в S3 в бинарный колоночный формат parquet. Данные всё так же доступны для запросов пользователей, однако дорогостоящее место в кластере Redshift они уже не занимают, что замечательно.
Пример выгрузки данных для архивирования в S3 (формат файлов parquet)
UNLOAD ('SELECT * FROM "hevo"."events_prod_clickstream_archive"') TO 's3://wheely_analytics/dwh/hevo/events_prod/clickstream_archive' IAM_ROLE '' MANIFEST FORMAT AS PARQUET NULL AS '' MAXFILESIZE AS 256 ENCRYPTED AUTO ;
В планах у меня еще одна грандиозная идея: хочется создать полноценный дата-лейк. Но об этом позже.
В случае факапа восстановитесь из бэкапа

Вместо тысячи слов
Обычно я не вставляю мемы в публикации, но тут не смог удержаться. Случайно наткнулся и нашел его очень смешным и жизненным. Ситуация может произойти с каждым, и я не исключение. Благо случай не был связан с витринами и production-таблицами, а произошел в рамках одной ad-hoc задачи.
Суть в том, что с недавнего времени появилась возможность восстановить единичные таблицы из бэкапа в указанное целевое место назначения (target table). Очень легко восстановить удаленную или испорченную таблицу из бэкапа за определенную дату. И именно таблицу, а не снапшот целиком. И это не может не радовать. Несколько раз пользовались, и, надеюсь, хватит.

Восстановить удаленную или испорченную таблицу из бэкапа теперь как никогда просто и быстро
Ну и, конечно же, стоит упомянуть что бэкапы выполняются автоматически с периодичностью в несколько часов и горизонтом в 7 суток.
Очень ждём: in-database ML, native semi-structured data support
Даже несмотря на все перечисленные достоинства всегда есть куда развиваться. И команде Wheely как искушенным пользователям всегда хочется большего.
Облизываясь, я смотрю на новые фичи Amazon Redshift, которые уже находятся в статусе preview (пока доступны для тестовых кластеров):
- Using machine learning in Amazon Redshift
- Ingesting and querying semistructured data in Amazon Redshift
Кажется, я уже придумал им достойное применение. Очень ждём! И, конечно, подготовим свежие обзоры и доклады.
Интересно? Присоединяйся к команде Wheely. Или свяжись со мной и задай вопросы — буду рад ответить.