Первоначально написал Вадим Ткаченко
Мы только что выпустили в качестве версии с открытым исходным кодом нашего нового percona-agent ( https://github.com/percona/percona-agent ) , агента для работы с Percona Cloud Tools. Этот агент написан на Go .
Я проведу вебинар под названием « Мониторинг всех метрик MySQL с помощью Percona Cloud Tools », который будет посвящен новым функциям Percona-Agent и Percona Cloud Tools, где я также объясню, как он работает. Вы можете зарегистрироваться сейчас и присоединиться ко мне.
Будет много постов о percona-agent, но пока что я хочу посвятить это Go, Go с MySQL и некоторым темам о производительности.
Я давно интересовался языком программирования Go, но в начальных версиях мне не очень понравилась производительность планировщика gorountine. См. Мой отчет более чем два года назад о времени выполнения: уменьшите конкуренцию за планирование в целом$GOMAXPROCS
.
Возможно, эта проблема с производительностью была исправлена в Go 1.1, так что сейчас самое время вернуться к моему эксперименту.
Простое выполнение вычисления простых чисел или чисел Фибоначчи в N потоках довольно скучно, поэтому я собираюсь выполнить запросы к Percona Server . Конечно, это добавляет некоторые сложности, поскольку есть больше движущихся частей (например, планировщик go, драйвер sql go, сам MySQL) , но это только делает эксперимент более интересным.
Исходный код моего теста: Go-pk-bench :
Вероятно, это не лучший пример того, как кодировать в Go, но это не было целью этого упражнения. Этот пост действительно о некоторых советах, которые необходимо учитывать при написании приложения на Go с использованием базы данных MySQL (Percona Server) .
Итак, во-первых, нам понадобится драйвер MySQL для Go. Тот, который я использовал два года назад ( https://github.com/Philio/GoMySQL ), довольно устарел. Кажется, самый популярный выбор сегодня — это Go-MySQL-Driver , и именно этот мы используем для внутренней разработки. Этот драйвер основан на стандартном пакете Go «database / sql» . Этот пакет предоставляет стандартный Go-способ для работы с базами данных, подобными SQL. «Database / sql», кажется, работает хорошо, с некоторыми сомнительными дизайнерскими решениями на мой вкус. Таким образом, используя «database / sql» и Go-MySQL-Driver, вам придется иметь дело с некоторыми причудами, такими как почти неуправляемый пул соединений.
Первое, что вы должны принять во внимание, это правильная настройка
runtime.GOMAXPROCS()
.
Если вы этого не сделаете, планировщик Go будет использовать значение по умолчанию, равное 1. Этот двоичный файл будет использовать один и только один ЦП (так много для современного параллельного языка) .
Команда runtime.GOMAXPROCS(runtime.NumCPU())
предписывает использовать все доступные процессоры. Всегда не забывайте использовать это, если вы заботитесь о многопоточной производительности.
Следующая проблема, с которой я столкнулся в тесте, заключается в том, что когда я запускаю запросы в цикле, т.е. повторяю как можно больше …
rows, err := db.Query("select k from sbtest"+strconv.Itoa(tab+1)+" where id = "+strconv.Itoa(i))
… Очень скоро у нас закончились порты TCP. Очевидно, «database / sql» и Go-MySQL-Driver и его пул интеллектуальных соединений создают НОВЫЕ СОЕДИНЕНИЯ для каждого запроса . Я могу объяснить, почему это происходит, но используя следующее утверждение:
'db.SetMaxIdleConns(10000)'
помогает (надеюсь, кто-то со знанием «database / sql» объяснит, что он делает) .
Таким образом, после этих корректировок мы теперь можем запустить тест, который по запросу, который вы видите, довольно прост — запустить поиск первичных ключей на Percona Server, который, как мы знаем, отлично масштабируется в этом сценарии (я использовал sysbench для создания 64 таблиц по 1 млн строк в каждой, все это подходит в память) . Я собираюсь запустить этот тест с 1, 2, 4, 8, 16, 24, 32, 48, 64 пользовательскими потоками.
Ниже вы можете увидеть графики для MySQL Throughput и CPU Usage (оба графика построены с использованием новых графиков метрик в Percona Cloud Tools )
MySQL Throughput (пользовательские потоки увеличиваются с 1 до 64)
Загрузка процессора (пользовательские потоки увеличиваются с 1 до 64)
Я бы сказал, что результат очень хорошо масштабируется, по крайней мере, он намного лучше, чем два года назад. Интересно сравнить с чем-то, так что есть график от идентичного прогона, но теперь я буду использовать sysbench + lua для основного драйвера рабочей нагрузки.
MySQL Throughput (sysbench, пользовательские потоки увеличиваются с 1 до 64)
Загрузка процессора (sysbench, пользовательские потоки увеличиваются с 1 до 64)
Из графиков (это то, за что они мне нравятся) мы ясно видим увеличение использования ЦП пользователями (и на самом деле мы можем использовать ЦП на 100% при использовании пользователя + системы), и это явно соответствует увеличению пропускной способности.
И если вы поклонник необработанных чисел:
MySQL Throughput, q/s (more is better) Threads | Go-MySQL | sysbench 1 | 13,189 | 16,765 2 | 26,837 | 33,534 4 | 52,629 | 65,943 8 | 95,553 | 116,953 16 | 146,979 | 182,781 24 | 169,739 | 231,895 32 | 181,334 | 245,939 48 | 198,238 | 250,497 64 | 207,732 | 251,972
(человек со знанием Универсального Закона о Масштабируемости может сделать прогноз до 1000 потоков, я оставляю это как домашнее задание)
Итак, в заключение я могу сказать, что Go + MySQL способен показывать приличные результаты, но он все же не так эффективен, как плановый raw C (sysbench) , так как кажется, что он тратит дополнительное системное время на системные вызовы.
Если вы хотите попробовать эти новые графики в Percona Cloud Tools и посмотреть, как они работают с вашей системой — присоединяйтесь к бесплатной бета-версии !