По мере экспоненциального роста данных традиционные монолитные архитектуры хранилищ сталкиваются с проблемой балансировки производительности и экономической эффективности. Чтобы поддерживать высокоскоростные запросы в реальном времени при снижении стоимости хранения огромных объёмов данных, CSS предлагает функцию разъединения хранилища и вычислений для кластеров Elasticsearch.
При раздельном хранилище и вычислениях часто запрашиваемые горячие данные сохраняются в высокопроизводительных носителях, тогда как редко запрашиваемые холодные данные мигрируют в недорогие носители — Object Storage Service (OBS). Это обеспечивает производительность запросов в реальном времени для горячих данных при снижении долгосрочных расходов на хранение.
Рисунок 1 Архитектура раздельного хранилища и вычислений

Вот как работает разъединение хранилища и вычислений:
Горячие данные записываются на высокопроизводительные локальные диски (SSDs) для обеспечения производительности запросов в реальном времени.
Редко запрашиваемые данные мигрируют с SSD в экономичный OBS (OBS‑бакеты невидимы пользователям), превращаясь из горячих данных в холодные. Вы можете вызвать API index freezing для ручного перевода горячих данных в холодные, либо определить политику жизненного цикла (например, период хранения 90 дней), чтобы процесс запускался автоматически. Холодные данные хранятся в OBS для экономии, однако их метаданные и поля даты сохраняются на локальных дисках для быстрого поиска.
В CSS индексы могут проходить следующие этапы в течение всего их жизненного цикла.
Разделённое хранение и вычисления могут быть автоматизированы с помощью политик управления жизненным циклом индекса. Подробнее см. Decoupling Storage and Compute Using ISM.
При заморозке индексы выгружаются в OBS, и класс хранения устанавливается как Standard. Бакеты OBS, в которых хранятся замороженные индексы, невидимы для пользователей — пользователи не могут просматривать или управлять ими в консоли OBS. Обратите внимание, что хранение индексов в бакетах OBS влечёт дополнительные расходы, которые начисляются по модели pay-per-use в зависимости от потребления объёма Standard.
Войдите в Kibana и перейдите к странице выполнения команд. Elasticsearch clusters поддерживают несколько методов доступа. В этом разделе используется Kibana в качестве примера для описания процедур выполнения.
Левая часть консоли представляет собой поле ввода команд, а треугольный значок в её правом верхнем углу является кнопкой выполнения. Правая часть отображает результат выполнения.
Заморозка индекса означает перемещение холодных данных с твердотельных накопителей (SSDs) в OBS, освобождая SSD‑хранилище для горячих, часто запрашиваемых данных. Замороженный индекс становится только для чтения.
Выполните следующую команду, чтобы выгрузить данные указанного индекса в OBS и установить для него класс хранения Standard:
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
index_name | String | N/A | Указывает один или несколько индексов.
|
Пример ответа:
{"freeze_uuid": "pdsRgUtSTymVDWR_HoTGFw" // ID of the index freezing task, which you can use to query the task progress.}
Если версия кластера Elasticsearch — 7.10.2 и версия образа — 7.10.2_25.9.0_xxx или более поздняя, задачи заморозки индексов не выполняются сразу после отправки. Вместо этого они временно кэшируются на настраиваемый период (по умолчанию: одна минута), а затем обрабатываются пакетно. Правила кэширования асинхронных задач заморозки индексов можно настроить. Подробнее см. Modify batch index freezing settings.
Выполните следующую команду, указав ID задачи, чтобы проверить прогресс заморозки индекса:
Если версия кластера Elasticsearch — 7.10.2 и версия образа — 7.10.2_25.9.0_xxx или более поздняя, возвращаются прогрессы нескольких задач заморозки индексов одной партии.
Пример ответа:
{"stage" : "STARTED","shards_stats" : {"INIT" : 0,"FAILURE" : 0,"DONE" : 0,"STARTED" : 1,"ABORTED" : 0},"indices" : {"data1" : [{"uuid" : "7OS-G1-tRke2jHZPlckexg","index" : {"name" : "data1","index_id" : "4b5PHXJITLaS6AurImfQ9A","shard" : 2},"start_ms" : 1611972010852,"end_ms" : -1,"total_time" : "10.5s","total_time_in_millis" : 10505,"stage" : "STARTED","failure" : null,"size" : {"total_bytes" : 3211446689,"finished_bytes" : 222491269,"percent" : "6.0%"},"file" : {"total_files" : 271,"finished_files" : 12,"percent" : "4.0%"},"rate_limit" : {"paused_times" : 1,"paused_nanos" : 946460970}}]}}
Параметр | Описание |
|---|---|
Стейдж | Состояние задачи заморозки индекса. Диапазон значений: |
shards_stats | Количество шардов в каждом состоянии. |
indices | Подробные сведения о состоянии каждого индекса, как описано в Table 3. |
Параметр | Описание |
|---|---|
uuid | Идентификатор задачи заморозки индекса. |
индекс | Информация об индексе и шарде. |
start_ms | Время начала задачи. |
end_ms | Время завершения задачи. Если задача всё ещё выполняется, отображается -1. |
total_time | Продолжительность выполнения задачи. |
total_time_in_millis | Продолжительность выполнения задачи в миллисекундах. |
stage | Состояние шарда. |
ошибка | Причина сбоя задачи. Если сбой не произошёл, возвращается null. |
size.total_bytes | Общее количество байтов, подлежащих заморозке. |
size.finished_bytes | Количество байтов, которые были заморожены. |
size.percent | Прогресс заморозки в терминах количества замороженных байтов по сравнению с общим количеством байтов для заморозки. |
file.total_bytes | Общее количество документов, подлежащих заморозке. |
file.finished_bytes | Количество документов, которые были заморожены. |
file.percent | Прогресс заморозки в терминах количества замороженных документов по сравнению с общим количеством документов для заморозки. |
rate_limit.paused_times | Количество раз, когда приостановка заморозки была выполнена из‑за ограничения скорости. |
rate_limit.paused_nanos | Продолжительность приостановки задачи заморозки из‑за ограничения скорости, в наносекундах. |
Когда заморозка индекса завершена, параметры настроек будут возвращены, как описано в Table 4.
Параметр | Описание |
|---|---|
index.frozen_low_cost | Замороженный индекс. Значение фиксировано как true. |
index.blocks.write | Запись в замороженный индекс запрещена. Значение фиксировано как true. |
index.store.type | Тип хранилища индекса. Значение фиксировано как obs. |
Здесь описаны только некоторые ключевые параметры для запроса списка замороженных индексов. Для получения дополнительной информации об API см. cat indices API.
Выполните следующую команду, чтобы запросить список замороженных индексов по статусу заморозки индекса:
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
STAGE | String | N/A | Этап заморозки индекса. Диапазон значений: |
Пример ответа:
green open data2 0bNtxWDtRbOSkS4JYaUgMQ 3 0 5 0 7.9kb 7.9kbgreen open data3 oYMLvw31QnyasqUNuyP6RA 3 0 51 0 23.5kb 23.5kb
После заморозки индекса его данные выгружаются в OBS. Чтобы уменьшить прямой доступ к данным из OBS и тем самым повысить производительность запросов, часть данных кэшируется в кластере. Данные, запрашиваемые впервые, извлекаются напрямую из OBS. Полученные данные затем кэшируются в памяти кластера. При последующих запросах система сначала ищет в кэше. CSS позволяет запрашивать статистику кэша для замороженных индексов, хранящихся в OBS buckets. Вы также можете сбросить состояние кэша и изменить конфигурацию кэша.
GET _frozen_stats
GET _frozen_stats/{node_id}
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
node_id | String | N/A | Указывает один или несколько узлов кластера.
Вы можете выполнить следующую команду для получения node IDs: |
Ниже приведён пример возвращённой информации при запросе статистики кэша замороженных индексов на всех узлах:
{"_nodes" : {"total" : 1, // Total number of nodes"successful" : 1, // Successful nodes"failed" : 0 // Failed nodes},"cluster_name" : "css-zzz1", //Cluster name"nodes" : {"7uwKO38RRoaON37YsXhCYw" : {"name" : "css-zzz1-ess-esn-2-1", //Node name"transport_address" : "10.0.0.247:9300", //Node transport address"host" : "10.0.0.247", //Node host"ip" : "10.0.0.247", //Node IP address"block_cache" : {"default" : {"type" : "memory", //Cache type. memory indicates in-memory cache."block_cache_capacity" : 8192, //Cache capacity"block_cache_blocksize" : 8192, //Single block size in the cache, in bytes. In the example, the block size is 8 KB."block_cache_size" : 12, //Cache capacity used"block_cache_hit" : 14, //Number of cache hits"block_cache_miss" : 0, //Number of cache misses"block_cache_eviction" : 0, //Number of cache evictions"block_cache_store_fail" : 0 //Number of cache storage failures, which occur when the cache is full.}},"obs_stats" : {"list" : {"obs_list_count" : 17, //Number of times the OBS list API was called."obs_list_ms" : 265, //Total length of time spent calling the OBS list API."obs_list_avg_ms" : 15 //Average time spent calling the OBS list API.},"get_meta" : {"obs_get_meta_count" : 79, //Number of times the OBS get metadata API was called."obs_get_meta_ms" : 183, //Total length of time spent calling the OBS get metadata API."obs_get_meta_avg_ms" : 2 //Average time spent calling the OBS get metadata API.},"get_obj" : {"obs_get_obj_count" : 12, //Number of times the OBS get object API was called."obs_get_obj_ms" : 123, //Total length of time spent calling the OBS get object API."obs_get_obj_avg_ms" : 10 //Average time spent calling the OBS get object API.},"put_obj" : {"obs_put_obj_count" : 12, //Number of times the OBS put object API was called."obs_put_obj_ms" : 2451, //Total length of time spent calling the OBS put object API."obs_put_obj_avg_ms" : 204 //Average time spent calling the OBS put object API.},"obs_op_total" : {"obs_op_total_ms" : 3022, //Total length of time spent calling OBS APIs."obs_op_total_count" : 120, //Total number of times calling OBS APIs."obs_op_avg_ms" : 25 //Average time spent calling OBS APIs.}},"reader_cache" : {"hit_count" : 0,"miss_count" : 1,"load_success_count" : 1,"load_exception_count" : 0,"total_load_time" : 291194714,"eviction_count" : 0}}}}
Выполните следующую команду для сброса статуса кэша для замороженных индексов:
POST _frozen_stats/reset
Эта команда используется для отладки проблем производительности. Если вы сбросите статус кэша и затем выполните команду запроса кэша, вы сможете проверить точный статус команды кэша. Не рекомендуется использовать эту команду во время выполнения.
Пример ответа:
{"_nodes" : {"total" : 1,"successful" : 1,"failed" : 0},"cluster_name" : "Es-0325-007_01","nodes" : {"mqTdk2YRSPyOSXfesREFSg" : {"result" : "ok"}}}
Elasticsearch получает доступ к различным типам файлов разными методами. Система кэша поддерживает многоуровневый кэш и использует блоки разного размера для кэширования различных типов файлов. Например, обычно большое количество небольших блоков используется для кэширования файлов .fdx и .tip, а небольшое количество крупных блоков — для кэширования файлов .fdt. Вы можете изменить конфигурацию кэша в соответствии с потребностями сервиса. Table 7 описывает настраиваемые параметры.
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
low_cost.obs.blockcache.names | Array | ["default"] | Список имен многоуровневых кэшей. Система кэширования поддерживает многоуровневые кэши для данных с различной гранулярностью доступа. Существует кэш по умолчанию с именем default. Если вы настраиваете этот параметр, значение должно включать как минимум кэш default, помимо других пользовательских имен кэшей. |
low_cost.obs.blockcache.<NAME>.type | ENUM | memory | Storage type of the cache named <NAME>. Диапазон значений:
|
low_cost.obs.blockcache.<NAME>.blockshift | Integer | 13 (означает 8 КБ) | Block size in the cache named <NAME> (in bytes). Формула: 2blockshift. Например, если значение равно 16, размер блока составляет 216 байт, то есть 65536 байт или 64 КБ. Значение: количество сдвигов влево |
low_cost.obs.blockcache.<NAME>.bank.count | Integer | 1 | Number of partitions in the cache named <NAME>. Each partition is an independent unit in the cache. |
low_cost.obs.blockcache.<NAME>.number.blocks.perbank | Integer | 8192 | Number of blocks in each partition of the cache named <NAME>. |
low_cost.obs.blockcache.<NAME>.exclude.file.types | Array | N/A | List of file name extensions for files that cannot be cached in the cache named <NAME>. If a file's extension is not in exclude.file.types or <NAME>.file.types (if configured), the default cache policy applies. |
low_cost.obs.blockcache.<NAME>.file.types | Массив | N/A | List of file name extensions for files that can be cached in the cache named <NAME>. If a file's extension is not in exclude.file.types or <NAME>.file.types (if configured), the default cache policy applies. |
index.frozen.obs.max_bytes_per_sec | Строка | 150MB | Максимальная скорость, с которой документы замороженных индексов загружаются в OBS. Формат значения: число + единица измерения Диапазон значений: от 0 до (263 – 1) байт Значение 0 указывает отсутствие ограничения. Изменение вступает в силу немедленно. |
low_cost.obs.index.upload.threshold.use.multipart | String | 1GB | Порог multipart upload. При выгрузке замороженных индексов в OBS, если размер отдельного документа превышает этот порог, выполняется multipart upload. Формат значения: число + единица измерения Диапазон значений: от 0 до (263 – 1) байт Значение 0 указывает, что multipart upload не выполняется. |
Ниже приведён типичный пример конфигурации кэша. Используется двухуровневая система кэша: default и large. Кэш default содержит в общей сложности 30 × 4096 блоков по 64 KB. Он используется для кэширования файлов, не являющихся .fdt. Кэш large содержит 5 × 1000 блоков по 2 MB. Он используется для кэширования файлов .fdx, .dvd и .tip.
low_cost.obs.blockcache.names: ["default", "large"]low_cost.obs.blockcache.default.type: filelow_cost.obs.blockcache.default.blockshift: 16low_cost.obs.blockcache.default.number.blocks.perbank: 4096low_cost.obs.blockcache.default.bank.count: 30low_cost.obs.blockcache.default.exclude.file.types: ["fdt"]low_cost.obs.blockcache.large.type: filelow_cost.obs.blockcache.large.blockshift: 21low_cost.obs.blockcache.large.number.blocks.perbank: 1000low_cost.obs.blockcache.large.bank.count: 5low_cost.obs.blockcache.large.file.types: ["fdx", "dvd", "tip"]
Если версия кластера Elasticsearch 7.10.2 и версия образа 7.10.2_25.9.0_xxx или новее, задачи замораживания индексов не выполняются сразу после отправки. Вместо этого они временно кэшируются на настраиваемый период, а затем обрабатываются пакетно. Правила кэширования асинхронных задач замораживания индексов могут быть настроены. Table 8 описывает соответствующие параметры.
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
low_cost.freeze.job.interval | TimeValue | 1m | Интервал выполнения задачи пакетной заморозки индексов. Диапазон значений: от 10s до 10m Если этот параметр установлен в 1m, система кэширует запросы на заморозку индексов в течение 1 минуты, а затем выполняет их все сразу. |
low_cost.freeze.job.batch_size | Integer | 20 | Максимальное количество индексов, которое может быть включено в одну задачу пакетной заморозки индексов. Диапазон значений: от 1 до 100 Если этот параметр установлен в 20, каждый пакет может содержать 20 индексов. Например, если задача Index Lifecycle Management (ILM) отправляет 100 индексов для заморозки одновременно, они будут разделены на пять пакетов и заморожены по одному пакету за раз. |
low_cost.freeze.job.start_time | String | 00:00 (executable all day) | Время начала пакетных задач заморозки индексов, означающее, что такие задачи не могут быть запущены до указанного времени. Если отправленная задача заморозки индекса ещё не началась, ей придётся ждать до указанного времени начала. Формат значения: hour:minute |
low_cost.freeze.job.end_time | String | 23:59 (выполняется весь день) | Время окончания пакетных задач заморозки индексов, означающее, что такие задачи не могут быть запущены после указанного времени. Текущие задачи не затрагиваются этой настройкой. Формат значения: hour:minute |
Например, выполните следующую команду для изменения настроек пакетной заморозки индексов по умолчанию:
PUT _cluster/settings{"persistent": {"low_cost.freeze.job.interval": "5m","low_cost.freeze.job.batch_size": 30,"low_cost.freeze.job.start_time": "22:00","low_cost.freeze.job.end_time": "07:00"}}
Только кластеры Elasticsearch 7.6.2 и 7.10.2, созданные после февраля 2023 г., поддерживают эту функцию.
Когда замороженные индексы запрашиваются на странице Discover в Kibana впервые, все данные необходимо получить из OBS, поскольку в кэше нет данных. Если требуется вернуть большое количество документов, получение соответствующих полей времени и метаданных документов из OBS занимает много времени. Кешируя эту часть данных в кластере, производительность запросов может значительно улучшиться. Так CSS повышает производительность запросов к замороженным индексам. Настройки локального кэша предустановлены. Вы можете просмотреть их и при необходимости изменить.
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
low_cost.local_cache.max.capacity | Целое число | 500 | Максимальное количество кэшей холодных данных, которые могут быть доступны на каждом узле. (Каждый шард соответствует кэшу.) Диапазон значений: 10–5000
|
index.low_cost.local_cache.threshold | Целое число | 50 | Процент полей date в индексе, используемый в качестве порога для включения или отключения локального кэширования холодных данных.
Диапазон значений: 0–100 Единица измерения: % |
index.low_cost.local_cache.evict_time | String | 30d | Продолжительность хранения холодных данных в локальном кэше. Значение определяется index.frozen_date (время заморозки индекса). Если index.frozen_date недоступно, значение определяется временем создания индекса. Рекомендуется скорректировать продолжительность хранения в зависимости от использования диска. Диапазон значений: от 1 до 365 дней Единица: d (дней) |
Ниже приведены некоторые примеры:
PUT _cluster/settings{"persistent": {"low_cost.local_cache.max.capacity": 1000}}
PUT {index_name}/_settings{"index.low_cost.local_cache.threshold": 20}
PUT {index_name}/_settings{"index.low_cost.local_cache.evict_time": "7d"}
GET /_frozen_stats/local_cache
GET /_frozen_stats/local_cache/{node_id}
Пример ответа:
{"_nodes" : {"total" : 1,"successful" : 1,"failed" : 0},"cluster_name" : "test","nodes" : {"6by3lPy1R3m55Dcq3liK8Q" : {"name" : "node-1","transport_address" : "127.0.0.1:9300","host" : "127.0.0.1","ip" : "127.0.0.1","local_cache" : {"get_stats" : {"get_total_count" : 562, //Total number of times data was retrieved from the local cold data cache."get_hit_count" : 562, //Total number of hits in the local cold data cache."get_miss_count" : 0, //Total number of local cold data cache misses."get_total_ns" : 43849200, //Total duration for retrieving data from the local cold data cache."get_avg_ns" : 78023 //Average duration for retrieving data from the local cold data cache.},"load_stats" : {"load_count" : 2, //Number of times cold data was loaded from the local cache"load_total_ms" : 29, //Total duration for loading cold data from the local cache"load_avg_ms" : 14, //Average duration for loading cold data from the local cache"load_fail_count" : 0, //Number of failures for loading cold data from the local cache"load_overflow_count" : 0 //Number of times the local cold data cache exceeds the cache pool size.},"reload_stats" : {"reload_count" : 0, //Number of times the local cold data cache was regenerated."reload_total_ms" : 0, //Total duration for regenerating the local cold data cache."reload_avg_ms" : 0, //Average duration for regenerating the local cold data cache."reload_fail_count" : 0 //Number of failures in regenerating the local cold data cache.},"init_stats" : {"init_count" : 0, //Number of times the local cold data cache was initialized."init_total_ms" : 0, //Total duration for initializing the local cold data cache."init_avg_ms" : 0, //Average duration for initializing the local cold data cache."init_fail_count" : 0 //Number of failures in initializing the local cold data cache.}}}}}
Только кластеры Elasticsearch 7.6.2 и 7.10.2, созданные после февраля 2023 года, поддерживают эту функцию.
Чтобы помочь вам понять, как плагин storage-compute decoupling работает с OBS, добавлен API для сбора статистики о реальных‑временных показателях OBS, и эти показатели записываются в индекс .freeze_obs_rate-YYYY.mm.dd.
Метод расчёта: средние показатели операций OBS за последние 5 секунд рассчитываются каждые 5 секунд.
Системный индекс .freeze_obs_rate-YYYY.mm.dd фиксирует статистику реальных‑временных показателей операций OBS, помогая вам понять соответствующие тенденции ресурсов OBS, хранящих холодные данные. Период хранения этого индекса по умолчанию составляет 30 дней.
GET _frozen_stats/obs_rate
GET _frozen_stats/obs_rate/{node_id}
Пример ответа:
Выполните следующую команду, чтобы изменить период хранения индекса на семь дней:
PUT _cluster/settings{"persistent": {"low_cost.obs_rate_index.evict_time": "7d"}}
Параметр | Тип | Значение по умолчанию | Описание |
|---|---|---|---|
low_cost.obs_rate_index.evict_time | String | 30d | Период удержания индекса .freeze_obs_rate-YYYY.mm.dd на каждом узле.
Любое изменение вступает в силу немедленно. |
Чтобы обеспечить приемлемую производительность запросов к холодным данным (например, при периодическом запросе исторических данных), используйте решение с многоуровневым хранением. Подробности см. Switching Between Hot and Cold Data.