memcached — связующее программное обеспечение, реализующее сервис кэширования данных в оперативной памяти на основе парадигмы хеш-таблицы.
memcached | |
---|---|
Тип | memcached |
Разработчик | Danga Interactive |
Написана на | C[1] |
Операционная система | Кроссплатформенное ПО |
Первый выпуск | 22 мая 2003 |
Последняя версия | 1.4.14[2] (30 июля 2012) |
Лицензия | BSD |
Сайт | memcached.org/ |
С помощью клиентской библиотеки (для C/C++, Ruby, Perl, PHP, Python, Java, CSharp/.Net и др.) позволяет кэшировать данные в оперативной памяти множества доступных серверов. Распределение реализуется путем сегментирования данных по значению хэша ключа по аналогии с сокетами хэш-таблицы. Клиентская библиотека, используя ключ данных, вычисляет хэш и использует его для выбора соответствующего сервера. Ситуация сбоя сервера трактуется как промах кэша, что позволяет повышать отказоустойчивость комплекса за счет наращивания количества memcached серверов и возможности производить их горячую замену.
В API memcached есть только базовые функции: выбор сервера, установка и разрыв соединения, добавление, удаление, обновление и получение объекта, а также Compare-and-swap. Для каждого объекта устанавливается время жизни, от 1 секунды до бесконечности. При исчерпании памяти более старые объекты автоматически удаляются. Для PHP также есть уже готовые библиотеки PECL для работы с memcached, которые дают дополнительную функциональность.
Содержание
Пример кода
Обратите внимание, что все функции, описанные в этом разделе, написаны на псевдокоде. Синтаксис вызова Memcached может отличаться в зависимости от используемого языка программирования и используемого API.Запрос к базе данных (без использования memcached) может выглядеть как в следующем примере:
function get_foo(int userid) { result = db_select(«SELECT * FROM users WHERE userid = ?», userid); return result; }
После введения использования memcached, этот же вызов может выглядеть следующим образом (здесь и далее используется псевдокод, синтаксис вызова memcached может отличаться):
function get_foo(int userid) { /* вначале проверить кэш */ data = memcached_fetch(«userrow:» + userid); if (!data) { /* не найдено: запросить БД */ data = db_select(«SELECT * FROM users WHERE userid = ?», userid); /* сохранить в кэше для будущих запросов */ memcached_add(«userrow:» + userid, data); } return data; }
Сервер вначале проверит, хранит ли Memcached значение с уникальным ключом «userrow: userid», где userid является некоторым числом. Если кэш не содержит такие данные, сервер сделает запрос к БД, как обычно, и установит уникальный ключ, используя вызов к memcached API.
Однако, если использовать только этот вызов к API, сервер может вернуть некорректные данные после любого обновления БД: Memcached будет хранить и возвращать устаревшие данные. Поэтому, в дополнение к вызову на занесение данных в кэш, также необходимо и обновление:
function update_foo(int userid, string dbUpdateString) { /* вначале обновить БД */ result = db_execute(dbUpdateString); if (result) { /* обновление БД состоялось: подготовить данные для занесения в кэш*/ data = db_select(«SELECT * FROM users WHERE userid = ?», userid); /* последняя строка также могла выглядеть наподобие data = createDataFromDBString(dbUpdateString); */ /* занести обновленные данные в кэш */ memcached_set(«userrow:» + userid, data); } }
Этот вызов обновит кэшированные данные, чтобы они соответствовали новым данным в базе данных, только если запрос на обновление базы закончится успехом. Другой подход может заключаться в том, чтобы очистить кэш по данному ключу с помощью функции Memcached, чтобы последующий вызов не нашел данные в кэше и запросил их в базе данных. Аналогичные действия нужны и в случае удаления данных из базы данных, чтобы кэш оставался корректным либо частично незаполненным.
Примечания
- ↑ InfoQ: JGroups Implementation of Memcached Supports Failover and JMX
- ↑ Memcached 1.4.14 Release notes (неопр.). Дата обращения: 30 июля 2012. Архивировано 25 июня 2012 года.