Производительность MySQL на большой таблице только для записи

Заранее спасибо за ваши ответы, и извините за мой плохой английский, я не являюсь носителем языка.

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

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

Таблица транзакций время от времени уникально читается в бэк-офисе.

Вот схема таблицы транзакций:

create table money_money_transaction (
  `id`              BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
  `userID`          INT UNSIGNED NOT NULL,
  `amount`          INT NOT NULL,
  `transactionType` TINYINT NOT NULL,
  `created`         DATETIME NOT NULL,

  CONSTRAINT money_money_transaction_userID FOREIGN KEY (`userID`) REFERENCES `user_user` (`id`)
    ON DELETE CASCADE
);

Мы планировали иметь много пользователей, таблица транзакций могла вырасти до 1 миллиарда строк, поэтому у меня следующие вопросы:

  • Повлияет ли это на производительность других таблиц?
  • Если база данных слишком велика для размещения в ОЗУ, имеет ли MySQL какую-то оптимизацию, сохраняя в ОЗУ только наиболее читаемую таблицу?
  • Сможет ли MySQL правильно масштабироваться до этой миллиардной строки? Знание, что мы в основном выполняем вставку, и что единственный индекс находится по идентификатору (идентификатор необходим для деталей), и что нет "массовой вставки" (не будет 1M вставки для одновременного выполнения в этой таблице)
  • Кроме того, мы находимся на сервере RDS, поэтому мы могли бы переключиться на Aurora и при необходимости попробовать репликацию master-master или master-slave. Как вы думаете, это поможет в этом случае?

1 ответ

Решение

Вы могли бы рассмотреть MyRocks (см. Http://myrocks.io), который является сторонним механизмом хранения, который разработан для быстрой INSERT-скорости и сжатого хранения данных. Я не буду рекомендовать вам перейти на MyRocks, потому что у меня недостаточно информации, чтобы сделать однозначное заявление об этом для вашей рабочей нагрузки. Но я рекомендую потратить ваше время, чтобы оценить его и посмотреть, работает ли он лучше для вашего приложения.

Если база данных слишком велика для размещения в ОЗУ, имеет ли MySQL какую-то оптимизацию, сохраняя в ОЗУ только наиболее читаемую таблицу?

Да, MySQL (с учетом механизма хранения InnoDB) хранит частичные таблицы в ОЗУ, в пуле буферов. Он разбивает таблицы на страницы и помещает страницы в буферный пул по запросу. Это как кеш. Со временем большинство запрашиваемых страниц остаются в пуле буферов, а другие выселяются. Таким образом, он в большей или меньшей степени уравновешивает обслуживание большинства ваших запросов как можно быстрее. Прочтите https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool.html для получения дополнительной информации.

Повлияет ли это на производительность других таблиц?

Таблицы не имеют производительности - запросы имеют производительность.

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

Сможет ли MySQL правильно масштабироваться до этой миллиардной строки?

MySQL имеет много функций, которые помогают повысить производительность и масштабируемость (это не одно и то же). Опять же, запросы имеют производительность, а не таблицы. Таблица без запросов просто сидит там. Это запросы, которые оптимизируются различными методами.

Знание, что мы в основном выполняем вставку, и что единственный индекс находится по идентификатору (идентификатор необходим для деталей), и что нет "массовой вставки" (не будет 1M вставки для одновременного выполнения в этой таблице)

Индексы действительно добавляют накладные расходы на вставки. Вы не можете исключить индекс первичного ключа, это необходимая часть каждой таблицы. Но, например, вы можете найти целесообразным сбросить свой FOREIGN KEY, который включает в себя индекс.

Обычно большинство таблиц читаются больше, чем они записаны, поэтому для удобства чтения стоит сохранить индекс (или даже UPDATE или DELETE, использующие предложение WHERE). Но если ваша рабочая нагрузка практически вся INSERT, возможно, дополнительный индекс для внешнего ключа является чисто служебным и не дает никакой выгоды для каких-либо запросов.

Кроме того, мы находимся на сервере RDS, поэтому мы могли бы переключиться на Aurora и при необходимости попробовать репликацию master-master или master-slave. Как вы думаете, это поможет в этом случае?

Я работал над тестами Aurora в начале 2017 года и обнаружил, что для приложения, которое мы тестировали, он не подходит для большого трафика записи. Вы должны всегда проверять это для своего приложения, а не зависеть от предположения кого-то в Интернете. Но я предсказываю, что Aurora в ее нынешнем виде (около 2017 года) будет полностью отстойной для вашей полной нагрузки.

Другие вопросы по тегам