powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как сделать сервис статистики для 20млн записей в сутки MySql?
19 сообщений из 19, страница 1 из 1
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548327
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго дня
Прошу всех специалистов в теме highload помочь со следующим заданием:

1) На базе PHP+MySQL нужно реализовать сервис приёма статистики игровых данных.
Cтруктура:
- ID игрока
- игровое время события
- ID устройства ( строка , 64 символа )
- платформа устройства (iPad, iPhone)
- набор произвольных данных (например, устройство отсылает событие с параметрами Event=Start, Money=15444 и т.д.)
2) Требования:
- сервис должен выдерживать приём 20 млн обращений в сутки.
- необходимо предусмотреть возможность выборки и удаления данных за предыдущий день ( например, 10 -го числа забираются и удаляются данные за 9 -е)
- сервис должен отвечать клиенту, что приём прошёл удачно либо неудачно

Свои идеи:
1. Структура БД
Т.к. данные будет писаться часто и много, а удаляться и читаться редко то вижу два варианта структуры БД:

1.1 Каждый день кроном (cron) создавать таблицу на следующий день - куда будут складываться данные.
Тогда удаление и чтение данных не будет оказывать влияния на вновь записываемые данные.
CREATE TABLE IF NOT EXISTS `day_data` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`user_id` int(10) NOT NULL,
`datetime` int(10) NOT NULL,
`device_id` varchar(64) NOT NULL,
`platform` enum('ipad','iphone') NOT NULL,
`data` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0;


1.2 Таблица создаётся одна, но в ней делаются партиции(PARTITION) по дню месяца(1-31)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
CREATE TABLE IF NOT EXISTS `day_data` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `day_of_month` tinyint(4) NOT NULL,
  `user_id` int(10) NOT NULL,
  `datetime` int(10) NOT NULL,
  `device_id` varchar(64) NOT NULL,
  `platform` enum('ipad','iphone') NOT NULL,
  `data` text NOT NULL,
  PRIMARY KEY (`id`,`day_of_month`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=0
PARTITION BY LIST (day_of_month)
(PARTITION p01 VALUES IN (1) ENGINE = InnoDB,
 PARTITION p02 VALUES IN (2) ENGINE = InnoDB,
 PARTITION p03 VALUES IN (3) ENGINE = InnoDB,
 PARTITION p04 VALUES IN (4) ENGINE = InnoDB,
 PARTITION p05 VALUES IN (5) ENGINE = InnoDB,
 PARTITION p06 VALUES IN (6) ENGINE = InnoDB,
 PARTITION p07 VALUES IN (7) ENGINE = InnoDB,
 PARTITION p08 VALUES IN (8) ENGINE = InnoDB,
 PARTITION p09 VALUES IN (9) ENGINE = InnoDB,
 PARTITION p10 VALUES IN (10) ENGINE = InnoDB,
 PARTITION p11 VALUES IN (11) ENGINE = InnoDB,
 PARTITION p12 VALUES IN (12) ENGINE = InnoDB,
 PARTITION p13 VALUES IN (13) ENGINE = InnoDB,
 PARTITION p14 VALUES IN (14) ENGINE = InnoDB,
 PARTITION p15 VALUES IN (15) ENGINE = InnoDB,
 PARTITION p16 VALUES IN (16) ENGINE = InnoDB,
 PARTITION p17 VALUES IN (17) ENGINE = InnoDB,
 PARTITION p18 VALUES IN (18) ENGINE = InnoDB,
 PARTITION p19 VALUES IN (19) ENGINE = InnoDB,
 PARTITION p20 VALUES IN (20) ENGINE = InnoDB,
 PARTITION p21 VALUES IN (21) ENGINE = InnoDB,
 PARTITION p22 VALUES IN (22) ENGINE = InnoDB,
 PARTITION p23 VALUES IN (23) ENGINE = InnoDB,
 PARTITION p24 VALUES IN (24) ENGINE = InnoDB,
 PARTITION p25 VALUES IN (25) ENGINE = InnoDB,
 PARTITION p26 VALUES IN (26) ENGINE = InnoDB,
 PARTITION p27 VALUES IN (27) ENGINE = InnoDB,
 PARTITION p28 VALUES IN (28) ENGINE = InnoDB,
 PARTITION p29 VALUES IN (29) ENGINE = InnoDB,
 PARTITION p30 VALUES IN (30) ENGINE = InnoDB,
 PARTITION p31 VALUES IN (31) ENGINE = InnoDB);



2. Удаление
С удалением проблем нет т.к. в первом варианте DROP таблицы происходит достаточно быстро
Во втором варианте делаем ALTER TABLE `day_data` TRUNCATE PARTITION p11 - это тоже быстро т.к. если очень грубо, то Mysql удаляет старый файл данных и создает новый. А эта операция выполняется значительно быстрее построчного удаления.

3. Чтение
Для того чтобы избежать потери данных и не вешать сервер на скачку 20млн записей на лету - предварительно сохраняем эти данные в csv файл на сервер и для скачки - даём ссылку на файл на сервере.
Сохранение производим в цикле по 10000 записей - устанавливая флаг в БД для данных уже сохранённх в файл.

4. Отдача клиенту
Ответ присылае в виде JSON
В случае удачи присылаем ok
В случае неудачи:
если данные неполные - ошибку с информацией о неполных данных
если есть ишибка при вставке в БД - информацию об ошибке вставки в БД и номер ошибки

5. Настройка БД
Для увеличения производительности - вероятно нужно дополнительно настроить БД затронув параметры:
innodb_buffer_pool_size
innodb_log_file_size
innodb_log_buffer_size
innodb_file_per_table
innodb_flush_method
innodb_flush_log_at_trx_commit
Можно здесь что-то подсказать

Заранее спасибо всем кто ответит.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548398
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...как данные вставляются? 20 млн в день, 0.9 млн в час,
250 ТХ в секунду в среднем, может быть 500 или 1000
трансакций в пике. PHP будет сильно удивлен...

...в нескольких проектах на среднем железе веб часть
обычно в >10 раз дольше чем сердние запросы к базе.
Т.е. вам нужен или очень серьезный комп или кластер
веб серверов как минимум на 10-20 машин....

1000 вставок в секунду -- нехило для среднего железа...
посмотрите еще:
* исползование быстрых операционных систем
* не исползовать ТЕХТ -- так как его может выбить в отдельный файл
...ну и соответсвено не принемать слишком длинное поле ДАТА
* продумать как будет отдаватся дануе?
если нужен только CSV -- то почеми бы просто не записывать файл?
(я не в курсе но может запись в файл будет тупо быстрее записи в базу)
* отключить все трансакции
* кажется ПХП не самый быстрый фреймвор на прием и обработку запросов
* ngnix быстрее Апачи....
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548442
machetero
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всю статистику нужно сначала писать в кэш(redis или тп), а потом бэкендом, одним запросом, из кэша всё писать в базу.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548482
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-zzxвижу два варианта структуры БД:
1.1 Каждый день кроном (cron) создавать таблицу на следующий день
1.2 Таблица создаётся одна, но в ней делаются партиции(PARTITION) по дню месяца(1-31)
Так это ж почти одно и то же. И оптимизирует фактически из озвученных задач только чистку - при том что это операция чуть ли не одноразовая.

Нет бы задуматься о секционировании, снижающем нагрузку на одну секцию от основного типа запроса - вставки. Т.е., например, при секционировании по дате каждую секцию партиционировать по, скажем, ID игрока. Раз Вы прогнозируете 20кк запросов в сутки, т.е. 230 запросов в секунду, с, например, 4х пиком, то есть смысл думать о 8 или 16 секциях при бинарном ID (последние 3 или 4 бита) либо о 10 секциях для десятичного (последняя цифра) ID. И секции следует создавать не на завтра, а на изрядно вперёд (ну минимум на десяток дней, а то и больше - всё равно пустые секции места не едят, и в цепи проверок выполнение до них не доходит).
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548564
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-zzx,

В описанных требованиях не вижу, нужно ли что-то делать с самими данными в порциях меньших, чем день.
Если не нужно, то тут СУБД вовсе не нужна. Достаточно формировать по csv-файлу на каждый день.

Если всё же нужно держать данные в виде отдельных записей, то какие требования к надежности и задержкам вставки?
Если, например, буферизировать данные по (например, часовым) порциям в файл, а затем вставлять этот файл пакетно командой LOAD DATA, то 20 млн в сутки не выглядят чем-то чрезмерным.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548629
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbc...в нескольких проектах на среднем железе веб часть
обычно в >10 раз дольше чем сердние запросы к базе.
Т.е. вам нужен или очень серьезный комп или кластер
веб серверов как минимум на 10-20 машин.....
Планируется размещение на амазоновских серверах - с этим вроде проблем быть не должно.

javajdbc* не исползовать ТЕХТ -- так как его может выбить в отдельный файл

Согласен. Пробовал поставить varchar 250 - 500 мне сделали замечание - почему так мало. А точную длинна данных не указана :(

javajdbc* продумать как будет отдаватся дануе?
если нужен только CSV -- то почеми бы просто не записывать файл?

Вроде я продумал механизм. В цикле читаем данные предыдущего дня и пишем их в csv файл. на прочитанные данные ставим флаг в таблицу.
Тоже думал сразу писать в csv файл но по условиям - нужно решение именно на базе PHP+MySQL


javajdbc* отключить все трансакции

Тоже как вариант, но целостность данных может пострадать при сбоях нет?

В любом случае спасибо за замечания.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548630
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
macheteroВсю статистику нужно сначала писать в кэш(redis или тп), а потом бэкендом, одним запросом, из кэша всё писать в базу.
Как бы да, но по условиям пока нужно делать именно PHP+MySQL
Спасибо за замечание.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548635
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akinaalex-zzxвижу два варианта структуры БД:
1.1 Каждый день кроном (cron) создавать таблицу на следующий день
1.2 Таблица создаётся одна, но в ней делаются партиции(PARTITION) по дню месяца(1-31)
Так это ж почти одно и то же. И оптимизирует фактически из озвученных задач только чистку - при том что это операция чуть ли не одноразовая.

Нет бы задуматься о секционировании, снижающем нагрузку на одну секцию от основного типа запроса - вставки. Т.е., например, при секционировании по дате каждую секцию партиционировать по, скажем, ID игрока. Раз Вы прогнозируете 20кк запросов в сутки, т.е. 230 запросов в секунду, с, например, 4х пиком, то есть смысл думать о 8 или 16 секциях при бинарном ID (последние 3 или 4 бита) либо о 10 секциях для десятичного (последняя цифра) ID. И секции следует создавать не на завтра, а на изрядно вперёд (ну минимум на десяток дней, а то и больше - всё равно пустые секции места не едят, и в цепи проверок выполнение до них не доходит).

Отличная идея. Сам думал о таком третьем варианте:
делать таблицы на каждый день и в этих таблицах секционировать данные по какому либо полю. Это получается такой "псевдогоризонтальный шардинг"
Но будет ли прирост производительности при инсертах - я не знаю.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548639
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftВ описанных требованиях не вижу, нужно ли что-то делать с самими данными в порциях меньших, чем день.
Если не нужно, то тут СУБД вовсе не нужна. Достаточно формировать по csv-файлу на каждый день.


С данными делать ничего не нужно. Их нужно только скачать в виде csv файла а потом удалить данные за выбранный день - это всё.
Тоже думал формировать csv файлы за каждый день но условия таковы что так делать нельзя :(
Может быть у вас есть какие либо пруфы подтверждающие что запись в файл будет быстрее чем в Mysql?


miksoftЕсли всё же нужно держать данные в виде отдельных записей, то какие требования к надежности и задержкам вставки?
Если, например, буферизировать данные по (например, часовым) порциям в файл, а затем вставлять этот файл пакетно командой LOAD DATA, то 20 млн в сутки не выглядят чем-то чрезмерным.
У меня нет этих требований :(
Тоже вроде неплохой вариант

Спасибо за замечания.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548708
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-zzxМожет быть у вас есть какие либо пруфы подтверждающие что запись в файл будет быстрее чем в Mysql?Это настолько очевидно, что даже не знаю.
MySQL же тоже данные хранит не в вакууме, а в файле. Почитайте устройство файлов движка InnoDB, там все непросто. А это "непросто" обходится не бесплатно.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548709
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-zzxС данными делать ничего не нужно. Их нужно только скачать в виде csv файла а потом удалить данные за выбранный день - это всё.
Тоже думал формировать csv файлы за каждый день но условия таковы что так делать нельзя :(Тогда при записи в MySQL не обязательно парсить исходные данные по полям/записям. Можно скопом/порциями писать в BLOB-поля (тот же TEXT, но без накладных расходов на кодировку).
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39548994
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbc1000 вставок в секунду -- нехило для среднего железа...
Вообще-то это маловато даже для старенького ноутбука, но связка с PHP, конечно, портит всю малину.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549031
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftalex-zzxМожет быть у вас есть какие либо пруфы подтверждающие что запись в файл будет быстрее чем в Mysql?Это настолько очевидно, что даже не знаю.
MySQL же тоже данные хранит не в вакууме, а в файле. Почитайте устройство файлов движка InnoDB, там все непросто. А это "непросто" обходится не бесплатно.
Вроде бы и да но если одновременно 200 человек будут пытаться записать в файл а в пике нагрузки целая тысяча - то пока 1 пишет остальным придётся ждать. И ждать они могут долго.
Прошу поправить если ошибаюсь.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549179
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftalex-zzxС данными делать ничего не нужно. Их нужно только скачать в виде csv файла а потом удалить данные за выбранный день - это всё.
Тоже думал формировать csv файлы за каждый день но условия таковы что так делать нельзя :(Тогда при записи в MySQL не обязательно парсить исходные данные по полям/записям. Можно скопом/порциями писать в BLOB-поля (тот же TEXT, но без накладных расходов на кодировку).
Это просто гениально!!! Спасибо!
Насколько я понимаю - запихнув всё в одно поле - получится сэкономить кучу ресурсов.

В итоге пришёл к такому решению
1) Все данные пришедшие от 1 клиента пишу сразу в одно поле BLOB
2) Делаю разбивку таблиц по дням - чтение и удаление за предыдущий день никак не тормозит запись новых данных.
3) Для каждой дневной таблицы делаю секционирование через HASH или KEY по id записи - это позволит ускорить одновременную запись данных.
Поправьте если ошибаюсь.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549222
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем секционирование? В таблице будет мизер записей, или вообще одна.Что там секционировать?
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549225
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

А почему там будет 1 запись?
Имеется в виду что в таблице будет 1 запись, в этой записи будет поле DATA типа BLOB и в него будут дописываться данные?
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549227
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Сначала подумал что на каждый запрос будет создаваться запись в таблице
id, data
и в поле data в формате BLOB будут писаться принятые данные
и таких записей в 1 таблице будет 20 млн
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549229
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex-zzxmiksoft,

А почему там будет 1 запись?
Имеется в виду что в таблице будет 1 запись, в этой записи будет поле DATA типа BLOB и в него будут дописываться данные?ну да, как файл, только в MySQL.
Хотя можно и каждое обращение новую запись писать, зависит от деталей проекта.
...
Рейтинг: 0 / 0
Как сделать сервис статистики для 20млн записей в сутки MySql?
    #39549245
alex-zzx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoft,

Протестировал скорость вставки через INSERT
И через UPDATE
В итоге получилось - если мы апдейтим одно и то же поле - постоянно дописывая в него - то скорость работы по сравнению с инсертом заметно ниже
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как сделать сервис статистики для 20млн записей в сутки MySql?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]