Friday, August 22, 2008

Репликации и кэширование данных

Интересный материал по поддержке репликаций в 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 - это обеспечение совместной работы кэша и базы данных. Так может возможность их совместной работы должна быть изначально?

3 comments:

Станислав said...

Подход со сбросом кэша через SQL запрос немного напоминает костыль, ибо логика по чтению и удалению кэшей размазывается по разным системам. ИМХО, решение, основанное на триггерах, выглядит в этом случае красивее.

Abava said...

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

Станислав said...

Я несколько не это имел ввиду.
Если измениться API кэша, или настройки конкретного хранилища, то менять их надо будет в двух местах. И т.д.