terratensor / kob-library-app

Поиск по толстым книгам ВП СССР
https://kob.svodd.ru
BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Ресурсы #47

Open iprst opened 1 year ago

iprst commented 1 year ago

Возможно имеет смысл локально имитировать работу ограниченных конфигураций сервера для проверки разных подходов к оптимизации и эффективности проектов и того, как они себя будут вести на малых ресурсах, где у них бутылочные горлышки, возможно ли что-то улучшить в сценариях.

Пока совсем не понятно и тёмный лес. Для некоммерческих проектов это критично.

Цель оправдывают средства (с)

audetv commented 1 year ago

Почитал, подумал, протестировал на общей библиотеку 7733 книг. При тесте был установлен .wslconfig для эмуляции текущих ресурсов сервера

# Settings apply across all Linux distros running on WSL 2
[wsl2]
memory=2GB 
processors=2
swap=2GB

Изменил настройки файла конфигурации manticore

source common_library {
  type             = pgsql
  sql_host         = postgres
  sql_user         = app
  sql_pass         = secret
  sql_db           = common-library
  sql_query_range  = SELECT MIN(id),MAX(id) FROM db_pg_paragraphs
  sql_range_step   = 1000
  sql_query        = SELECT id, uuid, book_id, book_name, text, position, length from db_pg_paragraphs WHERE id>=$start AND id<=$end
  sql_attr_uint    = book_id
  sql_attr_string  = uuid
  sql_attr_string  = book_name
  sql_field_string = text
  sql_attr_uint    = position
  sql_attr_uint    = length
 }

Далее установил значения как в примере из документации: Ranged queries

Main query, which needs to fetch all the documents, can impose a read lock on the whole table and stall the concurrent queries (eg. INSERTs to MyISAM table), waste a lot of memory for result set, etc. To avoid this, Manticore supports so-called ranged queries. With ranged queries, Manticore first fetches min and max document IDs from the table, and then substitutes different ID intervals into main query text and runs the modified query to fetch another chunk of documents. Here's an example.

Ranged query usage example:

sql_query_range = SELECT MIN(id),MAX(id) FROM documents sql_range_step = 1000 sql_query = SELECT * FROM documents WHERE id>=$start AND id<=$end If the table contains document IDs from 1 to, say, 2345, then sql_query would be run three times:

with $start replaced with 1 and $end replaced with 1000; with $start replaced with 1001 and $end replaced with 2000; with $start replaced with 2001 and $end replaced with 2345. Obviously, that's not much of a difference for 2000-row table, but when it comes to indexing 10-million-row table, ranged queries might be of some help.

Строка sql_query_range = SELECT MIN(id),MAX(id) FROM db_pg_paragraphs — задает максимальное и минимальное значение для диапазона sql_range_step = 1000 — задаёт шаг для диапазона sql_query = SELECT id, uuid, book_id, book_name, text, position, length from db_pg_paragraphs WHERE id>=$start AND id<=$end — сам запрос из таблицы с учетом запроса по диапазону значений.

UPD: Чтение в память происходит пакетами по 1000 записей, затем производится запись в индекс и читается следующий пакет.

Очистил предыдущий индекс мантикоры и запустил, получил такой результат: В процессе индексирования документов: 2023-07-08_13-45-11 Памяти было задействовано около 550 МБ и только в конце процесса показатели подскочили до 1.3Гб Итого volume — 22.7Гб 2023-07-08_13-45-23

И финальный скриншот 22.7 млн документов — 957 сек: 2023-07-08_13-42-22

На 2Гб оперативной памяти и 2х процессорах В процессе индексирования наблюдал за дисками, так вот по ощущениям запись идет сразу в volume. т.к. в процессе там было замечено увеличение диска. На боевом сервере еще не тестировал, протестирую, если все будет хорошо, я предполагаю, то это сильно упрощает процесс обновления индексов. Т.к. скорость индексирования 957 сек, много меньше, чем загружать уже собранный индекс с локальной машины, но плюс к этому, я думаю, что в таком режиме открывается больше вариантов автоматизации.

Далее в планах протестировать distributed tables. хочу разбить индекс на несколько таблиц 1,2,3,4 и соединить их через destrubed таблицу, по описанием это может дать прирост в скорости поиска, так как поиск будет происходить параллельно в 4 таблицах, ( если сделать 4) Distributed-searching

To scale well, Manticore has distributed searching capabilities. Distributed searching is useful to improve query latency (i.e. search time) and throughput (ie. max queries/sec) in multi-server, multi-CPU or multi-core environments. This is essential for applications which need to search through huge amounts data (ie. billions of records and terabytes of text).

The key idea is to horizontally partition searched data across search nodes and then process it in parallel.

Partitioning is done manually. You should:

setup several instances of Manticore on different servers put different parts of your dataset to different instances configure a special distributed table on some of the searchd instances and route your queries to the distributedtable This kind of table only contains references to other local and remote tables - so it could not be directly reindexed, and you should reindex those tables which it references instead.

When Manticore receives a query against distributed table, it does the following:

connects to configured remote agents issues the query to them at the same time searches configured local tables (while the remote agents are searching) retrieves remote agent's search results merges all the results together, removing the duplicates sends the merged results to client From the application's point of view, there are no differences between searching through a regular table, or a distributed table at all. That is, distributed tables are fully transparent to the application, and actually there's no way to tell whether the table you queried was distributed or local.

Read more about remote nodes.

В планах проверить.

iprst commented 1 year ago

Отлично, всё понятно.

Округлим для первого приближения: если у нас на сервере 2 CPU 2Gb MEM крутится мантикора с 11 Гб текста, то используется 22 Гб диска.

Когда потребуется, у меня уже заготовлен набор 100 тысяч fb2 текстов размером 66 Гб (по максимуму очищен от картинок и тд) — в целом ничего не мешает собрать тестовую базу такого размера и проверить как она будет работать. При желании можно всё это конвертировать в docx, чтобы не изобретать парсер под fb2, поскольку файлы уже без картинок, и эта конвертация по сути будет простым архивированием xml в bzip, без последующей зачиски, ещё и размер исходника сэкономим, вместо 66 будет 25-30 Гб.

Остальные примерно 60 тысяч файлов в очень разных форматах, полный винегрет. Тысяч десять из них уже оформлены в docx без картинок, остальное в размышлениях, где-то 10-20% будут дубликатами уже существующих в тексте документов, их я удалю, а остальные 45 тысяч это архивы (с ещё более разнообразным содержанием винегрета) и сканы в pdf или djvu где-то на 350 Гб.

audetv commented 1 year ago

Округлим для первого приближения: если у нас на сервере 2 CPU 2Gb MEM крутится мантикора с 11 Гб текста, то используется 22 Гб диска.

Сейчас 36Gb, еще БД postgress, но тут есть над чем подумать, т.е. если БД будет нужна только для загрузки данных, то надо пересмотреть способ загрузки, например собирать из csv, и потом их удалять, или наверняка есть еще варианты, надо подумать. Но если то, как сейчас, то параграфы лежат в бд ~13 Гб и мантикора ~23Гб.

Details Скриншот дисков

![2023-07-08_15-09-58](https://github.com/terratensor/kob-library-app/assets/10896447/7a4c89a1-16cd-4e70-8b67-927e36cfa00f)

UPD Получается, что пока основной ресурс — Диски

iprst commented 1 year ago

Сейчас 36Gb, еще БД postgress

А нам критично хранить постгресс на сервере, или его можно хранить локально?

сейчас, то параграфы лежат в бд ~13 Гб и мантикора ~23Гб

Да, я как раз имел в виду что если у нас текст 10 Гб, то мантикора для поиска в этом тексте будет 20 Гб. То есть если будет текста на 100 Гб, то мантикоре потребуется 200 Гб места. Всё остальное это улучшайзинг и оптимизации, допустим мы их можем делать локально, минимальная схема при полной отсечке всего «ненужного» упирается в размер хранилища в любом случае, независимо от того, как будет оптимизироваться память и процессор. Это очень полезная информация, спасибо.

audetv commented 1 year ago

Сейчас 36Gb, еще БД postgress

А нам критично хранить постгресс на сервере, или его можно хранить локально?

хранить то можно и локально, а вот если надо пользоваться им, то это другая история. Я поэтому и написал, есть над чем подумать. Зависеть это будет от того, будем ли мы postres использовать и как часто надо будет переиндексировать, пересобирать индекс в мантикоре, допускаю, что если окажется, что функция постгреса это только источник данных в индекс, а сами данные в pg вообще никак не нужны, то надо и пересмотреть вариант работы с постгрес. Возможно и вариант сборки пересмотреть. Но в любом случае исходные данные на момент обработки будут занимать место.

Например, пока идет активная разработка и тестирование, мне удобнее, чтобы данные лежали рядом, так как это оптимизирует мою эффективность работы с ними, мне так удобнее, чем гоняья гигабайты по интренету, но если все собрано и работает, то это другой сценарий.

Но тут есть еще один серьезный момент: при копировании архивов, они занимают место на сервере, пока идет копирование, и потом пока идет распаковка, т.е. если места в притык, то невозможно загрузить бд (это и к постгрес относится и к мантикоре) и работать с ней, вот поэтому у меня, сейчас на сервер запас 10-13 Гб, который в процессе пересборки занимается почти полностью, и это еще 5Гб на системном свободно. Т.е. если мы опять оставим на сервере притык 200 ГБ мантикоры и случится падение, то возможно придется добавлять диски для загрузки, И уменьшать диски нельзя! Это относится ко сем линукс системам и хостингам. Диски только увеличивают. Или удаляют полностью и затем собирают снова. Его нельзя уменьшить. Т.е. с дисками по любому возня будет. Но вот на процессорах и главное памяти, похоже можно серьезно сэкономить, при ограничениях на поиск, во всяком случае для сервера в интернете, а для сильных духом есть локальная сборка. Ну, или же если в будущем у нас изменяться условия по ресурсам, то сможем снять ограничения или увеличить память/процессоры.

Всё остальное это улучшайзинг и оптимизации, допустим мы их можем делать локально, минимальная схема при полной отсечке всего «ненужного» упирается в размер хранилища в любом случае, независимо от того, как будет оптимизироваться память и процессор. Это очень полезная информация, спасибо.

да

iprst commented 1 year ago

Зависеть это будет от того, будем ли мы postres использовать и как часто надо будет переиндексировать, пересобирать индекс в мантикоре, допускаю, что если окажется, что функция постгреса это только источник данных в индекс, а сами данные в pg вообще никак не нужны, то надо и пересмотреть вариант работы с постгрес. Возможно и вариант сборки пересмотреть. Но в любом случае исходные данные на момент обработки будут занимать место.

тут есть еще один серьезный момент: при копировании архивов, они занимают место на сервере, пока идет копирование, и потом пока идет распаковка, т.е. если места в притык, то невозможно загрузить бд (это и к постгрес относится и к мантикоре)

Если оптимизировать ресурсы прямо квадратно-гнездовым способом, то мы уже пробовали в голую мантикору забрасывать собранную локально базу, при необходимости такой метод можно отработать использовать и на боевом сервере. Локально эта база может собираться вообще любым необходимым образом так как нам это требуется. Это при условии, что у нас боевой сервер представляет собой именно поисковик по текстам в мантикоре.

Например, пока идет активная разработка и тестирование, мне удобнее, чтобы данные лежали рядом, так как это оптимизирует мою эффективность работы с ними, мне так удобнее, чем гоняья гигабайты по интренету, но если все собрано и работает, то это другой сценарий.

Разумеется. Но мы, конечно, не будем просто так забрасывать в разработку 200 Гб текстовых файлов. Это был бы номер. Отработать всё, связанное с текстом и мантикорой, можно на этих 10+ Гб, мы сделали ступенчатый прогресс — испытали 50 книг, затем 200 книг, затем 8000 книг, и теперь вполне представляем, что такое 150000 книг. Нам для непосредственной разработки всего этого не требуется их даже никуда загружать, мы уже знаем примерные границы того, что ожидать — в двадцать раз медленнее, чем сейчас, в двадцать раз больше места. Но это ничего, это вполне нормальные, условно рабочие условия. Теперь можно оптимизировать как угодно схему с 8000 книг, зная, что схема со 150000 будет в двадцать раз медленнее. При этом очевидно, что память будет играть какую-то роль, но не решит вообще всю эту проблему в целом, если конечно не покупать сервер с 384 Гб оперативной памяти (но даже это в теории решаемо).

Как-то так. В общем, с двух сторон более-менее картинка сложилась.

audetv commented 1 year ago

Как-то так. В общем, с двух сторон более-менее картинка сложилась.

Да, согласен.

И когда метод будет полностью отработан, я его доведу до автоматизма, то точно будет проще. Т.к. у нас будет и дальнейшее обновление баз, то придумываю метод, как обновлять БД, не перегружая её всю заново, т.к. 200-300-500 Гб датасеты пересобирать будет долго, понятно, что это не критично и пусть будет долго, если это будет автоматически, в общем улучшения просятся, и думаю в эту сторону. И пока надежда у меня на distributed table

iprst commented 1 year ago

Что касается «оракула» в этой ситуации, то представляется, что оптимизировать можно впоследствии и в другом измерении — локально исходя из задач можно разбить книги (вернее параграфы) на две категории: «полезные» и «бесполезные». Для каждой задачи, ну например географии, нам не потребуются все параграфы, поскольку нам практически ничего не дают параграфы, которые не содержат каких-то топонимов или координат. Равно для других схем работы это условие сохраняется — для «исторической библиотеки» практически бесполезны параграфы, в которых нет дат либо имён, и тд. В общем, для каждого метода существуют условия, которые мы можем спокойно обработать локально и не тягать ненужную информацию.

audetv commented 1 year ago

Что касается «оракула» в этой ситуации, то представляется, что оптимизировать можно впоследствии и в другом измерении — локально исходя из задач можно разбить книги (вернее параграфы) на две категории: «полезные» и «бесполезные». Для каждой задачи, ну например географии, нам не потребуются все параграфы, поскольку нам практически ничего не дают параграфы, которые не содержат каких-то топонимов или координат. Равно для других схем работы это условие сохраняется — для «исторической библиотеки» практически бесполезны параграфы, в которых нет дат либо имён, и тд. В общем, для каждого метода существуют условия, которые мы можем спокойно обработать локально и не тягать ненужную информацию.

Вот, спасибо, несколько дней смотрю на один сайт, читал документацию, изучал, и там есть в примерах метод поиска в тексте сущностей: персоны, места и организации. Мы ранее о чем то таком обсуждали в разных issue. И я думал, как мы можем это применить (уже понял, что надо будет еще питон изучать потихоньку), и вот теперь и от вас подтверждение мыслей есть:

Распознавание именованных сущностей https://demo.deeppavlov.ai/#/ru/ner

Я брал и вводил текс произвольно из параграфов с https://lib.svodd.ru в поле введите текст.

Интересные результаты.

iprst commented 1 year ago

метод поиска в тексте сущностей: персоны, места и организации. Мы ранее о чем то таком обсуждали в разных issue

Да, обсуждали. Есть естественно сложенный корпус сущностей, исходя из приоритетов ОСУ.

Хронологический — все формы оглашения дат. Фактологический — люди, события, объекты, координаты, топонимы, сценарии.

Всё это мы обсуждали, вариантов много, но главное то, что число их конечно и поддаётся анализу.

По сути фактологический + хронологический это один общий приоритет «материальных квитанций», и поскольку в концепции достаточно мало уделено внимания тому, что всё происходящее связано не столько ГИП, сколько планетой, мы можем это расширить: фактохронологический приоритет это по сути всё что касается материи, но не просто материи, а индексированной материи. То есть мы говорим о структуре! Иными словами этот индекс состоит из адресов — наименований сущностей — если есть сущность и у неё есть имя, здравствуйте, вы в индексе.

Это даты, места, объекты, люди. И далее ряд продолжается.

Откуда взять индекс времени? Это даты. Откуда взять индекс пространства? Это топонимы и координаты. Отккуда взять индекс акторов? Это имена людей, героев, архетипов и персонажей.

Три эти индекса составляют собой индекс «материальных» событий, абсолютно все из элементов индекса по определению имеют названия. При этом очевидно, что общее количество записей в индексах строго ограничено: топонимов всего несколько миллионов, слов в русском и английском языке всего полмиллиона, дат за время ГИП существовует всего менее трёх миллионов (столько в ГИП было дней-дат), плюс даже в самых щедрых прогнозах можно накинут ещё 100 тысяч дат вне ГИП.

В общем и целом это составляет 12 + 0,5 + 2,5 + 0,1 = 15 миллионов записей в «материальном индексе». Это даже меньше, чем в текущей библиотеке.

Даже если мы будем брать не топонимы, а скажем геохэши, то мы можем варьировать их размер и тем самым ограничивать базу так, как нам надо — например вся суша Земли кодируется всего 15 миллионами геохэшей размером 10 км²,

По полученными из практики данным всё это вполне рабочая технологическая схема. Нужно просто собрать эти базы. Библиотеки — это первый шаг в сторону формирования этих индексов.

iprst commented 1 year ago

Распознавание именованных сущностей https://demo.deeppavlov.ai/#/ru/ner

Я брал и вводил текс произвольно из параграфов с https://lib.svodd.ru в поле введите текст.

Да, отлично. Это буквально то, что ранее обсуждали с геохэшами, с топонимами и словарём русского языка, и о датах. Проиндексируем сущности, а затем найдём их в корпусе текстов.

audetv commented 1 year ago

Запустил на боевом сервере Indexer. Так как индекс уже существует, то предлагает запустить с опцией --rotate docker compose exec -it manticore-container indexer common_library --rotate

Или надо удалить весь индекс. Остановить мантикору, удалить данный с volume и запустит индексацию

Я не стал это делать, т.к. хотел проверить опцию --rotate, чтобы проверить 2 сценария, оба подтвердились, итого:

indexer успешно работал на боевом сервере, процессоров было занято примерно 1-1.5 в процессе, т.е. еще оставался запас для других сервисов (они у нас не такие загруженные), памяти было затрачено чуть больше 500 мб в сумме:

2023-07-08_21-04-47

сервер жил, но пришлось остановить процесс, так как rotate буквально создает параллельный индекс рядом, и занимает столько же диска, которого был запас всего 13 Гб, поэтому на 50 % остановил, чтобы не вводить сервер в аварийный режим. Т.к. и так понятно,

  1. что метод работает.
  2. для обновления индекса поверх существующего, чтобы не останавливать сервер, нужен запас дисков в размере текущего индекса.

В общем то, все более менее понятно.

audetv commented 1 year ago

Не про ресурс.

По сути фактологический + хронологический это один общий приоритет «материальных квитанций», и поскольку в концепции достаточно мало уделено внимания тому, что всё происходящее связано не столько ГИП, сколько планетой, мы можем это расширить: фактохронологический приоритет это по сути всё что касается материи, но не просто материи, а индексированной материи. То есть мы говорим о структуре! Иными словами этот индекс состоит из адресов — наименований сущностей — если есть сущность и у неё есть имя, здравствуйте, вы в индексе.

Это даты, места, объекты, люди. И далее ряд продолжается.

Откуда взять индекс времени? Это даты.

Ваше сообщение заставило меня задуматься над индексом времени, размышлял, мне видится, что время — это квитанция процесса, в котором участвует планета, буквально обороты вокруг оси и вокруг Солнца и т.д. т.е. квитанция с материи. Т.е. как вы и пишите, что факто и хронологические приоритеты — общий приоритет, и как минимум свзь времени выражается через процесс движения планеты, мы опять приходим к планете, как исходной суперситеме. Я не знаю как мы это можем применить в геоматрице, возможно никак, но эта мысль про время меня сегодня не отпускала)

iprst commented 1 year ago

Предлагаю ответвить про индексы отдельно, отвечу сразу там.

iprst commented 1 year ago

Запустил на боевом сервере Indexer.

Возможно операции стали причиной падения сервиса коротких ссылок? Или что-то другое случилось:

image

audetv commented 1 year ago

Да, спасибо, я тоже заметил и сейчас обновил конфигурацию, чтобы сервис рестартовал постоянно пока не запустится, ранее стоял режим 5 попыток и все, я сейчас даже не помню почему так сделал. А не работали ссылки 11 часов... Утром делал перезагрузку всего сервера, перед манипуляциями, и контейнер с бд почему-то не успел запуститься за 120 сек, кол-во попыток запуска было исчерпано и сервис отдыхал... Исправил, теперь будет подниматься до победного конца)

iprst commented 1 year ago

Утром делал перезагрузку всего сервера, перед манипуляциями, и контейнер с бд почему-то не успел запуститься за 120 сек, кол-во попыток запуска было исчерпано и сервис отдыхал...

У меня подобная ситуация была с базой постгрес в локальном проекте 8480 — какая-то служба в винде легла спать, и постгрес исчерпав три попытки запуска тоже не стал запускаться. Вопрос решился просто нахождением этой службы и перезапуском её, после чего вручную запустил постгрес, но это логику запомнил: «иногда службы падают и ничего не говорят». Вероятно из классических примеров «даже бабушка моего кота это знает».

PS. Да, короткие ссылки вновь работают!