optimization of a big postgresql database

39
Оптимизация производительности большой унаследованной PostgreSQL базы Электропрохладительный кислотный тест Александр Чистяков, главный инженер Git in Sky, 2014

Upload: alex-chistyakov

Post on 18-May-2015

1.566 views

Category:

Technology


0 download

DESCRIPTION

My presentation from Stachka'14 on PostgreSQL optimization

TRANSCRIPT

Page 1: Optimization of a big PostgreSQL database

Оптимизация производительности большой унаследованной PostgreSQL

базы

Электропрохладительный кислотный тест

Александр Чистяков, главный инженер Git in Sky,

2014

Page 2: Optimization of a big PostgreSQL database

Кто я?

§ Меня зовут Саша§ Я инженер, главный инженер§ В компании Git in Sky§ Я люблю оптимизировать производительность§ Потому что это как волшебная сказка!

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 3: Optimization of a big PostgreSQL database

Где я? Кто вы?

§ Любите волшебные сказки?§ Пришли послушать про базу данных?§ Пришли послушать про оптимизацию производительности?§ Разрабатываете проекты для веб?§ Поддерживаете проекты в веб?§ У вас уже есть PostgreSQL?

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 4: Optimization of a big PostgreSQL database

О чем речь?

§ Доклад в жанре “field report”§ Если угодно - “trip report” (см. подназвание доклада)§ Предыстория: http://www.slideshare.net/profyclub_ru/08-6§ Однажды ко мне в дверь постучал

добрый волшебник§ И все заверте...

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 5: Optimization of a big PostgreSQL database

Краткое содержание предыдущих серий

§ Заказчик — конструктор сайтов http://setup.ru§ Пользовательский статический контент (файлы) хранится в

базе данных (PostgreSQL)§ Для больших файлов используются large objects§ Приложение на Perl, работает под Apache + mod_perl§ Переходим из 2012-го года в 2014-й, и...

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 6: Optimization of a big PostgreSQL database

Наше время

§ Было 6 миллионов файлов в базе — стало 207 миллионов (с версиями)/85 миллионов (без версий)

§ Времена, когда индексы были 2Gb, давно прошли§ Синхронизация тоже не 100 файлов в секунду, а в лучшем

случае 80, обычно — от 20 до 50§ База данных занимает на дисках ~6Tb§ И объем будет только расти

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 7: Optimization of a big PostgreSQL database

Почему не ...?

§ Россия — страна советов! (Каждый суслик — агроном!)§ “Работает — не трогай” (на самом деле, нет, но)§ У решений могут быть бизнес-причины§ TIMTOWTDI! (Кстати, Perl же!)§ Один из путей — “долго и дорого”

(“никогда и дорого”?)§ Вывод очевиден?

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 8: Optimization of a big PostgreSQL database

Все же, почему не ...?

§ OpenStack Swif§ Elliptics§ Ceph, MogileFS, MooseFS, whatever§ Слово “кислотный” из подзаголовка (Atomicity, Consistency, etc)

§ Либо делать групповую транзакцию в бизнес-логике (переписать всё приложение)

§ Либо транзакции берет на себя хранилище^ Много ли мы знаем таких хранилищ?

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 9: Optimization of a big PostgreSQL database

Объекты предметной области и базы

§ Таблица domains — содержит имена доменов, пример — setup.ru

§ Таблица content — содержит метаинформацию о файле (время последнего изменения, на основании которого принимается решение об актуальности бинарных данных)

§ Таблица stat — содержит собственно сами бинарные данные и их sha1-хэш (дедупликация!)

§ Таблица deleted — содержит признак того, что файл был удален§ Итого, у нас есть четыре связанных между собой таблицы

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 10: Optimization of a big PostgreSQL database

Пользовательские сценарии

§ Публикация и синхронизация файлов:§ Публикуем изменения всегда на одну и ту же ноду§ Иначе пользователь будет видеть старый контент§ Кастомный синхронизатор не очень быстро

распространяет изменения на все узлы§ Отдача статического контента:

§ Нужно отдавать а) последнюю, б) неудаленную версию

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 11: Optimization of a big PostgreSQL database

Что не очень хорошо?

§ Отдача работает не очень быстро§ Публикация и синхронизация работают не очень быстро§ Существующее железо справляется не очень хорошо§ Пара слов о железе:

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 12: Optimization of a big PostgreSQL database

Полный Хетцнер!

§ Исходно — RAID0 на 2*3Tb SATA диска, 16G RAM, RAID1 на 2 SSD для pg_temp и временных файлов nginx — сортировка и объединение таблиц в PostgreSQL и буферизация в nginx работают быстро

§ Переезд на RAID10 4*4Tb SATA диска (стало не хватать места), 48G RAM

§ Несмотря на наличие технической возможности, поставить SSD под кэш или временные файлы больше нельзя — добро пожаловать в Хетцнер!

§ ^ Надо как-то жить с этим

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 13: Optimization of a big PostgreSQL database

Есть ли у вас план, мистер Фикс?

§ Как это делается обычно:§ slow queries log§ pgFouine или pgBadger§ Раз в сутки (или даже чаще) — красивый рейтинг «плохих»

запросов статистика с победителями§ Смотрим план (опять это слово!) запроса§ Кто знает, что такое “план запроса”?§ Кто не знает — тот тоже оптимизатор

(но поисковый)

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 14: Optimization of a big PostgreSQL database

За спичками

§ Дело не выглядит сложным, кстати:§ “Найти неудаленный файл” при отдаче - это запрос к

view§ “Найти данные для синхронизации” - это тоже запрос к

view§ Это самые распространенные запросы§ Их планы и надо смотреть и оптимизировать

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 15: Optimization of a big PostgreSQL database

And the Oscar goes to...

§ А вот и план, о котором мы так долго говорили:§

§

§

§

§

§ Что-то он какой-то большой

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 16: Optimization of a big PostgreSQL database

Чрезвычайные и срочные меры

§ Материализовать нематериализованный view!§ PostgreSQL 9.2 — нет “родной” поддержки materialized view§ ^ не беда§ В книге “Enterprise Rails” отлично описано, как эмулировать

materialized view при помощи триггеров§ BTW WTF is “Enterprise Rails”?§ У нас опять есть план — чего же мы ждем?

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 17: Optimization of a big PostgreSQL database

Кстати, как это работает?

§ Буквально в двух словах (explain to me like I'm five years old):§ “Поверх” нематериализованного view делается таблица

с такими же полями§ Она работает как кэш — записи в ней создаются по

запросу§ Сначала идем в эту таблицу, потом во view, если там не

нашлось§ Записи инвалидируется при помощи триггеров на всех

таблицах-участниках исходного view

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 18: Optimization of a big PostgreSQL database

Все сделал как в книге!

§ Надо как-то проверить, что все удалось?§ Честно скажу, pgBadger и pgFouine я не трогал вообще§ Потому что slow log нерепрезентативен и не отражает динамику§ Расширение pg_stat_statements§ ^ должно быть включено у всех без исключения

на планете Земля§ Позволяет смотреть статистику в реальном времени

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 19: Optimization of a big PostgreSQL database

pg_stat_statements

§ SELECT

(total_time / 1000 / 60) as total_minutes,

(total_time/calls) as average_time,

calls, query

FROM pg_stat_statements

ORDER BY total_minutes/average_time desc;

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 20: Optimization of a big PostgreSQL database

pg_stat_statements

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 21: Optimization of a big PostgreSQL database

Вскрытие показало

§ Кэширующая таблица действительно работает§ Примерно 30-40% запросов не попадает в кэш§ ^ Хорошо, надо подождать§ На второй день ожидания ситуация не изменилась

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 22: Optimization of a big PostgreSQL database

Знай и люби бизнес-логику!

§ Алгоритм:§ Посмотреть в таблице§ Посмотреть в исходном view (долго)

§ А что, если такого файла вообще нет?§ 30-40 процентов запросов — к файлам, которых вообще

нет§ Зачем ходить во view за ними?

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 23: Optimization of a big PostgreSQL database

Наступило утро, проснулся комиссар

§ Ночью — 15 миллисекунд в среднем§ Днем — 40-50 миллисекунд в среднем§ Вносить изменения лучше ночью§ Но результат будет известен только в середине дня!

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 24: Optimization of a big PostgreSQL database

Наступило утро, проснулся комиссар

§ Ночью — 15 миллисекунд в среднем§ Днем — 40-50 миллисекунд в среднем§ Вносить изменения лучше ночью§ Но результат будет известен только в середине дня!

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 25: Optimization of a big PostgreSQL database

Возвращение целесообразности

§ Наша главная метрика — время отдачи контента пользователю!

§ При чем тут pg_stat_statements?§ Zabbix§ Graphite/StatsD§ https://github.com/alexclear/ansible-graphite-playbook

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 26: Optimization of a big PostgreSQL database

Мониторинг/графики

Мониторинг нормального человека Мониторинг курильщика

Zabbix Cacti, Munin+NAGIOS

StatsD/Graphite Riemann+Collectd

NAGIOS passive checks

Мониторинг алкоголика Мониторинг наркомана

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 27: Optimization of a big PostgreSQL database

Мониторинг/графики

Мониторинг нормального человека Мониторинг курильщика

Zabbix Cacti, Munin+NAGIOS

StatsD/Graphite Riemann+Collectd

NAGIOS passive checks

Мониторинг алкоголика Мониторинг наркомана

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 28: Optimization of a big PostgreSQL database

Еще пара слов про Zabbix

§ ВоронКаркнул:НИКОГДА!

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 29: Optimization of a big PostgreSQL database

Ogres have layers

§ Graphite/StatsD stack:§ Dashboard (тысячи их, я просто взял стандартный, он

плох)§ Веб-интерфейс отдачи графиков (на Django)§ Collector w/RRD-like storage (Carbon)§ Aggregator/preprocessor w/UDP interface (StatsD)

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 30: Optimization of a big PostgreSQL database

StatsD implementation

§ На Go, Node.JS, Python, Perl, C, ... (тысячи их)§ Сначала я взял Python:

§ ^ Автобус не придет§ Старый добрый Perl!

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 31: Optimization of a big PostgreSQL database

Покой нам только снится

§ Снится не покой, а те самые 40-50 миллисекунд, которые не хотят уменьшаться

§ Что делать?§ Как обычно, построить более подходящие индексы

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 32: Optimization of a big PostgreSQL database

Момент истины

§ Для самого частого запроса построен хороший индекс на три столбца (до того был — на два столбца, а исходно был на один столбец)

§ В этот момент все стало еще хуже :)§ Размер индекса — 18 гигабайт§ Все предыдущие докладчики, наверняка, говорили, что

маленький индекс лучше, чем большой

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 33: Optimization of a big PostgreSQL database

One size does not fit all

§ Один из столбцов, по которому построен индекс — varchar§ Превращаем varchar в int:§ http://stackoverflow.com/a/9812029/601572§ create function h_int(text) returns int as $$

select ('x'||substr(md5($1),1,8))::bit(32)::int;

$$ language sql;§ Забыл сказать — я не боюсь хранимых процедур и триггеров

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 34: Optimization of a big PostgreSQL database

После шлифовки отполировать

§ SET enable_bitmapscan=false; <= старые добрые nested loops

SELECT something

FROM stat s JOIN domains d ON d.id = s.domain JOIN content c ON c.id = s.content

LEFT JOIN deleted e ON e.id = s.id

WHERE d.name = domname

AND h_int(s.name) = h_int(filename <= работает новый маленький индекс

AND s.name = filename

AND date_part('epoch'::text, s.ptime) = filerev

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 35: Optimization of a big PostgreSQL database

Начинаем спать по ночам

§ Индекс занимал 18 гигабайт, стал занимать 8 гигабайт§ Среднее время выполнения запроса днем в моменты

пиковой нагрузки было 40-50 миллисекунд, стало 20-25 миллисекунд

§ 90% запросов обслуживаются за 100 миллисекунд (время от момента начала обработки запроса Perl-приложением до момента конца обработки, включает все SQL-запросы)

§ В среднем запрос обслуживается приложением за 50 мс

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 36: Optimization of a big PostgreSQL database

Мы строили-строили, и, наконец...

§ ...и, наконец:

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 37: Optimization of a big PostgreSQL database

Zabbix strikes back

§ ...и, наконец:

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 38: Optimization of a big PostgreSQL database

Выводы:

§ «Теория малых дел», внезапно, работает^ несмотря на свой почтенный возраст

§ Ломать — не строить!§ Знание — сила!§ Учение Маркса всесильно, потому что оно

верно!§ Кажется, я не туда пишу...§ В планах — шардинг, да

Оптимизация производительности большой унаследованной PostgreSQL базы. 2014

Page 39: Optimization of a big PostgreSQL database

С вами был Александр Чистяков,главный инженер Git in Sky

[email protected]://gitinsky.com

http://meetup.com/DevOps-40

Пожалуйста, ваши вопросы.

Спасибо за понимание!