@Corn385

Словарь или БД?

Скрипт делает большое количество запросов к различным апи, и должен куда то записывать эти данные.
Важна каждая миллисекунда. Что быстрее будет на запись: БД(aiosqlite) или словарь?
Полученные данные обрабатываются отдельно, поэтому важна скорость записи.
  • Вопрос задан
  • 268 просмотров
Пригласить эксперта
Ответы на вопрос 3
Vindicar
@Vindicar
RTFM!
Есть целый ряд вопросов.
1.
Скрипт делает большое количество запросов к различным апи

Что-то мне подсказывает, что затык скорее будет тут, а не на записи. Ты делал замеры производительности и убедился, что bottleneck именно на сохранении данных?
2. И да, вопрос персистентности принципиален. Наскоько страшно потерять набранные данные?
3. А у тебя в оперативку данные влезут? Ты же понимаешь, что по исчерпании оперативки система начнёт свопиться, и вся производительность пойдёт коту под хвост? Вообще, если данные влезают в оперативку, это не такой уж большой объём для ввода/вывода.

Попробуй сначала сбрасывать в БД напрямую. Простое решение часто оказывается достаточным. Я очень подозреваю, что так и будет.

Если скорости всё же будет не хватать - клади в очередь в ОЗУ, параллельно перекидывай в БД. Если у тебя io-bound задача, то лучше писать асинхронный код, и использовать асинхронную же обёртку вокруг БД. Тогда у тебя хотя бы очередь будет расти медленнее

Если и это не поможет - посмотри, можно ли писать данные блоками фиксированного размера в какой-нибудь бинарный файл. Если там будет минимум преобразований типов (например, число-строка), скорость должна быть приемлемая. Этот файл может читать отдельный процесс, и уже преобразовывать и сохранять в приемлемом виде. Но я бы не советовал так извращаться.
Ответ написан
@rPman
Если данные обрабатываются отдельно, то самая быстрая реализация - записывать в файл в своем формате (даже если это будет построчно сериализованные json), обязательный flush после записи (кеш кстати можно отключить). Индекс строить в оперативной памяти в виде словаря (key->смещение в файле+размер или сами данные, если влезают). При перезапуске приложения после сбоя, файл перечитывается, индекс в памяти заполняется заново. Этот вариант подходит для случаев, когда параллельная аналитика уменьшает объем данных в этом файле, перенося их в базу данных (в этом случае нужно параллельно обновлять индекс в памяти основного приложения и при его перезапуске учитывать что именно читать из файла а что нет), один из способов реализации уменьшения размера файлов - хранить его кусками от времени, удаляя старые (при этом нужные данные повторно отправлять в систему, в общем дальше от задачи).

Решение с таким лог-файлом (или несколькими, например по одному на процесс/поток/ноду, тогда не понадобится синхронизация записи) и индексом в оперативной памяти будет давать считанные миллисекунды на операцию (упираться все будет в iops диска), если совсем труба, исключай файловую систему и пиши прямо в блочное устройство (выгадаешь еще 3х-10х ускорения)

Если хочется базу данных - бери что то типа mysql с отключенными транзакциями (myisam), и очень грамотно составленными индексами и партицированием (может даже самодельным). Большее количество задержек вносят именно индексы.

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

p.s. когда то давно я писал что то подобное, диск был медленный hdd но так как с него не было чтений, только записи на случай сбоя, а все данные были в оперативной памяти, скорость была огромной, десяток тысяч операций на очень слабом тогда железе
Ответ написан
Комментировать
work_jabir
@work_jabir
Используйте redis.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы