В последнее время разработка функций Kingshard замедлилась. С одной стороны, работа действительно очень загруженная, с другой стороны, я считаю, что функциональность Kingshard уже достаточно хорошо проработана, и основное внимание следует уделить оптимизации производительности. В конце концов, как MySQL proxy, если производительность пересылки SQL плохая, то дополнительные функции не принесут пользы. Поэтому на этих выходных я провёл всё время дома, оптимизируя производительность пересылки Kingshard. После двух дней исследований и разработок было обнаружено, что производительность пересылки запросов Kingshard была улучшена примерно на 18%. В ходе этого процесса я также узнал о некоторых знаниях. Воспользовавшись этой возможностью, чтобы поделиться ими, а также подстегнуть себя к написанию блога.
Прежде всего, для оптимизации производительности Kingshard необходимо определить, где находятся узкие места в его производительности. Go предоставляет отличные возможности для оптимизации производительности, и с помощью инструмента pprof языка Go мы можем легко получить информацию о времени выполнения каждой функции при пересылке запросов SQL.
Согласно руководству по использованию Kingshard, была создана среда прокси Kingshard. Я использовал Macbook для создания среды, параметры оборудования следующие:
CPU: 2.2GHZ * 4
内存:16GB
硬盘: 256GB
Конкретные шаги следующие:
go get github.com/pkg/profile
func main() {
defer profile.Start(profile.CPUProfile).Stop()
fmt.Print(banner)
runtime.GOMAXPROCS(runtime.NumCPU())
flag.Parse()
....
}
./bin/kingshard -config=etc/ks.yaml
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
go tool pprof -pdf ./kingshard cpu.pprof > report.pdf
С помощью вышеуказанной команды можно создать отчёт о времени выполнения основных функций во время стресс-теста. Из отчёта видно, что основная задержка связана со слоем 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, чтобы передавать как можно больше данных в каждом пакете, уменьшая количество системных вызовов.
После обнаружения узкого места производительности были внесены изменения в функции 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 )