Низкая задержка для многомиллионной базы данных записей в веб-приложении

Низкая задержка для многомиллионной базы данных записей в веб-приложении
Низкая задержка для многомиллионной базы данных записей в веб-приложении - growtika @ Unsplash

В качестве предупреждения, это для школьного проекта с другими школьными товарищами по команде, поэтому мой вопрос только ради изучения лучших практик. Мы создаем веб-приложение системы рекомендаций, которое в настоящее время состоит из 3 сервисов (интерфейсный интерфейс, сервер Flask, база данных postgres), где используемая нами база данных представляет собой простую базу данных «многие ко многим» с тремя таблицами (таблица пользователей, соединительная таблица, таблица элементов). В соединительной таблице 42 миллиона строк и 2 столбца, в таблице User — 1 миллион строк и 2 столбца, а в таблице Item — 2,3 миллиона строк и 14 столбцов. У нас есть несколько различных алгоритмов совместной и контентной фильтрации, с которыми мы работаем. Два разных метода:

  1. Получив товар A от пользователя X, найдите всех других пользователей в базе данных, которые также приобрели товар A, а затем найдите наиболее часто встречающийся товар B, который покупатели обычно приобретали вместе с ним.
  2. Учитывая элемент A от пользователя X, создайте матрицу расстояний от элемента A до любого другого элемента в базе данных, чтобы найти наиболее похожий алгоритм.

Эти методы легко реализовать, но время запроса может быть очень медленным, особенно для метода 1, поскольку он требует запроса таблицы из 42 миллионов записей. Я ищу рекомендации по увеличению отклика веб-приложения до чего-то разумного (менее 5 секунд) для каждого из этих методов. Одним из самых простых вариантов реализации будет загрузка таблицы Item в Pandas DataFrame при запуске и использование ее в качестве своего рода кеша на диске, но это кажется неправильным и, конечно, не масштабируемым. Существуют ли другие методы, которые используются чаще? Я совсем не знаком с базами данных в памяти, такими как Redis, но поможет ли что-то подобное в ускорении, которое мне нужно?

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

Мера

Часть этого состоит в том, чтобы установить базовый уровень, чтобы иметь хорошее представление о том, принесло ли изменение пользу или нет. Другая часть — профилирование для выявления потенциальных проблем с производительностью. Для баз данных это обычно включает некоторый способ проверки и профилирования запросов. Этот вопрос касается профайлера запросов postgres

Алгоритмические улучшения

Обычно это включает в себя более разумные способы сделать это, уменьшая вычислительную сложность проблемы. Что касается баз данных, это обычно включает в себя обеспечение того, чтобы таблицы имели соответствующие индексы, избегая необходимости сканирования целых таблиц. Другой довольно распространенной проблемой является фильтрация в приложении, а не в базе данных, что может привести к дополнительным задержкам, поскольку необходимо передать больше записей.

Кэширование

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

Аппаратное обеспечение

Если всего остального недостаточно, вы часто можете использовать аппаратное обеспечение для решения проблемы, то есть больше памяти, более быстрые диски, больше процессоров и т. д. Если одной машины недостаточно, postgres и многие другие базы данных поддерживают сегментирование, но, вероятно, будут работать лучше, когда существует некоторое разделение, так что запросам нужен доступ только к данным в одном сегменте, поэтому в вашем случае это может быть неприменимо.

Специализация

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


LetsCodeIt, 17 декабря 2022 г., 20:13

Похожие посты

Класс данных: распределить кодовую таблицу для каждой базы данных по нескольким копиям класса или усложнить исходный класс?Улучшение удобства использования больших баз данных. Разделение на мелкие таблицы. Экспертные советыКак добавить дополнительное поле в API: советы по проектированию REST API с полем ReplicateInManagerУправление источниками данных для фильмов и сериалов. Веб-скрапинг, ручной ввод в базу данных, использование сторонних API, API от платформ потокового воспроизведенияПроектирование базы данных для тренажерного зала: профили пользователей, тренировочные планы, расписания, упражнения, группы мышцКак определить, подходит ли Domain-Driven Design (DDD) для вашего проектаСоздание GPS-приложения для мобильных устройств: Wasm или Xamarin?Регулярное обновление страницы: эффективный способ обновления клиентской части без перезагрузки страницыЛокально-специфические руководства: трудности именования и форматирования имен в различных культурахСоздание комментариев для блога с использованием REST API - важный шаг для целостности данных