LINUX.ORG.RU

Реактивный поиск

 , fgrep,


4

6

Есть данные - миллиард строк в utf-8, для начала. Потенциально - 5-10 миллиардов. Простые строки.
Есть задача - быстро выбирать по этим данным. Желательно с любыми условиями, вплоть до регулярок.

grep/fgrep не подошли из-за скорости.
Начал пробовать elasticsearch, который на лоре как раз используют. Сначала радовал шустростью, но на импорте где-то 150кк записи начал адово тормозить. Но на тех данных, что он смог импортировать - скорость радует.

Может я куда-то не туда копаю и есть более очевидное решение этой задачи?

Вопрос 2 (очень важный): если я в elasticsearch залью все подряд данные с автогенерируемым _id, как я могу потом почистить базу от неуникальных значений?

P.S. Бонус - если рекомендуемое вами решение позволит контролировать уникальность строк (мне это крайне необходимо), то будет вобще супер. Сейчас приходится кормить elasticsearch данные в виде _id = string, видимо поэтому он так сильно тормозит.

★★☆☆

Последнее исправление: xtraeft (всего исправлений: 4)
Ответ на: комментарий от bj

Если выгрузка одноразовая, то можно и потерпеть.

Не одноразовая, иначе я бы просто сделал sort -u один раз для данных, которые нужно импортировать.

Если каждый день такие объемы, то тут или привинчивать дедупликацию при выборке, или препроцессить на хадуп кластере.

Объемы такие не каждый день, нужно залить 1-2 миллиарда, а потом максимум миллионов по 100 пару раз в месяц.

xtraeft ★★☆☆
() автор топика
Ответ на: комментарий от maxcom

Не получается.

{"error":"ProcessClusterEventTimeoutException[failed to process cluster event (close-indices [keywords]) within 30s]","status":503}

xtraeft ★★☆☆
() автор топика
Ответ на: комментарий от Hertz

ack, ack-grep. Замечательная грепалка.

Несмотря на то, что тред совсем не об этом, решил провести эксперимент. Результат тебя расстроит:

time fgrep 'word' file.uniq > fgrep

real	1m6.933s
user	0m17.989s
sys	0m10.729s

time ack 'fgrep' file.uniq > ack

real	8m58.759s
user	8m40.600s
sys	0m16.383s

Файл небольшой, около 400 миллионов строк.

xtraeft ★★☆☆
() автор топика

Бонус - если рекомендуемое вами решение позволит контролировать уникальность строк (мне это крайне необходимо), то будет вобще супер. Сейчас приходится кормить elasticsearch данные в виде _id = string, видимо поэтому он так сильно тормозит.

_id = sha1(string) и не париться, не?

x3al ★★★★★
()
Ответ на: комментарий от xtraeft

Эмм. id тебе нужен для контроля уникальности, не? sha1() — быстрый хэш (если у тебя говно мамонта, можно думать о md5, но рискуешь нарваться на коллизии). А проблемы со скоростью в том числе потому, что у тебя слишком длинный _id, который должен быть уникален: проверка на уникальность может есть слишком много RAM либо я ничего не понимаю во внутренней магии elasticsearch.

Посчитать sha1 будет на порядок быстрее, чем раздувать индекс _id имхо.

x3al ★★★★★
()
Ответ на: комментарий от Deleted

как это будет обрабатывать модуль полнотекстового поиска конечно непонятно

Уже понятно. Попробовал проиндексировать и повыбирать

Пробовал на рандомных строках от 10 до 256 символов длиной, типа такого:

njxw nmm uf fici cklw  xkb  xjdki djgy  c qgxqvbfa jugs pvathjsakk ks   labolmfs   phexaacjksvdijiikc

Насколько я понимаю то что там внутри творится, это довольно плохой случай для полнотекстового поиска

Индексация проходит мучительно долго - gin индекс для 10**6 строк строится около 400 секунд. gist быстрее где-то в два раза

А вот выборки довольно быстрые: для тех же 10**6 записей и gin-индексов с несколькими результатами в выборке время около 0.3-0.4 мс

То есть с такими параметрами партиционирования выборка из 10**9 записей должна быть где-то 0.3-0.4 секунды

Понятно что ТС такое не устроит(см. «Поиск средствами бд проигрывает в разы-порядки поиску сфинксом/эластиком и подобными»), но мне было интересно самому убедиться насколько все плохо и почему нельзя пользоваться СУБД для таких задач

Deleted
()
Ответ на: комментарий от Deleted

Интересный комментарий, спасибо.

xtraeft ★★☆☆
() автор топика
Ответ на: комментарий от Hertz

Я опечатался конечно же, там не «time ack 'fgrep' file.uniq > ack», а «time ack 'word' file.uniq > ack»

xtraeft ★★☆☆
() автор топика
Последнее исправление: xtraeft (всего исправлений: 1)
Ответ на: комментарий от Deleted

Хм, потестил на таблице из ~60 миллионов записей с именами (Имя + Фамилия). Запросы типа @@ ts_query('russian', 'Попов & Иван') выполняются 50-100 мс.

Когда последний раз тестил было намного хуже. Здорово.

pi11 ★★★★★
()
Ответ на: комментарий от xtraeft

а потом максимум миллионов по 100 пару раз в месяц.

Но выборки нужны по всему объему? Месячные партиции не вариант?

bj
()
Ответ на: комментарий от bj

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

xtraeft ★★☆☆
() автор топика
Последнее исправление: xtraeft (всего исправлений: 2)
Ответ на: комментарий от bj

без индексов

не поленись добавить уникальный индекс и повтори

Не, надо было так: не поленись сделать обычную непартиционированную таблицу с уникальным индексом и повтори

Deleted
()
Ответ на: комментарий от Deleted

обычную непартиционированную таблицу с уникальным индексом

Это само собой. Иначе какой смысл?

bj
()
Ответ на: комментарий от xtraeft

Не совсем. БД хранит, поисковик ищет по ней. Каждый занимается своей работой.

anonymous
()
Ответ на: комментарий от pi11

Никак не сделал, забил пока. Залил кусок на 400 миллионов без проверки уникальности, но это не вариант.

xtraeft ★★☆☆
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.