@EvgeniyMich

Как оптимизировать базу данных?

Есть высоко нагруженная БД для букмекерской конторы. В которой ежесекундно обновляются тысячи событий.

Событие = матч
В событии есть много различных коэффициентов. Победа первой команды, победа второй, Тоталы и т.д. Таких рынков коэффициентов порой доходит до тысячи.

Основной вопрос это архитектурный.
На данный момент у каждого события есть столбец longtext, где хранится огромный JSON со всеми рынками коэффициентов.

Вот хотелось бы понять как построить более производительную архитектуру. Продолжить ли хранить все коэффициенты в JSON, или создать отдельную таблицу где будут храниться все коэффициенты всех событий по отдельности. т.е. если у события 900 типов коэффициентов то создать 900 строк в новой таблице, куда их всех записать.

По поводу выборки по JSON то она не нужна.

Тут еще интересует не мало важный момент постоянного обновления коэффициентов. Если JSON можно просто обновить, то тут придется зацепить все 900 коэффициентов, сравнить их с новыми, и если они не совпадают то заменить. Запросов к БД получится огромное множество.
Конечно было бы намного удобнее если всё разделить, но будет ли это быстрее чем отправить один жирный запрос?

Тут еще суть в том что событий могут быть тысячи, а у каждого события коэффициентов под тысячу, и в добавок всё это обновляется очень часто ~2-5 сек. (сила парсеров =))

Коротко о БД: Postgres расположенная в RDS amazon
  • Вопрос задан
  • 700 просмотров
Пригласить эксперта
Ответы на вопрос 5
inoise
@inoise
Solution Architect, AWS Certified, Serverless
Тут сложно сказать наверняка. Стоит хотябы добавить порядки нагрузок на базу, какой инстанс используете на каких дисках, какая это часть нагрузки на весь сервер и все в таком духе. Кроме того это AWS RDS - всегда можно подкинуть ресурсов и Read Replca.

По структуре данных - всегда можно нормализовать записи и разбить на нормальные таблицы. Если у вас нет какого-то серьезного поиска по этой таблице то вообще можно вынести в DynamoDB.

Опций реально много
Ответ написан
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
Блоб по которому вы не ищете нет смысла нормализовать. Если сравнения, выборки и и сортировки по нему не производятся, а данные участвуют только в логических операциях вне БД, нормализация и перепроектировка не требуется.
Ответ написан
@mitya_k
Если у вас слишком большая таблица получаются, то вам поможет партицирование https://postgrespro.ru/docs/postgresql/10/ddl-part... Тогда UPDATEs станут быстрее работать, ибо id будет искаться не во всей таблице, а в конкретной секции. Если Postgres будет все-равно задыхаться под кол-во запросов, то придется применить шардирование. Завести еще один или несколько инстансов бд, в одной например будет таблица с матчами из Москвы, а в другой из Краснодара. Как выбрать ключ шардирования(по городу, региону, id, хэшу от чего-то и т.д) только вы можете решить исходя из бизнес логики и объема данных.

Если вы переписываете JSON целиком и не ищете в нем ничего, то смысла выносить в отдельные колонки нет.
Ответ написан
@mayton2019
Ent. Software engineer. Oracle. SQL. BigData.
Из того что автор описал - у меня возникает архитектурный вопрос. Кто придумал - использовать JSON для данных которые часто обновляются? Это - антипаттерн. Вы какое железо не поставте - у вас будет плохой перформанс.

Вам необходимо все данные которые имеют реляционный (точечный) доступ убрать из JSON. По сути - развалить его на модель EAV или что-то вроде того (Relational Data (RD)). Обновления станут быстрее. А для отчотности - если вам так уж важен JSON - отдельные джобы которые будут переливать данные из RD в JSON или формировать его на лету средствами клиента. В этом случае у вас не будет накладных расходов даже на хранение.
Ответ написан
yttrium
@yttrium
Частообновляющийся json/jsonb может существенно отжирать дисковое пространсто, необходимо агрессивно вакуумировать. В облаке вероятно это может быть незаметно, но это создает неоптимальную нагрузку на PG.
Возможно стоит пересмотреть архитектуру сбора данных. В зависимости от характера нагрузки, но к примеру если у вас событие длится конечное время, можно писать частообновляющиеся данные в память(например в Redis). А когда событие окончится - дампить в базу. Таким образом извлечение данных за прошедшие события будет оптимальным, и запись в postgresql будет оптимальная.
Ответ написан
Ваш ответ на вопрос

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

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