##One, основной принцип чтения и письма
Процесс записи данных в Elasticsearch
1) Клиент выбирает узел для отправки запроса в прошлом, этот узел является координационным узлом (координирующим узлом) 2) координирующий узел, маршрутизация документа и пересылка запроса на соответствующий узел (с первичным сегментом) 3) Первичный сегмент на фактическом узле обрабатывает запрос, а затем синхронизирует данные с узлом-репликой. 4) координирующий узел, если основной узел и все узлы-реплики найдены, он вернет результат ответа клиенту
Процесс чтения данных в Elasticsearch
1) Клиент отправляет запрос любому узлу, чтобы он стал координатным узлом 2) Координатный узел маршрутизирует документ и пересылает запрос на соответствующий узел.В это время используется циклический алгоритм случайного опроса для случайного выбора одного из основных осколков и всех его реплик, чтобы сбалансировать нагрузку запроса на чтение. . 3) Узел, получивший запрос, возвращает документ координатному узлу. 4) Координатный узел возвращает документ клиенту
1. При написании документа каждому документу автоматически присваивается глобально уникальный идентификатор, то есть идентификатор документа, а также хешируется и направляется на соответствующий первичный шард в соответствии с идентификатором документа. Вы также можете вручную указать идентификатор документа, например идентификатор заказа, идентификатор пользователя.
2. При чтении документа вы можете выполнить запрос по идентификатору документа, а затем выполнить хеширование в соответствии с идентификатором документа, чтобы определить, какой сегмент был назначен идентификатору документа в то время, и выполнить запрос из этого фрагмента.
Процесс поиска данных Elasticsearch
Самый мощный из них — полнотекстовый поиск. 1) Клиент отправляет запрос на узел координат 2) Координирующий узел также может перенаправить поисковый запрос на основной сегмент или сегмент реплики, соответствующий всем сегментам. 3) фаза запроса: каждый шард возвращает свои результаты поиска (фактически некоторые идентификаторы документов) на узел-координатор, который выполняет слияние данных, сортировку, разбиение на страницы и другие операции для получения конечного результата. 4) фаза выборки: затем координирующий узел извлекает фактические данные документа из каждого узла в соответствии с идентификатором документа и, наконец, возвращает их клиенту.
Основной принцип поиска: инвертированный индекс
Основной принцип записи данных Elasticsearch
1) Сначала записать в буфер, данные не могут быть найдены в буфере, при этом данные записываются в лог-файл транслога. 2) Если буфер почти заполнен, или через определенное время данные буфера будут обновлены до нового файла сегмента, но в это время данные не заносятся непосредственно в файл диска файла сегмента, а сначала заносятся в кеш ОС. Этот процесс является обновлением. Каждую 1 секунду es записывает данные из буфера в новый файл сегмента, и каждую секунду создается новый файл на диске, файл сегмента.Этот файл сегмента хранит данные, записанные в буфер за последнюю 1 секунду. Однако, если в это время в буфере нет данных, конечно, операция обновления выполняться не будет, и каждую секунду будет создаваться пустой файл сегмента.Если данные в буфере есть, операция обновления будет выполняться один раз в секунду по умолчанию, и будет сброшен новый файл сегмента. В операционной системе файлы на диске на самом деле имеют что-то, называемое кэшем ОС.Кэш операционной системы означает, что перед записью данных в файл на диске они сначала попадают в кеш ОС, а затем попадают в кеш памяти на уровне операционной системы. Пока данные в буфере обновляются и сбрасываются в кэш ОС, это означает, что данные можно искать.
Почему es называется квази-реальным временем? NRT, близкое к реальному времени, квази-реальное время. По умолчанию обновление выполняется каждую секунду, поэтому es работает в режиме квази-реального времени, потому что записанные данные можно увидеть только через 1 секунду.
Вы можете вручную выполнить операцию обновления через restful api или java api es, то есть вручную сбросить данные из буфера в кеш ОС, чтобы данные можно было искать немедленно.
Пока данные вводятся в кеш ОС, буфер будет очищен, потому что нет необходимости сохранять буфер, а данные были сохранены на диске в транслоге.
Во-вторых, настройка производительности
Настройка на системном уровне
Настройка на системном уровне в основном касается настройки памяти и избегания подкачки памяти. Память кучи, установленная по умолчанию после установки ES, составляет 1 Гб, что явно недостаточно, тогда будет вопрос: сколько памяти нам нужно установить для ES? На самом деле это зависит от объема памяти узлов нашего кластера и от того, хотим ли мы развернуть другие службы на узлах сервера. Если память относительно велика, например, 64 ГБ и выше, а другие службы не развернуты в кластере ES, то рекомендуется установить для памяти ES значение 31–32 ГБ, поскольку существует проблема с производительностью 32 ГБ. скажем прямо, даже если дать ES Если память кластера больше 32G, то его производительность не обязательно будет лучше, а то и хуже, чем производительность при установке 31G-32G. При настройке памяти кластера ES другим моментом является обеспечение того, чтобы минимальное значение (Xms) и максимальное значение (Xmx) памяти кучи были одинаковыми, чтобы программа не могла изменить размер памяти кучи во время выполнения. , который является процессом, который потребляет много системных ресурсов.
Отключение подкачки после того, как разрешена подкачка памяти и диска, приведет к фатальным проблемам с производительностью. Пространство подкачки — это часть дискового пространства.Операционная система использует это пространство для сохранения данных страницы, которые обычно не используются операционной системой, выгружаемой из памяти, чтобы можно было выделить больше памяти для кэша страниц. Это обычно улучшает пропускную способность и производительность ввода-вывода системы, но также создает много проблем. Частая подкачка страниц приведет к чтению/записи операций ввода-вывода и прерываниям операционной системы, что повлияет на производительность системы. Чем больше значение, тем агрессивнее операционная система будет использовать пространство подкачки. Автор: bootstrap.memory_lock: true в elasticsearch.yml, чтобы сохранить блокировку памяти JVM и обеспечить работоспособность ES.
Шардинг и реплики
Шардинг (шард): ЭС — это распределенная поисковая система, индекс обычно разбивается на разные части, часть данных, распределенных по разным узлам, — это шард. ES автоматически управляет сегментами и организует их, а также перебалансирует распределение данных сегментов, когда это необходимо, поэтому пользователям практически не нужно беспокоиться о деталях сегментирования. Количество осколков по умолчанию при создании индекса равно 5, и его нельзя изменить после создания.
Реплика: ES создает копию по умолчанию, что означает, что на основе 5 основных сегментов каждый основной сегмент имеет соответствующий сегмент реплики. Дополнительные реплики имеют свои плюсы и минусы.Некоторые реплики могут иметь более сильные возможности восстановления после сбоя, но они также занимают дисковое пространство, кратное соответствующим репликам.
Когда мы создаем индекс, сколько сегментов и реплик мы должны создать?
Что касается количества реплик, то лучше определить количество реплик, которое можно определить в зависимости от количества узлов нашего кластера и нашего пространства для хранения.У нас много серверов кластера и достаточно места для хранения.Мы можем установить больше реплик, обычно 1-3 реплики.Если кластерных серверов относительно немного и места для хранения не так уж и свободно, можно установить только одну копию для обеспечения аварийного восстановления (количество копий можно регулировать динамически).
По количеству осколков определить сложнее. Поскольку после того, как количество сегментов индекса определено, его нельзя изменить, поэтому перед созданием индекса мы должны полностью учитывать объем данных, хранящихся в индексе, который мы создадим в будущем, иначе будет создано несоответствующее количество сегментов. , Наша производительность имеет большое влияние.
Что касается размера количества шардов, то в отрасли согласны с тем, что количество шардов связано с памятью, считается, что 1 Гб динамической памяти соответствует 20-25 шардам, а размер одного шарда не должен превышать 50 Гб. конфигурация способствует работоспособности кластера. Но лично я считаю такой способ настройки слишком жестким, в процессе настройки ES кластера я устанавливаю соответствующие шарды по размеру общего объема данных, чтобы размер каждого шарда не превышал 50G (примерно в 40G ), но по сравнению с предыдущим количеством осколков эффект не очевиден. После этого я попытался увеличить количество осколков и обнаружил, что после увеличения количества осколков скорость запросов значительно улучшилась, а объем данных каждого осколка контролировался на уровне около 10G.
Запрос большого количества маленьких сегментов ускоряет обработку данных каждым сегментом. Значит ли это, что чем больше сегментов, тем быстрее наш запрос и выше производительность ES? На самом деле нет, потому что в процессе запроса происходит процесс слияния осколков.Если количество осколков продолжает увеличиваться, время слияния будет увеличиваться, и поскольку все больше задач необходимо ставить в очередь и обрабатывать по порядку, больше мелких осколков не обязательно быстрее, чем запрос меньшего количества больших осколков. Наличие множества небольших сегментов также снижает пропускную способность запросов при наличии нескольких одновременных запросов.
Если ваш сценарий заключается в том, что количество шардов не подходит, но вы не знаете, как его настроить, хорошее решение — создать индекс по времени, а затем выполнить запрос с подстановочными знаками. Если объем данных в день велик, вы можете создавать индекс ежедневно.Если объем данных, накопленных за месяц, велик, вы можете создавать индекс в месяц. Если вы хотите повторно разбить существующий индекс, вам нужно перестроить индекс, Количество сегментов для каждого индекса можно установить после всестороннего рассмотрения общего объема данных, нагрузки на запись и количества узлов, а затем регулярно проверять, является ли количество сегментов разумным в зависимости от состояния роста данных.
Техническая команда Tencent Cloud CES рекомендует следующее решение: Для индексов с небольшим объемом данных (менее 100 ГБ) давление записи и количество запросов часто относительно невелики.Как правило, устанавливается от 3 до 5 сегментов, а число_реплик может быть установлено равным 1 (то есть один главный и один подчиненный, всего с двумя репликами). Для индексов с большим объемом данных (более 100 ГБ): Как правило, объем данных одного сегмента контролируется на уровне (20–50 ГБ). Распределите давление индекса на несколько узлов: вы можете использовать параметр index.routing.allocation.total_shards_per_node, чтобы принудительно распределить количество осколков индекса на узле по разным узлам, насколько это возможно. Учитывая количество осколков во всем индексе, если количество осколков (исключая копии) превышает 50, это, вероятно, вызовет проблему увеличения процента отклонений. В этом случае вы можете рассмотреть возможность разделения индекса на несколько независимых индексов для совместного использования. объем данных.В то же время он используется с маршрутизацией, чтобы уменьшить количество сегментов, к которым должен обращаться каждый запрос.
Ниже я представлю настройку некоторых ключевых параметров ES.
Есть много сценариев, сколько процессорного времени занимает наш кластер ES и как это настроить. Высокая загрузка процессора может быть вызвана записью или запросом, как это проверить?
может пройти первымGET _nodes/{node}/hot_threadsПроверьте стек потоков, чтобы увидеть, какой поток занимает больше всего ЦП, если это такelasticsearch[{node}][search][T#10]Это вызвано запросом, если онelasticsearch[{node}][bulk][T#1]Это вызвано записью данных.
В реальной настройке загрузка ЦП очень высока, и вместо механического жесткого диска используется твердотельный диск (Solid State Disk). По сравнению с механическими дисками твердотельные накопители имеют эффективную скорость чтения и записи и стабильность. Если это не SSD, рекомендуется поставитьindex.merge.scheduler.max_thread_count: 1 Максимальное количество потоков для слияния индексов установлено равным 1, что позволяет эффективно регулировать производительность записи. Из-за одновременной записи на носитель данных производительность записи не улучшится, а только снизится из-за адресации.
Есть также несколько важных параметров, которые могут быть установлены учащимися в соответствии с их собственными условиями кластера и условиями данных.
index.refresh_interval: Этот параметр означает, что данные можно искать в секундах после записи, по умолчанию 1 с. Каждое обновление индекса будет генерировать новый сегмент lucene, что приведет к частому слиянию. Если бизнес-требования не так высоки в отношении производительности в реальном времени, вы можете увеличить этот параметр. Фактическая настройка говорит мне, что этот параметр действительно мощный. , загрузка процессора резко упала.
indices.memory.index_buffer_size: Если мы собираемся выполнять очень тяжелые операции записи с большим количеством параллельных операций, то лучше поставитьindices.memory.index_buffer_sizeсделать его больше,index bufferРазмер шарда общий для всех шардов, для каждого шарда дается максимум 512мб, так как какой бы большой шард ни был, производительность не улучшится. ES будет использовать этот параметр в качестве индексного буфера, разделяемого каждым шардом, и те сегменты, которые особенно активны, будут больше использовать этот буфер. Значение по умолчанию для этого параметра — 10 %, то есть 10 % кучи jvm.
Translog: чтобы гарантировать, что данные не будут потеряны, каждый раз, когда индексирование, массовое удаление, удаление и обновление будут завершены, ES будет запускать обновление Translog на диск. Конечно, повышая безопасность данных, это также немного снижает производительность. Если вас не волнует эта возможность и вам все же нужна производительность, вы можете установить следующие параметры:
"index.translog": {
"sync_interval": "120s", #sync间隔调高
"durability": "async", # 异步更新
"flush_threshold_size":"1g" #log文件大小
}
Этот параметр означает включение асинхронной записи на диск и установку временного интервала и размера записи, что помогает повысить производительность записи. Количество реплик
Для равномерного распределения созданного es-индекса на каждом датаноде количество шардов для одного и того же индекса на одном и том же датаноде не должно превышать трех. Формула расчета: (число_осколков * (1+число_реплик))
Параметры, связанные с дисковым кешем
vm.dirty_background_ratioЭтот параметр указывает, когда количество грязных страниц в кэше файловой системы достигает процента системной памяти (например, 5%), который будет активирован.pdflush/flush/kdmflushПодождите, пока запустится фоновый процесс обратной записи, и асинхронно сбросьте определенные кешированные грязные страницы во внешнюю память;
vm.dirty_ratio
Этот параметр указывает, когда количество грязных страниц, кэшированных файловой системой, достигает процента системной памяти (например, 10%), система должна начать обработку грязных страниц в кеше (поскольку количество грязных страниц уже велико в на этот раз, во избежание потери данных, необходимо сбросить некоторые грязные страницы во внешнюю память); во время этого процесса многие процессы приложения могут быть заблокированы, потому что система переходит к процессу файлового ввода-вывода.
При соответствующем уменьшении этого параметра принцип аналогичен (1). Если доля грязных данных в кэше (здесь доля MemTotal) превышает этот параметр, система остановит все операции записи ввода-вывода на прикладном уровне и будет ждать сброса данных для возобновления ввода-вывода. Поэтому, если эта операция системы сработает, это окажет большое влияние на пользователя.
sysctl -w vm.dirty_ratio=10
sysctl -w vm.dirty_background_ratio=5
Чтобы сохранить настройки навсегда, пропишите указанные выше элементы конфигурации в файле /etc/sysctl.conf.
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
объединить связанные параметры
"index.merge.policy.floor_segment": "100mb",
"index.merge.scheduler.max_thread_count": "1",
"index.merge.policy.min_merge_size": "10mb"
Также есть некоторые настройки параметров тайм-аута:
discovery.zen.ping_timeout 判断 master 选举过程中,发现其他 node 存活的超时设置
discovery.zen.fd.ping_interval 节点被 ping 的频率,检测节点是否存活
discovery.zen.fd.ping_timeout 节点存活响应的时间,默认为 30s,如果网络可能存在隐患,可以适当调大
discovery.zen.fd.ping_retries ping 失败/超时多少导致节点被视为失败,默认为 3
Конфигурация системных параметров Linux
дескриптор файла
В Linux максимальное количество дескрипторов файлов, открываемых каждым процессом, по умолчанию равно 1000, что явно слишком мало для серверного процесса./etc/security/limits.confувеличить максимальное количество открытых дескрипторов
* - nofile 65535
оптимизация чтения
① Избегайте больших наборов результатов и глубокого анализа. В предыдущей статье я говорил о процессе запроса в кластере.Например, чтобы запросить фрагменты данных размера, начиная с, вам нужно запросить фрагменты данных исходного+размера, которые ранжируются впереди в каждом сегменте. Совместный узел агрегирует собранные фрагменты данных n×(от+размер), снова сортирует их и возвращает размер фрагментов данных, начиная с от+размер. Когда один из from, size или n имеет большое значение, количество сортировок необходимо увеличить, и такой запрос будет потреблять много ресурсов ЦП, что приведет к снижению эффективности. Для повышения эффективности запросов ES предоставляет два режима запросов: Scroll и Scroll-Scan. Прокрутка: предназначена для получения большого количества результатов. Например, нам нужно запросить от 1 до 100 страниц данных, по 100 фрагментов данных на страницу. Если вы используете поисковый запрос: вам нужно каждый раз запрашивать из + 100 фрагментов данных с наивысшим баллом на каждом сегменте, а затем кооперативный узел объединяет собранные n × (из + 100) фрагментов данных и снова сортирует их. Каждый раз возвращает 100 фрагментов данных, начиная с +1, и повторяет выполнение 100 раз. Если используется запрос прокрутки: 10 000 фрагментов данных запрашиваются на каждом сегменте, а совместные узлы объединяют n × 10 000 фрагментов данных для слияния и сортировки и делают снимки первых 10 000 результатов. Преимущество этого заключается в уменьшении количества запросов и сортировки.
другое предложение
Вставка индекса автоматически генерирует идентификатор: когда писатель использует определенный идентификатор для записи данных в ES, ES проверяет, существует ли такой же идентификатор в соответствующем индексе.Эта операция будет увеличивать потребление по мере увеличения количества документов.Поэтому, если в бизнесе нет жестких требований, рекомендуется использовать идентификатор, автоматически сгенерированный ES, чтобы ускорить скорость записи.
Избегайте разреженного индекса: если индекс станет разреженным, это приведет к увеличению индексного файла. Ключевое слово, тип массива ES использует структуру Doc_Values, даже если поле равно null, каждый документ будет занимать определенное место, поэтому разреженный индекс увеличит диск, что приведет к снижению запросов и эффективности записи.
Настройка параметров
index.merge.scheduler.max_thread_count:1 # 索引 merge 最大线程数
indices.memory.index_buffer_size:30% # 内存
index.translog.durability:async # 这个可以异步写硬盘,增大写的速度
index.translog.sync_interval:120s #translog 间隔时间
discovery.zen.ping_timeout:120s # 心跳超时时间
discovery.zen.fd.ping_interval:120s # 节点检测时间
discovery.zen.fd.ping_timeout:120s #ping 超时时间
discovery.zen.fd.ping_retries:6 # 心跳重试次数
thread_pool.bulk.size:20 # 写入线程个数 由于我们查询线程都是在代码里设定好的,我这里只调节了写入的线程数
thread_pool.bulk.queue_size:1000 # 写入线程队列大小
index.refresh_interval:300s #index 刷新间隔
bootstrap.memory_lock: true#以保持JVM锁定内存,保证ES的性能。
О перестроении индексов
Перед перестроением индекса сначала обдумайте необходимость перестроения индекса, поскольку перестроение индекса занимает очень много времени. API переиндексации ES не будет пытаться установить целевой индекс и не будет копировать настройки исходного индекса, поэтому мы должны установить целевой индекс перед запуском операции _reindex, включая настройку маппинга (mapping), шардинга, реплик и т.д.
Первым шагом является создание нового индекса, подобного обычному индексу. Когда объем данных велик, необходимо установить интервал обновления, аrefresh_intervalsУстановите значение -1, то есть не обновляйте, число реплик number_of_replicas установлено равным 0 (поскольку количество реплик можно динамически регулировать, что помогает повысить скорость).
{
"settings": {
"number_of_shards": "50",
"number_of_replicas": "0",
"index": { "refresh_interval": "-1" }
}
"mappings":
{
}
}
Вторым шагом является вызов интерфейса переиндексации, рекомендуется добавитьwait_for_completion=falseУсловие параметра, поэтому переиндексация будет напрямую возвращать идентификатор задачи.
POST _reindex?wait_for_completion=false { "source": { "index": "old_index", //原有索引
"size": 5000 //一个批次处理的数据量
}, "dest": { "index": "new_index", //目标索引
}
}
Третий шаг — подождать. в состоянии пройтиGET _tasks?detailed=true&actions=*reindexчтобы запросить ход восстановления. Если вы хотите отменить задачу, позвоните_tasks/node_id:task_id/_cancel.
Четвертый шаг — удалить старый индекс, чтобы освободить место на диске. При перестроении индекса добавьте в параметры временную метку последнего перестроения индекса.Грубо говоря,например,наши данные 100G.В это время мы перестраиваем индекс,но эти 100G увеличиваются,поэтому когда мы пересобираем index, Необходимо записать временную метку перестроения индекса. Цель записи временной метки в том, что при следующем перестроении индекса и запуске задачи не обязательно перестраивать все, а только после временной метки. таким образом, пока объем данных нового и старого индексов не станет в основном одинаковым, чтобы переключить направление потока данных на имя нового индекса.
POST /_reindex
{
"conflicts": "proceed", //意思是冲突以旧索引为准,直接跳过冲突,否则会抛出异常,停止task
"source": { "index": "old_index" //旧索引
"query": { "constant_score" :
{ "filter" : {
"range" : { "data_update_time" :
{ "gte" : 123456789 //reindex开始时刻前的毫秒时间戳
}
}
}
}
}
},
"dest": { "index": "new_index", //新索引
"version_type": "external" //以旧索引的数据为准
}
}