эффективный парсинг
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
эффективный парсинг
Каким наиболее эффективно сделать следующее...
Процесс (назовем его процесс А) получает текстовую информацию. Блоками. Каждый блок имеет уникальный ID плюс непосредственно само тело, содержащее информацию. Информация сохраняется в базе данных.
Нужно : Отпарсить каждый блок по словам и запомнить вхождение каждого слова в блок. Это нужно для последующего поиска слов. Грубо говоря допустим создать multimap, Ключ - слово, значение - индекс блока, в котором слово найдено.
Что пришло на ум навскидку...
1. Создать отдельный поток, которому передавать индекс каждого нового блока и само тело. Поток отпарсит тело и сохранит результаты в каком нибудь мультимапе. Сразу возникает вопрос, а не получится ли так, что пока рабочий поток парсит тело, то произойдет переключение проца на основной поток и оставшаяся неотпарсенная информация потеряется?
2. Создать отдельный процесс "В", который будет этим заниматся. Тогда где лучше всего хранить результаты, потому что они будут нужны процессу "А" позже. Как лучше передавать параметры в процесс В из процесса А?
Также нужно иметь что то наподобие backup in case of failure когда процесс А упал (или В во втором случае) и надо восстановить будет то, что было отпарсено.
Собственно для чего это надо... Full text search который в SQL Server индексирует информацию недостаточно быстро и за асинхронности этого индексирования. Нужно создать своеобразный мост, который бы индексировал все синхронно и быстро все истории в течение первых пяти минут. Потом уже есть высокая гарантия того, что сиквельный full text search к тому времени проиндексирует то что надо...
Какие будут идеи по этому поводу, может кто уже делал что то подобное:)
Процесс (назовем его процесс А) получает текстовую информацию. Блоками. Каждый блок имеет уникальный ID плюс непосредственно само тело, содержащее информацию. Информация сохраняется в базе данных.
Нужно : Отпарсить каждый блок по словам и запомнить вхождение каждого слова в блок. Это нужно для последующего поиска слов. Грубо говоря допустим создать multimap, Ключ - слово, значение - индекс блока, в котором слово найдено.
Что пришло на ум навскидку...
1. Создать отдельный поток, которому передавать индекс каждого нового блока и само тело. Поток отпарсит тело и сохранит результаты в каком нибудь мультимапе. Сразу возникает вопрос, а не получится ли так, что пока рабочий поток парсит тело, то произойдет переключение проца на основной поток и оставшаяся неотпарсенная информация потеряется?
2. Создать отдельный процесс "В", который будет этим заниматся. Тогда где лучше всего хранить результаты, потому что они будут нужны процессу "А" позже. Как лучше передавать параметры в процесс В из процесса А?
Также нужно иметь что то наподобие backup in case of failure когда процесс А упал (или В во втором случае) и надо восстановить будет то, что было отпарсено.
Собственно для чего это надо... Full text search который в SQL Server индексирует информацию недостаточно быстро и за асинхронности этого индексирования. Нужно создать своеобразный мост, который бы индексировал все синхронно и быстро все истории в течение первых пяти минут. Потом уже есть высокая гарантия того, что сиквельный full text search к тому времени проиндексирует то что надо...
Какие будут идеи по этому поводу, может кто уже делал что то подобное:)
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
Dmitry67 wrote:Меня заинтересовало последнее время большое число задач с real time full text
А не опишите почему real time так важен ? Какая задержка считается неприемлимой ?
Самое интересное, что дай кастомеру transactional и synchronous FTS (что не такая уж и проблема) - тоже ведь комплайнов не оберешься. Начнут на блокировки, к примеру, жаловаться.
Эти задачи в другой плоскости решать надо. Тачанку многопроцессорную, быструю, памяти побольше. Развести процессы по разным процессорам, если MS Search страдает от жадности SQL Server'а. Поднять значение resource_usage. Отнять память у SQL Server'а. Уменьшить нагрузку на него. Диски быстрые поставить.
Глючные фильтры производителей (из-за которых индексировать иногда приходится в однопоточном режиме) заменить своими собственными, надежными, или поменять формат хранимых данных (например, вместо .PDF вести документацию в .DOC)
Пользователя тренировать, чтобы чудес не ждал. Хотя пять минут - это уж чересчур. За секунды уходить должно.
Вообще, крупным заказчикам, как оказывается, не нужна синхронность и офигенное время реакции для change tracking. Поэтому и не делаем.
Увидев друга, Портос вскрикнул от радости...
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Спасибо за ответы. Картина вот какая.
Сидит аналитик, у него куча программ, которые валят ему информацию. В основном текстовую (типа Блумберга). Ему нужно за короткий срок проанализировать информацию и выдать результат.
У него стоят фильтры конечно. Но все равно аналитику свойственно допустим что то пропустить, какую то информацию. Он "чувствует" что информация была, но он не знает где она, потому что информации тонны.. он запускает поиск допустим "IBM" и хочет получить все новости которые содержат слово IBM хотя бы раз.
Full text search работает очень хорошо, но недостаточно быстро. Время реагирования (время индексирования) должно идти на секунды. Иногда требуется, чтобы информация была проиндексирована буквально за секунду после того как она пришла. Это очень критично. Шеф говорит что аналитики жалуются, что информация не индексируется в течение двадцати минут, но я считаю что это полная чушь. Они что то не то делают значит. Я проводил тест. Максимум у меня история появилась в результате поиска через минуту после того как она пришла в базу... НО минута это все равно критично...
Памяти добавили на машине до двух гигов, Сиквел процесс ограничил я одним гигом, не более. Процессор один - четвертый пень, 2.4 гига. Дисковый массив - Raid 5, 7200 RPM.
Вот я и подумал, пусть мое приложение индексирует само входящие истории, хотя бы те, которые приходят в течение пяти минут.
Конечно пока не будет работать такие фичи как частичный поиск слов когда часть слова заменяется астериксом, но все же хочется попробовать.
Full text search я буду использовать как базу для более глобального поиска, в архивах например, но мгновенную индексацию все же хочу попробовать делать сам. Поглядеть справится ли:)
Сидит аналитик, у него куча программ, которые валят ему информацию. В основном текстовую (типа Блумберга). Ему нужно за короткий срок проанализировать информацию и выдать результат.
У него стоят фильтры конечно. Но все равно аналитику свойственно допустим что то пропустить, какую то информацию. Он "чувствует" что информация была, но он не знает где она, потому что информации тонны.. он запускает поиск допустим "IBM" и хочет получить все новости которые содержат слово IBM хотя бы раз.
Full text search работает очень хорошо, но недостаточно быстро. Время реагирования (время индексирования) должно идти на секунды. Иногда требуется, чтобы информация была проиндексирована буквально за секунду после того как она пришла. Это очень критично. Шеф говорит что аналитики жалуются, что информация не индексируется в течение двадцати минут, но я считаю что это полная чушь. Они что то не то делают значит. Я проводил тест. Максимум у меня история появилась в результате поиска через минуту после того как она пришла в базу... НО минута это все равно критично...
Памяти добавили на машине до двух гигов, Сиквел процесс ограничил я одним гигом, не более. Процессор один - четвертый пень, 2.4 гига. Дисковый массив - Raid 5, 7200 RPM.
Вот я и подумал, пусть мое приложение индексирует само входящие истории, хотя бы те, которые приходят в течение пяти минут.
Конечно пока не будет работать такие фичи как частичный поиск слов когда часть слова заменяется астериксом, но все же хочется попробовать.
Full text search я буду использовать как базу для более глобального поиска, в архивах например, но мгновенную индексацию все же хочу попробовать делать сам. Поглядеть справится ли:)
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
shadow7256 wrote:Сидит аналитик, у него куча программ, которые валят ему информацию. В основном текстовую (типа Блумберга).
[...]
Full text search работает очень хорошо, но недостаточно быстро. Время реагирования (время индексирования) должно идти на секунды.
[...]
Я проводил тест. Максимум у меня история появилась в результате поиска через минуту после того как она пришла в базу...
В одну минуту я еще могу поверить, зависит, в частности, от нагрузки на сервере.
Я предполагаю, что у вас включен автоматический change tracking. В этом случае информация об изменениях (table ids, full-text key values) складывается в специальную таблицу. Каждую секунду просыпается задача, которая вытягивает первые 256 (по-моему, число я правильно помню) notifications и посылает их MS Search. При частых обновлениях мы можем не успевать, и notifications будут накапливаться независимо от того, как быстро MS Search их индексирует. Проверьте, сколько записей в sysfulltextnotify.
Далее, поясните, что вы имеете в виду под "текстовой" информацией. Файлы MS Word тоже содержат текст, но индексируются медленнее, чем "просто" текст. Если вы храните данные в колонке типа image и указываете doctype column, вам не повезло, т.к. будут дополнительные тормоза - перед индексированием эти данные сваливаются на диск, потом чистятся. Если же это колонка типа (n)varchar или (n)text - будет быстрее.
Last edited by 8K on 18 May 2004 19:18, edited 1 time in total.
Увидев друга, Портос вскрикнул от радости...
-
- Уже с Приветом
- Posts: 23804
- Joined: 05 Jul 2003 22:34
- Location: Брест -> St. Louis, MO
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
katit wrote:А если ставить timestaps на каждую запись и Делать FTS индексирование пофиг когда.
Изменить процедуру поиска. Т.е. смотреть "старые" записи через FTS а "новые" через LIKE ?
LIKE искать внутри image не умеет, да и вообще тормозит. timestamp column не надо, т.к. кто за ней следить будет? Уж лучше выгребать новые (еще не проиндексированные) записи из sysfulltextnotify.
Как вариант, если секунды так уж критичны (хотя я слабо представляю себе аналитика, которые каждую секунду кнопку давит, чтобы получить самый свежий результат) - сделайте change tracking manual вместо auto и повесьте на шедулера (SQL agent) задачу, которая пропихивает все notifications сразу.
Увидев друга, Портос вскрикнул от радости...
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
shadow7256 wrote:Если не сработает, то попробую вариант от 8К
Только учтите что LIKE работает со строками
Так что решение от 8K работает только если текст не длиннее 8K
Ну или нарезан кусочками
А про аналитика который давит кнопку каждую секунду все равно непонятно
Зарегистрированный нацпредатель, удостоверение N 19719876044787 от 22.09.2014
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Текст в поле может быть длинее чем 8К, это точно.
Про аналитика суть такая. Сейчас у аналитика есть несколько софтверных приложений типа Bloomberg. Аналитик получает последние финансовые новости от этих приложений. Проблема в том, что он физически не может сконценрировать свое внимание на всех диалоговых приложениях сразу. У него стоят четыре монитора, и на каждом по две аппликации...
Я написал аппликацию, которая объединяет в себе несколько источников (пока два, но добавить еще не проблема). В итоге вместо двух диалоговыхз приложений аналитик смотрит в одно куда ему сыпятся новости из обоих источников и сыпятся очень быстро. Сыпятся только заголовки конечно, но если надо аналитик может достать всю статью целиком..
Ну так вот.. допустим аналитик отвлек свое внимание на пару секунда от монитора, в этот момент навалились какие то новости и одна новость очень важная, но аналитику некогда просматривать все заголовки которые он пропустил, на это уйдет очень много времени..
Аналитик запускает поиск и допустим вводит слово Microsoft в качестве поиска.. Ему конечно вываливаются статьи которые содержат это слово, но очень часто бывает что нет СОВСЕМ свежих статей, по причине того, что они еще не проиндексировались сервером... Аналитик точно знает что статьи есть, мы пока дублируем себя другими источниками.. Но он не может найти.. Статьи начинают появлятся только спустя минуту примерно.. иногда быстрее .. иногда медлеенее.. НО надо как можно быстро, сразу же.. времени ждать нет...
Про аналитика суть такая. Сейчас у аналитика есть несколько софтверных приложений типа Bloomberg. Аналитик получает последние финансовые новости от этих приложений. Проблема в том, что он физически не может сконценрировать свое внимание на всех диалоговых приложениях сразу. У него стоят четыре монитора, и на каждом по две аппликации...
Я написал аппликацию, которая объединяет в себе несколько источников (пока два, но добавить еще не проблема). В итоге вместо двух диалоговыхз приложений аналитик смотрит в одно куда ему сыпятся новости из обоих источников и сыпятся очень быстро. Сыпятся только заголовки конечно, но если надо аналитик может достать всю статью целиком..
Ну так вот.. допустим аналитик отвлек свое внимание на пару секунда от монитора, в этот момент навалились какие то новости и одна новость очень важная, но аналитику некогда просматривать все заголовки которые он пропустил, на это уйдет очень много времени..
Аналитик запускает поиск и допустим вводит слово Microsoft в качестве поиска.. Ему конечно вываливаются статьи которые содержат это слово, но очень часто бывает что нет СОВСЕМ свежих статей, по причине того, что они еще не проиндексировались сервером... Аналитик точно знает что статьи есть, мы пока дублируем себя другими источниками.. Но он не может найти.. Статьи начинают появлятся только спустя минуту примерно.. иногда быстрее .. иногда медлеенее.. НО надо как можно быстро, сразу же.. времени ждать нет...
-
- Уже с Приветом
- Posts: 433
- Joined: 26 Oct 2003 23:09
- Location: MA. USA
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 23804
- Joined: 05 Jul 2003 22:34
- Location: Брест -> St. Louis, MO
-
- Уже с Приветом
- Posts: 9392
- Joined: 18 Mar 2004 15:11
- Location: New York -> FL
Насчет цветовых гамм все сделано Все выводится как надо, разноцветным.
Насчет в туалет - можно. Аналитиков двое.
Насчет памяти .. я об этом и говорю вообще то. Но держать в памяти все новости было бы нецелесообразно. Держить ID новостей еще можно, в случае поиска нашел все ID новостей которые содержат то или иное слово и передал клиенту, а тот уже выберет заголовки из базы.
Вообщем я тут тестировал продукт норвежской компании IMP которая якобы заменяет full text search в SQL Server... да уж. Такое любой школьник напишет в качестве лабораторной работы. Поиск фраз - отсуствует.. поиск частичных слов - отсутствует... предикаты - отсутствуют.. Ищет толко целое слово и все. Да нафиг такой нужен... обещают в след. релизе все это сделать. ТОлько когда он будет - неизвестно...
Вообщем буду пытатся внедрять свои идеи.. для начала сделаю парсинг в главном потоке, посмотрю как он справлятся будет. Если будет медленно. то придется думать о многопоточности уже..
Насчет в туалет - можно. Аналитиков двое.
Насчет памяти .. я об этом и говорю вообще то. Но держать в памяти все новости было бы нецелесообразно. Держить ID новостей еще можно, в случае поиска нашел все ID новостей которые содержат то или иное слово и передал клиенту, а тот уже выберет заголовки из базы.
Вообщем я тут тестировал продукт норвежской компании IMP которая якобы заменяет full text search в SQL Server... да уж. Такое любой школьник напишет в качестве лабораторной работы. Поиск фраз - отсуствует.. поиск частичных слов - отсутствует... предикаты - отсутствуют.. Ищет толко целое слово и все. Да нафиг такой нужен... обещают в след. релизе все это сделать. ТОлько когда он будет - неизвестно...
Вообщем буду пытатся внедрять свои идеи.. для начала сделаю парсинг в главном потоке, посмотрю как он справлятся будет. Если будет медленно. то придется думать о многопоточности уже..
-
- Уже с Приветом
- Posts: 28294
- Joined: 29 Aug 2000 09:01
- Location: SPB --> Gloucester, MA, US --> SPB --> Paris
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
shadow7256 wrote:Поиск фраз - отсуствует.. поиск частичных слов - отсутствует... предикаты - отсутствуют.. Ищет толко целое слово и все.
Хи-хи. Я вам пятьдесят пять багов в этой аппликухе найду и вы поймете, что целые слова она искать тоже не умеет. Начать можно с различных видов пробелов (например 0x200B/0x00A0), с составных немецких слов и прочей фигни. Не забыть про турецкую i, акронимы и устоявшиеся названия вроде С#, C++. Case/accent sensitivity etc.
Увидев друга, Портос вскрикнул от радости...
-
- Уже с Приветом
- Posts: 12072
- Joined: 17 Nov 2002 03:41
- Location: английская колония
Обычный парсинг будет медленновато.
Я когдато делал реплесмент для гигабайтов текста. Работал очень быстро.
Смысл: аллокируем 64К например, где текст,
первые четыре буквы искомой фразы конвертируем то интегер, и лупим через 4 байта - если совпало - высока вероятность что и остальная часть совпадет - маркаем место, дальше сдвигаем на один байт и опять лупим. 4 раза. Потом промаркованные места внимательно с лупой анализируем.
Зависит конечно че надо найти..
Я когдато делал реплесмент для гигабайтов текста. Работал очень быстро.
Смысл: аллокируем 64К например, где текст,
первые четыре буквы искомой фразы конвертируем то интегер, и лупим через 4 байта - если совпало - высока вероятность что и остальная часть совпадет - маркаем место, дальше сдвигаем на один байт и опять лупим. 4 раза. Потом промаркованные места внимательно с лупой анализируем.
Зависит конечно че надо найти..
Верить нельзя никому - даже себе. Мне - можно!
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
-
- Уже с Приветом
- Posts: 12072
- Joined: 17 Nov 2002 03:41
- Location: английская колония
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
A. Fig Lee wrote:8K wrote:конечный автомат
А что ето?
Издеваетесь, да? Проблема текстового поиска (и замены) обсосана во всех возможных аспектах и подробностях, даже в популярных книжках. А уж про конечные автоматы in general так и вообще стыдно не знать, тем более программисту.
Увидев друга, Портос вскрикнул от радости...
-
- Уже с Приветом
- Posts: 12072
- Joined: 17 Nov 2002 03:41
- Location: английская колония
8K wrote:Издеваетесь, да? Проблема текстового поиска (и замены) обсосана во всех возможных аспектах и подробностях, даже в популярных книжках. А уж про конечные автоматы in general так и вообще стыдно не знать, тем более программисту.
Дык я ж не про стыдно, а про автомат. Может я его знаю, но не знаю, что ето автомат?
Верить нельзя никому - даже себе. Мне - можно!
-
- Posts: 11
- Joined: 04 Apr 2004 01:40
Re: эффективный парсинг
shadow7256 wrote:Каким наиболее эффективно сделать следующее...
Процесс (назовем его процесс А) получает текстовую информацию. Блоками. Каждый блок имеет уникальный ID плюс непосредственно само тело, содержащее информацию. Информация сохраняется в базе данных.
Нужно : Отпарсить каждый блок по словам и запомнить вхождение каждого слова в блок. Это нужно для последующего поиска слов. Грубо говоря допустим создать multimap, Ключ - слово, значение - индекс блока, в котором слово найдено.
Что пришло на ум навскидку...
1. Создать отдельный поток, которому передавать индекс каждого нового блока и само тело. Поток отпарсит тело и сохранит результаты в каком нибудь мультимапе. Сразу возникает вопрос, а не получится ли так, что пока рабочий поток парсит тело, то произойдет переключение проца на основной поток и оставшаяся неотпарсенная информация потеряется?
...
Чтобы ничего не терялось в варианте 1, можно, например, сделать так:
Thread A:
- получает входной блок (сам он не меняется всю дорогу),
делает к нему thread-safe reference counted handle,
запихивает копии хэндлов в очереди подписчиков
(подписчиками здесь будут threads B and C).
Очереди синхронизированы mutex-ом и в них, повторюсь,
лежат не сами блоки, а refcounted handles на них)
Thread B:
- имеет на входе свою очередь из хэндлов на поступающие блоки. Занимается построением того самого multimap.
Обработав блок - уничтожает свой хэндл на блок
Thread C:
- как B, читает из своей входной FIFO очереди хэндлы,
и запихивает в SQL базу соотв блоки с обработкой, убивает хэндл
Thread(s) D ( user thread(s) )
- ищет слово в multimap-е, и если надо - в самой базе. "Multimap" должен быть синхронизирован - есть писатель и "удалятель", pardon, и это узкое место.
Еще надо будет очищать "multimap" (thread C или dedicated thread)
Вместо threads можно использовать процессы и shared memory / in-memory database чтобы делать "multimap", очереди и временно хранить блоки, пока их обрабатывают
параллельно B и C.
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA
-
- Уже с Приветом
- Posts: 5552
- Joined: 20 Mar 2001 10:01
- Location: SFBA