500 000 строк в секунду — практика параллельной записи стресс-тестов MySQL
500 000 строк в секунду — практика параллельной записи стресс-тестов MySQL

В последней статье говорилось о нескольких однопоточных методах стресс-тестирования записи MySQL. Изначально я хотел представить некоторые идеи, но просто поделился личным опытом и идеями. Позже фанат оставил сообщение в фоновом режиме и захотел узнать, как бороться с параллелизмом, поэтому сегодня я написал эту статью.

Параллелизм широко используется при тестировании производительности. По моему личному опыту, параллелизм используется практически во всех стресс-тестах. Теперь позвольте мне рассказать об использовании параллелизма в тестировании производительности записи MySQL.

первый,Нам нужно выяснить проблему: одновременно объект. Для реальной ситуации в MySQLtest,я перечислил3индивидуальныйодновременнообъект:java.sql.Statementjava.sql.Connection а также database

Начну с самопроверки максимального количества строк, записываемых в секунду: 50w. Если я еще раз оптимизирую программу, оно должно быть выше, но по результатам теста оно будет ненамного выше. Грубая оценка в пределах 1 миллиона.

Контрольный показатель

Давайте сначала проведем Контрольный показатель,Потому что мой компьютер уже в состоянии Шрёдингера,производительность очень нестабильна. Для простой и быстрой демонстрации того, как его использовать.,На этот раз я использовал фиксированный sql.

Примеры использования следующие:

Язык кода:javascript
копировать
package com.funtest.temp  
  
import com.funtester.db.mysql.FunMySql  
import com.funtester.frame.SourceCode  
  
class MysqlTest extends SourceCode {  
  
    public static void main(String[] args) {  
        StringBuilder  s = new StringBuilder();  
        String sql = "insert into user (name, age, level, region, address) values ('FunTester', 23, 2, «глобальная деревня», 'Восемь пар')";  
        String ipPort = "127.0.0.1:3306";// Адрес сервера  
        String database = "funtester"// Адрес сервера  
        String user = "root";// имя пользователя  
        String password = "funtester";// пароль  
        def base = new FunMySql(ipPort, database, user, password);// Создать базовый класс операций с базой данных  
        def statement = base.connection.createStatement();// создавать SQL объект утверждения
        while (true) {  
            statement.executeUpdate(sql);// Выполнить оператор вставки  
        }  
        statement.close();// Закрыть ресурс  
        base.close();// Закрыть ресурс  
    }  
}

Результаты испытаний следующие:

количество строк

количество секунд

9826

36

10278

37

10208

38

10220

39

9802

40

8975

41

9957

42

9412

43

9884

44

9412

45

9640

46

10304

47

Видно, что результаты намного лучше, чем результаты предыдущих тестов. Теперь каждый сможет понять производительность моего компьютера по методу Шрёдингера.

Statement

обсуждалось ранее Statement Фактически, в сценарии запроса параллелизм не поддерживается. Исходный код также был проанализирован. Заинтересованные студенты могут прочитать исходную статью. Причины не будут повторяться. Что касается сценария написания, то соответствующего исходного кода нет. Для простоты мы его непосредственно протестировали.

Ниже приведен пример использования:

Язык кода:javascript
копировать
package com.funtest.temp  
  
import com.funtester.db.mysql.FunMySql  
import com.funtester.frame.SourceCode  
  
import java.util.concurrent.ExecutorService  
import java.util.concurrent.Executors  
  
class MysqlTest extends SourceCode {  
  
    public static void main(String[] args) {  
        StringBuilder s = new StringBuilder();  
        String sql = "insert into user (name, age, level, region, address) values ('FunTester', 23, 2, «глобальная деревня», 'Восемь пар')";  
        String ipPort = "127.0.0.1:3306";// Адрес сервера  
        String database = "funtester"// Адрес сервера  
        String user = "root";// имя пользователя  
        String password = "funtester";// пароль  
        def base = new FunMySql(ipPort, database, user, password);// Создать базовый класс операций с базой данных  
        def statement = base.connection.createStatement();// создавать SQL объект утверждения
        ExecutorService executors = Executors.newFixedThreadPool(10);// создать пул потоков  
        10.times {  
            executors.execute {// 10 тем  
                while (true) {  
                    statement.executeUpdate(sql);// осуществлять SQL заявление  
                }  
            }  
        }        statement.close();// Закрыть ресурс  
        base.close();// Закрыть ресурс  
    }  
}

Просто используйте 10 потоков, чтобы запустить и посмотреть. Результат следующий:

количество строк

время

9584

42

10263

43

10098

44

9744

45

8864

46

9019

47

10133

48

9768

49

9613

50

9886

51

9835

52

6585

53

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

Connection

Далее мы будем Connection Для параллелизма каждый поток создает Statement Это решение спроектировано так, чтобы быть простым и избегать взаимного вмешательства. Это хорошая стратегия изоляции.

Вариант использования следующий:

Язык кода:javascript
копировать
import com.funtester.db.mysql.FunMySql  
import com.funtester.frame.FunPhaser  
import com.funtester.frame.SourceCode  
  
import java.util.concurrent.ExecutorService  
import java.util.concurrent.Executors  
  
class MysqlTest extends SourceCode {  
  
    public static void main(String[] args) {  
        StringBuilder s = new StringBuilder();  
        String sql = "insert into user (name, age, level, region, address) values ('FunTester', 23, 2, «глобальная деревня», 'Восемь пар')";  
        String ipPort = "127.0.0.1:3306";// Адрес сервера  
        String database = "funtester"// Адрес сервера  
        String user = "root";// имя пользователя  
        String password = "funtester";// пароль  
        def base = new FunMySql(ipPort, database, user, password);// Создать базовый класс операций с базой данных  
        ExecutorService executors = Executors.newFixedThreadPool(10);// создать пул потоков  
        def phaser = new FunPhaser()// создавать Phaser        10.times {  
            phaser.register()// Зарегистрировать тему  
            executors.execute {// 10 тем  
                def statement = base.connection.createStatement();// создавать SQL объект утверждения  
                while (true) {  
                    statement.executeUpdate(sql);// осуществлять SQL заявление  
                }  
                phaser.done()// Завершить тему  
            }  
        }        executors.shutdown();// Закрыть пул потоков  
        phaser.await()// Подождите, пока все темы, которые интересуют, закончатся.  
        base.close();// Закрыть ресурс  
    }  
}

Результаты испытаний следующие:

количество строк

время

10193

57

10095

58

9952

59

9991

0

9893

1

9880

2

8195

3

7834

4

8695

5

8633

6

9078

7

8613

8

Видно, что производительность пока средняя, ​​почти такая же.

database

Дальше мы продолжим database уровни параллелизма, создавая больше Connection для достижения желаемой лучшей производительности записи.

количество строк

время

38549

32

43925

33

32172

34

44419

35

42545

36

40741

37

34487

38

47211

39

43269

40

45396

41

36748

42

Производительность сразу пошла вверх.

Давайте повторим метод с самой высокой однопоточной производительностью — вставку слов в N строк — и протестируем его еще раз. Результаты следующие:

количество строк

время

241440

12

250660

13

252880

14

246870

15

242760

16

214790

17

257260

18

250010

19

251720

20

Ощущается ли это так? MySQL Соответствует ли производительность записи требованиям?

Заключение

В реальной работе сценарий будет более сложным, и на производительность записи влияет множество факторов. Как и в первых двух случаях, хотя теоретически производительность будет значительно улучшена, фактические результаты почти такие же, вероятно, потому, что один Connection узкое место в производительности.

На производительность записи MySQL влияет множество факторов. Помимо аппаратного обеспечения, я кратко перечислю некоторые из них.

На производительность записи MySQL влияет множество факторов. Понимание и оптимизация этих факторов может значительно повысить эффективность записи в базу данных. Вот некоторые из основных влияющих факторов:

Конфигурация базы данных

  • innodb_buffer_pool_size:Увеличьте соответствующим образомInnoDBразмер буферного пула,Позволяет кэшировать больше данных и индексов в памяти.,Уменьшите дисковый ввод-вывод.
  • innodb_log_file_size:Файлы журналов большего размера уменьшают частоту переключения журналов.,Тем самым улучшая производительность письма.
  • innodb_flush_log_at_trx_commit:установлен на1может гарантировать, что каждыйиндивидуальный Когда транзакция зафиксирована, журналыписатьдиск,Храните данные в безопасности,Но это снизит производительность. Установите значение 2 или 0 для увеличения производительности.,но может привести к потере данных。индекс
  • индекс Количество и виды:соответствующийиндекс Может улучшить скорость запросов,Но слишком большой индекс увеличит накладные расходы на операции записи. Необходимо сбалансировать производительность запросов и производительность записи.
  • сложныйиндекс:Разумныйиспользоватьсложныйиндекс Может снизить потребность в обслуживаниииндексколичество,Тем самым улучшая производительность письма.дизайн стола
  • раздел таблицы:Разделить большую таблицу на несколькоиндивидуальный Раздел,Может уменьшить объем данных, которые необходимо обрабатывать при каждой записи.,Тем самым улучшая производительность письма.
  • Тип данных столбца:Использование соответствующих типов данных может уменьшить объем памяти иI/Oдействовать。Например,Используйте TINYINT вместо INT для хранения небольших диапазонов целых чисел.
  • Архивируйте и очищайте исторические данные:Регулярно архивируйте и очищайте исторические данные, которые больше не нужны.,Уменьшите размер таблицы и уменьшите накладные расходы на запись。управление транзакциями
  • Пакетная вставка:использовать Пакетная вставка вместо вставки построчно может существенно повысить производительность записи.
  • размер транзакции:соответствующийразмер Обработка может повысить производительность записи, а слишком большие или слишком маленькие транзакции могут повлиять на производительность.
  • блокировка конфликта:избегайте долгоговремяудерживать замок,может уменьшить конфликты блокировки,улучшатьодновременнописатьпроизводительность。Управление параллелизмом
  • пул соединений:использоватьпул соединения могут снизить затраты на установление и освобождение соединений и повысить производительность записи.
  • Количество одновременных подключений:Разумные настройки Количество одновременных подключений,Избегайте чрезмерных подключений, ведущих к конкуренции за ресурсы ипроизводительностьотклонить。Механизм базы данных
  • InnoDB vs MyISAM:InnoDBПоддерживает блокировку транзакций и строк.,Подходит для интенсивных операций одновременной записи. MyISAM лучше написан по производительности,но нет Поддерживает блокировку транзакций и строк.。сеть
  • сеть Задержка:Минимизируйте трение между клиентом и серверомсеть Задержка,Особенно в распределенных системах.
  • сетьпропускная способность:Убедитесь, что их достаточносетьпропускная способность,избегатьпропускная способностьвызванные недостаткамиузкое место в производительности.Операционная система и файловая система
  • Настройка операционной системы:КорректированиедействоватьсистематическийI/OАлгоритм планирования、Буферизация файловой системы и другие параметры,Может улучшить производительность записи.
  • Выбор файловой системы:Выбирайте высокийпроизводительностьфайловая система,Такие как EXT4, XFS,Оптимизированная файловая системапроизводительность。другой
  • Оптимизация запросов:Обязательно напишитедействовать Сделайте это максимально простым и эффективным,Избегайте сложных запросов и подзапросов.
  • Версия базы данных:использоватьпоследний Версия базы данных, содержит последние оптимизации производительности и исправления.

В реальных сценариях для разных факторов применяются разные стратегии, а техническая мощь повышается за счет непрерывного обучения.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose