Может ли задержка ввода / вывода привести к тому, что простое ОБНОВЛЕНИЕ займет несколько секунд в MySQL? - PullRequest
7 голосов
/ 11 марта 2012

В моем приложении MySQL низкая производительность при выполнении некоторых запросов UPDATE, INSERT и DELETE. В этом вопросе я буду обсуждать только один конкретный UPDATE, потому что этого достаточно, чтобы продемонстрировать проблему:

UPDATE projects SET ring = 5 WHERE id = 1

Этот UPDATE обычно достаточно быстрый, около 0,2 мс, но время от времени (достаточно, чтобы быть проблемой) это занимает несколько секунд . Вот выдержка из журнала (посмотрите на 4-ю строку):

 ~ (0.000282) UPDATE `projects` SET `ring` = 5 WHERE `id` = 1
 ~ (0.000214) UPDATE `projects` SET `ring` = 6 WHERE `id` = 1
 ~ (0.000238) UPDATE `projects` SET `ring` = 7 WHERE `id` = 1
 ~ (3.986502) UPDATE `projects` SET `ring` = 8 WHERE `id` = 1
 ~ (0.000186) UPDATE `projects` SET `ring` = 9 WHERE `id` = 1
 ~ (0.000217) UPDATE `projects` SET `ring` = 0 WHERE `id` = 1
 ~ (0.000162) UPDATE `projects` SET `ring` = 1 WHERE `id` = 1

projects - это таблица InnoDB с 6 столбцами типов INT и VARCHAR, 17 строками и индексом по id. Это происходит и с другими таблицами, но здесь я сосредоточусь на этом. Пытаясь решить проблему, я убедился, что все запросы были последовательными, так что это , а не проблема блокировки . UPDATE выше выполняется в контексте транзакции. Другая информация на сервере :

  • VPS с 4 ГБ ОЗУ (было 1 ГБ), 12 ГБ свободного дискового пространства
  • CentoOS 5,8 (было 5,7)
  • MySQL 5.5.10 (был 5.0.x)

Бит "было" выше означает, что он не работал до или после обновления.

То, что я до сих пор пробовал, безрезультатно :

  • Настройка innodb_flush_log_at_trx_commit на 0, 1 или 2
  • Настройка innodb_locks_unsafe_for_binlog вкл. Или выкл.
  • Настройка timed_mutexes вкл. Или выкл.
  • Изменение innodb_flush_method со значения по умолчанию на O_DSYNC или O_DIRECT
  • Увеличение innodb_buffer_pool_size по умолчанию до 600M, а затем до 3000M
  • Увеличение innodb_log_file_size по умолчанию до 128M
  • Компиляция MySQL из исходного кода
  • Запуск SHOW PROCESSLIST, который сообщает мне, что состояние "обновляется"
  • Запуск SHOW PROFILE ALL, который говорит, что почти все время было потрачено на «обновление», и что на этом этапе не так много времени было потрачено на циклы ЦП и было много произвольных переключений контекста (например, 30)
  • Мониторинг SHOW STATUS за изменениями Innodb_buffer_pool_pages_dirty. Может быть некоторая связь между удаляемыми грязными страницами и медленными запросами, но корреляция не ясна.

Затем я решил проверить задержку ввода / вывода системы с помощью ioping. Это мой первый VPS, поэтому Я был удивлен, увидев такой результат :

4096 bytes from . (vzfs /dev/vzfs): request=1 time=249.2 ms
4096 bytes from . (vzfs /dev/vzfs): request=2 time=12.3 ms
4096 bytes from . (vzfs /dev/vzfs): request=3 time=110.5 ms
4096 bytes from . (vzfs /dev/vzfs): request=4 time=232.8 ms
4096 bytes from . (vzfs /dev/vzfs): request=5 time=294.4 ms
4096 bytes from . (vzfs /dev/vzfs): request=6 time=704.7 ms
4096 bytes from . (vzfs /dev/vzfs): request=7 time=1115.0 ms
4096 bytes from . (vzfs /dev/vzfs): request=8 time=209.7 ms
4096 bytes from . (vzfs /dev/vzfs): request=9 time=64.2 ms
4096 bytes from . (vzfs /dev/vzfs): request=10 time=396.2 ms

Я бы сказал, довольно странно.

Сказав все это, я спрашиваю:

  1. Может ли задержка ввода-вывода иногда убивать производительность MySQL? Я всегда думал, что когда вы запускаете UPDATE, поток, заботящийся об этом соединении, не будет сбрасываться данные на диск или ждать такого сброса; он немедленно вернется, и очистка будет выполнена другим потоком в другое время.

  2. Если это не может быть дисковый ввод / вывод, Есть ли что-то еще, что я могу попробовать, кроме аренды выделенного сервера?

Ответы [ 4 ]

2 голосов
/ 14 марта 2012

Я отвечаю на свой вопрос дополнительными данными, которые я собрал на основе ваших ответов.

Я использовал два ноутбука, подключенных через беспроводную сеть.На ноутбуке A я смонтировал каталог ноутбука B, используя sshfs.Затем на ноутбуке AI запустил MySQL, указав этот смонтированный каталог в качестве своего каталога данных.Это должно обеспечить MySQL очень медленным устройством ввода-вывода.MySQL был запущен с innodb_flush_log_at_trx_commit = 0.

. Я определил 3 набора запросов, каждый из которых состоял из обновления и запроса выбора, повторенного 10000 раз, без явных транзакций.Эксперименты были:

  • US1SID: обновить и выбрать в определенной строке той же таблицы.Во всех итерациях использовалась одна и та же строка.
  • US1MID: обновить и выбрать конкретную строку в той же таблице.Строка была разной на каждой итерации.
  • US2MID: обновлять и выбирать строки разных таблиц.В этом случае таблица, читаемая селектором, вообще не изменилась во время эксперимента.

Каждый набор запускался дважды с использованием сценария оболочки (следовательно, время было медленнее, чем в моем исходном вопросе), одна в нормальных условиях, а другая после выполнения следующей команды:

tc qdisc replace dev wlan0 root handle 1:0 netem delay 200ms

Приведенная выше команда добавляет среднюю задержку в 200 мс при передаче пакетов через wlan0.

Во-первых, вот среднеевремя наибольших 99% самых быстрых обновлений и выборок, а нижних 1% обновляет и выбирает.

          |        Delay: 0ms        |       Delay: 200ms       |
          | US1SID | US1MID | US2MID | US1SID | US1MID | US2MID |
| top99%u | 0.0064 | 0.0064 | 0.0064 | 0.0063 | 0.0063 | 0.0063 |
| top99%s | 0.0062 | 0.0063 | 0.0063 | 0.0062 | 0.0062 | 0.0062 |
| bot01%u | 1.1834 | 1.2239 | 0.9561 | 1.9461 | 1.7492 | 1.9731 |
| bot01%s | 0.4600 | 0.5391 | 0.3417 | 1.4424 | 1.1557 | 1.6426 |

Как видно, даже при очень низкой производительности ввода-вывода MySQL удается выполнять большинство запросов.действительно быстро.Но больше всего меня беспокоит наихудший случай, так что вот еще одна таблица, показывающая 10 самых медленных запросов.«U» означает, что это было обновление, а «s» - выбор.

|          Delay: 0ms         |          Delay: 200ms          |
| US1SID  | US1MID  | US2MID  | US1SID   | US1MID   | US2MID   |
| 5.443 u | 5.946 u | 5.315 u | 11.500 u | 10.860 u | 11.424 s |
| 5.581 u | 5.954 s | 5.466 u | 11.649 s | 10.995 u | 11.496 s |
| 5.863 s | 6.291 u | 5.658 u | 12.551 s | 11.020 u | 12.221 s |
| 6.192 u | 6.513 u | 5.685 u | 12.893 s | 11.370 s | 12.599 u |
| 6.560 u | 6.521 u | 5.736 u | 13.526 u | 11.387 u | 12.803 u |
| 6.562 u | 6.555 u | 5.743 u | 13.997 s | 11.497 u | 12.920 u |
| 6.872 u | 6.575 u | 5.869 u | 14.662 u | 12.825 u | 13.625 u |
| 6.887 u | 7.908 u | 5.996 u | 19.953 u | 12.860 u | 13.828 s |
| 6.937 u | 8.100 u | 6.330 u | 20.623 u | 14.015 u | 16.292 u |
| 8.665 u | 8.298 u | 6.893 u | 27.102 u | 22.042 s | 17.131 u |

Выводы:

  1. Плохая производительность ввода-вывода может действительно замедлить MySQL доползать.Непонятно , почему или , когда точно, но это случается.

  2. Замедление применяется как к выборкам, так и к обновлениям, с обновлениями, страдающимиподробнее.

  3. По какой-то причине даже операции выбора в таблице, которые не были вовлечены в какие-либо изменения и которые недавно были заполнены, также были замедлены, как видно из US2MID выше.

  4. Что касается тестовых примеров, предложенных mentatkgs, кажется, что обновление разных строк вместо одних помогает немного, но не решает проблему.

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

Спасибо всем за комментарии.

1 голос
/ 13 марта 2012

Поскольку вы размещаете свой VPS в облаке, вы можете столкнуться с проблемами, которые находятся вне вашего контроля.

VPS подчиняются прихотям хост-серверов, на которых они работают. Например, приоритет цикла ЦП в Rackspace Cloud взвешивается в зависимости от размера VPS. Чем больше ваш VPS, тем выше вероятность того, что ваше приложение будет работать без сбоев. Если на хосте вы используете больший VPS, возможно, возможно , что виноват взрыв по весу. Сложно сказать.

Вы пытались запустить это локально на своей машине? Если он отлично работает в вашей собственной системе и вам требуется гарантированная производительность, тогда вам лучше всего перейти на выделенный сервер.

1 голос
/ 13 марта 2012

У вас проблема с вводом-выводом, связанная с VPS. Это не вина MySQL.

Вы случайно не используете Elastic Block Store с Amazon или, возможно, RDS? Оба используют удаленное хранилище и уровень протокола IP для связи с хранилищем; иногда они могут иметь неприятное отставание.

0 голосов
/ 13 марта 2012

Вопрос 1) Да.

Для проверки напишите 2 приложения:

Контрольный пример 1: будет делать это каждую минуту в течение нескольких часов

UPDATE `projects` SET `ring` = 5 WHERE `id` = 1
UPDATE `projects` SET `ring` = 6 WHERE `id` = 1

Контрольный пример 2: будет делать это каждую минуту в течение нескольких часов

UPDATE `projects` SET `ring` = 7 WHERE `id` = 1
UPDATE `projects` SET `ring` = 8 WHERE `id` = 2

Тестовый пример 1 должен иметь задержку, в то время как тестовый пример 2 не должен.

Вопрос 2) Использование базы данных noSQL.

...