Важно: Данный раздел актуален для Платформы данных On-Premise.
Наименование системы: RT.WideStore.
RT.WideStore – столбцовая система управления базами данных, предназначенная для онлайн обработки аналитических запросов (OLAP).
В настоящем документе использованы и определены следующие термины и сокращения:
Термин/ Сокращение |
Определение |
---|---|
Docker | Платформа, которая упрощает процесс сборки, запуска, управления и распространения приложений с помощью виртуализации операционной системы, на которой он установлен. |
OLAP | (англ. online analytical processing, интерактивная аналитическая обработка) – технология обработки данных, заключающаяся в подготовке суммарной (агрегированной) информации на основе больших массивов данных, структурированных по многомерному принципу. |
RAM | Оперативная память. |
RBAC | (англ. Role Based Access Contro) Управление доступом на основе ролей, развитие политики избирательного управления доступом, при этом права доступа субъектов системы на объекты группируются с учётом специфики их применения, образуя роли. |
SQL | (англ. structured query language, язык структурированных запросов) –декларативный язык программирования, применяемый для создания, модификации и управления данными в реляционной базе данных, управляемой соответствующей системой управления базами данных. |
Воркфлоу | Поток работ (англ. workflow) – графическое представление потока задач в процессе и связанных с ним подпроцессах, включая специфические работы, информационные зависимости и последовательность решений и работ. |
ОС | Операционная система. |
Система | Система «RT.WideStore». |
СУБД | Система управления базами данных. |
Шард | Сервер входящий в кластер. |
RT.WideStore реализует параллельную обработку данных и использует все доступные аппаратные ресурсы. При выборе процессора учитывайте, что RT.WideStore работает более эффективно в конфигурациях с большим количеством ядер, но с более низкой тактовой частотой, чем в конфигурациях с меньшим количеством ядер и более высокой тактовой частотой. Например, 16 ядер с 2600 MHz предпочтительнее, чем 8 ядер с 3600 MHz.
Рекомендуется использовать технологии Turbo Boost и hyper-threading. Их использование существенно улучшает производительность при типичной нагрузке.
Мы рекомендуем использовать как минимум 4 ГБ оперативной памяти, чтобы иметь возможность выполнять нетривиальные запросы. Сервер RT.WideStore может работать с гораздо меньшим объёмом RAM, память требуется для обработки запросов.
Необходимый объём RAM зависит от:
Для расчета объёма RAM необходимо оценить размер промежуточных данных для операций GROUP BY, DISTINCT, JOIN, а также других операций, которыми вы пользуетесь.
RT.WideStore может использовать внешнюю память для промежуточных данных. Подробнее смотрите в разделе GROUP BY во внешней памяти.
Отключайте файл подкачки в продуктовых средах.
Для установки RT.WideStore необходимо 2ГБ свободного места на диске.
Объём дискового пространства, необходимый для хранения ваших данных, необходимо рассчитывать отдельно. Расчёт должен включать:
Можно взять образец данных и получить из него средний размер строки. Затем умножьте полученное значение на количество строк, которое вы планируете хранить.
Чтобы оценить коэффициент сжатия данных, загрузите некоторую выборку данных в RT.WideStore и сравните действительный размер данных с размером сохранённой таблицы. Например, данные типа clickstream обычно сжимаются в 6-10 раз.
Для оценки объёма хранилища, примените коэффициент сжатия к размеру данных. Если вы планируете хранить данные в нескольких репликах, то необходимо полученный объём умножить на количество реплик.
По возможности, используйте сети 10G и более высокого класса.
Пропускная способность сети критически важна для обработки распределенных запросов с большим количеством промежуточных данных. Также, скорость сети влияет на задержки в процессах репликации.
RT.WideStore разработан для семейства операционных систем Linux. Рекомендуемый дистрибутив Linux – Ubuntu. В системе должен быть установлен пакет tzdata.
RT.WideStore может работать и в других семействах операционных систем, например, в FreeBSD или Mac OS X.
Администратор Системы должен иметь навыки работы со следующими продуктами:
Вы можете отслеживать:
RT.WideStore не отслеживает состояние аппаратных ресурсов самостоятельно.
Рекомендуем контролировать:
Например, можно использовать команды операционной системы: dmesg – для вывода сообщений драйверов устройств и turbostat – для вывода данных о топологии процессора, частоты, статистики состояния питания в режиме ожидания, температуре и мощности на X86 процессорах.
Сервер RT.WideStore имеет встроенные инструменты мониторинга.
Для отслеживания событий на сервере используйте логи. Параметры логгирования настраиваются секции logger конфигурационного файла.
RT.WideStore собирает:
Метрики находятся в таблицах:
Можно настроить экспорт метрик из RT.WideStore в Graphite, для отображения в виде графика. Смотрите секцию graphite конфигурационного файла RT.WideStore. Перед настройкой экспорта метрик необходимо настроить Graphite, как указано в официальном руководстве.
Можно настроить экспорт метрик из RT.WideStore в Prometheus. Смотрите секцию prometheus конфигурационного файла RT.WideStore. Перед настройкой экспорта метрик необходимо настроить Prometheus, как указано в официальном руководстве.
Также, можно отслеживать доступность сервера через HTTP API. Отправьте HTTP GET к ресурсу /ping. Если сервер доступен, он отвечает 200 OK.
Для мониторинга серверов в кластерной конфигурации необходимо установить параметр max_replica_delay_for_distributed_queries и использовать HTTP ресурс /replicas_status. Если реплика доступна и не отстаёт от других реплик, то запрос к /replicas_status возвращает 200 OK. Если реплика отстаёт, то запрос возвращает 503 HTTP_SERVICE_UNAVAILABLE, включая информацию о размере отставания.
Основные типы проблем, связанных с установкой и эксплуатацией RT.WideStore:
Возможные проблемы соединения с сервером:
Если сервер не запущен:
Проверьте, запущен ли сервер командой:
$ sudo service clickhouse-server status
Если сервер не запущен, запустите его с помощью команды:
$ sudo service clickhouse-server start
Проверьте журналы:
Основной лог clickhouse-server по умолчанию – /var/log/clickhouse-server/clickhouse-server.log.
В случае успешного запуска вы должны увидеть строки, содержащие:
<Information> Application: starting up. – сервер запускается.
<Information> Application: Ready for connections. – сервер запущен и готов принимать соединения.
Если clickhouse-server не запустился из-за ошибки конфигурации вы увидите <Error> строку с описанием ошибки. Например:
2019.01.11 15:23:25.549505 [ 45 ] {} <Error> ExternalDictionaries: Failed reloading
'event2id' external dictionary: Poco::Exception. Code: 1000, e.code() = 111, e.displayText() =
Connection refused, e.what() = Connection refused
Если вы не видите ошибки в конце файла, просмотрите весь файл начиная со строки:
<Information> Application: starting up.
При попытке запустить второй экземпляр clickhouse-server журнал выглядит следующим образом:
2019.01.11 15:25:11.151730 [ 1 ] {} <Information> : Starting ClickHouse 19.1.0 with revision
54413
2019.01.11 15:25:11.154578 [ 1 ] {} <Information> Application: starting up
2019.01.11 15:25:11.156361 [ 1 ] {} <Information> StatusFile: Status file ./status already
exists - unclean restart. Contents:
PID: 8510
Started at: 2019-01-11 15:24:23
Revision: 54413
2019.01.11 15:25:11.156673 [ 1 ] {} <Error> Application: DB::Exception: Cannot lock file
./status. Another server instance in same directory is already running.
2019.01.11 15:25:11.156682 [ 1 ] {} <Information> Application: shutting down
2019.01.11 15:25:11.156686 [ 1 ] {} <Debug> Application: Uninitializing subsystem: Logging
Subsystem
2019.01.11 15:25:11.156716 [ 2 ] {} <Information> BaseDaemon: Stop SignalListener thread
Проверьте логи system.d:
Если из логов clickhouse-server вы не получили необходимой информации или логов нет, то вы можете посмотреть логи system.d командой:
$ sudo journalctl -u clickhouse-server
Запустите clickhouse-server в интерактивном режиме:
$ sudo -u clickhouse /usr/bin/clickhouse-server --config-file /etc/clickhouse-server/config.xml
Эта команда запускает сервер как интерактивное приложение со стандартными параметрами скрипта автозапуска. В этом режиме clickhouse-server выводит сообщения в консоль.
Проверьте:
При запуске ClickHouse в Docker в сети IPv6 убедитесь, что установлено `network=host`.
Параметры endpoint:
Проверьте настройки
[listen_host](server_configuration_parameters/settings.md#server_configuration_parameters-
listen_host)
и
[tcp_port](server_configuration_parameters/settings.md#server_configuration_parameters-
tcp_port).
По умолчанию, сервер ClickHouse принимает только локальные подключения.
Настройки протокола HTTP:
Проверьте настройки протокола для HTTP API.
Параметры безопасного подключения:
Проверьте:
- Настройку `tcp_port_secure`.
- Параметры для SSL-сертификатов.
Используйте правильные параметры при подключении. Например, используйте параметр
`port_secure` при использовании `clickhouse_client`.
Возможно, вы используете неверное имя пользователя или пароль.
Если RT.WideStore не может обработать запрос, он отправляет клиенту описание ошибки. В clickhouse-client вы получаете описание ошибки в консоли. При использовании интерфейса HTTP, RT.WideStore отправляет описание ошибки в теле ответа. Например:
$ curl 'http://localhost:8123/' --data-binary "SELECT a"
Code: 47, e.displayText() = DB::Exception: Unknown identifier: a. Note that there are no
tables (FROM clause) in your query, context: required_names: 'a' source_tables:
table_aliases: private_aliases: column_aliases: public_columns: 'a' masked_columns:
array_join_columns: source_columns: , e.what() = DB::Exception
Если вы запускаете clickhouse-client c параметром stack-trace, то RT.WideStore возвращает описание ошибки и соответствующий стек вызовов функций на сервере.
Может появиться сообщение о разрыве соединения. В этом случае необходимо повторить запрос. Если соединение прерывается каждый раз при выполнении запроса, следует проверить журналы сервера на наличие ошибок.
Если вы видите, что RT.WideStore работает слишком медленно, необходимо профилировать загрузку ресурсов сервера и сети для ваших запросов.
Для профилирования запросов можно использовать утилиту clickhouse-benchmark. Она показывает количество запросов, обработанных за секунду, количество строк, обработанных за секунду и процент или времени обработки запросов.
RT.WideStore поддерживает управление доступом на основе подхода RBAC, то есть основанную на управление доступом на основе ролей.
Объекты системы доступа в RT.WideStore:
Вы можете настроить объекты системы доступа, используя:
Функциональность необходимо включить управление доступом (см. п.2.3.9).
Рекомендуется использовать SQL-воркфлоу. Оба метода конфигурации работают одновременно, поэтому, если для управления доступом вы используете конфигурационные файлы, вы можете плавно перейти на SQL-воркфлоу.
Внимание: Нельзя одновременно использовать оба метода для управления одним и тем же объектом системы доступа.
Чтобы посмотреть список всех пользователей, ролей, профилей и пр., а также все привилегии, используйте запрос SHOW ACCESS.
По умолчанию сервер RT.WideStore предоставляет аккаунт пользователя default, для которого выключена функция SQL-ориентированного управления доступом, но у него есть все права и разрешения. Аккаунт default используется во всех случаях, когда имя пользователя не определено. Например, при входе с клиента или в распределенных запросах. При распределенной обработке запроса default используется, если в конфигурации сервера или кластера не указаны свойства user и password.
Если вы начали пользоваться RT.WideStore недавно, попробуйте следующий сценарий:
Существуют следующие особенности реализации выдачи разрешений:
Аккаунт пользователя – это объект системы доступа, позволяющий авторизовать кого-либо в RT.WideStore. Аккаунт содержит:
Привилегии присваиваются аккаунту пользователя с помощью запроса GRANT или через назначение ролей. Отозвать привилегию можно с помощью запроса REVOKE. Чтобы вывести список присвоенных привилегий, используется выражение SHOW GRANTS.
Запросы управления:
Настройки могут быть заданы разными способами: для аккаунта пользователя, для назначенных ему ролей или в профилях настроек. При входе пользователя, если настройка задана для разных объектов системы доступа, значение настройки и ее ограничения применяются в следующем порядке (от высшего приоритета к низшему):
Роль – это контейнер объектов системы доступа, которые можно присвоить аккаунту пользователя.
Роль содержит:
Привилегии можно присвоить роли с помощью запроса GRANT. Для отзыва привилегий у роли RT.WideStore предоставляет запрос REVOKE.
Политика доступа к строкам – это фильтр, определяющий, какие строки доступны пользователю или роли. Политика содержит фильтры для конкретной таблицы, а также список ролей и/или пользователей, которые должны использовать данную политику.
Запросы управления:
Профиль настроек – это набор настроек. Профиль настроек содержит настройки и ограничения, а также список ролей и/или пользователей, по отношению к которым применяется данный профиль.
Запросы управления:
Квота ограничивает использование ресурсов. См. п. 2.6.
Квота содержит набор ограничений определенной длительности, а также список ролей и/или пользователей, на которых распространяется данная квота.
Запросы управления:
Для включения SQL-ориентированного управления доступом:
RT.WideStore хранит конфигурации объектов системы доступа в каталоге, установленном в конфигурационном параметре сервера access_control_path.
По умолчанию управление доступом на основе SQL выключено для всех пользователей. Вам необходимо настроить хотя бы одного пользователя в файле конфигурации users.xml и присвоить значение 1 параметру access_management.
Репликация обеспечивает защиту от аппаратных сбоев, но не защищает от человеческих ошибок: случайного удаления данных, удаления не той таблицы, которую надо было, или таблицы на не том кластере, а также программных ошибок, которые приводят к неправильной обработке данных или их повреждению. Во многих случаях подобные ошибки влияют на все реплики. RT.WideStore имеет встроенные средства защиты для предотвращения некоторых типов ошибок – например, по умолчанию не получится удалить таблицы *MergeTree, содержащие более 50 Гб данных, одной командой. Однако эти средства защиты не охватывают все возможные случаи и могут быть обойдены.
Для того чтобы эффективно уменьшить возможные человеческие ошибки, следует тщательно подготовить стратегию резервного копирования и восстановления данных заранее.
Каждая компания имеет различные доступные ресурсы и бизнес-требования, поэтому нет универсального решения для резервного копирования и восстановления RT.WideStore, которое будет подходить в каждой ситуации. То, что работает для одного гигабайта данных, скорее всего, не будет работать для десятков петабайт. Существует множество возможных подходов со своими плюсами и минусами, которые будут рассмотрены ниже. Рекомендуется использовать несколько подходов вместо одного, чтобы компенсировать их различные недостатки.
Примечание: Имейте в виду, что, если вы создали резервную копию чего-то и никогда не пытались восстановить её, скорее всего, восстановление не будет работать должным образом, когда вам это действительно понадобится (или, по крайней мере, это займет больше времени, чем будет приемлемо для бизнеса). Поэтому, какой бы подход к резервному копированию вы ни выбрали, обязательно автоматизируйте процесс восстановления и регулярно запускайте его на резервном кластере RT.WideStore.
Часто данные, которые поступают в RT.WideStore, доставляются через некоторую отказоустойчивую очередь, например Apache Kafka. В этом случае можно настроить дополнительный набор подписчиков, которые будут считывать один и тот же поток данных во время записи в RT.WideStore и хранить его в холодном хранилище. Большинство компаний уже имеют некоторые рекомендуемые по умолчанию холодные хранилища, которые могут быть хранилищем объектов или распределенной файловой системой, например HDFS.
Некоторые локальные файловые системы позволяют делать снимки (например, ZFS)), но они могут быть не лучшим выбором для обслуживания живых запросов. Возможным решением является создание дополнительных реплик с такой файловой системой и исключение их из Distributed таблиц, используемых для запросов SELECT. Снимки на таких репликах будут недоступны для запросов, изменяющих данные. В качестве бонуса, эти реплики могут иметь особые конфигурации оборудования с большим количеством дисков, подключенных к серверу, что будет экономически эффективным.
clickhouse-copier – это универсальный инструмент, который изначально был создан для перешардирования таблиц с петабайтами данных. Его также можно использовать для резервного копирования и восстановления, поскольку он надёжно копирует данные между таблицами и кластерами RT.WideStore.
Для небольших объёмов данных можно применять "INSERT INTO ... SELECT ..." в удалённые таблицы.
RT.WideStore позволяет использовать запрос "ALTER TABLE ... FREEZE PARTITION ..." для создания локальной копии партиций таблицы. Это реализуется с помощью жестких ссылок (hardlinks) на каталог /var/lib/clickhouse/shadow/, поэтому такая копия обычно не занимает дополнительное место на диске для старых данных. Созданные копии файлов не обрабатываются сервером RT.WideStore, поэтому вы можете просто оставить их там: у вас будет простая резервная копия, которая не требует дополнительной внешней системы, однако при аппаратных проблемах вы можете утратить и актуальные данные и сохраненную копию. По этой причине, лучше удаленно скопировать их в другое место, а затем удалить локальную копию. Распределенные файловые системы и хранилища объектов по-прежнему являются хорошими вариантами для этого, однако можно использовать и обычные присоединенные файловые серверы с достаточно большой ёмкостью (в этом случае передача будет происходить через сетевую файловую систему или, возможно, rsync).
Для автоматизации этого подхода доступен инструмент от сторонних разработчиков: clickhouse-backup (инструмент для простого резервного копирования и восстановления RT.WideStore с поддержкой облачных хранилищ).
RT.WideStore поддерживает многофайловое управление конфигурацией. Основной конфигурационный файл сервера — /etc/clickhouse-server/config.xml
или /etc/clickhouse-server/config.yaml
. Остальные файлы должны находиться в директории /etc/clickhouse-server/config.d
. Обратите внимание, что конфигурационные файлы могут быть записаны в форматах XML или YAML, но смешение этих форматов в одном файле не поддерживается. Например, можно хранить основные конфигурационные файлы как config.xml
и users.xml
, а дополнительные файлы записать в директории config.d
и users.d
в формате .yaml
.
Все XML файлы должны иметь одинаковый корневой элемент, обычно <clickhouse>
. Для YAML элемент clickhouse:
должен отсутствовать, так как парсер вставляет его автоматически.
Некоторые настройки, определенные в основном конфигурационном файле, могут быть переопределены в других файлах:
replace
или remove
.replace
, сервер заменит весь элемент на указанный.remove
, сервер удалит элемент.Также возможно указать атрибуты как переменные среды с помощью from_env="VARIABLE_NAME"
:
<clickhouse>
<macros>
<replica from_env="REPLICA" />
<layer from_env="LAYER" />
<shard from_env="SHARD" />
</macros>
</clickhouse>
В конфигурационном файле могут быть указаны «подстановки». Если у элемента присутствует атрибут incl
, то в качестве значения будет использована соответствующая подстановка из файла. По умолчанию путь к файлу с подстановками - /etc/metrika.xml
. Он может быть изменён в конфигурации сервера в элементе include_from. Значения подстановок указываются в элементах /clickhouse/имя_подстановки
этого файла. Если подстановка, заданная в incl
, отсутствует, то делается соответствующая запись в лог. Чтобы RT.WideStore фиксировал в логе отсутствие подстановки, необходимо указать атрибут optional="true"
(например, настройки для macros).
Если нужно заменить весь элемент подстановкой, можно использовать include
как имя элемента.
Пример подстановки XML:
<clickhouse>
<!-- Appends XML subtree found at `/profiles-in-zookeeper` ZK path to `<profiles>` element. -->
<profiles from_zk="/profiles-in-zookeeper" />
<users>
<!-- Replaces `include` element with the subtree found at `/users-in-zookeeper` ZK path. -->
<include from_zk="/users-in-zookeeper" />
<include from_zk="/other-users-in-zookeeper" />
</users>
</clickhouse>
Подстановки могут также выполняться из ZooKeeper. Для этого укажите у элемента атрибут from_zk = "/path/to/node"
. Значение элемента заменится на содержимое узла /path/to/node
в ZooKeeper. В ZooKeeper-узел также можно положить целое XML-поддерево, оно будет целиком вставлено в исходный элемент.
В элементе users_config
файла config.xml
можно указать относительный путь к конфигурационному файлу с настройками пользователей, профилей и квот. Значение users_config
по умолчанию — users.xml
. Если users_config
не указан, то настройки пользователей, профилей и квот можно задать непосредственно в config.xml
.
Настройки пользователя могут быть разделены в несколько отдельных файлов аналогичных config.xml
и config.d\
. Имя директории задаётся также как users_config
. Имя директории задаётся так же, как имя файла в users_config
, с подстановкой .d
вместо .xml
/.yaml
. Директория users.d
используется по умолчанию, также как users.xml
используется для users_config
. Например, можно иметь по отдельному конфигурационному файлу для каждого пользователя:
$ cat /etc/clickhouse-server/users.d/alice.xml
<clickhouse>
<users>
<alice>
<profile>analytics</profile>
<networks>
<ip>::/0</ip>
</networks>
<password_sha256_hex>...</password_sha256_hex>
<quota>analytics</quota>
</alice>
</users>
</clickhouse>
Для каждого конфигурационного файла, сервер при запуске генерирует также файлы file-preprocessed.xml
. Эти файлы содержат все выполненные подстановки и переопределения, и предназначены для информационных целей. Если в конфигурационных файлах были использованы ZooKeeper-подстановки, но при старте сервера ZooKeeper недоступен, то сервер загрузит конфигурацию из preprocessed-файла.
Сервер следит за изменениями конфигурационных файлов, а также файлов и ZooKeeper-узлов, которые были использованы при выполнении подстановок и переопределений, и перезагружает настройки пользователей и кластеров на лету. То есть, можно изменять кластера, пользователей и их настройки без перезапуска сервера.
Здесь можно рассмотреть пример реальной конфигурации записанной на YAML: config.yaml.example.
Между стандартами XML и YAML имеются различия, поэтому в этом разделе будут перечислены некоторые подсказки для написания конфигурации на YMAL.
Для записи обычной пары ключ-значение следует использовать Scalar:
key: value
Для создания тега, содержащего подтеги следует использовать Map:
map_key:
key1: val1
key2: val2
key3: val3
Для создания списка значений или подтегов, расположенных по определенному ключу, следует использовать Sequence:
seq_key:
- val1
- val2
- key1: val3
- map:
key2: val4
key3: val5
В случае, если необходимо объявить тег, аналогичный XML-атрибуту, необходимо задать скаляр, имеющий ключ с префиксом @ и заключенный в кавычки:
map:
"@attr1": value1
"@attr2": value2
key: 123
Из такой Map мы получим после конвертации:
<map attr1="value1" attr2="value2">
<key>123</key>
</map>
Помимо Map, можно задавать атрибуты для Sequence:
seq:
- "@attr1": value1
- "@attr2": value2
- 123 - abc
Таким образом получая аналог следующей записи на XML:
<seq attr1="value1" attr2="value2">123</seq>
<seq attr1="value1" attr2="value2">abc</seq>
При старте сервера для каждого конфигурационного файла создаются файлы предобработки file-preprocessed.xml
. Они содержат все выполненные подстановки и переопределения (эти сведения записываются просто для информации). Если в конфигурационном файле настроены подстановки ZooKeeper, но при старте сервера ZooKeeper не доступен, то сервер загружает конфигурацию из соответствующего файла предобработки.
Сервер отслеживает как изменения в конфигурационных файлах, так и файлы и узы ZooKeeper, которые были использованы при выполнении подстановок и переопределений, и на ходу перезагружает настройки для пользователей и кластеров. Это означает, что можно изменять кластеры, пользователей и их настройки без перезапуска сервера.
Квоты позволяют ограничить использование ресурсов за некоторый интервал времени, или просто подсчитывать использование ресурсов.
Квоты настраиваются в конфиге пользователей. Обычно это users.xml.
В системе есть возможность ограничить сложность одного запроса. Для этого смотрите раздел «Ограничения на сложность запроса».
В отличие от них, квоты:
Рассмотрим фрагмент файла users.xml, описывающего квоты:
<!-- Квоты. -->
<quotas>
<!-- Имя квоты. -->
<default>
<!-- Ограничения за интервал времени. Можно задать много интервалов с разными ограничениями. -->
<interval>
<!-- Длина интервала. -->
<duration>3600</duration>
<!-- Без ограничений. Просто считать соответствующие данные за указанный интервал. -->
<queries>0</queries>
<errors>0</errors>
<result_rows>0</result_rows>
<read_rows>0</read_rows>
<execution_time>0</execution_time>
</interval>
</default>
Видно, что квота по умолчанию просто считает использование ресурсов за каждый час, но не ограничивает их.
Подсчитанное использование ресурсов за каждый интервал, выводится в лог сервера после каждого запроса:
<statbox>
<!-- Ограничения за интервал времени. Можно задать много интервалов с разными ограничениями. -->
<interval>
<!-- Длина интервала. -->
<duration>3600</duration>
<queries>1000</queries>
<errors>100</errors>
<result_rows>1000000000</result_rows>
<read_rows>100000000000</read_rows>
<execution_time>900</execution_time>
</interval>
<interval>
<duration>86400</duration>
<queries>10000</queries>
<errors>1000</errors>
<result_rows>5000000000</result_rows>
<read_rows>500000000000</read_rows>
<execution_time>7200</execution_time>
</interval>
</statbox>
Для квоты с именем statbox заданы ограничения за каждый час и за каждые 24 часа (86 400 секунд). Интервал времени считается, начиная от некоторого implementation defined фиксированного момента времени. То есть, интервал длины 24 часа начинается не обязательно в полночь.
Когда интервал заканчивается, все накопленные значения сбрасываются. То есть, в следующий час, расчёт квоты за час, начинается заново.
Рассмотрим величины, которые можно ограничить:
Если за хотя бы один интервал, ограничение превышено, то кидается исключение с текстом о том, какая величина превышена, за какой интервал, и когда начнётся новый интервал (когда снова можно будет задавать запросы).
Для квоты может быть включена возможность указывать «ключ квоты», чтобы производить учёт ресурсов для многих ключей независимо. Рассмотрим это на примере:
<!-- Для глобального конструктора отчётов. -->
<web_global>
<!-- keyed - значит в параметре запроса передаётся "ключ" quota_key,
и квота считается по отдельности для каждого значения ключа.
Например, в качестве ключа может передаваться логин пользователя в Метрике,
и тогда квота будет считаться для каждого логина по отдельности.
Имеет смысл использовать только если quota_key передаётся не пользователем, а программой.
Также можно написать <keyed_by_ip /> - тогда в качестве ключа квоты используется IP-адрес.
(но стоит учесть, что пользователь может достаточно легко менять IPv6-адрес)
-->
<keyed />
Квота прописывается для пользователей в секции users конфига. Смотрите раздел «Права доступа».
При распределённой обработке запроса, накопленные величины хранятся на сервере-инициаторе запроса. То есть, если пользователь пойдёт на другой сервер - там квота будет действовать «с нуля».
При перезапуске сервера, квоты сбрасываются.
RT.WideStore запускает профилировщик выборки, позволяющий анализировать выполнение запроса. Используя профилировщик, вы можете найти процедуры исходного кода, которые наиболее часто используются во время выполнения запроса. Вы можете отслеживать время процессора и реальное время, включая время простоя.
Чтобы использовать профилировщик:
В этом разделе настраивается системная таблица trace_log, содержащая результаты работы профилировщика. Он настроен по умолчанию. Помните, что данные в этой таблице действительны только для работающего сервера. После перезапуска сервера RT.WideStore не очищает таблицу, и весь сохраненный адрес виртуальной памяти может стать недействительным.
Эти параметры позволяют настраивать таймеры профилировщика. Поскольку это настройки сеанса, вы можете получить различную частоту выборки для всего сервера, отдельных пользователей или профилей пользователей, для вашего интерактивного сеанса и для каждого отдельного запроса.
Частота дискретизации по умолчанию – одна выборка в секунду, при этом включены как ЦП, так и таймеры реального времени. Такая частота позволяет собрать достаточно информации о кластере RT.WideStore. При этом, работая с такой периодичностью, профилировщик не влияет на производительность сервера RT.WideStore. Если вам нужно профилировать каждый отдельный запрос, попробуйте использовать более высокую частоту выборки.
Чтобы проанализировать системную таблицу trace_log:
Если вам нужно визуализировать trace_log информацию, используйте flamegraph и speedscope.
Пример использования профилировщика запросов представлен в Приложении 1.
Системные таблицы содержат следующую информацию:
Системные таблицы:
Большинство системных таблиц хранят свои данные в оперативной памяти. Сервер RT.WideStore создает эти системные таблицы при старте.
В отличие от других системных таблиц, таблицы с системными логами metric_log, query_log, query_thread_log, trace_log, part_log, crash_log и text_log используют движок таблиц MergeTree и по умолчанию хранят свои данные в файловой системе. Если удалить таблицу из файловой системы, сервер RT.WideStore снова создаст пустую таблицу во время следующей записи данных. Если схема системной таблицы изменилась в новом релизе, то RT.WideStore переименует текущую таблицу и создаст новую.
Таблицы с системными логами log можно настроить, создав конфигурационный файл с тем же именем, что и таблица в разделе /etc/clickhouse-server/config.d/, или указав соответствующие элементы в /etc/clickhouse-server/config.xml. Настраиваться могут следующие элементы:
Пример:
<widestore>
<query_log>
<database>system</database>
<table>query_log</table>
<partition_by>toYYYYMM(event_date)</partition_by>
<ttl>event_date + INTERVAL 30 DAY DELETE</ttl>
<!--
<engine>ENGINE = MergeTree PARTITION BY toYYYYMM(event_date) ORDER BY (event_date, event_time) SETTINGS index_granularity = 1024</engine>
-->
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
</query_log>
</widestore>
По умолчанию размер таблицы не ограничен. Управлять размером таблицы можно используя TTL для удаления устаревших записей журнала. Также вы можете использовать функцию партиционирования для таблиц MergeTree.
Описание системных таблиц представлено в Приложении 2.
Для сбора системных показателей сервер RT.WideStore использует:
Если для сервера RT.WideStore не включено CAP_NET_ADMIN, он пытается обратиться к ProcfsMetricsProvider. ProcfsMetricsProvider позволяет собирать системные показатели для каждого запроса (для CPU и I/O).
Если procfs поддерживается и включена в системе, то сервер RT.WideStore собирает следующие системные показатели:
Раздел содержит описания настроек сервера, которые не могут изменяться на уровне сессии или запроса.
Рассмотренные настройки хранятся в файле config.xml сервера RT.WideStore.
Прочие настройки описаны в разделе «Настройки».
Перед изучением настроек ознакомьтесь с разделом Конфигурационные файлы, обратите внимание на использование подстановок (атрибуты incl и optional).
Все настройки, описанные ниже, могут быть заданы несколькими способами.
Настройки задаются послойно, т.е. каждый следующий слой перезаписывает предыдущие настройки.
Способы задания настроек, упорядоченные по приоритету:
Устанавливаются в элементе <profiles>.
Настройки, которые можно задать только в конфигурационном файле сервера, в разделе не рассматриваются.
В дополнение к общим настройкам, пользователи могут определять собственные настройки.
Название пользовательской настройки должно начинаться с одного из предопределённых префиксов. Список этих префиксов должен быть задан в параметре custom_settings_prefixes конфигурационного файла сервера.
<custom_settings_prefixes> custom_</custom_settings_prefixes>
Чтобы задать значение пользовательской настройке, используйте команду SET:
SET custom_a = 123;
Чтобы получить текущее значение пользовательской настройки, используйте функцию getSetting():
SELECT getSetting('custom_a');
Запросы в RT.WideStore можно разделить на несколько типов:
SELECT
, SHOW
, DESCRIBE
, EXISTS
.INSERT
, OPTIMIZE
.SET
, USE
.CREATE
, ALTER
, RENAME
, ATTACH
, DETACH
, DROP
TRUNCATE
.KILL QUERY
.Разрешения пользователя по типу запроса регулируются параметрами:
Разрешения пользователя по типу запроса регулируются параметрами:
KILL QUERY выполняется с любыми настройками.
Ограничивает разрешения для запросов на чтение данных, запись данных и изменение параметров.
Разделение запросов по типам смотрите по тексту выше по тексту.
Возможные значения:
После установки readonly = 1 или 2 пользователь не может изменить настройки readonly и allow_ddl в текущей сессии.
При использовании метода GET в HTTP интерфейсе, readonly = 1 устанавливается автоматически. Для изменения данных используйте метод POST.
Установка readonly = 1 запрещает изменение всех настроек. Существует способ запретить изменения только некоторых настроек, см. ограничения на изменение настроек.
Значение по умолчанию: 0.
Разрешает/запрещает DDL запросы.
Разделение запросов по типам смотрите по тексту выше по тексту.
Возможные значения:
Если allow_ddl = 0, то невозможно выполнить SET allow_ddl = 1 для текущей сессии.
Значение по умолчанию: 1.
Ограничения на сложность запроса - часть настроек.
Используются, чтобы обеспечить более безопасное исполнение запросов из пользовательского интерфейса.
Почти все ограничения действуют только на SELECT-ы.
При распределённой обработке запроса, ограничения действуют на каждом сервере по отдельности.
Ограничения проверяются на каждый блок обработанных данных, а не на каждую строку. В связи с этим, ограничения могут быть превышены на размер блока.
Ограничения вида «максимальное количество чего-нибудь» могут принимать значение 0, которое обозначает «не ограничено».
Для большинства ограничений также присутствует настройка вида overflow_mode - что делать, когда ограничение превышено.
Оно может принимать одно из двух значений: throw или break; а для ограничения на агрегацию (group_by_overflow_mode) есть ещё значение any.
throw – кинуть исключение (по умолчанию).
break – прервать выполнение запроса и вернуть неполный результат, как будто исходные данные закончились.
any (только для group_by_overflow_mode) – продолжить агрегацию по ключам, которые успели войти в набор, но не добавлять новые ключи в набор.
Параметры ограничения на сложность запросов представлены в Приложении 3.
Профиль настроек – это набор настроек, сгруппированных под одним именем.
Примечание: Для управления профилями настроек рекомендуется использовать SQL-ориентированный воркфлоу, который также поддерживается в RT.WideStore.
Название профиля может быть любым. Вы можете указать один и тот же профиль для разных пользователей. Самое важное, что можно прописать в профиле – readonly=1, это обеспечит доступ только на чтение.
Профили настроек поддерживают наследование. Это реализуется указанием одной или нескольких настроек profile перед остальными настройками, перечисленными в профиле. Если одна настройка указана в нескольких профилях, используется последнее из значений.
Все настройки профиля можно применить, установив настройку profile.
Пример:
Установить профиль web:
SET profile = 'web'
Профили настроек объявляются в конфигурационном файле пользователей. Обычно это users.xml.
Пример:
<!-- Settings profiles -->
<profiles>
<!-- Default settings -->
<default>
<!-- The maximum number of threads when running a single query. -->
<max_threads>8</max_threads>
</default>
<!-- Settings for quries from the user interface -->
<web>
<max_rows_to_read>1000000000</max_rows_to_read>
<max_bytes_to_read>100000000000</max_bytes_to_read>
<max_rows_to_group_by>1000000</max_rows_to_group_by>
<group_by_overflow_mode>any</group_by_overflow_mode>
<max_rows_to_sort>1000000</max_rows_to_sort>
<max_bytes_to_sort>1000000000</max_bytes_to_sort>
<max_result_rows>100000</max_result_rows>
<max_result_bytes>100000000</max_result_bytes>
<result_overflow_mode>break</result_overflow_mode>
<max_execution_time>600</max_execution_time>
<min_execution_speed>1000000</min_execution_speed>
<timeout_before_checking_execution_speed>15</timeout_before_checking_execution_speed>
<max_columns_to_read>25</max_columns_to_read>
<max_temporary_columns>100</max_temporary_columns>
<max_temporary_non_const_columns>50</max_temporary_non_const_columns>
<max_subquery_depth>2</max_subquery_depth>
<max_pipeline_depth>25</max_pipeline_depth>
<max_ast_depth>50</max_ast_depth>
<max_ast_elements>100</max_ast_elements>
<readonly>1</readonly>
</web>
</profiles>
В примере задано два профиля: default и web.
Профиль default имеет специальное значение – он обязателен и применяется при запуске сервера. Профиль default содержит настройки по умолчанию.
Профиль web – обычный профиль, который может быть установлен с помощью запроса SET или параметра URL при запросе по HTTP.
Ограничения на изменение настроек могут находиться внутри секции profiles файла user.xml и запрещают пользователю менять некоторые настройки с помощью запроса SET.
Выглядит это следующим образом:
<profiles>
<имя_пользователя>
<constraints>
<настройка_1>
<min>нижняя_граница</min>
</настройка_1>
<настройка_2>
<max>верхняя_граница</max>
</настройка_2>
<настройка_3>
<min>нижняя_граница</min>
<max>верхняя_граница</max>
</настройка_3>
<настройка_4>
<readonly/>
</настройка_4>
</constraints>
</имя_пользователя>
</profiles>
Если пользователь пытается выйти за пределы, установленные этими ограничениями, то кидается исключение и настройка сохраняет прежнее значение.
Поддерживаются три типа ограничений: min, max и readonly. Ограничения min и max указывают нижнюю и верхнюю границы для числовых настроек и могут использоваться вместе.
Ограничение readonly указывает, что пользователь не может менять настройку.
Пример:
Пусть файл users.xml содержит строки:
<profiles>
<default>
<max_memory_usage>10000000000</max_memory_usage>
<force_index_by_date>0</force_index_by_date>
...
<constraints>
<max_memory_usage>
<min>5000000000</min>
<max>20000000000</max>
</max_memory_usage>
<force_index_by_date>
<readonly/>
</force_index_by_date>
</constraints>
</default>
</profiles>
Каждый из следующих запросов кинет исключение:
SET max_memory_usage=20000000001;
SET max_memory_usage=4999999999;
SET force_index_by_date=1;
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be greater than 20000000000.
Code: 452, e.displayText() = DB::Exception: Setting max_memory_usage should not be less than 5000000000.
Code: 452, e.displayText() = DB::Exception: Setting force_index_by_date should not be changed.
Примечание: профиль с именем default обрабатывается специальным образом: все ограничения на изменение настроек из этого профиля становятся дефолтными и влияют на всех пользователей, кроме тех, где эти ограничения явно переопределены.
Раздел users конфигурационного файла user.xml содержит настройки для пользователей.
Примечание: Для управления пользователями рекомендуется использовать SQL-ориентированный воркфлоу, который также поддерживается в RT.WideStore.
Структура раздела users:
<users>
<!-- If user name was not specified, 'default' user is used. -->
<user_name>
<password></password>
<!-- Or -->
<password_sha256_hex></password_sha256_hex>
<access_management>0|1</access_management>
<networks incl="networks" replace="replace">
</networks>
<profile>profile_name</profile>
<quota>default</quota>
<databases>
<database_name>
<table_name>
<filter>expression</filter>
<table_name>
</database_name>
</databases>
</user_name>
<!-- Other users settings -->
</users>
Пароль можно указать в текстовом виде или в виде SHA256 (шестнадцатеричный формат):
Например, `<password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5
</password_sha256_hex>`.
Пример создания пароля в командной строке:
```
PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
```
Первая строка результата — пароль. Вторая строка — соответствующий ему хэш SHA256.
Для совместимости с клиентами MySQL, пароль можно задать с помощью двойного хэша SHA1, поместив его в элемент password_double_sha1_hex.
Например, `<password_double_sha1_hex>08b4a0f1de6ad37da17359e592c8d74788a83eb0</password_double_sha1_hex>`.
Пример создания пароля в командной строке:
```
PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha1sum |
tr -d '-' | xxd -r -p | sha1sum | tr -d '-'
```
Первая строка результата — пароль. Вторая строка — соответствующий ему двойной хэш SHA1.
Включает или выключает SQL-ориентированное управление доступом для пользователя.
Возможные значения:
Значение по умолчанию: 0.
Список сетей, из которых пользователь может подключиться к серверу RT.WideStore.
Каждый элемент списка имеет одну из следующих форм:
Примеры: `213.180.204.3`, `10.0.0.1/8`, `10.0.0.1/255.255.255.0`, `2a02:6b8::3`,
`2a02:6b8::3/64`, `2a02:6b8::3/ffff:ffff:ffff:ffff::`.
Пример: `example01.host.ru`.
Для проверки доступа выполняется DNS-запрос, и все возвращенные IP-адреса сравниваются с
адресом клиента.
Пример, `^example\d\d-\d\d-\d\.host\.ru$`
Для проверки доступа выполняется [DNS запрос PTR](https://en.wikipedia.org/wiki/Reverse_DNS_lookup)
для адреса клиента, а затем применяется заданное регулярное выражение. Затем, для результатов запроса
PTR выполняется другой DNS-запрос и все полученные адреса сравниваются с адресом клиента.
Рекомендуем завершать регулярное выражение символом $.
Все результаты DNS-запросов кэшируются до перезапуска сервера.
Примеры:
Чтобы открыть доступ пользователю из любой сети, укажите:
<ip>::/0</ip>
Внимание: Открывать доступ из любой сети небезопасно, если у вас нет правильно настроенного брандмауэра или сервер не отключен от интернета.
Чтобы открыть только локальный доступ, укажите:
<ip>::1</ip>
<ip>127.0.0.1</ip>
Пользователю можно назначить профиль настроек. Профили настроек конфигурируются в отдельной секции файла users.xml. Подробнее читайте в п. 2.13.
Квотирование позволяет отслеживать или ограничивать использование ресурсов в течение определённого периода времени. Квоты настраиваются в разделе quotas конфигурационного файла users.xml.
Пользователю можно назначить квоты. Подробное описание настройки квот смотрите в п. 2.6.
В этом разделе вы можете ограничить выдачу RT.WideStore запросами SELECT для конкретного пользователя, таким образом реализуя базовую защиту на уровне строк.
Пример:
Следующая конфигурация задаёт, что пользователь user1 в результате запросов SELECT может получать только те строки table1, в которых значение поля id равно 1000.
<user1>
<databases>
<database_name>
<table1>
<filter>id = 1000</filter>
</table1>
</database_name>
</databases>
</user1>
Элемент filter содержать любое выражение, возвращающее значение типа UInt8. Обычно он содержит сравнения и логические операторы. Строки database_name.table1, для которых фильтр возвращает 0 не выдаются пользователю. Фильтрация несовместима с операциями PREWHERE и отключает оптимизацию WHERE→PREWHERE.
Приложение 1. Пример использования профилировщика запросов.
Приложение 2. Описание системных таблиц.
Приложение 3. Описание параметров ограничения на сложность запросов.
Приложение 4. Описание дополнительных настроек RT.WideStore.