Разделяй и властвуй — основная идея вычислений больших данных. Я хотел бы поделиться естественной распределенной полнотекстовой поисковой системой — Elastic Search. Как объединить — ключевая проблема принципа «разделяй и властвуй». В архитектуре узлов кластера высокой доступности, как распределить основные и резервные шарды каждого узла и как получить окончательный результат из результатов поиска каждого шарда...
Введение | Вспомните мыслительный процесс выполнения kibana dsl-скрипта.
Когда необходимо реализовать десятки миллионов или даже большие объемы данных, как в традиционных реляционных базах данных СУБД, требуется нечеткий поиск и полнотекстовый поиск в больших объемах данных, а также требуется определенная степень эффективности поиска, чтобы преодолеть узкое место в производительности традиционных систем. СУБД, тогда ES очень подходит для использования с реляционными базами данных, дополняющими друг друга. ES обладает высокой производительностью в области поиска, в то время как традиционные БД. Запрос комбинации подбазы данных и подтаблицы реляционной базы данных MS довольно затруднителен, в то время как комбинация ES является гибкой и автоматической маршрутизацией (разработчикам не нужно слишком сильно вмешиваться в бизнес-уровень. Конечно, в случае сложных запросов с большим размером). объемы данных, необходимо оптимизировать глубокую пейджинг, что просто. Запросить миллиарды запросов не составляет большой проблемы. Если он слишком велик, вы можете использовать кластер, а затем использовать ES-ClickHouse.
Хотя данные в традиционных таблицах реляционной базы данных СУБД можно синхронизировать с ES с помощью ряда решений, основанных на реальном бизнесе (моделирование данных), когда большие пакеты данных синхронизируются с одним узлом ES или данные копирования переносятся с узла на кластер, отправка данных в пакетном режиме на основе logstash или ES-Transport. Данные необходимо обновлять в реальном времени или инициализировать в автономном режиме, а также производительность агрегации и некоторые расширенные атрибуты, такие как копирование. к приложению механизма сценариев, сопоставлению дизайна динамических шаблонов для сопоставления динамических индексов или сопоставления готовых динамических шаблонов с указанными индексами и т. д.
один、Эластичный поиск Script Полнотекстовый поиск по истории-История скриптового движка
В ранних версиях ES использовались скрипты MVEL, но для решения рисков безопасности появились скрипты Groovy.
Впоследствии произошли уязвимости безопасности и утечки памяти, поэтому по случаю версии ES5.0 был официально анонсирован безболезненный скрипт. Прошло несколько лет с тех пор, как безболезненный скрипт появился перед разработчиками.
Например, Elasticsearch Script ApplyCenarios-Распределенный полнотекстовый поиск-Приложение скриптового движкасцена
Мы все знакомы с полнотекстовой поисковой системой Elasticsearch, которая предоставляет богатый синтаксис dsl в каждой серии версий — добавление, удаление, изменение и запрос — здесь мы берем серию версий 6.x — 6.8.6 (
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/docs.html)Например。
Его легко добавлять, удалять, изменять и осуществлять поиск в более чем 80% бизнес-сценариев, но его можно использовать и в относительно сложных бизнес-сценариях:
Пользовательское обновление нескольких полей, пользовательское переиндексирование, динамическое добавление пользовательских полей массива...
https://www.elastic.co/guide/en/elasticsearch/painless/6.8/painless-regexes.html
Конечно, также можно вручную разрабатывать плагины на основе скриптовых движков.
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-engine.html
Смысл безболезненного сценария заключается в том, что он «безболезненный» и не имеет лазеек, но необходимо уделить особое внимание — вы не можете запустить es с учетной записью root и не раскрывать путь es другим пользователям.
Судя по официальному введению в использование Script, первым приоритетом являются проблемы производительности, а вторым — использование бизнес-сценариев, что eBay также отражает это в англоязычной версии практик оптимизации производительности.
https://www.ebayinc.com/stories/blogs/tech/elasticsearch-performance-tuning-practice-at-ebay/
Также отметьте здесь китайскую версию.
https://www.infoq.cn/article/elasticsearch-performance-tuning-practice-at-ebay
в,80%Вышеописанный бизнессцена:Резюме редактора ссылокЭнциклопедия Elasticsearch+Kibana+Dsl-Crud
GET _search
{
"query": {
"match_all": {}
}
}
#Информация об узле
GET _cat/nodes?v
GET _cat/master
#Каждый узел-машина хранит информацию
GET _cat/allocation?v
#индексная информация
GET _cat/indices?v
GET /_cat/count
GET /_cat/count/yd-2021
GET _cat/indices/yd-hlht-test-2022
#Информация о фрагментации
GET _cat/shards?v
GET _cat/shards/yd-hlht-test-2022
#Просмотр состояния восстановления всех сегментов. Эта команда проверяет ход восстановления инициализируемых сегментов.
GET _cat/recovery/
GET _cat/recovery/yd-hlht-test-2022
GET _cluster/health
GET _cluster/nodes/hot_threads
#Проверьте причину, по которой шарды не распределяются
GET /_cat/shards?h=index,shard,prirep,state,unassigned.*,unassigned.reason | grep UNASSIGNED
#Проверьте причину, по которой не выделяются определенные шарды
GET _cluster/allocation/explain
{
"index":"yd-hlht-test-2022",
"shard":0,
"primary":false
}
#Регистрация совместного использования хранилища моментальных снимков
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/home/user/yxd179/es/backup"
}
}
#Просмотр информации о складе
GET /_snapshot/my_backup?pretty
#Просмотр результатов сохранения хранилища снимков
GET _snapshot
#Создайте снимок. При этом все открытые индексы будут сохранены в снимке с именем snapshot_yd в хранилище my_backup. Этот вызов немедленно вернется, и снимок будет запущен в фоновом режиме. Если вы хотите дождаться завершения сценария, вы можете добавить wait_for_completion Отметьте реализацию, это заблокирует вызов до тех пор, пока снимок не будет завершен (если это большой снимок, возврат займет много времени), что приведет к резервному копированию только информации индекса 809iJpOmSI2ZmJrUqKRR0Q.
PUT /_snapshot/my_backup/snapshot_yd?wait_for_completion=true
{
"indices": "809iJpOmSI2ZmJrUqKRR0Q",
"ignore_unavailable": true,
"include_global_state": false,
"metadata": {
"taken_by": "phr",
"taken_because": "backup before upgrading"
}
}
#Просмотреть снимок
GET /_snapshot/my_backup/snapshot_yd
#Просмотреть все снимки
GET /_snapshot/my_backup/_all
#Удалить снимок
DELETE /_snapshot/my_backup/snapshot_yd
#Отслеживание процесса создания или восстановления моментального снимка
GET /_snapshot/my_backup/snapshot_yd/_status
#Восстановить снимок
POST /_snapshot/my_backup/snapshot_yd/_restore
#динамическийшаблон
PUT /_template/yxd179_tpl
{
"index_patterns": [
"yxd179-2021*"
],
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1
},
"mappings": {
"yd": {
"dynamic_templates": [
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"index": true,
"copy_to": "full_context",
"analyzer": "ik_max_word",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
],
"properties": {
"full_context": {
"type": "text",
"analyzer": "ik_max_word",
"fielddata": true,
"store": true
}
}
}
}
}
#Копируем настройки распределения шардов
PUT /yxd179-2021/_settings
{
"number_of_replicas": "1"
}
#Пейджинговый запрос
GET /yxd179-2021/yd/_search
{
"from": 0,
"size": 30
}
#Запрос по идентификатору
GET /yxd179-2021/yd/647461503271768064
#bool query dsl-запрос
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"regNumber": "20203030651"
}
}
]
}
},
{
"term": {
"status": "1"
}
}
]
}
},
"sort": [
{
"createTime": {
"order": "desc"
}
}
],
"from": 0,
"size": 10
}
#Разрешить настройки распределения максимального скользящего числа ES
PUT /yxd179-2021/_settings
{
"index": {
"max_result_window": 13000000
}
}
#Просмотр процесса сегментации слов поля
POST /yxd179-2021/_analyze
{
"field": "regNumber",
"text": «Национальный стандарт на машиностроение № 20203030651»
}
#нечеткое соответствие запроса
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"wildcard": {
"regNumber.keyword": "*20203030651*"
}
}
]
}
},
{
"term": {
"status": "1"
}
}
]
}
},
"sort": [
{
"createTime": {
"order": "desc"
}
}
],
"from": 0,
"size": 10
}
#Задаем запрос сегментатора слов для указанного поля
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"hdsd0001004": {
"query": "1828551417",
"analyzer": "char_analyzer"
}
}
}
]
}
},
"from": 0,
"size": 30
}
#нечеткое соответствие запроса
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"wildcard": {
"hdsd0001002.keyword": "*yxd179*"
}
}
]
}
},
"from": 0,
"size": 30
}
#Закрыть индекс:
POST yxd179-2021/_close
#Открытый индекс:
POST yxd179-2021/_open
#Устанавливаем токенизатор для указанного поля
PUT /yxd179-2021/_mapping/yd
{
"properties": {
"hdsd0001004": {
"type": "text",
"analyzer": "char_analyzer"
}
}
}
#Просмотр информации о структуре сопоставления
GET yxd179-2021/_mapping
#Устанавливаем анализатор сегментации слов
PUT yxd179-2021/_settings
{
"analysis": {
"analyzer": {
"char_analyzer": {
"tokenizer": "char_tokenizer",
"filter": "lowercase"
}
},
"tokenizer": {
"char_tokenizer": {
"type": "pattern",
"pattern": "|"
}
}
}
}
#minimum_should_match
GET /yxd179-2021/yd/_search
{
"query": {
"query_string": {
"query": "182855141y7",
"type": "phrase",
"operator": "AND",
"minimum_should_match": "100%",
"fields": [
"hdsd0001004"
]
}
}
}
#Поля отображения
GET /yxd179-2021/yd/_search
{
"_source": {
"include": [
"id",
"productId"
]
},
"query": {
"bool": {
"must": [
{
"terms": {
"productId": [
636654265306419462
]
}
}
]
}
},
"from": 0,
"size": 30
}
#HighlightQuery
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": []
}
},
{
"term": {
"status": "1"
}
},
{
"term":{
"id":636662671736099971
}
}
]
}
},
"sort": [
{
"id": {
"order": "asc"
}
}
],
"highlight": {
"pre_tags": [
"<span class='title-key'>"
],
"post_tags": [
"</span>"
],
"fields": {
"commonName": {
"type": "plain"
}
}
},
"from": 0,
"size": 10
}
#read_only_allow_delete
PUT /yxd179-2021/_settings
{
"index":{
"blocks":{
"read_only_allow_delete":"false"
}
}
}
#Шаблон запроса
GET /_template
GET /yxd179-2021*/yd/_search
{
"from": 0,
"size": 30
}
#Bool-запрос с одним полем
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"id": "636651493706133509"
}
}
]
}
},
"from": 0,
"size": 30
}
#партия
POST /_bulk
{"index":{"_index":"yxd179-2021","_type":"yd","_id":"65965969996688"}}
{"id":"65965969996688","HDSD0001002":"sdff","HDSD0001008":"fsdf","HDSD0001006":"000000000000000000","create_time":"2021-07-29","cancel_flag":0}
{"index":{"_index":"yxd179-2021","_type":"yd","_id":"66049829996688"}}
{"id":"66049829996688","HDSD0001002":"sdgsdg","HDSD0001008":"fsdfsdf","HDSD0001006":"000000000000000000","create_time":"2021-07-29","cancel_flag":1}
#Запрос внешнего пересечения
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"bool": {
"should": [
{
"match": {
"regNumber": "странаsd20182642128" }
}
]
}
},
{
"term": {
"status": "1"
}
}
]
}
},
"sort": [
{
"createTime": {
"order": "desc"
}
}
],
"from": 0,
"size": 10
}
#Сложная лого-взвешенная сортировка по результатам запроса
GET /yxd179-2021/yd/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"cancelFlag": {
"value": "0",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
{
"bool": {
"should": [
{
"match": {
"yhe": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
},
{
"match": {
"yhr": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
},
{
"match": {
"yht": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
},
{
"match": {
"yhg": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"explain": true,
"sort": [
{
"id": {
"order": "desc"
}
}
]
}
#Запрос профиля трудоемкого статистического анализа
GET /yxd179-2021/yd/_search
{
"profile": true,
"query":{
"term":{
"tu":6583120
}
}
}
#Изменить на основе идентификатора
POST /yxd179-2021/yd/b00e89b652484b0b8da16e090302e012/_update
{
"doc":{
"fd":"1"
}
}
#Modify_update_by_query скриптовый движок безболезненно
POST /yxd179-2021/_update_by_query
{
"query":{
"term":{
"fdh":6583120
}
},
"script":{
"lang":"painless",
"source": "ctx._source.cancelFlag=params.cancelFlag;ctx._source.updateTime=params.updateTime",
"params": {
"cancelFlag":"0",
"updateTime":"2021-07-28T01:17:36.000Z"
}
}
}
#Запрос на пересечение и сохранение всего
GET /yxd179-2021/yd/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"cancelFlag": "0"
}
},
{
"bool": {
"must": [
{
"wildcard": {
"hdsd0001002.keyword": "*yxd179*"
}
},
{
"match": {
"hdsd0001003": "2"
}
}
]
}
}
]
}
},
"sort": [
{
"id": {
"order": "desc"
}
}
],
"highlight": {
"pre_tags": [
"<span class='title-key'>"
],
"post_tags": [
"</span>"
],
"fields": {
"hdsd0001002": {
"type": "plain"
}
}
},
"from": 0,
"size": 30
}
#Запрос внешнего Пересечения – запрос на пересечение внутреннего слоя.
GET /yxd179-2021/yd/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"term": {
"cancelFlag": {
"value": "0",
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
{
"bool": {
"must": [
{
"match": {
"hdsd0001002": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
},
{
"match": {
"hdsd0001003": {
"query": "2",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"explain": true
}
#Запрос объединения
GET /yxd179-2021/yd/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"term": {
"cancelFlag": {
"value": "0",
"boost": 1
}
}
}
],
"should": [
{
"match": {
"hdsd0001002": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"explain": true
}
#Запрос объединение - отображение полей
GET /yxd179-2021/yd/_search
{
"from": 0,
"size": 10,
"query": {
"bool": {
"must": [
{
"match": {
"cancelFlag": {
"query": "0",
"operator": "AND",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"should": [
{
"match": {
"hdsd0001002": {
"query": "открыть",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
},
{
"match": {
"hdsd0001002.pinyin": {
"query": "zhang",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"explain": true,
"_source": {
"includes": [
"id",
"th001Id",
"createTime",
"updateTime",
"hdsd0001001",
"hdsd0001002",
"cancelFlag"
],
"excludes": []
}
}
#Если вам нужны более частые обновления, вы можете использовать es принудительное обновление API
GET /yxd179-2021/_refresh
#Удалить по идентификатору
DELETE /yxd179-2021/yd/ud6-5XkBwVbB7HKjg5k0
#Удалить индекс
DELETE /yxd179-2021
#Удалить динамическое сопоставление шаблона
DELETE /_template/yxd179_tpl
#сортировка
GET /yxd179-2021/yd/_search
{
"sort": [
{
"createTime": {
"order": "desc"
}
}
],
"from": 0,
"size": 30
}
Например, Elasticsearch Script ActualCombat-Механизм распределенного полнотекстового поиска в действии
Здесь мы возьмем только Update-By-Query в качестве примера:
Среди них lang указывает движок скрипта: безболезненный, source — фрагмент скрипта, а params — значение параметра скрипта.
Причина, по которой он передается через параметры, может нарушить ограничения компиляции сценария ES. Хотя настройку верхнего предела синтаксического анализа также можно изменить с помощью следующих операций:
PUT /_cluster/settings
{
"transient": {
"script.max_compilations_per_minute": 40
}
}
Важно: для больших пакетов данных ES требует отдельной компиляции и анализа. При массовом обновлении, если каждый скрипт компилируется в реальном времени, вполне возможно, что верхний предел скоро будет достигнут. Зная это, мы знаем, почему ES будет анализировать скрипт только в первый раз, и тогда нет необходимости анализировать его снова. Когда в скрипте есть постоянные переменные, ES скомпилирует скрипт в реальном времени, поэтому в сочетании с ними. функция param в скрипте. Попробуйте передать переменные в скрипте через param, что может фундаментально решить проблему ограничений компиляции и синтаксического анализа скрипта.
Далее посмотрим, как собрать tcp-клиент на базе версии 6.8.6 на Java для безболезненного выполнения скриптового движка?
Добавлено: вызов API updateByQuery начинается с создания моментального снимка индекса, который использует внутреннее управление версиями для поиска любых документов.
Рассмотрим конфликт версий, который возникает при изменении документа между моментом создания моментального снимка и процессом запроса индекса. Если версии совпадают, updateByQuery обновляет документ и увеличивает номер версии. Чтобы предотвратить прерывание updateByQuery из-за конфликта версий, вы также можете установить abortOnVersionConflict(false). Причина этого заключается в том, что возможно, что он пытается получить изменения онлайн-сопоставления, а конфликт версий означает запуск updateByQuery с адреса. В то же время и при попытке обновить конфликтующий документ документа обновление будет получать обновления онлайн-сопоставления, updateByQuery также может использовать узел приема, указав конвейер. Среди них API UpdateByQueryRequestBuilder может поддерживать фильтрацию обновленных документов, ограничение общего количества обновляемых документов и использование сценариев для обновления документов, мгновенной записи на диск, времени повтора и т. д.
Retry:
Когда клиенты A и B получают один и тот же документ почти одновременно, они получают информацию о версии _version вместе, предполагая, что _version=1 в этот момент.
Затем клиент А изменяет часть содержимого документа и записывает изменения в индекс. При записи индекса Elasticsearch проверяет информацию о версии документа, отправленного клиентом A (здесь она по-прежнему равна 1), и информацию о версии существующего документа (здесь она также равна 1). Найдя ее, он выполняет операцию записи. и изменяет номер версии _version=2. Затем клиент B также изменяет часть содержимого документа, и его работа записывается обратно в индекс с несколько меньшей скоростью. В это время процесс записи ES также обнаруживает, что версия документа, отправленная клиентом. B равен 1, а версия существующего документа — 2. , то есть возникает конфликт, и это частичное обновление завершится неудачей — попробуйте еще раз.
Стратегия управления параллелизмом: стратегия управления параллелизмом с частичным обновлением — оптимистическая блокировка
Небольшой тестовый пример: как указать несколько полей для обновления через механизм сценариев?
Способ №1:
ctx._source.putAll(params)
Способ №2:
for (k in params.keySet()){if (!k.equals('ctx')){ctx._source.put(k, params.get(k))
AIM:Время летит,мимолетный,думал,после работы,существоватьESПоле поискаодин Есть много вещей, которые я всегда хотел сделать...
ES-ORM:структура реляционного отображения,Аналогично MP framework Mybatis-Plus,Пользователям не придется сталкиваться со сложным синтаксисом DSL.,Сосредоточьтесь на разработчиках, использующих Elastic,Доступ к ES становится проще!
конец:Следовать заJavaрамочная система,Технологическая система баз данных,Расширенные кейсы системы больших данных и реальный бой будут обновлены одновременно.,Синхронизация публичной учетной записи WeChat,Цель состоит в том, чтобы поделиться,Добро пожаловать, чтобы внести ценные предложения ^_^