Это сообщение от Вадима Ткаченко из MySQL Performance Blog.
Этот пост является продолжением моего исследования механизма хранения TokuDB, чтобы понять, подходит ли он для рабочих нагрузок временных рядов .
Хотя вставка LOAD DATA INFILE в пустую таблицу показывает отличные результаты для TokuDB, было бы более интересно увидеть некоторые реалистичные рабочие нагрузки.
Итак, на этот раз давайте посмотрим на тест INSERT .
Я собираюсь вставить данные из 16 параллельных потоков в таблицу из предыдущего поста:
CREATE TABLE `sensordata` ( `ts` int(10) unsigned NOT NULL DEFAULT '0', `sensor_id` int(10) unsigned NOT NULL, `data1` double NOT NULL, `data2` double NOT NULL, `data3` double NOT NULL, `data4` double NOT NULL, `data5` double NOT NULL, `cnt` int(10) unsigned NOT NULL, PRIMARY KEY (`sensor_id`,`ts`) )
Вставки представляют собой объемные вставки с последовательным увеличением ts
и sensor_id
от 1 до 1000 .
Хотя вставки не являются полностью последовательными, поскольку первичный ключ (sensor_id, ts)
достаточен для загрузки рабочей памяти, я не ожидаю снижения производительности, когда данные превышают объем памяти. Это будет играть в пользу InnoDB, поскольку известно, что TokuDB работает хуже в ориентированных на CPU тестах.
Тест выполняет миллион событий, каждое событие добавляет 1000 записей. Когда он закончится, у нас должно быть около одного миллиарда записей в таблице.
Итак, давайте посмотрим, как работает InnoDB (сжатый 8K против несжатого).
Пропускная способность (чем больше, тем лучше):
Время отклика (лог 10, шкала по оси Y) (чем меньше, тем лучше):
Итак, InnoDB поставляется со следующими номерами:
- InnoDB без сжатия в среднем составляет 350 вставок в секунду с временем отклика 80-100 мс на транзакцию. Размер финального стола составляет 82 ГБ
- InnoDB со сжатием 8K имеет пропускную способность 130 вставок в секунду с временем отклика 250 мс . Размер финального стола 60 ГБ
Теперь у нас довольно плохая степень сжатия, потому что я использовал равномерное распределение для значений столбцов data1-data5, а равномерное может не подходить для сжатия. И, на самом деле, в реальном случае я ожидаю гораздо больше повторяющихся значений, поэтому я собираюсь провести повторное тестирование с распределением по Парето (zipfian).
Для TokuDB (протестированы форматы tokudb_fast и tokudb_small):
Пропускная способность (чем больше, тем лучше):
Время отклика (лог 10, шкала по оси Y) (чем меньше, тем лучше):
ТокуДБ наблюдения:
- После первоначального прогрева TokuDB демонстрирует весьма несовместимую производительность с форматами tokudb_fast и tokudb_small.
- Для tokudb_fast пропускная способность составляет около 150 вставок в секунду , а время отклика 95% составляет ~ 160 мс . Однако существуют периодические задержки, когда пропускная способность падает почти до нуля, а время отклика увеличивается до 10 секунд (!!!) на транзакцию.
- Для tokudb_small пропускная способность еще менее стабильна и составляет около 100 вставок в секунду, а время отклика начинается с 300 мс на транзакцию, с задержками до 30 секунд на транзакцию
Размеры файлов для TokuDB:
- tokudb_fast: 50 ГБ
- tokudb_small: 45 ГБ .
Опять же, мне соответствует плохая степень сжатия для равномерного распределения. Если мы переключимся на pareto, размер файла для tokudb_fast составит 21 ГБ , а tokudb_small — 13 ГБ.
Если увеличить масштаб до 900 секунд, мы увидим периодическое поведение TokuDB:
Теперь я рассматриваю эти киоски в TokuDB как серьезные и не думаю, что могу рекомендовать использовать их в производственных условиях в таких условиях нагрузки, пока проблема не будет устранена.
Вы можете найти скрипты для теста временных рядов для sysbench v0.5 здесь .
Версии программного обеспечения для InnoDB: Percona Server 5.6-RC3, для TokuDB: mariadb-5.5.30-tokudb-7.0.4
ОБНОВЛЕНИЕ (5 сентября 2013 г.) .
По многочисленным просьбам я обновляю сообщение следующей информацией:
пропускная способность TokuDB (формат строки tokudb_small) с распределением по Парето, для двух случаев:
- 1. ПЕРВИЧНЫЙ КЛЮЧ (
sensor_id
,ts
) (на графике:tokudb_small
) - 2. ПЕРВИЧНЫЙ КЛЮЧ (
ts
,sensor_id
), КЛЮЧ (sensor_id
,ts
) (на графике:tokudb_small_key
)
Пропускная способность в этом случае:
Мы видим, что максимальная пропускная способность для for tokudb_small_key
меньше, чем для for tokudb_small
, но также имеется меньшая разница в пропускной способности.
My.cnf Файлы
Для InnoDB:
[mysqld] # gdb log-error=error.log innodb_file_per_table = true innodb_data_file_path = ibdata1:100M:autoextend innodb_flush_method = O_DIRECT innodb_log_buffer_size = 256M innodb_flush_log_at_trx_commit = 1 innodb_buffer_pool_size = 40G innodb_buffer_pool_instances=1 innodb_file_format = Barracuda innodb_checksum_algorithm = crc32 innodb_log_file_size = 4G innodb_log_files_in_group = 2 #innodb_log_block_size=4096 #####plugin options innodb_read_io_threads = 16 innodb_write_io_threads = 4 innodb_io_capacity = 4000 #not innodb options (fixed) port = 3306 back_log = 50 max_connections = 2000 max_prepared_stmt_count=500000 max_connect_errors = 10 table_open_cache = 2048 max_allowed_packet = 16M binlog_cache_size = 16M max_heap_table_size = 64M sort_buffer_size = 4M join_buffer_size = 4M thread_cache_size = 1000 query_cache_size = 0 query_cache_type = 0 thread_stack = 192K tmp_table_size = 64M server-id = 10 key_buffer_size = 8M read_buffer_size = 1M read_rnd_buffer_size = 4M bulk_insert_buffer_size = 8M myisam_sort_buffer_size = 8M myisam_max_sort_file_size = 10G myisam_repair_threads = 1 myisam_recover socket=/var/lib/mysql/mysql.sock user=root
Для TokuDB (в значительной степени по умолчанию):
[mysqld] gdb skip-innodb #not innodb options (fixed) port = 3306 back_log = 50 max_connections = 2000 max_prepared_stmt_count=500000 max_connect_errors = 10 table_open_cache = 2048 max_allowed_packet = 16M binlog_cache_size = 16M max_heap_table_size = 64M sort_buffer_size = 4M join_buffer_size = 4M thread_cache_size = 1000 query_cache_size = 0 query_cache_type = 0 ft_min_word_len = 4 #default_table_type = InnoDB thread_stack = 192K tmp_table_size = 64M server-id = 10 key_buffer_size = 8M read_buffer_size = 1M read_rnd_buffer_size = 4M bulk_insert_buffer_size = 8M myisam_sort_buffer_size = 8M myisam_max_sort_file_size = 10G #myisam_max_extra_sort_file_size = 10G myisam_repair_threads = 1 myisam_recover socket=/var/lib/mysql/mysql.sock user=root