LINUX.ORG.RU

Инвалидация кеша в РСУБД

 , , ,


0

1

Как решается на практике? Есть куча жирных таблиц и надо знать, что определённые записи поменялись, причём узнать это надо быстро и просто. В оракле были какие-то таймштампы по таблицам/записям, но их извлечение не намного быстрее, чем сам запрос по ключу. Парсить логи - тоже не вариант. Подключать раббит к ораклу и отсылать события через триггер? Сомнительно. Конечно, есть некоторые особенности функционирования ИС, когда в таблицы только добавляются записи или ведётся какой-нибудь свой лог, где по одной записи можно сделать много выводов, однако интересуют универсальные готовые решения, не обязательно в оракле.

не намного быстрее, чем сам запрос по ключу

Потенциально есть 1 способ получить от рсубды быстрее, чем «по ключу» - отдельная нормально пустая табличка с непотреблёнными пока изменениями. Что есть плохая реализация очереди своими руками, Т.ч. если индекс слишком дорогой - «в очередь».

Триггеры вполне работоспособны, если не отсылать слишком далеко и синхронно.

Ещё за много денег у оракля есть goldengate, парсящий его логи для залития изменения в другие места — может оно умеет в не-БД,

А ещё некоторые говорят, что архитектор засунул БД в систему слишком глубоко, и её полезно оттуда выковырять на периферию.

DonkeyHot ★★★★★ ()

Можешь поменять архитектуру и сделать

логи

source of truth (именно их писать в какую-нибудь базу, хоть постгрес, но можно и что-то специфичное), и отдельными сервисами — строить кэш и писать в твой постгрес/оракл для репортов, в лучших традициях event sourcing. Минусы: это — заметно менее гибкая архитектура с уймой подводных камней и требует понимания domain, с которым работаешь. Плюсы: любое изменение рано или поздно дойдёт и до БД, и до кэша и ты можешь управлять консистентностью и того, и другого. По сути РСУБД становится ещё одним как-бы-кэшем и твоему приложению становится фиолетово, что там в РСУБД поменялось.

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

А как выглядит исходная задача?

Да всё банально. Есть таблица в бд, есть приложение которое тянет оттуда данные себе и кеширует. Конечно, бд лучше не дёргать лишний раз и надо какой-то механизм, чтобы по-быстрому узнать изменились наши данные или нет.
Как сделать вариантов на самом деле масса нужен какой-то универсальный механизм, но не уведомления, т.к. это слишком жирно (20 клиентов, 1м записей = 20м уведомлений. Уууу.)

Может таки эти уведомления стоит вытягивать с уровня СУБД на уровень выше?

Если уведомления, то это надо или триггеры, которые будут впадать в бешенство, когда кто-то будет заливать много или событие выставлять в апи (перед заливкой, например) а это сложно, тут уже много чего написано от этого уже голова начинает болеть, а я еще даже не думал, как это можно сделать.
В идеале что-то должно записываться в inmemory таблицу, откуда уже все кому надо читают, но это как-то внутри субд должно всё быть в виде какого-нибудь b-tree индекса. Можно конечно и сколхозить, но, опять же, надо триггеры везде выставлять руками и т.д.

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

надо какой-то механизм, чтобы по-быстрому узнать изменились наши данные или нет

просто факт изменения таблицы? как вариант можно затолкать таймштампу последнего изменения в какой-нибудь in-memory cache (тот же redis или memcached). и обновлять при инсерте (лучше не триггером, а бэкендом)

Sectoid ★★★★★ ()

Ты про кешу процессора или про какую то ещё?

Если оно под онтопиком, то поидее можно штатный prof использовать или lttng. Кстати, если модуль который отвечает за эту самую инвалидацию нативный, не пострипанный и инструментированный то с помощью lttng о5 же можно вести лог вызова функций которые эту самую инвалидацию производят.

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

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

У меня для вас плохие новости, потому что это примерно = https://ru.wikipedia.org/wiki/MOESI

Варианта три:

1. VersionVerify+Retry. Обновляющие запросы к БД реализуется через хранимки, которые одним из параметров получают версию закэшированных на клиенте данных. Соответственно хранимка проверяет и просит перечитать/повторить если клиентский кэш протух. Идея думаю понятна, а вариаций может быть масса.

2. Уведомления, но по мотивам MOESI/MESI (уведомления отправляются только когда у клиента в кэше есть обновляемая строка). Велосипедить достаточно сложно, но иногда вполне приемлемо. Из готового наверное http://www.alachisoft.com/ncache/ Ну и в богомезском ASP.NET что-то подобное вроде-бы было.

3. Не кэшировать.

erthink ()

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

Делаем в postgres

"SELECT id FROM tablename TABLESAMPLE SYSTEM (0.01) REPEATABLE ($hash);";
где $hash - уникальное и постоянное число. Если таблица не менялась, результат будет неизменен. Выполняться будет очень быстро.

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

Ну а если при неизменном $hash у тебя другой результат - таблица изменилась! Правда не знаю, что будет если поменять куски таблицы без изменения их размера и общего. Надо проверить :)

anonymous ()