Интересный материал по поддержке репликаций в Facebook. 2 териториально разнесенных дата-центра (на разных побережьях США). Для MySQL, соответственно, схема master-slave. Задержка в передаче данных при репликации может достигать 20 секунд. Если, например, обновили мастер-базу и послали реплику в другую систему, то кэш на удаленной стороне (используется memcached) все равно будет содержать старое значение. Для решения этой проблемы расширили реализацию SQL. По сути - добавили триггер, который при получении обновления еще и удаляет старое значение из своего кэша. Так, чтобы при следующем обращении оно уже запросилось бы из базы. Вот так, например, выглядит модифицированный SQL запрос (изменение имени в профайле):
REPLACE INTO profile ('first_name') VALUES ('Monkey') WHERE 'user_id'='jsobel' MEMCACHE_DIRTY 'jsobel:first_name'
MEMCACHE_DIRTY - и есть добавка к синтаксису
На самом деле это даже более общий вопрос. Он, например, и в J2EE сообществах периодически поднимался. Кэш уровня приложения - он точно должен быть самостоятельным, или являться частью БД? Те же старые entity beans, применительно к EJB? Ведь то, что делает Facebook - это обеспечение совместной работы кэша и базы данных. Так может возможность их совместной работы должна быть изначально?
Подход со сбросом кэша через SQL запрос немного напоминает костыль, ибо логика по чтению и удалению кэшей размазывается по разным системам. ИМХО, решение, основанное на триггерах, выглядит в этом случае красивее.
ReplyDelete>кэшей размазывается по разным >системам
ReplyDeleteа это смотря где принимается решение о сбросе/обновлении кэша. В данном случае - именно в приложении
Я несколько не это имел ввиду.
ReplyDeleteЕсли измениться API кэша, или настройки конкретного хранилища, то менять их надо будет в двух местах. И т.д.