mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-19 14:11:58 +00:00
247 lines
13 KiB
ReStructuredText
247 lines
13 KiB
ReStructuredText
|
.. _dicts-external_dicts_dict_layout:
|
|||
|
|
|||
|
**************************
|
|||
|
Хранение словарей в памяти
|
|||
|
**************************
|
|||
|
|
|||
|
Словари можно размещать в памяти :ref:`множеством способов <dicts-external_dicts_dict_layout-manner>`.
|
|||
|
|
|||
|
Рекомендуем :ref:`dicts-external_dicts_dict_layout-flat`, :ref:`dicts-external_dicts_dict_layout-hashed` и :ref:`dicts-external_dicts_dict_layout-complex_key_hashed`. Скорость обработки словарей при этом максимальна.
|
|||
|
|
|||
|
Размещение с кэшированием не рекомендуется использовать из-за потенциально низкой производительности и сложностей в подборе оптимальных параметров. Читайте об этом подробнее в разделе ":ref:`dicts-external_dicts_dict_layout-cache`".
|
|||
|
|
|||
|
Повысить производительнось словарей можно следующими способами:
|
|||
|
|
|||
|
* Вызывать функцию для работы со словарём после ``GROUP BY``.
|
|||
|
* Помечать извлекаемые атрибуты как инъективные. Атрибут называется инъективным, если разным ключам соответствуют разные значения атрибута. Тогда при использовании в ``GROUP BY`` функции, достающей значение атрибута по ключу, эта функция автоматически выносится из ``GROUP BY``.
|
|||
|
|
|||
|
При ошибках работы со словарями ClickHouse генерирует исключения. Например, в следующих ситуациях:
|
|||
|
|
|||
|
* При обращении к словарю, который не удалось загрузить.
|
|||
|
* При ошибке запроса к ``cached``-словарю.
|
|||
|
|
|||
|
|
|||
|
Список внешних словарей и их статус можно посмотреть в таблице ``system.dictionaries``.
|
|||
|
|
|||
|
Общий вид конфигурации:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<dictionaries>
|
|||
|
<dictionary>
|
|||
|
...
|
|||
|
<layout>
|
|||
|
<layout_type>
|
|||
|
<!-- layout settings -->
|
|||
|
</layout_type>
|
|||
|
</layout>
|
|||
|
...
|
|||
|
</dictionary>
|
|||
|
</dictionaries>
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-manner:
|
|||
|
|
|||
|
Способы размещения словарей в памяти
|
|||
|
====================================
|
|||
|
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-flat`
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-hashed`
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-cache`
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-range_hashed`
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-complex_key_hashed`
|
|||
|
* :ref:`dicts-external_dicts_dict_layout-complex_key_cache`
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-flat:
|
|||
|
|
|||
|
flat
|
|||
|
----
|
|||
|
|
|||
|
Словарь полностью хранится в оперативной памяти в виде плоских массивов. Объем памяти, занимаемой словарем? пропорционален размеру самого большого (по размеру) ключа.
|
|||
|
|
|||
|
Ключ словаря имеет тип ``UInt64`` и его величина ограничена 500 000. Если при создании словаря обнаружен ключ больше, то ClickHouse бросает исключение и не создает словарь.
|
|||
|
|
|||
|
Поддерживаются все виды источников. При обновлении, данные (из файла, из таблицы) читаются целиком.
|
|||
|
|
|||
|
Это метод обеспечивает максимальную производительность среди всех доступных способов размещения словаря.
|
|||
|
|
|||
|
Пример конфигурации:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<layout>
|
|||
|
<flat />
|
|||
|
</layout>
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-hashed:
|
|||
|
|
|||
|
hashed
|
|||
|
------
|
|||
|
|
|||
|
Словарь полностью хранится в оперативной памяти в виде хэш-таблиц. Словарь может содержать произвольное количество элементов с произвольными идентификаторами. На практике, количество ключей может достигать десятков миллионов элементов.
|
|||
|
|
|||
|
Поддерживаются все виды источников. При обновлении, данные (из файла, из таблицы) читаются целиком.
|
|||
|
|
|||
|
Пример конфигурации:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<layout>
|
|||
|
<hashed />
|
|||
|
</layout>
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-complex_key_hashed:
|
|||
|
|
|||
|
complex_key_hashed
|
|||
|
------------------
|
|||
|
|
|||
|
Тип размещения предназначен для использования с составными :ref:`ключами <dicts-external_dicts_dict_structure>`. Аналогичен hashed.
|
|||
|
|
|||
|
Пример конфигурации:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<layout>
|
|||
|
<complex_key_hashed />
|
|||
|
</layout>
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-range_hashed:
|
|||
|
|
|||
|
range_hashed
|
|||
|
------------
|
|||
|
|
|||
|
Словарь хранится в оперативной памяти в виде хэш-таблицы с упорядоченным массивом диапазонов и соответствующих им значений.
|
|||
|
|
|||
|
Этот способ размещения работает также как и hashed и позволяет дополнительно к ключу использовать дипазоны по дате/времени, если они указаны в словаре.
|
|||
|
|
|||
|
Пример: таблица содержит скидки для каждого рекламодателя в виде:
|
|||
|
|
|||
|
+------------------+-----------------------------+------------+----------+
|
|||
|
| id рекламодателя | дата начала действия скидки | дата конца | величина |
|
|||
|
+==================+=============================+============+==========+
|
|||
|
| 123 | 2015-01-01 | 2015-01-15 | 0.15 |
|
|||
|
+------------------+-----------------------------+------------+----------+
|
|||
|
| 123 | 2015-01-16 | 2015-01-31 | 0.25 |
|
|||
|
+------------------+-----------------------------+------------+----------+
|
|||
|
| 456 | 2015-01-01 | 2015-01-15 | 0.05 |
|
|||
|
+------------------+-----------------------------+------------+----------+
|
|||
|
|
|||
|
Столбцы с датами в словаре должны иметь тип ``Date``.
|
|||
|
|
|||
|
Чтобы использовать выборку по диапазонам дат, необходимо в :ref:`structure <dicts-external_dicts_dict_structure>` определить элементы ``range_min``, ``range_max``.
|
|||
|
|
|||
|
Пример:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<structure>
|
|||
|
<id>
|
|||
|
<name>Id</name>
|
|||
|
</id>
|
|||
|
<range_min>
|
|||
|
<name>first</name>
|
|||
|
</range_min>
|
|||
|
<range_max>
|
|||
|
<name>last</name>
|
|||
|
</range_max>
|
|||
|
...
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Для работы с такими словарями в функцию ``dictGetT`` необходимо передавать дополнительный аргумент - дату: ::
|
|||
|
|
|||
|
dictGetT('dict_name', 'attr_name', id, date)
|
|||
|
|
|||
|
Функция возвращает значение для заданных ``id`` и диапазона дат, в который входит переданная дата.
|
|||
|
|
|||
|
Особенности алгоритма:
|
|||
|
|
|||
|
* Если не найден ``id`` или для найденного ``id`` не найден диапазон, то возвращается значение по умолчанию для словаря.
|
|||
|
* Если есть перекрывающиеся диапазоны, то можно использовать любой подходящий.
|
|||
|
* Если граница диапазона ``NULL`` или некорректная дата (1900-01-01, 2039-01-01), то диапазон считается открытым. Диапазон может быть открытым с обеих сторон.
|
|||
|
|
|||
|
|
|||
|
Пример конфигурации:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<dictionaries>
|
|||
|
<dictionary>
|
|||
|
|
|||
|
...
|
|||
|
|
|||
|
<layout>
|
|||
|
<range_hashed />
|
|||
|
</layout>
|
|||
|
|
|||
|
<structure>
|
|||
|
<id>
|
|||
|
<name>Abcdef</name>
|
|||
|
</id>
|
|||
|
<range_min>
|
|||
|
<name>StartDate</name>
|
|||
|
</range_min>
|
|||
|
<range_max>
|
|||
|
<name>EndDate</name>
|
|||
|
</range_max>
|
|||
|
<attribute>
|
|||
|
<name>XXXType</name>
|
|||
|
<type>String</type>
|
|||
|
<null_value />
|
|||
|
</attribute>
|
|||
|
</structure>
|
|||
|
|
|||
|
</dictionary>
|
|||
|
</dictionaries>
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-cache:
|
|||
|
|
|||
|
cache
|
|||
|
-----
|
|||
|
|
|||
|
Словарь хранится в кэше, состоящем из фиксированного количества ячеек. Ячейки содержат часто используемые элементы.
|
|||
|
|
|||
|
При поиске в словаре сначала просматривается кэш. На каждый блок данных, все не найденные в кэше или устаревшие ключи запрашиваются у источника с помощью ``SELECT attrs... FROM db.table WHERE id IN (k1, k2, ...)``. Затем, полученные данные записываются в кэш.
|
|||
|
|
|||
|
Для cache-словарей может быть задано время устаревания (:ref:`lifetime <dicts-external_dicts_dict_lifetime>`) данных в кэше. Если от загрузки данных в ячейке прошло больше времени, чем ``lifetime``, то значение не используется, и будет запрошено заново при следующей необходимости его использовать.
|
|||
|
|
|||
|
Это наименее эффективный из всех способов размещения словарей. Скорость работы кэша очень сильно зависит от правильности настройки и сценария использования. Словарь типа cache показывает высокую производительность лишь при достаточно больших hit rate-ах (рекомендуется 99% и выше). Посмотреть средний hit rate можно в таблице ``system.dictionaries``.
|
|||
|
|
|||
|
Чтобы увеличить производительность кэша, используйте подзапрос с ``LIMIT``, а снаружи вызывайте функцию со словарём.
|
|||
|
|
|||
|
Поддерживаются :ref:`источники <dicts-external_dicts_dict_sources>`: MySQL, ClickHouse, executable, HTTP.
|
|||
|
|
|||
|
Пример настройки:
|
|||
|
|
|||
|
.. code-block:: xml
|
|||
|
|
|||
|
<layout>
|
|||
|
<cache>
|
|||
|
<!-- Размер кэша в количестве ячеек. Округляется вверх до степени двух. -->
|
|||
|
<size_in_cells>1000000000</size_in_cells>
|
|||
|
</cache>
|
|||
|
</layout>
|
|||
|
|
|||
|
Укажите достаточно большой размер кэша. Количество ячеек следует подобрать экспериментальным путём:
|
|||
|
|
|||
|
1. Выставить некоторое значение.
|
|||
|
2. Запросами добиться полной заполненности кэша.
|
|||
|
3. Оценить потребление оперативной памяти с помощью таблицы ``system.dictionaries``.
|
|||
|
4. Увеличивать/уменьшать количество ячеек до получения требуемого расхода оперативной памяти.
|
|||
|
|
|||
|
.. warning:: Не используйте в качестве источника ClickHouse, поскольку он медленно обрабатывает запросы со случайным чтением.
|
|||
|
|
|||
|
|
|||
|
.. _dicts-external_dicts_dict_layout-complex_key_cache:
|
|||
|
|
|||
|
complex_key_cache
|
|||
|
-----------------
|
|||
|
|
|||
|
Тип размещения предназначен для использования с составными :ref:`ключами <dicts-external_dicts_dict_structure>`. Аналогичен ``cache``.
|
|||
|
|