Использование гибридного хранилища в Managed Service for ClickHouse®
Гибридное хранилище позволяет хранить часто используемые данные на сетевых дисках кластера Managed Service for ClickHouse®, а редко используемые данные — в Yandex Object Storage. Автоматическое перемещение данных между этими уровнями хранения поддерживается только для таблиц семейства MergeTree
Чтобы воспользоваться гибридным хранилищем:
- Создайте таблицу.
- Наполните таблицу данными.
- Проверьте размещение данных таблицы в кластере.
- Выполните тестовый запрос.
Если созданные ресурсы вам больше не нужны, удалите их.
Перед началом работы
Подготовьте инфраструктуру
-
Создайте кластер Managed Service for ClickHouse®:
-
Тип диска — стандартные (
network-hdd
), быстрые (network-ssd
) или нереплицируемые (network-ssd-nonreplicated
) сетевые диски. -
Размер — не менее 15 ГБ.
-
Управление пользователями через SQL — выключено.
-
Имя БД —
tutorial
. -
Гибридное хранилище — включено.
-
-
Настройте права доступа так, чтобы вы могли выполнять в этой базе запросы на чтение и запись.
-
Если у вас еще нет Terraform, установите его.
-
Получите данные для аутентификации. Вы можете добавить их в переменные окружения или указать далее в файле с настройками провайдера.
-
Настройте и инициализируйте провайдер. Чтобы не создавать конфигурационный файл с настройками провайдера вручную, скачайте его
. -
Поместите конфигурационный файл в отдельную рабочую директорию и укажите значения параметров. Если данные для аутентификации не были добавлены в переменные окружения, укажите их в конфигурационном файле.
-
Скачайте в ту же рабочую директорию файл конфигурации clickhouse-hybrid-storage.tf
.В этом файле описаны:
- сеть;
- подсеть;
- группа безопасности по умолчанию и правила, необходимые для подключения к кластеру из интернета;
- кластер Managed Service for ClickHouse® с включенным гибридным хранилищем.
-
Укажите в файле
clickhouse-hybrid-storage.tf
имя пользователя и пароль, которые будут использоваться для доступа к кластеру Managed Service for ClickHouse®. -
Проверьте корректность файлов конфигурации Terraform с помощью команды:
terraform validate
Если в файлах конфигурации есть ошибки, Terraform на них укажет.
-
Создайте необходимую инфраструктуру:
-
Выполните команду для просмотра планируемых изменений:
terraform plan
Если конфигурации ресурсов описаны верно, в терминале отобразится список изменяемых ресурсов и их параметров. Это проверочный этап: ресурсы не будут изменены.
-
Если вас устраивают планируемые изменения, внесите их:
-
Выполните команду:
terraform apply
-
Подтвердите изменение ресурсов.
-
Дождитесь завершения операции.
-
В указанном каталоге будут созданы все требуемые ресурсы. Проверить появление ресурсов и их настройки можно в консоли управления
. -
Настройте инструменты командной строки
-
Установите инструменты
curl
иunxz
:apt-get update && apt-get install curl xz-utils
-
Настройте clickhouse-client и подключитесь с его помощью к базе данных.
Познакомьтесь с тестовым набором данных (необязательный шаг)
Для демонстрации работы гибридного хранилища используются анонимизированные данные о хитах (hits_v1
) Яндекс Метрики. Этот датасет
Таблица tutorial.hits_v1
будет настроена при создании таким образом, чтобы все свежие
данные в таблице с 21 марта 2014 года и позже попали в хранилище на сетевых дисках, а более старые данные (с 17 марта по 20 марта 2014 года) — в объектное хранилище.
Создайте таблицу
Создайте таблицу tutorial.hits_v1
, которая использует гибридное хранилище. Для этого выполните SQL-запрос, подставив вместо <схема>
схему таблицы из документации ClickHouse®
CREATE TABLE tutorial.hits_v1
(
<схема>
)
ENGINE = MergeTree()
PARTITION BY EventDate
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)
TTL EventDate + toIntervalDay(dateDiff('day', toDate('2014-03-20'), now())) TO DISK 'object_storage'
SETTINGS index_granularity = 8192
Запрос с заполненной схемой
CREATE TABLE tutorial.hits_v1
(
`WatchID` UInt64,
`JavaEnable` UInt8,
`Title` String,
`GoodEvent` Int16,
`EventTime` DateTime,
`EventDate` Date,
`CounterID` UInt32,
`ClientIP` UInt32,
`ClientIP6` FixedString(16),
`RegionID` UInt32,
`UserID` UInt64,
`CounterClass` Int8,
`OS` UInt8,
`UserAgent` UInt8,
`URL` String,
`Referer` String,
`URLDomain` String,
`RefererDomain` String,
`Refresh` UInt8,
`IsRobot` UInt8,
`RefererCategories` Array(UInt16),
`URLCategories` Array(UInt16),
`URLRegions` Array(UInt32),
`RefererRegions` Array(UInt32),
`ResolutionWidth` UInt16,
`ResolutionHeight` UInt16,
`ResolutionDepth` UInt8,
`FlashMajor` UInt8,
`FlashMinor` UInt8,
`FlashMinor2` String,
`NetMajor` UInt8,
`NetMinor` UInt8,
`UserAgentMajor` UInt16,
`UserAgentMinor` FixedString(2),
`CookieEnable` UInt8,
`JavascriptEnable` UInt8,
`IsMobile` UInt8,
`MobilePhone` UInt8,
`MobilePhoneModel` String,
`Params` String,
`IPNetworkID` UInt32,
`TraficSourceID` Int8,
`SearchEngineID` UInt16,
`SearchPhrase` String,
`AdvEngineID` UInt8,
`IsArtifical` UInt8,
`WindowClientWidth` UInt16,
`WindowClientHeight` UInt16,
`ClientTimeZone` Int16,
`ClientEventTime` DateTime,
`SilverlightVersion1` UInt8,
`SilverlightVersion2` UInt8,
`SilverlightVersion3` UInt32,
`SilverlightVersion4` UInt16,
`PageCharset` String,
`CodeVersion` UInt32,
`IsLink` UInt8,
`IsDownload` UInt8,
`IsNotBounce` UInt8,
`FUniqID` UInt64,
`HID` UInt32,
`IsOldCounter` UInt8,
`IsEvent` UInt8,
`IsParameter` UInt8,
`DontCountHits` UInt8,
`WithHash` UInt8,
`HitColor` FixedString(1),
`UTCEventTime` DateTime,
`Age` UInt8,
`Sex` UInt8,
`Income` UInt8,
`Interests` UInt16,
`Robotness` UInt8,
`GeneralInterests` Array(UInt16),
`RemoteIP` UInt32,
`RemoteIP6` FixedString(16),
`WindowName` Int32,
`OpenerName` Int32,
`HistoryLength` Int16,
`BrowserLanguage` FixedString(2),
`BrowserCountry` FixedString(2),
`SocialNetwork` String,
`SocialAction` String,
`HTTPError` UInt16,
`SendTiming` Int32,
`DNSTiming` Int32,
`ConnectTiming` Int32,
`ResponseStartTiming` Int32,
`ResponseEndTiming` Int32,
`FetchTiming` Int32,
`RedirectTiming` Int32,
`DOMInteractiveTiming` Int32,
`DOMContentLoadedTiming` Int32,
`DOMCompleteTiming` Int32,
`LoadEventStartTiming` Int32,
`LoadEventEndTiming` Int32,
`NSToDOMContentLoadedTiming` Int32,
`FirstPaintTiming` Int32,
`RedirectCount` Int8,
`SocialSourceNetworkID` UInt8,
`SocialSourcePage` String,
`ParamPrice` Int64,
`ParamOrderID` String,
`ParamCurrency` FixedString(3),
`ParamCurrencyID` UInt16,
`GoalsReached` Array(UInt32),
`OpenstatServiceName` String,
`OpenstatCampaignID` String,
`OpenstatAdID` String,
`OpenstatSourceID` String,
`UTMSource` String,
`UTMMedium` String,
`UTMCampaign` String,
`UTMContent` String,
`UTMTerm` String,
`FromTag` String,
`HasGCLID` UInt8,
`RefererHash` UInt64,
`URLHash` UInt64,
`CLID` UInt32,
`YCLID` UInt64,
`ShareService` String,
`ShareURL` String,
`ShareTitle` String,
`ParsedParams` Nested(
Key1 String,
Key2 String,
Key3 String,
Key4 String,
Key5 String,
ValueDouble Float64),
`IslandID` FixedString(16),
`RequestNum` UInt32,
`RequestTry` UInt8
)
ENGINE = MergeTree()
PARTITION BY EventDate
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)
TTL EventDate + toIntervalDay(dateDiff('day', toDate('2014-03-20'), now())) TO DISK 'object_storage'
SETTINGS index_granularity = 8192
Примечание
Эта таблица использует политику хранения default
(по умолчанию).
Выражение TTL ...
задает политику работы с устаревающими данными:
- TTL задает время жизни строки таблицы (в данном случае — это количество дней от текущей даты до 20 марта 2014 года).
- Для данных в таблице проверяется значение
EventDate
:- если количество дней от текущей даты до
EventDate
меньше значения TTL (то есть время жизни еще не истекло), то эти данные остаются в хранилище на сетевых дисках; - если количество дней от текущей даты до
EventDate
больше или равно значению TTL (то есть время жизни уже истекло), то эти данные помещаются в объектное хранилище согласно политикеTO DISK 'object_storage'
;
- если количество дней от текущей даты до
Указывать TTL для использования гибридного хранилища необязательно, однако это позволяет явно контролировать, какие данные будут находиться в Object Storage. Если не указывать TTL, то данные будут помещаться в объектное хранилище, только когда в хранилище на сетевых дисках закончится место. Подробнее см. в разделе Типы дисков в Managed Service for ClickHouse®.
Примечание
Сложность выражения для TTL в примере выше обусловлена выбранным тестовым набором данных: необходимо искусственно разделить давно собранные фиксированные данные на части для размещения на разных уровнях хранения. Для большинства таблиц, в которые постоянно поступают новые данные, будет достаточно более простого выражения для TTL, например, EventDate + INTERVAL 5 DAY
: данные старше пяти дней будут перемещены в объектное хранилище.
Данные между хранилищем на сетевых дисках и объектным хранилищем перемещаются не построчно, а кускамиEventDate
.
Подробнее о настройке TTL см. в документации ClickHouse®
Наполните таблицу данными
-
Отключитесь от базы данных.
-
Загрузите тестовый датасет:
curl https://storage.yandexcloud.net/doc-files/managed-clickhouse/hits_v1.tsv.xz | unxz --threads=`nproc` > hits_v1.tsv
Объем загруженного датасета — около 10 ГБ.
-
Вставьте данные из этого датасета в ClickHouse® с помощью
clickhouse-client
:clickhouse-client \ --host <FQDN_хоста_ClickHouse®> \ --secure \ --user <имя_пользователя> \ --database tutorial \ --port 9440 \ --ask-password \ --query "INSERT INTO tutorial.hits_v1 FORMAT TSV" \ --max_insert_block_size=100000 < hits_v1.tsv
FQDN хоста можно получить со списком хостов в кластере.
-
Дождитесь завершения операции, вставка данных может занять некоторое время.
Подробнее см. в документации ClickHouse®
Проверьте размещение данных в кластере
-
Посмотрите, где размещены строки таблицы:
SELECT table, partition, name, rows, disk_name FROM system.parts WHERE active AND (table = 'hits_v1') AND (database = 'tutorial')
Партиции таблицы, для которых значение
EventDate
выходит за заданный TTL должны находиться на диске с именемobject_storage
, то есть в объектном хранилище, все прочие партиции — на дискеdefault
:┌─table───┬─partition──┬─name───────────────┬───rows─┬─disk_name──────┐ │ hits_v1 │ 2014-03-17 │ 20140317_6_80_2 │ 571657 │ object_storage │ │ hits_v1 │ 2014-03-17 │ 20140317_86_125_1 │ 287545 │ object_storage │ │ ... │ │ hits_v1 │ 2014-03-20 │ 20140320_109_145_1 │ 250484 │ object_storage │ │ hits_v1 │ 2014-03-20 │ 20140320_149_200_1 │ 420081 │ object_storage │ │ hits_v1 │ 2014-03-21 │ 20140321_3_57_1 │ 612616 │ default │ │ hits_v1 │ 2014-03-21 │ 20140321_65_65_0 │ 53382 │ default │ │ ... │ │ hits_v1 │ 2014-03-23 │ 20140323_191_191_0 │ 11145 │ default │ │ hits_v1 │ 2014-03-23 │ 20140323_197_197_0 │ 98910 │ default │ └─────────┴────────────┴────────────────────┴────────┴────────────────┘
-
Получите число строк на каждом из уровней хранения:
SELECT sum(rows), disk_name FROM system.parts WHERE active AND (database = 'tutorial') AND (table = 'hits_v1') GROUP BY disk_name
В результате будет отражено распределение строк таблицы по уровням хранения:
┌─sum(rows)─┬─disk_name──────┐ │ 2711246 │ default │ │ 6162652 │ object_storage │ └───────────┴────────────────┘
Как видно из результатов выполнения SQL-команд, данные в таблице были успешно распределены в гибридном хранилище между разными уровнями хранения.
Выполните тестовый запрос
Выполните тестовый запрос к таблице tutorial.hits_v1
, который затрагивает данные сразу на нескольких уровнях хранения:
SELECT
URLDomain AS Domain,
AVG(SendTiming) AS AvgSendTiming
FROM tutorial.hits_v1
WHERE (EventDate >= '2014-03-19') AND (EventDate <= '2014-03-22')
GROUP BY Domain
ORDER BY AvgSendTiming DESC
LIMIT 10
Результат:
┌─Domain──────────────────────────────┬──────AvgSendTiming─┐
│ realty.ru.msn.com.travel │ 101166.85714285714 │
│ podbor.ru.msn.com.uazbukatusprosima │ 76429.16666666667 │
│ club.metalia-woman │ 64872.333333333336 │
│ avito.rusfootki │ 51099 │
│ papas.drimmirkvart │ 50325.642857142855 │
│ apps.oyunuoyna.com.uazbukadelight │ 32761.666666666668 │
│ voyeurhit │ 31501.625 │
│ yandex.ru.com.travesti.net │ 31427.5 │
│ sozcu.com.ua.alm.slands │ 29439 │
│ hasters.ru │ 18365.666666666668 │
└─────────────────────────────────────┴────────────────────┘
Как видно из результата выполнения SQL-запроса, с точки зрения пользователя таблица выступает единой сущностью: ClickHouse® успешно выполняет запросы к такой таблице вне зависимости от фактического места расположения данных в ней.
Отслеживайте объем, занимаемый данными в Object Storage (необязательный шаг)
Чтобы узнать, какой объем занимают куски таблиц MergeTreech_s3_disk_parts_size
в сервисе Yandex Monitoring:
-
В консоли управления
выберите сервис Monitoring. -
Перейдите в раздел Обзор метрик.
-
Выполните запрос:
"ch_s3_disk_parts_size"{service="managed-clickhouse", resource_type="cluster", node="by_host", resource_id="<идентификатор_кластера>", subcluster_name="clickhouse_subcluster"}
Удалите созданные ресурсы
Удалите ресурсы, которые вы больше не будете использовать, чтобы за них не списывалась плата:
-
В терминале перейдите в директорию с планом инфраструктуры.
Важно
Убедитесь, что в директории нет Terraform-манифестов с ресурсами, которые вы хотите сохранить. Terraform удаляет все ресурсы, которые были созданы с помощью манифестов в текущей директории.
-
Удалите ресурсы:
-
Выполните команду:
terraform destroy
-
Подтвердите удаление ресурсов и дождитесь завершения операции.
Все ресурсы, которые были описаны в Terraform-манифестах, будут удалены.
-
ClickHouse® является зарегистрированным товарным знаком ClickHouse, Inc