Открыть список
Как стать автором
Обновить
24.2
Карма
0
Рейтинг
Иван Осадчий @iosadchiy

Инженер-программист

Проекты в контролируемой среде или краткий пересказ PRINCE2

К сожалению, пока что индустрия предпочитает укладывать всё в прокрустово ложе скрама и канбана. Думаю, когда-нибудь она дойдет до понимания, что эти двое попросту не покрывают все аспекты управления разработкой, да и не предназначены для этого. А раз какие-то вопросы не покрыты методологией, то они будут закрыты как придётся, и вряд ли выйдет что-то путное.


К тому же, на мой взгляд, большинство реальных проектов находятся в complicated домене, а не в complex по киневину, а следовательно не требуют постоянного контролируемого эксперимента и могли бы выиграть от применения классических методов проектного управления.

NTFS Reparse Points

Я смотрю, однажды озвученная в университеткой столовке хотелка "we need to go deeper" завела весьма глубоко)


RP является одной из ключевых фич файловой системы NTFS, которая бывает полезна в решении задач резервного копирования и восстановления

А можно поподробнее про цели этой работы? Выглядит немного вырванной из контекста.

Платформа как сервис в Авито: как это устроено

Спасибо за статью! Узнал много интересного.


Получается, helmgen нынче не имеет отношения к helm?


Вообще, главный минус PaaS, на мой взгляд, в том, что все равно нужно разбираться, как устроена нижележащая инфраструктура. Только теперь ее "прячет" PaaS, с соответствующими последствиями: неполной документацией и неожиданными изменениями. Для простых кейсов PaaS упрощает жизнь, позволяет быстрее онбордиться. Но как только что-то пойдет не так — тут платформа больше мешает, чем помогает. Например, дашборд позволяет настроить секреты для Prod и Non-prod. ОК, тогда почему окружение для нагрузочных тестов не видит секретов ни из Prod, ни из Non-prod? Как в него передать секреты? Через платформу — никак! Только разбираться с vault.


Думаю, это системная проблема любой PaaS. Единственный способ борьбы — доводить стабильность фичей до идеальной, чтобы разработчику не приходилось лезть под платформу вообще.


И вот вам фича реквест заодно: сделайте перевыкатку сервиса из того образа, который уже в проде. Сейчас 24/7 вынуждены пересобирать сервис из мастера с непредсказуемыми последствиями. Имхо, достаточно научить rollback перевыкатывать текущую версию, а не только предыдущие.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Да, искать в квадрате вокруг точки — это из-за применения обычных btree. Кружок заданного радиуса будет даже лучше.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

почему без провайдера?

Тэги уникальны насквозь по всем провайдерам, поэтому провайдер не нужен.


А так да, ищем ближайшую точку для каждого провайдера, берем от них тэги, потом ищем связанные по тэгам точки в пределах области.


кажется, тут будет в тему диаграмма Вороного

Звучит очень круто, но как применить на практике? Заранее вокруг каждой точки строим область, в которой она будет являться ближайшей? Сможем ли мы делать это быстро и, желательно, в Постгресе? Как хранить полигоны в базе, как их индексировать и как проверять попадание координат в один из полигонов?


Вообще, направление выглядит перспективно. Мне надо почитать и найти ответы на вопросы выше. Подсказки и ссылки приветствуются!

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

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


these operator classes will not outperform the equivalent standard B-tree index methods

Поясните, если не трудно

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Это да, h3 планируем использовать

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Кажется, понял. Предлагаете группировать терминалы по городу и использовать json, чтобы хранить все терминалы города.


Группировку терминалов с одинаковыми правилами доставки мы делаем (это поле tag_from_id). Чаще всего тэг — это и есть город. Но не всегда. Более того, понятие города у всех разное; даже в одной службе доставки в разное время к городу могут относиться разные терминалы.


Насчет JSON — наверное, можно и так, надо пробовать. Асимптотическая сложность вроде бы та же самая.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Если что, ниже в комментах выложил план запроса (свежеснятый, с оговорками)

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Да, объем используемой части близок к объему БД. Старые данные мы в этих таблицах не храним, уносим в архив. Диск ограничен квотой на IOPS для lxc контейнера с базой.


Тулзу оценил!

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

За наводку на тулзу, конечно, спасибо. Она шикарна.


Вот план запроса. Прошу учесть, что это свежеснятый план. Оригинал, который в статью картинкой вставлен, у меня не сохранился. Статья все-таки написана по боевому кейсу, а оптимизация проводилась еще в июле-августе. С тех пор и структура БД немного поменялась, и запрос, и железо. Я попытался в меру сил приблизить запрос к тому, что описан в статье. Но все же напрямую сравнивать нельзя. Но суть та же.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Ещё вопрос: в выборку у нас не попадают поля из таблицы send, запрос точно правильный?

send нужен, чтобы найти tag_from_id. Потом tag_from_id подается на вход receive. Именно поэтому на receive сделан индекс receive(tag_from_id, lon, lat).


остальные поля не имеют смысла, т.к. индексы не умеют по второй части индекса range если первая тоже range, т.е. так работать будет только первая часть индекса

В моем представлении, таки будет работать. Да, базе придется перебрать все lat в записях, попавших под lon between ? and ?. Но зато для фильтрации не понадобиться поход в таблицу, можно смотреть прямо в индекс. Это подтверждается результатами нагрузочных тестов: заметно небольшое (незначительное) улучшение при включении lat в индекс.


Вы попробуйте создать геоиндекс, дело 15 минут на тест, у вас всё залетает, производительность на порядок увеличится

Я-то создам, мне не лень повозиться, чтобы разобраться. Вопрос в том, что конкретно создавать. Я уже не один геоиндекс здесь попробовал и пока результата не добился. Если вы про create index on receive using spgist(lat,lon), то он дает весьма существенную просадку по производительности.


Надо все-таки достать сырой план запроса. Тут проблема в том, что стенд, на котором проводилось тестирование, уже не доступен. Статья написана о событиях июля-августа; с тех пор структура БД и запрос немного усложнились. Но я попробую.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Кстати, как более опытный автор, вы бы что посоветовали, оставить статью в хабе Go или все-таки убрать?

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

И действительно :) Но! 1) Сервис на Go, 2) начало истории тоже в этом хабе, а там код таки есть. А так да, конечно, немного за уши притянуто

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Замечу, что аппаратные ресурсы выросли примерно в четыре раза (16Гб -> 64Гб), а производительность — в сто раз. Это довольно эффективное использование кредитки :)


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


Выбор постгрес здесь был совершенно неочевиден; долгое время постгрес оставался в аутсайдерах, уступая сфинксу и эластику. Но по совокупности факторов таки выиграл.


Конкретно in-memory базу рассматривали, но в итоге отказались: трудно обеспечить быстрое восстановление после сбоя + усложненная поддержка за счет еще одной технологии в команде.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Не совсем понял. Допустим, есть Москва (1000 терминалов) и Владивосток (500 терминалов). Создадим для каждого таблицу… а что в нее класть? Считать мы хотим цену между любыми двумя терминалами. Действительно, для всех терминалов в пределах одного города цена будет одинаковой, но у разных служб доставок границы города могут отличаться. Поясните, пожалуйста, как это будет поддержано схемой с таблицей для каждого города.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

pg_total_relation_size считает уже с индексами, т.е. вам должно хватить и 21Gb

Класс, спасибо!


Да, тоже опасался, что планирование такого здорового запроса будет занимать вечность. Но нет, все довольно быстро. Как считаете, есть ли смысл пробовать "describe" режим (с анонимными prepared statements)?

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Хорошее замечание! Изначально мы как раз смотрели в сторону геоиндексов, причем не только в постгрес (spgist, postgis), но и в эластике и редисе. В итоге пришли к выводу, что геоиндексы здесь не совсем подходят. Проблема в том, что нужно искать одновременно и по координатам, и по другим полям, а r-деревья с этим плохо справляются. А как бы вы их применили здесь, чтобы получить прирост в десяток раз?


Насчет убрать лишние поля из индексов — тоже очень логично. Мы так пробовали. Казалось, что долгота должна быть достаточно селективна, и широта в индексе необязательна. Но перформанс тесты показали, что с таким набором полей все же немного быстрее. Возможно, дело в том, что службы доставки передают нам координаты терминалов с ограниченной точностью, в итоге некоторые терминалы имеют одинаковую долготу, даже если находятся в разных городах. Впрочем, сокращенный индекс может иметь смысл, т.к. он меньше; возможно, еще вернемся к нему.

Оптимизация работы с PostgreSQL в Go: от 50 до 5000 RPS

Сошлюсь еще на свой комментарий, где как раз на этот вопрос отвечал подробнее

1

Информация

В рейтинге
6,110-й
Работает в
Зарегистрирован
Активность