Pull to refresh
15
0
skaurus @Skaurus

cto, perl, go

Send message
Да ладно, не драматизируйте, получилось в пару строчек и вполне надежно :-)
Просто проверка пары дат.
Да я уже гвоздями прикрутил (да-да, именно так!) выбор напрямую нужной партиции :-)

Красиво будет разобраться, конечно, но оно работает — а более животрепещущих проблем навалом.

Но спасибо, я буду в будущем меньше опасаться партиций.
О! А я заметил, что если у меня партиционирование по времени, и я делаю запрос по интервалу времени, который целиком укладывается в одну партицию, то намного быстрее запрос идет, если делать его напрямую к ней, а не к сводной таблице.

Не помню уже — то ли разы разницы, а то ли и порядок.
Я не готов :-)

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

Мне кажется, суть вполне понятна — вот есть запрос, в нем есть условие по полю intarray, всё работает по индексу (индексу именно по Intarray, именно это поле наиболее селективно), чудесно. Добавляем ещё одно условие на это поле — и кровь кишки :-)

Я не пытаюсь сказать, что тут гарантированно виноват PostgreSQL, я безусловно не понимаю ситуацию до конца, чтобы вот прямо багрепорт пойти написать — но это безусловно было очень странно.
Я не знаю лучшего способа, чем выключить в конфиге стратегию, которая ему нравится, перезапустить сервер и сравнить cost запросов.

Вообще, если планировщик явно тупит, то первое, что стоит сделать — это ANALYZE таблицы. Ещё можно попробовать сбросить статистику планировщика и дать ей накопиться снова — мало ли, характер нагрузки на сервер изменился.

Но перед сбросом — подумать, почему PostgreSQL может себя так вести.
Например, у вас маленькая таблица, она в кеше — её проще перебрать так, действительно.
Или у вас неселективный запрос — тогда тоже проще считать всё и отфильтровать; потому что если постгрес сначала пойдет в индекс — ему после получения списка строк из индекса придется за каждой пойти в таблицу и перепроверить — получается больше работы с диском, чем подряд.
Это связано с MVCC; в 9.2 появились index-only запросы, но и у них, кажется, есть свои ограничения, я не помню деталей.

По-моему, вот этой причиной — проще считать таблицу, чем делать кучу seek-ов по диску — объясняется большинство случаев выбора Seq Scan постгресом.

Может быть ещё забавное. У меня вот недавно была ситуация — я получал несколько сотен тысяч айдишников в скрипте и по 1000 за раз брал их из базы. Получал таймауты (2 секунды у нас в коде прикручено). Отсортировал айдишники перед тем, как брать из них порции — таймауты ушли :-) И это понятно.
Чаще всего таки планировщик оказывается умнее человека :-)
И это прекрасно, очень приятно с Postgres-ом работать.
Так а куда в итоге сдать картридж на переработку? В комментах ответа нет…
О да, это же супер-дупер сурьезный пост :-)
А так ещё проще, да.
По поводу три — первая мысль «он нарисовал круг», да. Но можно же хитрее — «он сделал жест, который приложение понимает как нарисовать круг вокруг текущей активной точки» :-)
memcached, когда ему начинает не хватать места, начинает выкидывать данные, причем выкидывает он их целыми кусками, блоками.

То есть любой ключ может пропасть раньше времени наступления expire-а.

Одна из нод кластера может ребутнуться, наконец.
А если memcached решить выкинуть слаб с частью тегов?
Массовый дроп может быть плох, если у Вас после этого приложение ломанется в базу так активно, что ляжет :)
Речь только о массовом, теги так вряд ли используются, с ними должно быть ок.

Менять префиксы не самый лучший способ.

Ну, я все это рассказываю в применении к memcached. Там старые данные рано или поздно уплывут, риска переполнения кеша вообще нет.
То есть, например, когда в таблице пользователей появляется новое поле, надо все старые кеши инвалидировать?
Ну или просто по какой-то причине мы знаем, что у нас половина кеша сломана?

Искать по префиксу в мемкеше вроде и не надо, просто меняем префикс в коде и оп, все пошли за свежим кешем.

А если вот так разом сбрасывать опасно — можно написать скриптик, который будет проходить по базе и дропать кеши постепенно, опционально — вызывать ф-цию, которая проставит правильный кеш.

Вообще ключи я привык формировать так: NAMESPACE-PREFIX-id, где NAMESPACE отделяет друг от друга виды сущностей, а PREFIX отдельные кеши внутри сущности.

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

Как бы я поступал в таком случае.

Во-первых, надо определиться, допустимы ли тут устаревшие данные и если да, то насколько.

Для начала, пусть допустимы.

Тогда я бы получал список групп для показа, в нужном порядке, и кешировал бы эти группы — в виде id сущностей. На какое-то время, определяемое задачей. Скажем, 5 минут.
Потом на каждый запрос я бы обращался к этому кешу, собирал все id, и забирал отдельный кеш каждой сущности.
В memcached есть get_multi, кстати — экономия на накладных расходах существенная. Да и запросы в базу для cache miss тоже можно группировать, так что, конечно, групповые lookup-ы надо для каждой сущности реализовать.
Рендерил страницу, отдавал.

Теперь пусть неактуальность недопустима.

Снова развилка — как часто потенциально может обновляться информация на сводной странице?

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

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

Либо это грамотно огранизованная таблица/таблицы в РСУБД с правильными индексами, либо это, скажем, Redis или что-то ещё, работающее в памяти.

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

В общем, весь этот очень длинный текст сводится к тому, что не надо дважды одну информацию класть в два места, если вам важна когерентность этих мест. Просто вот не надо и всё. Придумывайте по-другому.
Если у вас одновременно работают десять тысяч пользователей, то, наверно, популярность вашего приложения позволит вам и (целый!) гигабайт выделить на кеш.
Ну обратите внимание на set_something — когда мы закешированную сущность меняем в базе, сбрасываем её кеш.

В случае memcached «добавить expire» выливается в добавление ", $expire".

Если в вашей системе кеширования нет встроенного expire, то я надеюсь, что там есть хотя бы вытеснение старых данных новыми — сойдет и это.
Ну, кеш на сервере с одной стороны это хорошо, близко.

С другой стороны, разумно сделать кластер memcached-ов на этих 10 серверах и не париться.

Если становятся важны единицы миллисекунд — то ок, можно перенести кеши на каждый сервер в отдельности; но тогда надо придумывать способы, чтобы пользователь всегда приходил на один сервер.

Information

Rating
Does not participate
Location
Россия
Registered
Activity