предисловие
Производительность может быть не такой хорошей, как вы думаете. Во многих случаях объем данных велик, особенно когда имеются сотни миллионов фрагментов данных, вы можете обнаружить, что вынуждены выполнять поиск.5~10s
, яма отца. При поиске в первый раз5~10s
, последний быстрее, может быть, несколько сотен миллисекунд.
Чтобы больше не путаться в этих проблемах, я рассмотрю места и решения, которые можно оптимизировать внутри ES, в нескольких частях.
Убийца оптимизации производительности — кеш файловой системы
Данные, которые вы записываете в es, на самом деле записываются в файл на диске,когда спрашиваешь, операционная система автоматически кэширует данные в файле на диске, чтобыfilesystem cache
Войти в помещение.
поисковая система es в значительной степени зависит от лежащего в основеfilesystem cache
, если датьfilesystem cache
Больше памяти, постарайтесь, чтобы память могла вместить всеidx segment file
Индексируйте файлы данных, тогда вы в основном переходите в память при поиске, и производительность будет очень высокой.
Насколько большим может быть разрыв в производительности? Во многих наших предыдущих тестах и нагрузочных тестах, если зайти на диск, то это обычно занимает секунды, а производительность поиска точно на втором уровне, 1 секунда, 5 секунд, 10 секунд. Но если ты пойдешьfilesystem cache
, заключается в использовании чистой памяти, то, вообще говоря, производительность на порядок выше, чем у диска, в основном в миллисекундах, от нескольких миллисекунд до сотен миллисекунд.
Вот реальный случай. Узел es компании имеет 3 машины, каждая машина имеет много памяти, 64 ГБ, а общая память составляет64 * 3 = 192G
. Каждая машина дает кучу es jvm да32G
, то остальное остаетсяfilesystem cache
что каждая машина32G
, общий кластер даетfilesystem cache
является32 * 3 = 96G
ОЗУ. В это время файлы индексных данных на всем диске занимают в общей сложности 3 машины.1T
емкость диска, объем данных es1T
, то количество данных на машину равно300G
. Хорошо ли это работает?filesystem cache
Памяти всего 100G, десятую часть данных можно разместить в памяти, а остальные на диске, а потом вы выполняете поисковые операции, большая часть которых выполняется на диске, и производительность однозначно плохая.
В конечном счете, вы хотите, чтобы es работал лучше, и в лучшем случае память вашей машины могла вместить как минимум половину вашего общего объема данных.
Согласно практическому опыту, лучше всего хранить в es лишь небольшой объем данных, т. е. если вы хотитете индексы, которые используются для поиска, если память зарезервирована дляfilesystem cache
составляет 100G, тогда вы управляете данными индекса в100G
В этом случае почти все ваши данные ищутся в памяти, и производительность очень высока, как правило, в течение 1 секунды.
Скажем, теперь у вас есть ряд данных.id,name,age ....
30 полей. Но вы ищете сейчас, просто нужноid,name,age
Три поля для поиска. Если тупо записать все поля строки данных в es, то получится сказать90%
Данные не используются для поиска, а результат просто занимает машину esfilesystem cache
пространства, чем больше объем данных одного фрагмента данных, темfilesystem cahce
Чем меньше данных можно кэшировать. На самом деле, просто напишите es, чтобы использовать его для поиска.несколько полейВот так, например, просто напишите esid,name,age
Три поля, а затем вы можете хранить данные других полей в mysql/hbase, мы обычно рекомендуем использоватьes + hbase
такая структура.
Характеристики hbase:Онлайн-хранилище для больших данных, то есть вы можете записывать массивные данные в hbase, но не выполнять сложный поиск, а просто выполнять несколько простых операций, таких как запросы на основе идентификатора или диапазона. Поиск по имени и возрасту от es, и вы можете получить 20 результатовdoc id
, то согласноdoc id
Перейдите к hbase, чтобы запросить каждыйdoc id
соответствующийполные данные, чтобы выяснить это, а затем вернуться в интерфейс.
Данные, записываемые в es, предпочтительно меньше или равны или немного больше объема памяти кэша файловой системы es. Затем вы можете потратить 20 мс на получение данных из es, а затем перейти к hbase для запроса в соответствии с идентификатором, возвращенным es, и проверить 20 фрагментов данных, это может занять 30 мс.Может быть, вы раньше так играли, 1T данных помещается es, и каждый раз запрос составляет 5~10 секунд, а сейчас производительность может быть очень высокой, и каждый запрос составляет 50 мс.
Прогрев данных
Предположим, даже если вы будете следовать приведенному выше плану, объем данных, записываемых каждой машиной в кластере es, все равно превышаетfilesystem cache
Двойной, например, если вы записываете 60G данных на машину, результатfilesystem cache
Всего 30G, на диске осталось еще 30G данных.
на самом деле может сделатьПрогрев данных.
Например, возьмем Weibo в качестве примера, вы можете поставить какой-то большой V, обычно много данных людей, вы можете настроить систему в фоновом режиме заранее, время от времени, свою собственную фоновую систему для поиска горячих данных , почиститьfilesystem cache
Когда пользователи на самом деле просматривают эти горячие данные позже, они выполняют поиск непосредственно в памяти, очень быстро.
Или для электронной коммерции вы можете заранее создать программу в фоновом режиме для некоторых продуктов, которые вы просматриваете чаще всего, таких как iphone 8 и горячие данные, и посещать ее самостоятельно каждую 1 минуту.filesystem cache
войти в помещение.
Для данных, которые вы считаете горячими и часто используемыми, лучше всегоСделать выделенную подсистему прогрева кеша, то есть заранее получать доступ к горячим данным время от времени, чтобы данные поступалиfilesystem cache
Войти в помещение. Таким образом, производительность будет намного лучше, когда другие посетят его в следующий раз.
Горячее и холодное разделение
es может делать горизонтальное разбиение аналогично mysql, то есть писать отдельный индекс для большого объема данных, к которым обращаются редко и нечасто, а затем писать отдельный индекс для горячих данных, к которым обращаются часто. лучше всегоХолодные данные записываются в один индекс, а горячие данные записываются в другой индекс., что гарантирует, что после разогрева горячих данных постараться сохранить их как можно дольшеfilesystem os cache
внутри,Не позволяйте холодным данным смыть.
Видите ли, допустим, у вас есть 6 машин, 2 индекса, один для холодных данных, один для горячих данных, по 3 сегмента на индекс. 3 машины поставили индекс тепловых данных, а остальные 3 машины поставили индекс холодных данных. В этом случае вы тратите много времени на доступ к индексу горячих данных, а горячие данные могут составлять 10% от общего объема данных, в это время объем данных очень мал, и почти все хранится в индекс.filesystem cache
Внутри вы можете убедиться, что производительность доступа к горячим данным очень высока. Но для холодных данных он находится в другом индексе, не на той же машине, что и индекс для горячих данных, и все друг с другом не связаны. Если кто-то обращается к холодным данным, на диске может быть большой объем данных.В это время производительность низкая, 10% людей обращаются к холодным данным, а 90% людей обращаются к горячим данным, это не не важно.
макет документа
Для MySQL у нас часто есть сложные реляционные запросы. Как играть в es, старайтесь не использовать сложные реляционные запросы в es, после использования производительность вообще не очень.
Лучше всего сначала завершить ассоциацию в системе Java и записать связанные данные непосредственно в es. При поиске нет необходимости использовать синтаксис поиска es для завершения связанных поисков, таких как соединение.
Дизайн модели документа очень важен.Операций много.Не хочется выполнять разные сложные и грязные операции при поиске. Существует не так много операций, которые может поддерживать es, не рассматривайте возможность использования es для некоторых вещей, с которыми непросто работать. Если есть такая операция, постарайтесь выполнить ее, когда модель документа будет разработана и написана. Кроме того, следует по возможности избегать некоторых слишком сложных операций, таких как объединение/вложение/поиск родитель-потомок, а производительность будет очень низкой.
Оптимизация производительности пейджинга
Пагинация es более ямочная, почему? Например, если у вас есть 10 фрагментов данных на странице, и вы хотите запросить 100-ю страницу, вы фактически проверите первые 1000 фрагментов данных, хранящихся на каждом сегменте, на координирующем узле. данные для каждого шарда, а затем координирующий узел объединяет и обрабатывает эти 5000 фрагментов данных, после чего получает последние 10 фрагментов данных на 100-й странице.
Распределенный, вы хотите проверить 10 кусков данных на странице 100. Нельзя сказать, что из 5 шардов каждый шард будет проверять 2 куска данных, и окончательно сливаться в 10 кусков данных на координирующем узле, верно? тыдолженВы должны проверить 1000 фрагментов данных из каждого сегмента, затем отсортировать, отфильтровать и т. д. в соответствии с вашими потребностями и, наконец, снова разбить на страницы, чтобы получить данные на 100-й странице. Когда вы перелистываете страницы, чем глубже вы перелистываете, тем больше данных возвращает каждый шард и тем дольше обрабатывается координирующий узел, что очень раздражает. Поэтому, когда вы используете es для пейджинга, вы обнаружите, что чем больше вы поворачиваетесь назад, тем медленнее он будет.
Мы также сталкивались с этой проблемой раньше.Используя es в качестве нумерации страниц, первые несколько страниц занимают всего несколько десятков миллисекунд.Когда мы переходим к 10 или десяткам страниц, в основном требуется 5-10 секунд, чтобы найти страницу данных.
Есть ли решение?
Глубокое пейджинг не разрешено (низкая производительность глубокого пейджинга по умолчанию)
Скажите продакт-менеджеру, что ваша система не позволяет вам так глубоко перелистывать страницы. Чем глубже вы перелистываете по умолчанию, тем хуже производительность.
Похожие на рекомендуемые товары в приложении постоянно вытягиваются страница за страницей
Как и в Weibo, потяните вниз, чтобы провести Weibo, и пролистайте страницу за страницей, вы можете использоватьscroll api
, о том, как использовать, ищите в Интернете сами.
прокрутка будет сгенерирована для вас за один разМоментальный снимок всех данных, а затем каждый переход на страницу назад проходит черезкурсор scroll_id
Переместить, получить следующую страницу и следующую страницу, производительность будет намного выше, чем производительность пейджинга, упомянутая выше, в основном в миллисекундах.
Однако единственное, что это подходит для типа выпадающей страницы Weibo,Сценарии, в которых вы не можете перейти на любую страницу по своему желанию. То есть нельзя перейти на страницу 10, потом перейти на страницу 120, потом вернуться на страницу 58, и нельзя просто прыгать. Поэтому многие продукты сейчас не позволяют листать страницы по желанию, есть приложения, а есть и некоторые веб-сайты, которые делают то, что вы можете только прокручивать вниз и листать страницу за страницей.
Должен быть указан при инициализацииscroll
параметр, указывающий, как долго сохранять контекст для этого поиска. Вы должны убедиться, что пользователь не будет перелистывать страницы в течение нескольких часов, иначе это может привести к сбою с тайм-аутом.
помимо использованияscroll api
, вы также можете использоватьsearch_after
сделать это,search_after
Идея состоит в том, чтобы использовать результаты предыдущей страницы, чтобы помочь получить данные следующей страницы.Очевидно, что этот метод не позволяет вам листать страницы по желанию, вы можете только листать страницу за страницей. При инициализации необходимо использовать поле с уникальным значением в качестве поля сортировки.