1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/blackeybaord-kingshard

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
kingshard_performance_profiling.md 14 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 29.11.2024 18:42 b4fbb46

Кингшард: оптимизация производительности в сфере сетевого взаимодействия

В последнее время разработка функций Kingshard замедлилась. С одной стороны, работа действительно очень загруженная, с другой стороны, я считаю, что функциональность Kingshard уже достаточно хорошо проработана, и основное внимание следует уделить оптимизации производительности. В конце концов, как MySQL proxy, если производительность пересылки SQL плохая, то дополнительные функции не принесут пользы. Поэтому на этих выходных я провёл всё время дома, оптимизируя производительность пересылки Kingshard. После двух дней исследований и разработок было обнаружено, что производительность пересылки запросов Kingshard была улучшена примерно на 18%. В ходе этого процесса я также узнал о некоторых знаниях. Воспользовавшись этой возможностью, чтобы поделиться ими, а также подстегнуть себя к написанию блога.

1. Определение узких мест в производительности Kingshard

Прежде всего, для оптимизации производительности Kingshard необходимо определить, где находятся узкие места в его производительности. Go предоставляет отличные возможности для оптимизации производительности, и с помощью инструмента pprof языка Go мы можем легко получить информацию о времени выполнения каждой функции при пересылке запросов SQL.

1.1 Настройка среды

Согласно руководству по использованию Kingshard, была создана среда прокси Kingshard. Я использовал Macbook для создания среды, параметры оборудования следующие:

CPU: 2.2GHZ * 4
内存:16GB
硬盘: 256GB

1.2 Шаги тестирования производительности

Конкретные шаги следующие:

  1. Получить библиотеку анализа производительности:
go get github.com/pkg/profile
  1. Импортировать этот компонент в проект.
  2. Добавить функцию запуска и остановки мониторинга производительности процессора в начале основной функции kingshard/cmd/kingshard/main.go:
func main() {
    defer profile.Start(profile.CPUProfile).Stop()
    fmt.Print(banner)
    runtime.GOMAXPROCS(runtime.NumCPU())
    flag.Parse()
    ....
}
  1. Перекомпилировать проект и запустить Kingshard:
./bin/kingshard -config=etc/ks.yaml
  1. После запуска Kingshard в терминале появится следующее сообщение:
2015/10/31 10:28:06 profile: cpu profiling enabled, /var/folders/4q/zzb55sfj377b6vdyz2brt6sc0000gn/T/profile205276958/cpu.pprof

Путь после сообщения — это путь к файлу анализа производительности pprof, который можно остановить, нажав Ctrl+C. 6. Затем используйте sysbench для стресс-тестирования Kingshard, чтобы получить QPS (для установки и использования sysbench обратитесь к Google). Конкретный код выглядит следующим образом:

sysbench --test=oltp --num-threads=16 --max-requests=160000 --oltp-test-mode=nontrx --db-driver=mysql --mysql-db=kingshard --mysql-host=127.0.0.1 --mysql-port=9696 --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-user=kingshard --mysql-password=kingshard --oltp-nontrx-mode=select --db-ps-mode=disable run

Полученные результаты:

OLTP test statistics:
    queries performed:
        read:                            160071
        write:                           0
        other:                           0
        total:                           160071
    transactions:                        160071 (16552.58 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 160071 (16552.58 per sec.)
    other operations:                    0      (0.00 per sec.)

Test execution summary:
    total time:                          9.6705s
    total number of events:              160071
    total time taken by event execution: 154.4474
    per-request statistics:
         min:                                  0.29ms
         avg:                                  0.96ms
         max:                                 14.17ms
         approx.  95 percentile:               1.37ms

Threads fairness:
    events (avg/stddev):           10004.4375/24.95
    execution time (avg/stddev):   9.6530/0.00
  • Согласно вышеуказанным шагам, тест проводился три раза (16 552,58, 16 769,72, 16 550,16), и среднее значение было взято для получения QPS до оптимизации Kingshard, которое составило 16 624,15.
  • Следуя вышеуказанным шагам, напрямую подключитесь к MySQL. Протестируйте QPS прямого подключения к MySQL, также протестируйте три раза QPS (27 730,90, 28 499,05, 27 119,20), и получите QPS прямого подключения к MySQL 27 783,05.
  • Из этих данных можно рассчитать, что производительность Kingshard при пересылке SQL составляет около 59% от прямого подключения MySQL.
  1. Скопируйте файл cpu.prof в каталог, где находится bin/kingshard.
  2. Используйте инструмент go для создания PDF-документа о производительности CPU:
go tool pprof -pdf ./kingshard cpu.pprof > report.pdf

2. Анализ отчёта о тестировании производительности

С помощью вышеуказанной команды можно создать отчёт о времени выполнения основных функций во время стресс-теста. Из отчёта видно, что основная задержка связана со слоем TCP для передачи данных. Таким образом, мы должны сосредоточиться на том, как оптимизировать производительность слоя TCP для передачи данных. Оптимизируя эффективность передачи TCP, первое, о чём я подумал, это уменьшить количество системных вызовов, передавая как можно больше данных в каждом пакете данных.

При использовании TCP-сокета для связи данные разбиваются на блоки данных, которые затем могут быть инкапсулированы в TCP payload (полезную нагрузку TCP-пакета) соединения. Размер TCP payload зависит от нескольких факторов (например, максимальный размер пакета и маршрут), но эти факторы известны при установлении соединения. Чтобы достичь наилучшей производительности, наша цель состоит в том, чтобы использовать как можно больше доступных данных для заполнения каждого пакета данных. Когда данных недостаточно для заполнения сегмента пакета (также известного как максимальный сегмент размера или MSS), TCP будет использовать алгоритм Nagle для объединения небольших буферов в сегмент пакета. Это может повысить эффективность приложения за счёт минимизации количества отправляемых пакетов и облегчить общую проблему перегрузки сети.

Поскольку этот алгоритм объединяет данные, пытаясь сформировать полный сегмент TCP-пакетов, он вводит некоторую задержку. Однако этот алгоритм может минимизировать количество пакетов, отправляемых по сети, тем самым уменьшая перегрузку сети. Но в ситуациях, когда требуется минимизировать задержку передачи, API Sockets в GO может предоставить решение. То есть через:

func (c *TCPConn) SetNoDelay(noDelay bool) error

Эта функция в Go по умолчанию установлена в true, что означает, что опция задержки отключена. Нам нужно установить её в false, чтобы передавать как можно больше данных в каждом пакете, уменьшая количество системных вызовов.

2.1 Модификация кода и тестирование производительности

После обнаружения узкого места производительности были внесены изменения в функции newClientConn в proxy/server/server.go и ReConnect в backend/backend_conn.go, соответственно установив соединение между клиентом и Kingshard и соединение между Kingshard и MySQL для минимизации задержки передачи. Конкретные изменения кода можно увидеть в этом коммите.

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

OLTP test statistics:
    queries performed:
        read:
``` **Запись**: 0
**Другое**: 0
**Всего**: 160174

**Транзакции**: 160 174 (21 291,68 в секунду)
**Тупиковые ситуации**: 0 (0,00 в секунду)
**Запросы на чтение/запись**: 160 174 (21 291,68 в секунду)
**Другие операции**: 0 (0,00 в секунду).

**Итоги выполнения теста**:
* Общее время: 7,5228 с.
* Общее количество событий: 160 174.
* Время, затраченное на выполнение события: 119,9655.
* Статистика по запросам:
    * min: 0,26 мс.
    * avg: 0,75 мс.
    * max: 10,78 мс.
    * примерно 95-й процентиль: 1,13 мс.

**Справедливость потоков**:
* События (среднее значение/стандартное отклонение): 10 010,8750/38,65.
* Время выполнения (среднее значение/стандартное отклонение): 7,4978/0.

QPS после трёх тестов: 21 291,68; 21 670,85; 21 463,44. **Что соответствует примерно 77% производительности прямого MySQL и улучшению производительности примерно на 18% после оптимизации**.

## Заключение

В этой статье подробно описаны шаги для анализа производительности kingshard с помощью pprof, предоставляемого языком Go. Другие проекты на Go также могут использовать аналогичные шаги для создания отчётов о производительности. Ключевым моментом в оптимизации производительности является выявление узких мест, а затем поиск решений для их устранения. Иногда простые оптимизации могут привести к неожиданным результатам. Надеюсь, эта статья даст разработчикам Go представление о том, как подходить к оптимизации производительности. В заключение хочу сделать объявление: kingshard — это проект с открытым исходным кодом, который поддерживает сегментирование и стал довольно стабильным. После оптимизации производительность пересылки SQL значительно улучшилась. В будущем я планирую продолжить оптимизацию kingshard в области блокировок и памяти, так что следите за обновлениями.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/blackeybaord-kingshard.git
git@api.gitlife.ru:oschina-mirror/blackeybaord-kingshard.git
oschina-mirror
blackeybaord-kingshard
blackeybaord-kingshard
master