Статьи

TokuDB против InnoDB в тесте INSERT

Это сообщение от Вадима Ткаченко из 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 против несжатого).
Пропускная способность (чем больше, тем лучше):
InnoDB-Тр

Время отклика (лог 10, шкала по оси Y) (чем меньше, тем лучше):
innodb_resp

Итак, InnoDB поставляется со следующими номерами:

  • InnoDB без сжатия в среднем составляет 350 вставок в секунду с временем отклика 80-100 мс на транзакцию. Размер финального стола составляет 82 ГБ
  • InnoDB со сжатием 8K имеет пропускную способность 130 вставок в секунду с временем отклика 250 мс . Размер финального стола 60 ГБ

Теперь у нас довольно плохая степень сжатия, потому что я использовал равномерное распределение для значений столбцов data1-data5, а равномерное может не подходить для сжатия. И, на самом деле, в реальном случае я ожидаю гораздо больше повторяющихся значений, поэтому я собираюсь провести повторное тестирование с распределением по Парето (zipfian).

Для TokuDB (протестированы форматы tokudb_fast и tokudb_small):

Пропускная способность (чем больше, тем лучше):
tokudb_thr

Время отклика (лог 10, шкала по оси Y) (чем меньше, тем лучше):
tokudb_resp

ТокуДБ наблюдения:

  • После первоначального прогрева 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)

Пропускная способность в этом случае:
tokudb_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