Перейти к основному содержимому
Перейти к основному содержимому

Сравнение PostgreSQL и ClickHouse

Postgres против ClickHouse: Эквивалентные и разные концепции

Пользователи, приходящие из систем OLTP, которые привыкли к транзакциям ACID, должны понимать, что ClickHouse сознательно идет на компромиссы, не обеспечивая их в полной мере в обмен на производительность. Семантика ClickHouse может обеспечить высокие гарантии надежности и высокую скорость записи, если она хорошо понята. Мы выделяем ключевые концепции ниже, с которыми пользователи должны быть знакомы перед работой с ClickHouse из Postgres.

Шардинг против Реплик

Шардинг и репликация — две стратегии, используемые для масштабирования за пределами одной инстанции Postgres, когда хранилище и/или вычисления становятся узким местом для производительности. Шардинг в Postgres подразумевает разделение большой базы данных на меньшие, более управляемые части, распределенные по нескольким узлам. Однако Postgres не поддерживает шардирование на уровне ядра. Вместо этого шардирование можно реализовать с помощью расширений, таких как Citus, в которых Postgres становится распределенной базой данных, способной к горизонтальному масштабированию. Этот подход позволяет Postgres обрабатывать более высокие скорости транзакций и большие наборы данных, распределяя нагрузку по нескольким машинам. Шарды могут быть на основе строк или схем для обеспечения гибкости типов нагрузки, таких как транзакционная или аналитическая. Шардинг может внести значительную сложность в управление данными и выполнение запросов, так как требует координации между несколькими машинами и обеспечения их согласованности.

В отличие от шардов, реплики — это дополнительные инстанции Postgres, которые содержат все или часть данных из основного узла. Реплики используются по разным причинам, включая увеличение производительности чтения и сценарии HA (высокой доступности). Физическая репликация является родной функцией Postgres, которая подразумевает копирование всей базы данных или значительных ее частей на другой сервер, включая все базы данных, таблицы и индексы. Это происходит за счет потоковой передачи сегментов WAL с основного узла к репликам через TCP/IP. Напротив, логическая репликация является более высоким уровнем абстракции, который потоково передает изменения на основе операций INSERT, UPDATE и DELETE. Хотя те же результаты могут применяться к физической репликации, для целевых таблиц и операций, а также для преобразования данных обеспечивается большая гибкость и поддержка различных версий Postgres.

В отличие от этого, шары и реплики ClickHouse — две ключевые концепции, связанные с распределением и избыточностью данных. Реплики ClickHouse можно рассматривать как аналогичные репликам Postgres, хотя репликация является в конечном итоге согласованной без понятия первичного узла. Шардинг, в отличие от Postgres, поддерживается на уровне ядра.

Шард — это часть данных вашей таблицы. У вас всегда есть как минимум один шард. Шардинг данных по нескольким серверам может использоваться для деления нагрузки, если вы превышаете мощность одного сервера, при этом все шарды используются для параллельного выполнения запроса. Пользователи могут вручную создавать шарды для таблицы на разных серверах и напрямую вставлять данные в них. В качестве альтернативы можно использовать распределенную таблицу с ключом шардирования, определяющим, на какой шард направляются данные. Ключ шардирования может быть случайным или результатом хеш-функции. Важно, что шард может состоять из нескольких реплик.

Реплика — это копия ваших данных. ClickHouse всегда имеет как минимум одну копию ваших данных, поэтому минимальное количество реплик равно одной. Добавление второй реплики ваших данных обеспечивает отказоустойчивость и потенциально дополнительное вычисление для обработки большего числа запросов (Параллельные Реплики также могут использоваться для распределения вычислений для одного запроса, тем самым снижая задержку). Реплики достигаются с помощью движка таблиц ReplicatedMergeTree, который позволяет ClickHouse поддерживать несколько копий данных в синхронизации между различными серверами. Репликация является физической: между узлами передаются только сжатые части, а не запросы.

В общем, реплика — это копия данных, которая обеспечивает избыточность и надежность (и потенциально распределенную обработку), в то время как шард является подмножеством данных, которое позволяет распределенную обработку и балансировку нагрузки.

ClickHouse Cloud использует одну копию данных, размещенных в S3 с несколькими вычислительными репликами. Данные доступны каждому узловой реплике, каждая из которых имеет локальный SSD-кэш. Это зависит от репликации метаданных только через ClickHouse Keeper.

Конечная согласованность

ClickHouse использует ClickHouse Keeper (реализацию ZooKeeper на C++, также можно использовать ZooKeeper) для управления своей внутренней механикой репликации, сосредоточив внимание в первую очередь на хранении метаданных и обеспечении конечной согласованности. Keeper используется для назначения уникальных последовательных номеров для каждой вставки в распределенной среде. Это критически важно для поддержания порядка и согласованности операций. Эта система также обрабатывает фоновые операции, такие как слияния и мутации, гарантируя распределение их исполнения в том же порядке на всех репликах. В дополнение к метаданным, Keeper функционирует как комплексный центр управления репликацией, включая отслеживание контрольных сумм для хранимых частей данных, и действует как распределенная система уведомлений среди реплик.

Процесс репликации в ClickHouse (1) начинается, когда данные вставляются в любую реплику. Эти данные, в их сырой форме вставки, (2) записываются на диск вместе с их контрольными суммами. После записи реплика (3) пытается зарегистрировать эту новую часть данных в Keeper, выделяя уникальный номер блока и фиксируя детали новой части. Другие реплики, обнаружив (4) новые записи в журнале репликации, (5) загружают соответствующую часть данных через внутренний протокол HTTP, проверяя ее по контрольным суммам, указанным в ZooKeeper. Этот метод гарантирует, что все реплики в конечном итоге содержат согласованные и актуальные данные, несмотря на различные скорости обработки или потенциальные задержки. Более того, система способна одновременно обрабатывать несколько операций, оптимизируя процессы управления данными и позволяя масштабировать систему и обеспечить ее устойчивость к аппаратным отличиям.

Обратите внимание, что ClickHouse Cloud использует оптимизированный для облака механизм репликации, адаптированный к своей архитектуре, разделяющей хранилище и вычисления. Храня данные в общем объектном хранилище, данные автоматически доступны для всех вычислительных узлов без необходимости физической репликации данных между узлами. Вместо этого Keeper используется только для обмена метаданными (где находятся данные в объектном хранилище) между вычислительными узлами.

PostgreSQL использует другую стратегию репликации по сравнению с ClickHouse, в основном использующую потоковую репликацию, которая включает модель первичной реплики, где данные постоянно передаются от первичной реплики к одной или нескольким репликациям. Этот тип репликации обеспечивает почти реальную согласованность и может быть синхронным или асинхронным, давая администраторам контроль над балансом между доступностью и согласованностью. В отличие от ClickHouse, PostgreSQL полагается на WAL (журнал предварительной записи) с логической репликацией и декодированием для потоковой передачи объектов данных и изменений между узлами. Этот подход в PostgreSQL более прямолинеен, но может не предоставить тот же уровень масштабируемости и отказоустойчивости в высокораспределенных средах, как это достигается ClickHouse с его сложным использованием Keeper для координации распределенных операций и конечной согласованности.

Последствия для пользователей

В ClickHouse возможность "грязных" чтений — когда пользователи могут записывать данные в одну реплику, а затем читать потенциально не реплицированные данные из другой — возникает из его модели репликации с конечной согласованностью, управляемой через Keeper. Эта модель подчеркивает производительность и масштабируемость в распределенных системах, позволяя репликам работать независимо и синхронизироваться асинхронно. В результате новые вставленные данные могут не быть немедленно видимыми на всех репликах, в зависимости от запаздывания репликации и времени, необходимого для распространения изменений по системе.

В противоположность этому, модель потоковой репликации PostgreSQL обычно может предотвращать грязные чтения, используя синхронные варианты репликации, при которых первичный узел ждет подтверждения хотя бы одной реплики о получении данных перед завершением транзакций. Это обеспечивает гарантии, что после завершения транзакции данные доступны в другой реплике. В случае сбоя первичного узла реплика обеспечит, чтобы запросы видели подтвержденные данные, тем самым поддерживая более строгий уровень согласованности.

Рекомендации

Пользователи, новые для ClickHouse, должны быть осведомлены об этих различиях, которые проявятся в реплицированных средах. Обычно конечная согласованность является достаточной в аналитике по миллиардам, если не триллионам, точек данных — где метрики более стабильны или оценка достаточно точна, поскольку новые данные постоянно вводятся с высокими скоростями.

Существуют несколько вариантов для повышения согласованности чтений, если это необходимо. Оба примера требуют либо увеличенной сложности, либо дополнительных ресурсов — что снижает производительность запросов и затрудняет масштабирование ClickHouse. Мы советуем использовать эти подходы только в случае абсолютной необходимости.

Согласованная маршрутизация

Чтобы преодолеть некоторые ограничения конечной согласованности, пользователи могут обеспечить маршрутизацию клиентов к одним и тем же репликам. Это полезно в случаях, когда несколько пользователей запрашивают ClickHouse и результаты должны быть детерминированными для разных запросов. Несмотря на то, что результаты могут отличаться, поскольку новые данные вставляются, запросы должны обращаться к одним и тем же репликам, обеспечивая согласованный вид.

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

ClickHouse Cloud

ClickHouse Cloud использует одну копию данных, размещенных в S3 с несколькими вычислительными репликами. Данные доступны каждому узлу реплики, у которого есть локальный SSD-кэш. Чтобы обеспечить согласованные результаты, пользователи поэтому должны только обеспечить согласованную маршрутизацию к одному и тому же узлу.

Связь с узлами службы ClickHouse Cloud осуществляется через прокси. HTTP и соединения с нативным протоколом будут маршрутизированы к одному и тому же узлу на протяжении времени, в течение которого они будут открыты. В случае подключений HTTP 1.1 от большинства клиентов это зависит от окна Keep-Alive. Это можно настроить на большинстве клиентов, например, Node Js. Это также требует настройки на стороне сервера, которая будет выше, чем у клиента, и установлена на 10 секунд в ClickHouse Cloud.

Чтобы обеспечить согласованную маршрутизацию между соединениями, например, если используется пул соединений или если соединения истекают, пользователи могут обеспечить использование одного и того же соединения (что проще для нативного) или запросить раскрытие "липких" конечных точек. Это предоставляет набор конечных точек для каждого узла в кластере, позволяя клиентам гарантировать, что запросы маршрутизируются детерминированно.

Свяжитесь со службой поддержки для доступа к липким конечным точкам.

ClickHouse OSS

Чтобы достичь этого поведения в OSS, это зависит от вашей топологии шарда и реплики и от того, используете ли вы распределенную таблицу для выполнения запросов.

Когда у вас есть только один шард и реплики (что обычно, так как ClickHouse вертикально масштабируется), пользователи выбирают узел на уровне клиента и напрямую запрашивают реплику, обеспечивая ее детерминированный выбор.

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

В этом случае пользователи должны обеспечить выполнение согласованной маршрутизации узлов на основании свойства, например, session_id или user_id. Настройки prefer_localhost_replica=0, load_balancing=in_order должны быть установлены в запросе. Это гарантирует, что любые локальные реплики шардов будут предпочтительными, с репликами, предпочтительными в соответствии с конфигурацией иначе - при условии, что у них одинаковое количество ошибок - переключение произойдет с случайным выбором, если ошибок больше. load_balancing=nearest_hostname может также использоваться как альтернатива для этого детерминированного выбора шарда.

При создании распределенной таблицы пользователи укажут кластер. Это определение кластера, указанное в config.xml, будет перечислять шарды (и их реплики) - тем самым позволяя пользователям контролировать порядок, в котором они используются из каждого узла. Используя это, пользователи могут гарантировать детерминированный выбор.

Последовательная согласованность

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

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

С точки зрения пользователя это обычно проявляется как необходимость записывать данные в ClickHouse и гарантировать, что при чтении данных будут возвращены последние вставленные строки. Это может быть достигнуто несколькими способами (в порядке предпочтения):

  1. Чтение/Запись на том же узле - Если вы используете нативный протокол или сессию для выполнения своей записи/чтения через HTTP, вы должны быть подключены к одной и той же реплике: в этом сценарии вы читаете напрямую с узла, куда вы записываете, и ваши чтения всегда будут согласованными.
  2. Синхронизировать реплики вручную - Если вы пишете в одну реплику и читаете из другой, вы можете выполнить команду SYSTEM SYNC REPLICA LIGHTWEIGHT перед чтением.
  3. Включить последовательную согласованность - с помощью настройки запроса select_sequential_consistency = 1. В OSS также необходимо указать настройку insert_quorum = 'auto'.

Смотрите здесь для получения дополнительных сведений о включении этих настроек.

Использование последовательной согласованности будет создавать большую нагрузку на ClickHouse Keeper. Это может привести к замедлению вставок и чтений. SharedMergeTree, используемый в ClickHouse Cloud в качестве основного движка таблицы, имеет меньшую нагрузку и будет лучше масштабироваться. Пользователи OSS должны использовать этот подход осторожно и измерять нагрузку на Keeper.

Поддержка транзакционного (ACID) контекста

Пользователи, мигрирующие из PostgreSQL, могут быть привыкли к его надежной поддержке свойств ACID (Атомарность, Согласованность, Изоляция, Долговечность), что делает его надежным выбором для транзакционных баз данных. Атомарность в PostgreSQL гарантирует, что каждая транзакция рассматривается как единое целое, которое либо полностью выполняется, либо полностью отменяется, предотвращая частичные обновления. Согласованность поддерживается за счет применения ограничений, триггеров и правил, которые гарантируют, что все транзакции базы данных приводят к допустимому состоянию. Уровни изоляции, от Read Committed до Serializable, поддерживаются в PostgreSQL, что позволяет точно контролировать видимость изменений, внесенных конкурентными транзакциями. Наконец, Долговечность достигается путем ведения журнала предварительной записи (WAL), что гарантирует, что после завершения транзакции она остается такой даже в случае сбоя системы.

Эти свойства обычно характерны для OLTP баз данных, которые действуют как источник истины.

Хотя мощные, эти свойства имеют свои ограничения и затрудняют работу с большими объемами. ClickHouse идет на компромисс в этих свойствах, чтобы обеспечить быстрые аналитические запросы в масштабах, сохраняя при этом высокую скорость записи.

ClickHouse предоставляет свойства ACID при ограниченных конфигурациях — чаще всего при использовании не реплицированной инстанции движка таблицы MergeTree с одной партицией. Пользователи не должны ожидать этих свойств вне этих случаев и убедиться, что они не являются необходимыми.

Репликация или миграция данных Postgres с помощью ClickPipes (работает на основе PeerDB)

к сведению

PeerDB теперь доступен нативно в ClickHouse Cloud - Оперативная репликация Postgres в ClickHouse с помощью нашего нового соединителя ClickPipe - сейчас в публичной бета-версии.

PeerDB позволяет вам без усилий реплицировать данные из Postgres в ClickHouse. Вы можете использовать этот инструмент для

  1. непрерывной репликации с использованием CDC, позволяя Postgres и ClickHouse сосуществовать — Postgres для OLTP и ClickHouse для OLAP; и
  2. миграции из Postgres в ClickHouse.