LINUX.ORG.RU

Хранить эфемерные статусы в постгресе, не записывая их на диск

 


0

3

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

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

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

Правильно ли я понимаю, что у постгреса пока нет ничего для этого решения, которое вроде кажется разумным?

Я бы попробовал потестить. Обычно те записи, к которым недавно были обращения, будут лежать либо в page cache, либо даже во внутреннем кеше БД. Посмотри на pg_statio_user_tables, потюнь конфигурацию кешей - если «против» для редиса только то, что не хочется отдельной БД, то это как раз твой случай. Т.е. просто дай ему всю память, которую иначе использовал бы редис и проверь, оно или нет.

cdshines ★★★★ ()
Ответ на: комментарий от neversleep

подумал, всё ещё хочу.

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

А вот хранить это всё в отдельном редисе (уже не говоря о сервисе) — жутко неудобно для постгреса.

max_lapshin ★★★ ()
Ответ на: комментарий от max_lapshin

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

neversleep ★★ ()
Последнее исправление: neversleep (всего исправлений: 1)
Ответ на: комментарий от max_lapshin

На самом деле есть ещё варианты:

  • послушать разработчиков, которые уверены что если таблица активная, то она и так всегда будет в кеше и не надо заморачиваться
  • какое-нибудь расширение, реализующее in_memory
vvn_black ★★★★★ ()

Хочется … хранить

Писать … не хочется

Какие-то противоречивые требования - «хочу, но не хочу».

А так, скорее всего, надо смотреть в сторону способов создания таблиц: temporary, нежурналируемый, и тп. Также tablespace’ы, которые можно хранить на разных носителях (можно ли в tmpfs? - не знаю, и вообще я не разбираюсь psql)

anonymous ()

Автор, это не так работает. При апдейте таблицы пишется на диск WAL и обновляется значение в кэше. Синхронно файлы данных никто не обновляет. Когда-нибудь, при очередном чекпоинте, эти данные окажутся на диске, но далеко не сразу.

То, что ты хочешь - это не задача для РСУБД.

А что ты вообще пытаешься починить? Какой IO просаживается, диска с WAL или диска с данными? Или это преждевременная оптимизация без особого понимания?

nanonymous ()
Ответ на: комментарий от nanonymous

угу, я уже примерно до этого же догадался. Нельзя попросить по-разному писать в wal =(

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

max_lapshin ★★★ ()
Ответ на: комментарий от max_lapshin

Не ходить руками в постгрес за какими-то бизнес-данными напрямую, а реализовать вьюху, которая данные из редиса и постгреса сопоставит

grazor ()
Последнее исправление: grazor (всего исправлений: 1)
Ответ на: комментарий от zolden

Там же вроде по дефолту fsync производится на каждую транзакцию?

Это для транзакционных логов (WAL). Сами данные в таблицах и индексах обновляются на диске при чекпоинте:

https://www.postgresql.org/docs/13/wal-configuration.html

nanonymous ()
Ответ на: комментарий от max_lapshin

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

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

В худшем случае, можно пробежаться по ключам редис.

neversleep ★★ ()

Хочется там же в постгресе хранить их статусы: онлайн/офлайн.

Офлайн проверяется по неактивности в n минут после последнего действия? Пиши ключ в редис с экспайром, если ключа с id юзера нет - он оффлайн. При активности юзера обновляй ключ.

tfeartx ()

СУБД PostgreSQL 12

«Добавлена поддержка «генерируемых столбцов», значение которых вычисляется на основе выражения, охватывающего значения других столбцов в той же таблице (аналог представлений, но для отдельных столбцов). Генерируемые столбцы могут быть двух типов - хранимые и виртуальные. В первом случае значение вычисляется в момент добавления или изменения данных, а во втором - при каждом чтении на основе текущего состояния других столбцов. В настоящее время в PostgreSQL поддерживаются только хранимые генерируемые столбцы».

iZEN ★★★★★ ()
Ответ на: комментарий от max_lapshin

Нельзя попросить по-разному писать в wal =(

Можно, выше писали — unlogged tables.

Unlogged tables пишутся на диск только при выключении или если их вытесняет из-за нехватки места в shared_buffers. При обычно checkpoint они на диск не пишутся.

anonymous ()