Когда дело доходит до настройки производительности среды, часто первое, с чего начать, — это база данных. Причина этого в том, что большинство приложений очень сильно зависят от какой-либо базы данных.
К сожалению, базы данных могут быть одной из самых сложных областей для настройки. Причина, по которой я это говорю, заключается в том, что для правильной настройки службы базы данных часто требуется настроить больше, чем сама служба базы данных; это часто требует внесения изменений в оборудование, ОС или даже приложения.
Помимо того, что требуется разнообразный набор навыков, одна из самых больших проблем при настройке базы данных — это создание достаточного количества имитируемого трафика базы данных для нагрузки на службу базы данных. Вот почему в сегодняшней статье будет рассмотрен pgbench
, инструмент для тестирования производительности, используемый для измерения производительности экземпляра PostgreSQL .
PostgreSQL — это очень популярная реляционная база данных с открытым исходным кодом. Одна из приятных особенностей PostgreSQL заключается в том, что было создано немало инструментов, помогающих управлять PostgreSQL; pgbench
— один из таких инструментов.
Исследуя pgbench
, мы также будем использовать его для измерения прироста / потери производительности для обычной настраиваемой версии PostgreSQL.
Настройка экземпляра PostgreSQL
Прежде чем мы сможем использовать pgbench
для настройки службы базы данных, мы должны сначала запустить эту службу базы данных. Ниже приведены шаги по настройке базового экземпляра PostgreSQL на сервере Ubuntu 16.04 .
Установка с помощью apt-get
Установить PostgreSQL в системе Ubuntu довольно просто. Большая часть работы выполняется простым запуском команды apt-get
.
1
|
# apt-get install postgresql postgresql-contrib |
Приведенная выше команда apt-get
устанавливает оба пакета postgresql
и postgresql-contrib
. Пакет postgresql
устанавливает базовый сервис PostgreSQL.
Пакет postgresql-contrib
устанавливает дополнительные материалы для PostgreSQL. Эти материалы еще не были добавлены в официальный пакет, но часто предоставляют довольно мало функциональности.
С установленными пакетами у нас теперь есть работающий экземпляр PostgreSQL. Мы можем проверить это с помощью команды systemctl
чтобы проверить состояние PostgreSQL.
1
2
3
4
5
6
7
8
9
|
# systemctl status postgresql ● postgresql.service - PostgreSQL RDBMS Loaded: loaded (/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled) Active: active (exited) since Mon 2017 - 01 - 02 21 : 14 : 36 UTC; 7h ago Process: 16075 ExecStart=/bin/ true (code=exited, status= 0 /SUCCESS) Main PID: 16075 (code=exited, status= 0 /SUCCESS) Jan 02 21 : 14 : 36 ubuntu-xenial systemd[ 1 ]: Starting PostgreSQL RDBMS... Jan 02 21 : 14 : 36 ubuntu-xenial systemd[ 1 ]: Started PostgreSQL RDBMS. |
Выше указано, что наш экземпляр запущен без проблем. Теперь мы можем перейти к следующему шагу — созданию базы данных.
Создание базы данных
Когда мы установили пакет postgresql
, этот пакет включал создание пользователя с именем postgres
. Этот пользователь используется как владелец запущенного экземпляра. Он также служит администратором для службы PostgreSQL.
Чтобы создать базу данных, нам нужно будет войти в систему этому пользователю, что достигается выполнением команды su
.
1
|
# su - postgres |
После переключения на пользователя postgres
мы можем войти в работающий экземпляр с помощью клиента PostgreSQL, psql
.
1
2
3
4
5
|
$ psql psql ( 9.5 . 5 ) Type "help" for help. postgres=# |
После выполнения команды psql
мы оказались в среде командной строки PostgreSQL. Отсюда мы можем выдавать операторы SQL или использовать специальные клиентские команды для выполнения действий.
Например, мы можем вывести список текущих баз данных, выполнив команду \list
.
01
02
03
04
05
06
07
08
09
10
|
postgres-# \list List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | template0 | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | =c/postgres + | | | | | postgres=CTc/postgres ( 3 rows) |
После выполнения команды \list
были возвращены три базы данных. Это базы данных по умолчанию, которые были созданы в процессе первоначальной установки.
Для нашего сегодняшнего тестирования мы будем создавать новую базу данных. Давайте продолжим и создадим эту базу данных, назвав ее примером . Мы можем сделать это, выполнив следующую инструкцию SQL:
1
|
CREATE DATABASE example; |
После выполнения мы можем проверить, что база данных была создана, снова выполнив команду \list
.
01
02
03
04
05
06
07
08
09
10
11
|
postgres=# \list List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- example | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | postgres | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | template0 | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF- 8 | en_US.UTF- 8 | =c/postgres + | | | | | postgres=CTc/postgres ( 4 rows) |
На данный момент у нас есть пустая база данных с именем example . С этого момента нам нужно вернуться в нашу оболочку bash
для выполнения команд pgbench
. Мы можем сделать это, введя команду \q
(quit).
1
|
postgres-# \q |
Выйдя из среды командной строки PostgreSQL, мы можем начать использовать pgbench
для оценки производительности нашего экземпляра базы данных.
Использование pgbench для измерения производительности
Одной из самых сложных вещей в измерении производительности базы данных является генерирование достаточной нагрузки. Популярный вариант — просто бомбардировать тестовые экземпляры целевого приложения или приложений тестовыми транзакциями. Хотя это полезный тест, который обеспечивает производительность БД по отношению к приложению, иногда он может быть проблематичным, поскольку узкие места приложения могут ограничивать тестирование базы данных.
В таких ситуациях такие инструменты, как pgbench
пригодятся. С помощью pgbench
вы можете использовать пример базы данных, поставляемой с pgbench
или сделать так, чтобы pgbench
выполнял пользовательские запросы к базе данных приложения.
В этой статье мы будем использовать пример базы данных, которая поставляется с pgbench
.
Настройка примера базы данных pgbench
Настройка примера базы данных довольно проста и довольно быстра. Мы можем запустить этот процесс, выполнив pgbench
с опцией -i
(initialize).
1
2
3
4
5
6
|
$ pgbench -i -s 50 example creating tables... 5000000 of 5000000 tuples ( 100 %) done (elapsed 5.33 s, remaining 0.00 s) vacuum... set primary keys... done. |
В приведенной выше команде мы выполнили pgbench
с параметром -i
и параметром -s
за которым следует имя базы данных ( example
).
Опция -i
(initialize) скажет pgbench
инициализировать указанную базу данных. Это означает, что pgbench
создаст следующие таблицы в базе данных example
.
1
2
3
4
5
6
|
table # of rows --------------------------------- pgbench_branches 1 pgbench_tellers 10 pgbench_accounts 100000 pgbench_history 0 |
По умолчанию pgbench
создаст таблицы выше с количеством строк, показанных выше. Это создает простую базу данных 16MB
.
Поскольку мы будем использовать pgbench
для измерения изменений в производительности, небольшой базы данных размером 16MB
будет недостаточно, чтобы подчеркнуть нашу ситуацию. Здесь вступает в игру опция -s
(масштабирование).
Опция -s
используется для умножения количества строк, введенных в каждую таблицу. В приведенной выше команде мы ввели опцию «масштабирования», равную 50
. Это сказало pgbench
создать базу данных в 50 раз больше размера по умолчанию.
Это означает, что наша таблица pgbench_accounts
теперь содержит 5,000,000
записей. Это также означает, что размер нашей базы данных теперь составляет 800MB
50 x 16MB
( 50 x 16MB
).
Чтобы убедиться, что наши таблицы были созданы успешно, давайте продолжим и снова запустим клиент psql
.
1
2
3
4
5
|
$ psql -d example psql ( 9.5 . 5 ) Type "help" for help. example=# |
В приведенной выше команде мы использовали флаг -d
(база данных), чтобы сообщить psql
не только о подключении к службе PostgreSQL, но и о переключении на пример базы данных.
Поскольку в настоящее время мы используем пример базы данных, мы можем выполнить команду \dt
для просмотра списка таблиц, доступных в этой базе данных.
1
2
3
4
5
6
7
8
9
|
example=# \dt List of relations Schema | Name | Type | Owner --------+------------------+-------+---------- public | pgbench_accounts | table | postgres public | pgbench_branches | table | postgres public | pgbench_history | table | postgres public | pgbench_tellers | table | postgres ( 4 rows) |
Из таблицы выше видно, что pgbench
создал четыре ожидаемые таблицы. Это означает, что наша база данных заполнена и готова к использованию для измерения производительности нашего экземпляра базы данных.
Установление базовой линии
При любой настройке производительности лучше всего сначала установить базовую производительность. Этот базовый уровень будет служить для измерения того, повлияли ли внесенные вами изменения на увеличение или снижение производительности.
Давайте продолжим и вызовем pgbench
чтобы установить базовый уровень для нашего «готового» экземпляра PostgreSQL.
01
02
03
04
05
06
07
08
09
10
11
12
|
$ pgbench -c 10 -j 2 -t 10000 example starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 number of transactions per client: 10000 number of transactions actually processed: 100000 / 100000 latency average: 4.176 ms tps = 2394.718707 (including connections establishing) tps = 2394.874350 (excluding connections establishing) |
При вызове pgbench
мы добавляем в команду довольно много опций. Первым является -c
(клиенты), который используется для определения количества клиентов, с которыми нужно соединиться. Для этого тестирования я использовал 10
чтобы указать pgbench
выполнить с 10 клиентами.
Это означает, что когда pgbench
выполняет тесты, он открывает 10 разных сессий.
Следующая опция — флаг -j
(threads). Этот флаг используется для определения количества рабочих процессов для pgbench
. В приведенной выше команде я указал значение 2
. Это скажет pgbench
запустить два рабочих процесса во время бенчмаркинга.
Третий параметр — -t
(транзакции), который используется для указания количества транзакций, которые нужно выполнить. В приведенной выше команде я указал значение 10,000
. Однако это не означает, что с нашей службой базы данных будет выполнено только 10,000
транзакций. Это означает, что каждый клиентский сеанс будет выполнять 10,000
транзакций.
Подводя итог, можно сказать, что базовый тестовый запуск состоял из двух рабочих процессов pgbench
имитирующих 10,000
транзакций от 10
клиентов, в общей сложности 100,000
транзакций.
С этим пониманием давайте посмотрим на результаты этого первого теста.
01
02
03
04
05
06
07
08
09
10
11
12
|
$ pgbench -c 10 -j 2 -t 10000 example starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 number of transactions per client: 10000 number of transactions actually processed: 100000 / 100000 latency average: 4.176 ms tps = 2394.718707 (including connections establishing) tps = 2394.874350 (excluding connections establishing) |
Вывод pgbench
содержит довольно мало информации. Большинство из них описывает выполняемые тестовые сценарии. Больше всего нас интересует следующее:
1
2
|
tps = 2394.718707 (including connections establishing) tps = 2394.874350 (excluding connections establishing) |
Исходя из этих результатов, наша базовая линия составляет 2,394
транзакции базы данных в секунду. Давайте продолжим и посмотрим, сможем ли мы увеличить это число, изменив простой параметр конфигурации в PostgreSQL.
Добавляем больше кеша
Одним из параметров перехода для любого, кто настраивает PostgreSQL, является параметр shared_buffers
. Этот параметр используется для указания объема памяти, который служба PostgreSQL может использовать для кэширования. Этот механизм кэширования используется для хранения содержимого таблиц и индексов в памяти.
Чтобы показать, как мы можем использовать pgbench
для настройки производительности, мы будем корректировать это значение для тестирования прироста / снижения производительности.
По умолчанию значение shared_buffers
установлено в 128MB
, что является довольно низким значением, учитывая объем доступной памяти на большинстве серверов сегодня. Мы можем убедиться в этом сами, посмотрев содержимое файла /etc/postgresql/9.5/main/postgresql.conf
. В этом файле мы должны увидеть следующее.
1
2
3
4
|
# - Memory - shared_buffers = 128MB # min 128kB # (change requires restart) |
Давайте продолжим и переключим это значение на 256MB
, фактически удвоив доступное пространство кеша.
1
2
3
4
|
# - Memory - shared_buffers = 256MB # min 128kB # (change requires restart) |
После завершения нам нужно будет перезапустить сервис PostgreSQL. Мы можем сделать это, выполнив команду systemctl
с параметром restart
.
1
|
# systemctl restart postgresql |
Как только сервис будет полностью запущен, мы можем снова использовать pgbench
для измерения нашей производительности.
01
02
03
04
05
06
07
08
09
10
11
12
|
$ pgbench -c 10 -j 2 -t 10000 example starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 number of transactions per client: 10000 number of transactions actually processed: 100000 / 100000 latency average: 3.921 ms tps = 2550.313477 (including connections establishing) tps = 2550.480149 (excluding connections establishing) |
В нашем предыдущем базовом тесте мы смогли достичь скорости 2,394
транзакций в секунду. В этом последнем запуске после обновления параметра shared_buffers
мы смогли выполнить 2,550
транзакций в секунду, увеличившись на 156
. Хотя это неплохое начало, мы все равно можем пойти дальше.
Хотя параметр shared_buffers
может начинаться с 128MB
, рекомендуемое значение этого параметра — одна четвертая системной памяти. Наша тестовая система имеет 2GB
системной памяти, значение, которое мы можем проверить с помощью команды free
.
1
2
3
4
|
$ free -m total used free shared buff/cache available Mem: 2000 54 109 548 1836 1223 Swap: 0 0 0 |
В приведенном выше выводе мы видим, что в столбце 2000MB
в строке для памяти 2000MB
значение 2000MB
. В этом столбце отображается общий объем физической памяти, доступной для системы. Мы также можем видеть в available
столбце, что 1223MB
показывает доступные. Это означает, что у нас есть до 1.2
ГБ свободной памяти, которую мы можем использовать в наших настройках.
Если мы изменим наш параметр shared_buffers
на рекомендуемое значение одной четвертой системной памяти, нам потребуется изменить его на 512MB
. Давайте сделаем это изменение и повторно pgbench
наш тест pgbench
.
1
2
3
4
|
# - Memory - shared_buffers = 512MB # min 128kB # (change requires restart) |
shared_buffers
значение shared_buffers
в /etc/postgresql/9.5/main/postgresql.conf
, мы можем продолжить и перезапустить службу PostgreSQL.
1
|
# systemctl restart postgresql |
После перезапуска перезапустим наш тест.
01
02
03
04
05
06
07
08
09
10
11
12
|
$ pgbench -c 10 -j 2 -t 10000 example starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 number of transactions per client: 10000 number of transactions actually processed: 100000 / 100000 latency average: 3.756 ms tps = 2662.750932 (including connections establishing) tps = 2663.066421 (excluding connections establishing) |
На этот раз нашей системе удалось достичь 2,662
транзакций в секунду, что дополнительно увеличило 112
транзакций в секунду. Поскольку количество транзакций в секунду увеличилось как минимум в 100
раз, давайте сделаем еще один шаг и посмотрим, что произойдет, если изменить это значение на 1GB
.
1
2
3
4
|
# - Memory - shared_buffers = 1024MB # min 128kB # (change requires restart) |
После обновления значения нам нужно будет еще раз перезапустить сервис PostgreSQL.
1
|
# systemctl restart postgresql |
После перезапуска службы мы можем перезапустить наш тест.
01
02
03
04
05
06
07
08
09
10
11
12
|
$ pgbench -c 10 -j 2 -t 10000 example starting vacuum...end. transaction type: TPC-B (sort of) scaling factor: 50 query mode: simple number of clients: 10 number of threads: 2 number of transactions per client: 10000 number of transactions actually processed: 100000 / 100000 latency average: 3.744 ms tps = 2670.791865 (including connections establishing) tps = 2671.079076 (excluding connections establishing) |
На этот раз количество транзакций в секунду увеличилось с 2,662
до 2,671
и число операций выросло на 9
в секунду. Это ситуация, когда мы получаем убывающую отдачу.
Хотя во многих средах возможно увеличить значение shared_buffers
за пределы одной четвертой рекомендации, это не возвращает те же результаты для этой тестовой базы данных.
Резюме
Исходя из результатов нашего тестирования, мы видим, что изменение значения shared_buffers
со 128MB
до 512MB
в нашей тестовой системе привело к увеличению производительности на 268
транзакций в секунду. Исходя из наших базовых результатов, это увеличение производительности на 10 процентов .
Мы сделали все это на базовом экземпляре PostgreSQL, используя образец базы данных pgbench
. Это значит, что нам не нужно было загружать наше приложение, чтобы получить базовый показатель эффективности работы PostgreSQL.
Хотя мы смогли увеличить нашу пропускную способность, изменив параметр shared_buffers
в PostgreSQL, доступно гораздо больше параметров настройки. Для тех, кто хочет настроить экземпляр PostgreSQL, я настоятельно рекомендую проверить вики PostgreSQL.
Ссылка: | Настройка PostgreSQL с pgbench от нашего партнера по JCG Бена Кейна в блоге Codeship Blog . |