хранение индекса, проблемы

12
GW
На сайте с 11.01.2003
Offline
45
3057

Здравствуйте

Пишу поисковую систему, есть пара вопросов :)

Раньше хранил индекс в одном файле.

Структура примерно такая:

word_id1 : resource_id1 : page_id1

word_id1 : resource_id1 : page_id2

...

word_id1 : resource_id2 : page_id1

...

word_id2 : ....

но как только размер индекса перевалил за 4 гига, пришлось искать альтернативу

Как вариант сейчас тестирую такой:

создаём файловую структуру:


word_id1
resource_id1
pages.index1
resource_id2
pages.index2
...

word_id2
resource_id1
pages.index1
...
...

pages.indexN - это список страниц, ресурса с resource_idN, где встречается данное слово word_idN

однако есть некоторые загвоздки и куча вопросов.

(Количество файлов в данной структуре, сейчас получилось 20 миллионов, это на 500 000 проиндексированных страниц.)

1. Оптимально ли хранить индекс в таком виде, и не будет ли слишком долго из него считывать файлы. Файловая система Raiserfs

2. Спайдер, и индекс по которому будет производится поиск, разнесены по разным серверам. Как можно безболезненно синхронизировать такое количество файлов? Вернее, даже так - как вообще их можно синхронизировать? Пробовал через rsync - умирает :) Пробовал паковать архиватором чтобы потом просто скопировать на другой сервер, тоже умирает. Пробовал по ftp передавать - ооочень долго если консольным. Если пытаться каким нибудь клиентом, типа filezilla - то они тоже умирают

Подскажите, в какую сторону копать, что делать, и имеет ли право на жизнь такая структура индекса ?

Заранее спасибо

Сам пришел
На сайте с 05.05.2007
Offline
174
#1

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

GW
На сайте с 11.01.2003
Offline
45
#2

Форум для того и существует, чтобы можно было обсудить и узнать чужое мнение. Разве нет? :)

Меня просто гложут смутные сомнения, что я что-то упускаю. Понятно, что оно и так будет работать, но душа требует более идеального решения :)

VT
На сайте с 27.01.2001
Offline
130
#3
1. Оптимально ли хранить индекс в таком виде, и не будет ли слишком долго из него считывать файлы. Файловая система Raiserfs

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

2. Спайдер, и индекс по которому будет производится поиск, разнесены по разным серверам. Как можно безболезненно синхронизировать такое количество файлов? Вернее, даже так - как вообще их можно синхронизировать? Пробовал через rsync - умирает Пробовал паковать архиватором чтобы потом просто скопировать на другой сервер, тоже умирает. Пробовал по ftp передавать - ооочень долго если консольным. Если пытаться каким нибудь клиентом, типа filezilla - то они тоже умирают

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

O
На сайте с 21.05.2007
Offline
13
#4

Что можно:

1. хранить индекс не в одном файле и не в одном файле на слово, а, например, файл на 256 слов.

Такой индекс сложнее обрабатывать, но удобнее использовать для поиска (нагрузка на файловую систему меньше)

Готовый файл индекса можно и сжать - больше нагрузка на проц, меньше - на ввод-вывод (если там узкое место)

2. сделать чтобы на каждой машине - свой кусок индекса и свой паук - тогда передача будет и вовсе не нужна;

если же захотите избыточность - передача снова потребуется; заметим, что rsync - достаточно сложный протокол,

который сам находит, что изменилось и передаёт разницу; может быть, (вычислительно) проще будет передавать

изменения, зная, что изменилось (процесс инициирует соединение, передаёт имя изменённого файла, его длину

и само содержимое файла - проще даже чем ftp).

3. прямой индекс преобразовывать в обратный только для не очень часто обновляемых страниц; 1-2% самых

"горячих" оставлять в прямом индексе - пока не остынут - позволит как избежать слишком частого перестраивания

индексов, так и перестраивать его не для каждого текста, а как накопится штук так 256. Поиск, соответственно,

проводится как по прямому, так и по обратному индексу, результаты объединяются. Побочный эффект - файл

появляется в поиске сразу же, как до него добредёт паук.

xant
На сайте с 17.12.2008
Offline
65
#5

(имхо) не изобретайте велосипед, а переложите подобные заботы на базу данных. Если не создавать лишних индексов и смоделировать в БД аналог структуры типа "файл", можно выжать очень высокую производительность за счет продвинутых алгоритмов бд (Б* деревья, продвинутые кэши и т.п.)

Эксклюзивные сайты и веб-2.0 приложения под ключ. Дорого.
O
На сайте с 21.05.2007
Offline
13
#6
xant:
(имхо) не изобретайте велосипед, а переложите подобные заботы на базу данных. Если не создавать лишних индексов и смоделировать в БД аналог структуры типа "файл", можно выжать очень высокую производительность за счет продвинутых алгоритмов бд (Б* деревья, продвинутые кэши и т.п.)

Речь идёт ведь об обратных списках?

Если хранить вхождения в __обычных__ таблицах, то в таблице должно быть (в простом случае) 3 поля

[text_id] [word_id] [position]

итого, 3 числа на запись (не считаем байты)

при хранении в файле, путь до которого взаимно-однозначно соответствует word_id,

остаётся только два числа;

по мере роста индекса растёт не столько число таких файлов (за счёт новых слов), сколько их размер;

тогда издержки файловой системы состоят из двух частей - путь до файла и набор кластеров файла;

первая часть - константа, вторая - не более процента от объёма; в таком случае при росте индекса

отношение объёмов стремится к 3/2.

Причём файловая система очень хорошо оптимизирована для операции "взять файл по имени и читать его подряд",

а именно так и производится поиск списка документов/вхождений (в первом приближении список и есть результат).

Слияние списков также не противоречит данному подходу - параллельно читаются два заранее известных файла,

каждый из которых читается последовательно.

В базе данных требуется индекс чтобы просто найти вхождения одного слова. То есть сначала ищутся

вхождения word_id в записи таблицы, а потом читаются из этих записей text_id и position.

При простом индексировании (слова заносятся в порядке их нахождения в тексте) вхождения будут разбросаны

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

Отношение объёма при наличии индекса уже в районе 2/1 и прибавки скорости на поиске по сравнению

с файлами не даст. Без индекса работа с такой таблицей практически невозможна (медленнее на порядки)

и сравнима с прямым поиском.

При создании же на основе базы данных файловой системы, мы вынуждены хранить собственно данные в полях типа

blob, что не даст выигрыша по сравнении с файловой системой на операции поиска, но сильно усложнит доступ к данным.

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

текстов, веса, служебную информацию для пауков и распределение данных по узлам кластера.

U
На сайте с 17.01.2009
Offline
9
#7

Можно использовать нереляционную базу данных типа couchdb или еще какуюнить построенную на tokyo kabinet.

S
На сайте с 02.04.2009
Offline
1
#8

Страшно представить объем работы, за которую вы взялись...

DM
На сайте с 03.05.2009
Offline
3
#9
Sevruk:
Страшно представить объем работы, за которую вы взялись...

это зависит от сложности поисковика. Похвально если кто-то хочет переплюнуть гугл или яндекс!

forum.searchengines.ru (forum.searchengines.ru)
K
На сайте с 27.11.2000
Offline
80
#10
Golden Wolf:
Здравствуйте
Пишу поисковую систему, есть пара вопросов :)
Как вариант сейчас тестирую такой:
создаём файловую структуру:


word_id1
resource_id1
pages.index1
resource_id2
pages.index2
...

word_id2
resource_id1
pages.index1
...
...


Подскажите, в какую сторону копать, что делать, и имеет ли право на жизнь такая структура индекса ?

Сначала, мне кажется, надо зарыть то, что уже выкопано. А потом сложить всё в один или несколько файлов. А к ним сделать оглавление. Типа "с позиции такой-то по такую-то лежат номера документов, содержащих слово <жопа>, в порядке возрастания".

Это решит массу твоих проблем.

С уважением, Андрей Коваленко aka Keva
12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий