LINUX.ORG.RU

Во что конвертировать огромный, сотни ГБ, CSV-файл для максимально быстрого чтения по «ключу»?

 , , ,


0

3

Есть csv, от десятков ГБ до 1 ТБ, то есть,сильно больше чем моя RAM. В строке таблицы порядка 5 полей. Размер одного поля можно считать нефиксированным, но до 50КБ. Число строк от 100 млн до 2 млрд. Будет именно чтение одним пользователем, никаких записей в файл.

В таблицах есть уникальное поле, «хеш». Во что мне конвертировать csv файл, чтобы максимально быстро получать доступ к строке по индексу?-

А) sql. типа postgre. удобно но эта БД поддерживает многопользовательскую запись, репликации- всё это мне не нужно, оверкилл

Б) sql типа sqllight. на малых объемах летает. но не уверен что она хорошо работает с большими файлами, в том числе сможет быстро создавать индексы

В) nosql база типа mongo?

Г) файлы с индексами - обработка python-ом

Я думаю что вариант Г) - оптимальный. или есть иные варианты? куда именно смотреть?


Ответ на: комментарий от Result-Code

по крайней мере в 2015 писали, что в районе 1 ТБ могут быть проблемы «If you’re under 1 TB of data, Postgres will give you a good price to performance ratio» наверняка сейчас стало лучше. хотелось бы услышать от тех кто гонял такие базы

Tvorog
() автор топика

Если файл уместится в лимит файла для твоей ФС, то sqlite норм
https://www.sqlite.org/whentouse.html#:~:text=An SQLite database is limited,t....


CSV там искаропки поддерживается, поэтому ты в одну команду можешь сделать базу и проверить proof-of-concept уже сегодня.
Но я конечно не верю, что ты сможешь

zolden ★★★★★
()

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

pfg ★★★★★
()

Ну, как выше сказали, PostgreSQL, и неважно про твой написанный оверкилл, ты же не будешь его юзать. Главное правильные индексы сделай под свои поля.

Теоретически можешь ещё попробовать ElasticSearch + Kibana(для красоты). Заодно побенчишь для ЛОРа лучшее из двух решений :)

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

выбери «лутшего»

конфига для одной единственной опробованой бд.

deep-purple ★★★★★
()

Разместить в памяти (заранее подготлвить и грузить его с диска) вектор пар хэш:смещение в исходном файле (отсортированный по хэшам) и делать в нем поиск половинным делением. Если не лезет в память отмапировать с диска.

Исходный толстый файл и вектор разместить на ssd.

Если будет тормозить можно поиск по вектору переписать на плюсах.

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

Что подразумевается под «уметь хеши»?
Судя по описанию, это же просто готовое текстовое поле, движку ничего не надо вычислять самому для его заполнения

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

спасибо! звучит интересно. может уже что то сделано? «Разместить в памяти вектор пар хэш:смещение»

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

Конечно сделано, так БД работают:-)

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

Это меньше 100 строк кода и хорошее упражнение, если такого раньше не делали.

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

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

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

поскольку у меня индекс в память не влезает - желательно бы еще и patitioning уметь делать. ClickHouse вроде делает но как то под капотом, без явного указания на что делить. например у google bigquery можно сделать партиции по дням, удобно же.

Tvorog
() автор топика

Если в sqlite отключить транзакции то быстро

Jopich1
()

А ты рядом индекс сделай :) с помощью awk и sed :)

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

Это если у ТС есть ssd’шка на которой можно выделить раздел с xfs :). Но да, быстрее scylla сейчас мало что есть.

ei-grad ★★★★★
()
Последнее исправление: ei-grad (всего исправлений: 1)

Ещё хороший вариант - lmdb

ei-grad ★★★★★
()
Ответ на: комментарий от nikolnik

ScyllaDB

Какое минимальное количество узлов надо настроить и запустить, чтобы прочитать локальный файл?

anonymous
()

Разумеется, сначала надо именно sqlite и postgress попробовать. И другие решения И уж сильно потом (или ежели очень руки чешутся) можно велосипед свелосипедить.

Лучший велосипед, имхо, такой: Получить пары хеш-смещение, отсортировать по хешу, положить в файл в виде записей равной длины, искать двоичным поиском (или поиском по хешу, у Кнута всё есть). Я такое даже на баше делал.

legolegs ★★★★★
()
Ответ на: комментарий от ei-grad

ОП:

В строке таблицы порядка 5 полей. Размер одного поля можно считать нефиксированным, но до 50КБ. Число строк от 100 млн до 2 млрд. Будет именно чтение одним пользователем, никаких записей в файл.

Это ж логи по описанию. Какой-такой кей-валуй? )

vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)

Г) файлы с индексами - обработка python-ом

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

vtVitus ★★★★★
()
Ответ на: комментарий от ei-grad

docker

Это еще что за зверь? Сколько узлов этого зверя надо настроить и запустить, чтобы прочитать локальный файл?

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

так вопрос то был какой?)

Во что мне конвертировать csv файл, чтобы максимально быстро получать доступ к строке по индексу?

Если советуешь ClickHouse то посчитай хотя бы какую granularity надо выставить чтоб и файл засечек в память влезал и чтоб оно 50кб*8000 с диска не поднимало на каждый запрос по индексу.

ei-grad ★★★★★
()

А вообще ты не сказал какая нагрузка будет - сколько запросов в секунду и какая задержка терпима.

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

А вообще ты не сказал какая…

…локальность запросов будет. Какой сценарий использования - последовательный доступ вперед или назад по индексу, случайный доступ, специально подобранный наихудщий для построенного индекса доступ?

anonymous
()

Оптимальный - это тот, при котором у тебя меньше телодвижений будет.

И это варианты А, Б, В. Какой выбрать? Какой быстрее применишь. Я бы взял постгрес, потому что могу быстро.

bvn13 ★★★★★
()

Я бы тупо взял и сравнил варианты А и Б. И написал бы на ЛОРе о результатах.

Только не «sqllight», а sqlite.

И поскольку я не уверен, как такой файл будет жеваться стандартной импортилкой, возможно, целесообразно набросать свою, в два потока (чтобы она адекватно отдавала информацию о прогрессе, по которой можно сделать вывод, сколько ещё осталось ждать, 10 минут или двое суток). Но это не точно, возможно, что и стандартная постгряшная серверная COPY нормально справится.

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

Оптимальный - это тот, при котором у тебя меньше телодвижений будет.

Это оптимизация первого запроса - как быстро будет выполнен первый запрос (включая настройку-запуск всех необхоимых узлов).

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

anonymous
()

Быстрый поиск по гитхабу выдал https://github.com/BurntSushi/xsv

Не читал, но…

Rust. Работает с сырым csv (нет бесконечно долгого импорта базы!), умеет строить индекс.

anonymous
()

Может так оказаться, что данные прекрасно сжимаются в десятки-сотни раз. Тогда есть шанс провернуть трюк с zram или аналогами.

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

свою, в два потока (чтобы она адекватно отдавала информацию о прогрессе, по которой можно сделать вывод, сколько ещё осталось ждат

Для этого есть pv и pv -d <pid>.

legolegs ★★★★★
()
Последнее исправление: legolegs (всего исправлений: 1)

индекс это номер?

тогда как уже сказали создаёшь индекс смещений - и тогда для чтения i-строки читаешь с [i] смещения по [i+1] смещения не включая.

для однородности при генерации индекса добавляешь лишнее нулевое поле - смотрящее за конец последнего кортежа

тогда чтение i- сsv строки

есть fseek(pos(i)), read(pos(i+1)-pos(i))

т.е если ещё более в низ то два чтения

если размер смещения это n То

fseek(fileofindex,i*n)
indexes=read(fileofindex,n*2)
fseek(rawcsv,indexes[0])
data=read(rawcsv,index[1]-index[0])
qulinxao3
()

Решал подобную задачу. Использовал Postgres.

deterok ★★★★★
()

Возможно эксперты по СУБД поправят, но для больших объёмов при импорте часто лучше отключить индексы и пересоздать после наполнения, чем импортировать с подключенным индексом.

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

А если оно всё в транзакции или вообще COPY, то сама СУБД не догадается соптимизировать? Ведь пока транзакция не завершена индекс не нужен, это можно доказать.

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

Это если в лоб брать сырой pandas, у data scientists целая куча инструментов для обработки данных, которые не влазят в память.

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

«Куча инструментов» - это spark и всё что работает вокруг него, но судя по вопросу у ТСа нет под рукой кластера hadoop’a.

phoen ★★
()

Во что конвертировать огромный, сотни ГБ, CSV-файл для максимально быстрого чтения по «ключу»?

Вы морду уже набили «создателю» таких CSV?

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