Как оптимизировать базу данных для тяжелых операций ввода-вывода из обновлений (программных и аппаратных)

20

Ситуация У меня есть база данных postgresql 9.2, которая постоянно сильно обновляется. Таким образом, система связана с вводом / выводом, и в настоящее время я планирую сделать еще одно обновление, мне просто нужно несколько указаний, с чего начать улучшение.

Вот картина того, как выглядела ситуация последние 3 месяца:

введите описание изображения здесь

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

введите описание изображения здесь

Как видите, максимальная скорость записи составляет около 20 МБ / с.

Программное обеспечение Сервер работает под управлением Ubuntu 12.04 и Postgresql 9.2. Тип обновлений мало обновляется, как правило, в отдельных строках, идентифицированных по идентификатору. Например UPDATE cars SET price=some_price, updated_at = some_time_stamp WHERE id = some_id. Я удалил и оптимизировал индексы настолько, насколько я думаю, насколько это возможно, и конфигурация серверов (как ядра Linux, так и postgres conf) также довольно оптимизирована.

Аппаратное обеспечение Аппаратное обеспечение представляет собой выделенный сервер с 32 ГБ оперативной памяти ECC, 4x 600 ГБ 15.000 об / мин дисков SAS в массиве RAID 10, управляемый контроллером LSI raid с BBU и процессором Intel Xeon E3-1245 Quadcore.

Вопросов

  • Является ли производительность, видимая графиками, приемлемой для системы такого калибра (чтение / запись)?
  • Должен ли я, следовательно, сосредоточиться на обновлении аппаратного обеспечения или глубже исследовать программное обеспечение (настройка ядра, настройки, запросы и т. Д.)?
  • Если обновление аппаратного обеспечения, является ли количество дисков ключом к производительности?

------------------------------ОБНОВИТЬ------------------- ----------------

Теперь я обновил свой сервер базы данных четырьмя твердотельными дисками Intel 520 вместо старых дисков SAS 15k. Я использую тот же контроллер рейда. Вещи значительно улучшились, как вы можете видеть из следующих пиковых показателей производительности ввода-вывода, которые увеличились примерно в 6-10 раз - и это здорово! введите описание изображения здесь Однако я ожидал чего-то большего, например, улучшения в 20-50 раз в зависимости от ответов и возможностей ввода / вывода новых твердотельных накопителей. Так что здесь идет еще один вопрос.

Новый вопрос Есть ли что-то в моей текущей конфигурации, что ограничивает производительность ввода / вывода моей системы (где узкое место)?

Мои конфигурации:

/etc/postgresql/9.2/main/postgresql.conf

data_directory = '/var/lib/postgresql/9.2/main'
hba_file = '/etc/postgresql/9.2/main/pg_hba.conf'
ident_file = '/etc/postgresql/9.2/main/pg_ident.conf'
external_pid_file = '/var/run/postgresql/9.2-main.pid'
listen_addresses = '192.168.0.4, localhost'
port = 5432
unix_socket_directory = '/var/run/postgresql'
wal_level = hot_standby
synchronous_commit = on
checkpoint_timeout = 10min
archive_mode = on
archive_command = 'rsync -a %p postgres@192.168.0.2:/var/lib/postgresql/9.2/wals/%f </dev/null'
max_wal_senders = 1
wal_keep_segments = 32
hot_standby = on
log_line_prefix = '%t '
datestyle = 'iso, mdy'
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
default_text_search_config = 'pg_catalog.english'
default_statistics_target = 100
maintenance_work_mem = 1920MB
checkpoint_completion_target = 0.7
effective_cache_size = 22GB
work_mem = 160MB
wal_buffers = 16MB
checkpoint_segments = 32
shared_buffers = 7680MB
max_connections = 400 

/etc/sysctl.conf

# sysctl config
#net.ipv4.ip_forward=1
net.ipv4.conf.all.rp_filter=1
net.ipv4.icmp_echo_ignore_broadcasts=1
# ipv6 settings (no autoconfiguration)
net.ipv6.conf.default.autoconf=0
net.ipv6.conf.default.accept_dad=0
net.ipv6.conf.default.accept_ra=0
net.ipv6.conf.default.accept_ra_defrtr=0
net.ipv6.conf.default.accept_ra_rtr_pref=0
net.ipv6.conf.default.accept_ra_pinfo=0
net.ipv6.conf.default.accept_source_route=0
net.ipv6.conf.default.accept_redirects=0
net.ipv6.conf.default.forwarding=0
net.ipv6.conf.all.autoconf=0
net.ipv6.conf.all.accept_dad=0
net.ipv6.conf.all.accept_ra=0
net.ipv6.conf.all.accept_ra_defrtr=0
net.ipv6.conf.all.accept_ra_rtr_pref=0
net.ipv6.conf.all.accept_ra_pinfo=0
net.ipv6.conf.all.accept_source_route=0
net.ipv6.conf.all.accept_redirects=0
net.ipv6.conf.all.forwarding=0
# Updated according to postgresql tuning
vm.dirty_ratio = 10
vm.dirty_background_ratio = 1
vm.swappiness = 0
vm.overcommit_memory = 2
kernel.sched_autogroup_enabled = 0
kernel.sched_migration_cost = 50000000

/etc/sysctl.d/30-postgresql-shm.conf

# Shared memory settings for PostgreSQL
# Note that if another program uses shared memory as well, you will have to
# coordinate the size settings between the two.
# Maximum size of shared memory segment in bytes
#kernel.shmmax = 33554432
# Maximum total size of shared memory in pages (normally 4096 bytes)
#kernel.shmall = 2097152
kernel.shmmax = 8589934592
kernel.shmall = 17179869184
# Updated according to postgresql tuning

Выход из MegaCli64 -LDInfo -LAll -aAll

Adapter 0 -- Virtual Drive Information:
Virtual Drive: 0 (Target Id: 0)
Name                :
RAID Level          : Primary-1, Secondary-0, RAID Level Qualifier-0
Size                : 446.125 GB
Sector Size         : 512
Is VD emulated      : No
Mirror Data         : 446.125 GB
State               : Optimal
Strip Size          : 64 KB
Number Of Drives per span:2
Span Depth          : 2
Default Cache Policy: WriteBack, ReadAhead, Direct, Write Cache OK if Bad BBU
Current Cache Policy: WriteBack, ReadAhead, Direct, Write Cache OK if Bad BBU
Default Access Policy: Read/Write
Current Access Policy: Read/Write
Disk Cache Policy   : Disk's Default
Encryption Type     : None
Is VD Cached: No
Нильс Кристиан
источник
(1). Если столбцы не проиндексированы, вы можете воспользоваться функцией HOT (см. Git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/… ). (2). Попробуйте synchronous_commit = off, прочитав документы на postgresql.org/docs/9.2/static/wal-async-commit.html . (3). Как выглядит ваша конфигурация? Например. Результаты этого запроса:SELECT name, current_setting(name), source FROM pg_settings WHERE source NOT IN ('default', 'override');
BMA
@bma Позвольте мне добавить предупреждение synchronous_commit: «Асинхронная фиксация - это опция, которая позволяет транзакциям завершаться быстрее, за счет того, что самые последние транзакции могут быть потеряны в случае сбоя базы данных».
Дезсо
@dezso Я должен был быть более откровенным о разделе документов, на который я ссылался. Благодарю за разъяснение. Причина, по которой я это поднял, заключалась в том, что один из наших серверов под высокой нагрузкой (использующий Hibernate) страдал, поэтому я принял осознанное решение переключиться на асинхронную фиксацию, и 40% нагрузки практически исчезло. Не рекомендуется для большинства систем, но в некоторых случаях это может выиграть время между обновлениями сервера и изменениями приложений.
BMA

Ответы:

10

Если обновление аппаратного обеспечения, является ли количество дисков ключом к производительности?

Да, поскольку жесткий диск - даже SAS - имеет головку, для перемещения которой требуется время.

Хотите HUGH обновление?

Убейте диски SAS, перейдите на SATA. Подключите SATA SSD - корпоративного уровня, как Samsung 843T.

Результат? Вы можете выполнить около 60 000 (то есть 60 тысяч) операций ввода-вывода в секунду на диск.

По этой причине твердотельные накопители являются убийцами в пространстве БД и намного дешевле, чем любой диск SAS. Прядильный диск Phyiscal просто не успевает за возможностями дисков IOPS.

Ваши диски SAS были довольно посредственным выбором (слишком большой, чтобы получить много операций ввода-вывода в секунду). Для базы данных с более высоким уровнем использования (более мелкие диски означали бы гораздо больше операций ввода-вывода в секунду), но в конце SSD меняют правила игры.

По поводу программного обеспечения / ядра. Любая приличная база данных будет делать много операций ввода-вывода в секунду и очищать буферы. Файл журнала должен быть ЗАПИСАН для обеспечения основных условий ACID. Единственные настройки ядра, которые вы могли бы сделать, сделали бы недействительной вашу транзакционную целостность - частично вы МОЖЕТЕ сойти с рук. Контроллер Raid в режиме обратной записи сделает это - подтвердит запись как сброшенную, даже если это не так - но он может это сделать, поскольку предполагается, что BBU спасает день, когда отключается питание. Все, что вы делаете выше в ядре - лучше знать, что вы можете жить с негативными побочными эффектами.

В конце концов, базам данных требуется IOPS, и вы можете быть удивлены, увидев, насколько крошечные ваши настройки по сравнению с некоторыми другими здесь. Я видел базы данных со 100+ дисками только для того, чтобы получить необходимые IOPS. Но на самом деле, сегодня вы покупаете SSD и выбираете их размер - они настолько превосходят возможности IOPS, что нет смысла бороться с этой игрой с накопителями SAS.

И да, ваши цифры IOPS не выглядят плохо для оборудования. В пределах того, что я ожидал.

TomTom
источник
6

Если вы можете себе это позволить, поместите pg_xlog на отдельную пару дисков RAID 1 на своем собственном контроллере с ОЗУ с резервным питанием от батареи, сконфигурированным для обратной записи. Это верно, даже если вам нужно использовать вращающуюся ржавчину для pg_xlog, в то время как все остальное находится на SSD.

Если вы используете SSD, убедитесь, что у него есть суперконденсатор или другие средства для сохранения всех кэшированных данных при сбое питания.

В общем, чем больше шпинделей, тем больше пропускная способность ввода / вывода.

kgrittn
источник
К сожалению, у меня есть только четыре жестких диска в контроллере рейда. Зачем вам помещать pg_xlogs в отдельный массив, если все остальные диски были SSD?
Нильс Кристиан
2
@NielsKristian Я думаю, что я прав, когда говорю, что в большинстве систем журнал транзакций является наиболее часто записываемой вещью на диске. Кроме того, написание это происходит в основном параллельно с записью данных. Эти два нельзя сделать одновременно с жестким диском, так как заголовок находится либо в pg_xlog, либо в папках данных. (Серьезное предупреждение об упрощении!) Разделение двух задач распределяет нагрузку ввода-вывода на два независимых диска / массива.
Дезсо
2
В дополнение к тому, что сказал @dezso, жесткие диски подходят для хранения данных, предназначенных для WAL, потому что доступ почти полностью последовательный, поэтому время поиска минимально ..
kgrittn
1

Предполагая, что вы работаете в Linux, обязательно установите планировщик дискового ввода-вывода.

Исходя из прошлого опыта, переключение на noop даст вам довольно существенное ускорение (особенно для SSD).

Смена планировщика ввода-вывода может быть выполнена на лету без простоев.

то есть. echo noop> / sys / block // очередь / планировщик

Смотрите: http://www.cyberciti.biz/faq/linux-change-io-scheduler-for-harddisk/ для получения дополнительной информации.

Пол Майлз
источник