RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Глава 18. Высокая доступность и масштабируемость

Данные валюта сегодняшней сети, мобильной, социальной, предприятий и облачных приложений. Обеспечение данных всегда доступными это высший приоритет для любой организации. Минуты простоя могут привести к существенной потере дохода и репутации.

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

MySQL предлагает диапазон гарантированных и поддержанных решений, поставляя соответствующие уровни высокой доступности и масштабируемости, чтобы ответить требованиям уровня обслуживания. Такие решения простираются от репликации и виртуализации до географической избыточности и решений мультиинформационного центра, предоставляющих надежность работы на 99.999%.

Выбор правильного высоконадежного решения для приложения в значительной степени зависит от:

  • Уровень доступности.

  • Тип развертываемого приложения.
  • Принятые методы в пределах Вашей собственной среды.

Основные решения, поддержанные MySQL, включают:

Дальнейшие опции доступные решения третьей стороны.

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

  • Репликация.

  • Кластеры и виртуализация.
  • Географически копируемые кластеры.

Как иллюстрировано на следующем рисунке, каждая архитектура предлагает прогрессивно более высокие уровни продолжительности работы, которая должна быть сбалансирована относительно потенциально больших уровней стоимости и сложности. Просто развертывание высоконадежной архитектуры не является гарантией фактического предоставления HA. Фактически, плохо осуществленный и поддержанный кластер не может легко поставить более низкие уровни доступности, чем простое решение для репликации данных.

Рис. 18.1. Стоимость и сложность против доступности

Следующая таблица сравнивает HA и способности масштабируемости различных решений MySQL:

Таблица 18.1. Сравнение особенностей решений MySQL HA

ТребованиеРепликация MySQL MySQL Cluster
Доступность
Поддержка платформВсе поддержанные сервером MySQL (http://www.mysql.com/support/supportedplatforms/database.html )Все поддержанные MySQL Cluster (http://www.mysql.com/support/supportedplatforms/cluster.html )
Автоматизированный IP FailoverНет Зависит от соединителя и конфигурации
Автоматизированный Failover базы данныхНет Да
Автоматическая пересинхронизация данныхНет Да
Типичное время FailoverЗависит от пользователя или скриптаСекунда или меньше
Синхронная репликацияНет, асинхронная и полусинхроннаяДа
Совместно используемое хранениеНет, распределенноеНет, распределенное
Географическая поддержка избыточностиДа Yes, через репликацию MySQL
Схема обновления онлайнНетДа
Масштабируемость
Число узловОдно ведущее устройство, много ведомых255
Встроенное балансирование нагрузки Чтение, через репликацию MySQLДа, чтение и запись
Поддерживает интенсивные рабочие нагрузки чтения ДаДа
Поддерживает интенсивные рабочие нагрузки Да, через уровень приложенияДа, автоматически
Масштабирование онлайн (добавление узлов, перераспределение и т. д.)НетДа

18.1. Использование репликации ZFS

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

Файловая система ZFS обеспечивает функциональность, чтобы создать снимок содержания файловой системы, передать снимок другой машине и извлечь из снимка данные, чтобы обновить файловую систему. В любое время Вы можете создать снимок, и Вы можете создать так много снимков, как Вам нравится. Непрерывно создавая, передавая и восстанавливая снимки, Вы можете обеспечить синхронизацию между одной или более машинами способом, подобным DRBD.

Следующий пример показывает простую систему Solaris, работающую с единственным бассейном ZFS, установленным в /scratchpool:

Filesystem        size  used  avail capacity  Mounted on
/dev/dsk/c0d0s0   4.6G  3.7G   886M      82%  /
/devices            0K    0K     0K       0%  /devices
ctfs                0K    0K     0K       0%  /system/contract
proc                0K    0K     0K       0%  /proc
mnttab              0K    0K     0K       0%  /etc/mnttab
swap              1.4G  892K   1.4G       1%  /etc/svc/volatile
objfs               0K    0K     0K       0%  /system/object
swap              1.4G   40K   1.4G       1%  /tmp
swap              1.4G   28K   1.4G       1%  /var/run
/dev/dsk/c0d0s7    26G  913M    25G       4%  /export/home
scratchpool        16G   24K    16G       1%  /scratchpool
/usr/lib/libc/libc_hwcap1.so.1
                  4.6G  3.7G   886M      82%  /lib/libc.so.1
fd                  0K    0K     0K       0%  /dev/fd

Данные MySQL хранятся в каталоге на /scratchpool. Чтобы помочь продемонстрировать часть основной функциональности репликации, есть также другие элементы, сохраненные в /scratchpool, а именно:

total 17
drwxr-xr-x  31 root bin   50 Jul 21 07:32 DTT/
drwxr-xr-x   4 root bin    5 Jul 21 07:32 SUNWmlib/
drwxr-xr-x  14 root sys   16 Nov  5 09:56 SUNWspro/
drwxrwxrwx  19 1000 1000  40 Nov  6 19:16 emacs-22.1/

Чтобы создать снимок файловой системы, Вы используете zfs snapshot, определяя бассейн и имя снимка:

root-shell> zfs snapshot scratchpool@snap1

Перечислять уже взятые снимки можно так:

root-shell> zfs list -t snapshot
NAME             USED AVAIL  REFER  MOUNTPOINT
scratchpool@snap   10   -    24.5K  -
scratchpool@snap   20   -    24.5K  -

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

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

Вы не можете непосредственно поддержать снимки, потому что они существуют в пределах метаданных о файловой системе, а не как регулярные файлы. Чтобы получить снимок в формат, который Вы можете скопировать в другую файловую систему, ленту и так далее, Вы используете команду zfs send, чтобы создать потоковую версию снимка.

Например, чтобы записать снимок в файл:

root-shell> zfs send scratchpool@snap1 >/backup/scratchpool-snap1

Или на ленту:

root-shell> zfs send scratchpool@snap1 >/dev/rmt/0

Вы можете также записать возрастающие изменения между двумя снимками с помощью zfs send:

root-shell> zfs send scratchpool@snap1 scratchpool@snap2 >/backup/scratchpool-changes

Чтобы возвратить снимок, Вы используете zfs recv, которая применяет информацию о снимке к новой файловой системе или к существующей.

18.1.1. Использование ZFS для репликации файловой системы

Поскольку zfs send и zfs recv используют потоки, чтобы обменяться информациями, Вы можете использовать их, чтобы копировать информацию с одной системы в другую, объединяя zfs send, ssh и zfs recv.

Например, чтобы скопировать снимок файловой системы scratchpool к новой файловой системе slavepool на новом сервере Вы использовали бы следующую команду. Эта последовательность комбинирует снимок scratchpool, передачу к ведомой машине (используя ssh с параметрами входа в систему) и восстановление снимка на ведомом устройстве, используя zfs recv:

root-shell> zfs send scratchpool@snap1 |ssh id@host pfexec zfs recv -F slavepool

Первая часть трубопровода, zfs send scratchpool@snap1, передает снимок потоком. Команда ssh и команда, которую это выполняет на другом сервере, pfexec zfs recv -F slavepool, получает переданные потоком данные о снимке и пишет это в slavepool. В этом случае я определил опцию -F, которая вынуждает данные о снимке быть примененными в любом случае и является поэтому разрушительной. Это прекрасно, поскольку я создаю первую версию копируемой файловой системы.

На ведомой машине копируемая файловая система содержит тот же самый контент:

root-shell> ls -al /slavepool/
total 23
drwxr-xr-x   6 root root   7 Nov  8 09:13 ./
drwxr-xr-x  29 root root  34 Nov  9 07:06 ../
drwxr-xr-x  31 root bin   50 Jul 21 07:32 DTT/
drwxr-xr-x   4 root bin    5 Jul 21 07:32 SUNWmlib/
drwxr-xr-x  14 root sys   16 Nov  5 09:56 SUNWspro/
drwxrwxrwx  19 1000 1000  40 Nov  6 19:16 emacs-22.1/

Как только снимок был создан, чтобы синхронизировать файловую систему снова, Вы создаете новый снимок и затем используете возрастающую функцию снимка zfs send, чтобы послать изменения между этими двумя снимками к ведомой машине снова:

root-shell> zfs send -i scratchpool@snapshot1 scratchpool@snapshot2 |ssh id@host pfexec zfs recv slavepool

Эта работа преуспевает, если файловая система на ведомой машине не была изменена вообще. Вы не можете применить возрастающие изменения целевой файловой системы, которая изменилась. В примере выше команда ls вызвала бы проблемы, изменяя метаданные, такие как время доступа для файлов или каталогов.

Чтобы предотвратить изменения на ведомой файловой системе, установите файловую систему на ведомом устройстве только для чтения:

root-shell> zfs set readonly=on slavepool

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

В основном, ведомая файловая система только статическая копия оригинальной файловой системы. Однако, даже когда конфигурована только для чтения, файловая система может принимать снимки. На установленной только для чтения файловой системе запускаем повторно начальную копию:

root-shell> zfs send scratchpool@snap1 |ssh id@host pfexec zfs recv -F slavepool

Теперь Вы можете произвести изменения в оригинальной файловой системе и скопировать их к ведомому устройству.

18.1.2. Конфигурирование MySQL для репликации ZFS

Конфигурирование MySQL является созданием данных по файловой системе, которую Вы намереваетесь копировать. Конфигурационный файл в примере ниже был обновлен, чтобы использовать /scratchpool/mysql-data как каталог данных, и теперь Вы можете инициализировать таблицы:

root-shell> mysql_install_db --defaults-file=/etc/mysql/5.5/my.cnf --user=mysql

Чтобы синхронизировать начальную информацию, выполните новый снимок и затем посылайте новые снимки на ведомое устройство с использованием команды zfs send:

root-shell> zfs snapshot scratchpool@snap2
root-shell> zfs send -i scratchpool@snap1 scratchpool@snap2|ssh id@host pfexec zfs recv slavepool

Перепроверьте, что у ведомого устройства есть данные, просмотрев каталог данных MySQL на slavepool:

root-shell> ls -al /slavepool/mysql-data/

Теперь Вы можете запустить MySQL, создать некоторые данные, а затем копировать изменения с использованием zfs send/zfs recv на ведомое устройство, чтобы синхронизировать изменения.

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

Чтобы автоматизировать процесс, создайте скрипт, который выполняет снимок, посылает и принимает его. Используйте cron, чтобы синхронизировать изменения во времени.

18.1.3. Обработка восстановления MySQL с ZFS

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

В случае отказа следуйте этой последовательности:

  1. Остановите скрипт на ведущем устройстве, если он все еще в порядке.

  2. Установите ведомую файловую систему на чтение и запись:
    root-shell> zfs set readonly=off slavepool
    
  3. Запустите mysqld на ведомом устройстве. Если Вы используете InnoDB, Вы получаете автовосстановление, если оно необходимо, чтобы удостовериться, что табличные данные правильны, как показано здесь:
    InnoDB: The log sequence number in ibdata files does not match
    InnoDB: the log sequence number in the ib_logfiles!
    081109 15:59:59  InnoDB: Database was not shut down normally!
    InnoDB: Starting crash recovery.
    InnoDB: Reading tablespace information from the .ibd files...
    InnoDB: Restoring possible half-written data pages from the doublewrite
    InnoDB: buffer...
    081109 16:00:03  InnoDB: Started; log sequence number 0 1142807951
    081109 16:00:03 [Note] /slavepool/mysql-5.0.67-solaris10-i386/bin/mysqld: ready for connections.
    Version: '5.0.67'  socket: '/tmp/mysql.sock'  port: 3306  MySQL Community Server (GPL)
    

Используйте таблицы InnoDB и регулярную синхронизацию, чтобы уменьшить риск существенной потери данных. На таблицах MyISAM Вы, возможно, должны были бы выполнить REPAIR TABLE.

18.2. Использование MySQL с memcached

memcached простой, хорошо масштабируемый основанный на ключе кэш, который хранит данные и объекты везде, где свободная RAM доступна для быстрого доступа приложений, не проходя уровни дискового I/O или парсинга. Чтобы использовать, Вы выполняете команду memcached на одном или более хостах и затем применяете совместно используемый кэш, чтобы хранить объекты. Для большего количества инструкций см. раздел 18.2.2.

Выгода от использования memcached включает:

  • Поскольку вся информация хранится в RAM, скорость доступа быстрее, чем загрузка информации каждый раз с диска.

  • Поскольку у части значения пары "ключ-значение" нет никаких ограничений типа данных, Вы можете кэшировать данные, такие как сложные структуры, документы, изображения или смесь таких вещей.
  • Если Вы используете кэш-памяти, чтобы считать переходную информацию или как кэш только для чтения для информации, сохраненной в базе данных, отказ любого сервера memcached не важен. Для постоянных данных Вы можете отступить к альтернативному методу поиска, используя запросы базы данных, и перезагрузить данные в RAM на ином сервере.

Типичная окружающая среда использования должна изменить Ваше приложение так, чтобы информация была считана из кэша, обеспеченного memcached. Если информация не находится в memcached, то данные загружены из базы данных MySQL и записаны в кэш так, чтобы будущие запросы для того же самого объекта обращались к кэшируемым данным.

Рис. 18.2. Обзор архитектуры memcached

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

Тот же самый алгоритм используется снова, когда клиент запрашивает тот же самый ключ. Тот же самый ключ производит тот же самый хеш, и тот же самый memcached сервер выбран как источник для данных. Используя этот метод, кэшируемые данные распространены среди всех серверов memcached, а кэшируемая информация доступна с любого клиента.

Данные, проводимые в пределах традиционного сервера memcached никогда не хранятся на диске (только в RAM, что означает, что нет никакого постоянства данных), и кэш RAM всегда заполняется из внешней памяти (базы данных MySQL). Если сервер memcached рухнул, данные могут всегда восстанавливаться из базы данных MySQL.

18.2.1. Установка memcached

Вы можете создать и установить memcached из исходного кода непосредственно, или Вы можете использовать существующий пакет операционной системы.

Установка memcached из двочного дистрибутива.

Чтобы установить memcached на Red Hat или Fedora, используйте yum:

root-shell> yum install memcached

На CentOS Вы можете быть в состоянии получить подходящий RPM из другого источника, или использовать tar-архив.

Чтобы установить memcached на Debian или Ubuntu, используйте apt-get:

root-shell> apt-get install memcached

Чтобы установить memcached на Gentoo, используйте emerge:

root-shell> emerge install memcached

Построение memcached из исходных текстов

На других основанных на Unix платформах, включая Solaris, AIX, HP-UX, OS X и Linux Вы должны установить из пакет из исходных текстов. Для Linux удостоверьтесь, что у Вас есть ядро на основе 2.6, которое включает улучшенный интерфейс epoll. Для всех платформ гарантируйте, что Вы имеете libevent 1.1 или выше. Вы можете получить libevent с libevent web page.

Вы можете получить исходные тексты для memcached с memcached Web site.

Чтобы собрать memcached, надо:

  1. Извлеките исходный пакет memcached :

    shell> gunzip -c memcached-1.2.5.tar.gz | tar xf -
    
  2. Перейдите в каталог memcached-1.2.5:
    shell> cd memcached-1.2.5
    
  3. Запустите configure:
    shell> ./configure
    

    Некоторые дополнительные опции Вы можете определить к configure:

    • --prefix

      Чтобы определить иной каталог установки, используйте опцию --prefix:

      shell> ./configure --prefix=/opt
      

      Значение по умолчанию должно использовать каталог /usr/local.

    • --with-libevent

      Если Вы установили libevent libevent и configure не может найти библиотеку, надо использовать опцию --with-libevent, чтобы определить местоположение установленной библиотеки.

    • --enable-64bit

      Чтобы создать 64-битовую версию memcached (которая позволяет Вам использовать большой объем RAM), надо использовать --enable-64bit.

    • --enable-threads

      Чтобы включить поддержку многопоточности в memcached, которая улучшает время отклика относительно серверов с тяжелым контентом, используйте опцию --enable-threads. У Вас должна быть поддержка потоков POSIX в пределах Вашей операционной системы, чтобы включить поддержку потока. Для получения дополнительной информации о поддержке поточной обработки см. раздел 18.2.2.8.

    • --enable-dtrace

      memcached включает диапазон потоков DTrace, которые могут использоваться, чтобы контролировать и определять эффективность memcached.

  4. Запустите make для построения memcached:

    shell> make
    
  5. Запустите make install для установки memcached:
    shell> make install
    

18.2.2. Применение memcached

Чтобы начать использовать memcached, запустите службу memcached на одном или более серверов. Выполнение memcached настраивает сервер, выделяет память и начинает слушать соединения от клиентов.

Вы не должны быть привилегированным пользователем (root), чтобы выполнить memcached, кроме работы на одном из привилегированных портов TCP/IP (ниже 1024). Вы должны, однако, использовать пользователя, у которого не было ограниченного использования пределов памяти setrlimit или подобного.

Чтобы запустить сервер, выполните memcached как непривилегированный (то есть, не-root) пользователь:

shell> memcached

По умолчанию memcached использует следующие настройки:

  • Распределение памяти 64 МБ.

  • Слушать соединения на всех сетевых интерфейсах, используя порт 11211.
  • Поддерживает максимум 1024 одновременных соединений.

Как правило, Вы определили бы полную комбинацию опций, которые Вы хотите, запуская memcached, и обычно обеспечиваете скрипт запуска, чтобы обработать инициализацию memcached. Например, следующая строка запускает memcached с максимумом RAM 1024 МБ для кэша, слушающего на порту 11211 на IP-адресе 192.168.0.110, работая как фоновый демон:

shell> memcached -d -m 1024 -p 11211 -l 192.168.0.110

Чтобы гарантировать, что memcached запущен в начальной загрузке, проверьте скрипт init и параметры конфигурации.

18.2.2.1. Параметры командной строки memcached

memcached поддерживает следующие опции:

  • -u user

    Если Вы запускаете memcached как root, используйте опцию -u, чтобы определить пользователя для того, чтобы выполнить memcached :

    shell> memcached -u memcache
    
  • -m memory

    Установите объем памяти, выделенный memcached для хранения объекта. Значение по умолчанию составляет 64 МБ. Чтобы увеличить объем памяти, выделенный для кэша, используйте опцию -m, чтобы определить количество RAM, которая будет выделена (в мегабайтах). Чем больше RAM, которую Вы выделяете, тем больше данных Вы можете сохранить и поэтому более эффективен Ваш кэш.

    Не определяйте памяти, больше чем Ваша доступная RAM. Если Вы определяете слишком большое значение, то некоторая RAM, выделенная для memcached, использует область подкачки, а не физическую RAM. Это может привести к задержкам, потому что данные сохранены на диск, вместо того, чтобы хранить данные непосредственно в RAM.

    Вы можете использовать вывод команды vmstat, чтобы получить свободную память, как показано в столбце free:

    shell> vmstat
    k thr memory  page   disk faults                                             cpu
    r b w   swap  free    re  mf pi po fr de sr s1 s2 -- --   in   sy   cs us sy id
    0 0 0 5170504 3450392 2    7  2  0  0  0  4  0  0  0  0  296   54  199  0  0 100
    

    Например, чтобы выделить 3GB RAM:

    shell> memcached -m 3072
    

    На 32-битовых x86 системах, где Вы используете PAE, чтобы получить доступ к памяти выше 4GB, Вы не можете выделить RAM вне максимального размера процесса. Вы можете обойти это, выполняя много копий memcached, каждая на своем порте:

    shell> memcached -m 1024 -p11211
    shell> memcached -m 1024 -p11212
    shell> memcached -m 1024 -p11213
    

    На всех системах, особенно 32-битовых, гарантируйте, что Вы оставляете достаточно места для memcached в дополнение к буферу памяти. Например, если у Вас есть специализированный хост memcached с 4GB RAM, не устанавливайте размер памяти выше 3500 МБ. Отказ сделать это может вызвать или катастрофический отказ или серьезные исполнительные проблемы.

  • -l interface

    Определите сетевой интерфейс/адрес, чтобы слушать соединения. Значение по умолчанию: на всех доступных адресах (INADDR_ANY).

    shell> memcached -l 192.168.0.110
    

    Поддержка IPv6 была добавлена в memcached 1.2.5.

  • -p port

    Определите порт TCP, чтобы использовать для соединений. Значение по умолчанию 18080.

    shell> memcached -p 18080
    
  • -U port

    Определите порт UDP, чтобы использовать для соединений. Значение по умолчанию 11211, 0 выключает UDP.

    shell> memcached -U 18080
    
  • -s socket

    Определите сокет Unix.

    Если Вы выполняете memcached на том же самом сервере, где работает клиент, Вы можете отключить сетевой интерфейс и использовать сокет Unix через опцию -s:

    shell> memcached -s /tmp/memcached
    

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

  • -a mask

    Определите маску доступа, которая будет использоваться для сокета Unix в октальном формате. Значение по умолчанию 0700.

  • -c connections

    Определите максимальное количество одновременных соединений с сервисом memcached. Значение по умолчанию 1024.

    shell> memcached -c 2048
    

    Используйте эту опцию, чтобы сократить количество соединений (чтобы предотвратить перегрузку сервиса memcached) или увеличьте число, чтобы сделать более эффективным использование сервера, работающего с сервисом memcached.

  • -t threads

    Определите число потоков, чтобы использовать, обрабатывая входящие запросы.

    По умолчанию memcached сконфигурирован, чтобы использовать 4 параллельных потока. Поточная обработка улучшает исполнение хранения и получения данных в кэше, использование блокировок, чтобы предотвратить перезапись потоков или обновление тех же самых значений. Чтобы увеличить или сократить число потоков, используйте опцию -t option:

    shell> memcached -t 8
    
  • -d

    Запустить memcached как демон (фоновый) процесс:

    shell> memcached -d
    
  • -r

    Максимум размер файла ядра. В случае отказа сервер пытается сбросить все из памяти на диск как файл ядра до любых пределов, наложенных setrlimit.

  • -M

    Возвратить ошибку клиенту, когда память была исчерпана. Это заменяет нормальное поведение удаления более старых элементов из кэша, чтобы освободить место для новых элементов.

  • -k

    Заблокировать все страницы памяты. Это резервирует память перед использованием, вместо того, чтобы выделить новые блоки, когда новые элементы сохранены в кэше.

    Есть предел на уровне пользователя, сколько памяти Вы можете заблокировать. Попытка выделить больше, чем доступная память терпит неудачу. Вы можете установить предел для пользователя, с которого Вы запустили демона (не для пользователя -u user) в пределах оболочки при использовании ulimit -S -l NUM_KB.

  • -v

    Многословный режим. Ошибки и предупреждения выводятся.

  • -vv

    Очень многословный режим. В дополнение к информации, напечатанной -v, также печатает каждую команду клиента и ответ.

  • -vvv

    Чрезвычайно многословный режим. В дополнение к информации, напечатанной -vv, также покажет переходы внутреннего состояния.

  • -h

    Напечатает сообщение справки.

  • -i

    Напечатает лицензии memcached и libevent.

  • -I mem

    Определить максимальный размер, разрешенный для того, чтобы хранить объект в пределах memcached. Размер поддерживает единицы postfix (k для килобайт, m для мегабайт). Например, чтобы увеличить максимальный поддержанный размер объекта до 32 МБ:

    shell> memcached -I 32m
    

    Максимальный размер объекта, который Вы можете определить, составляет 128 MB, значение по умолчанию 1MB. Эта опция была добавлена в 1.4.2.

  • -b

    Установите неудовлетворенный предел очереди. Неудовлетворенная очередь конфигурирует, сколько сетевых соединений может ждать обработки memcached. Увеличение этого предела может уменьшить ошибки, полученные клиентом, которого это не в состоянии соединить с memcached, но не улучшает исполнение сервера. Значение по умолчанию 1024.

  • -P pidfile

    Сохранить ID memcached в file.

  • -f

    Установите фактор роста размера блока. Когда выделяются новые блоки памяти, выделенный размер новых блоков определен, умножая размер блока памяти по умолчанию на этот параметр.

    Чтобы видеть эффекты этой опции без обширного тестирования, используйте параметр командной строки -vv, чтобы показать расчетные размеры блоков. Для получения дополнительной информации см. раздел 18.2.2.9.

  • -n bytes

    Минимальное пространство, выделенное для информации key+value+flags. Значение по умолчанию составляет 48 байтов.

  • -L

    На системах, которые поддерживают большие страницы памяти, их применять. Использование больших страниц памяти позволяет memcached выделить кэш элемента в одном большом куске, который может улучшить работу, уменьшая число промахов, получая доступ к памяти.

  • -C

    Отключить использование операций сравнения и свопа (CAS). Эта опция была добавлена в memcached 1.3.x.

  • -D char

    Установить символ значения по умолчанию, который будет использоваться в качестве разделителя между префиксами ключа и ID. Это используется для сообщения статистики по префиксам (см. раздел 18.2.4). Значение по умолчанию двоеточие (:). Если эта опция используется, набор статистики включен автоматически. Если не используется, Вы можете включить статистику, посылая серверу команду stats detail on. Эта опция была добавлена в memcached 1.3.x.

  • -R num

    Устанавливает максимальное количество запросов на процесс событий. Значение по умолчанию 20.

  • -B protocol

    Установить обязательный протокол, то есть значение по умолчанию протокола memcached соединений клиента. Опции: ascii, binary или auto. Автоматический (auto) по умолчанию. Эта опция была добавлена в memcached 1.4.0.

18.2.2.2. Развертывание memcached

Вы можете использовать много различных потенциальных стратегий развертывания и топологии memcached. Точная стратегия использовать зависит от Вашего приложения и окружающей среды. Развивая систему для того, чтобы развернуть memcached в пределах Вашей системы, имейте в виду следующие моменты:

  • memcached только кэширующий механизм. Это не должно использоваться, чтобы хранить информацию, которую Вы не можете позволить себе потерять и затем загрузить из иного места.

  • Нет никакой безопасности, встроенной в протокол memcached. Как минимум, удостоверьтесь, что серверы, работающие с memcached, доступны только изнутри Вашей сети, и что используемые сетевые порты заблокированы (используя брандмауэр, например). Если информация, которая хранится на серверах memcached, является чувствительной, то зашифруйте информацию прежде, чем сохранить ее в memcached.
  • memcached не обеспечивает никакого аварийного переключения. Поскольку нет никакой связи между различными копиями memcached, то когда сервер терпит неудачу, Ваше приложение должно быть способно удалить его из списка, обеспечить перезагрузку данных и затем начать запись данных в другой экземпляр memcached.
  • Время ожидания между клиентами и memcached может быть проблемой, если Вы используете различные физические машины для этих задач. Если Вы находите, что время ожидания проблема, переместите memcached на клиента.
  • Длина ключа определена сервером memcached. Максимум размера ключа по умолчанию составляет 250 байт.
  • Попытайтесь использовать по крайней мере два сервера memcached, специально для многих клиентов, чтобы избежать получить единственный пункт отказа. Идеально, создайте так много хостов memcached, насколько возможно. При добавлении и удалении memcached из бассейна, хеширование и распределение пар "ключ/значение" могут быть затронуты. Для информации о том, как избежать проблем см. раздел 18.2.2.5.

18.2.2.3. Использование пространства имен

memcached очень простая массивная система хранения ключа/значения, и нет никакого способа разделить данные автоматически в различные разделы. Например, если Вы сохраните информацию об уникальных ID, возвращенных из базы данных MySQL, а затем данные от двух различных таблиц, можете столкнуться с проблемами, потому что те же самые ID могут быть допустимы в обеих таблицах.

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

Вы можете осуществить тот же самый основной принцип при использовании ключей, которые описывают объект и уникальный идентификатор в пределах ключа, который Вы поставляете, когда объект сохраняется. Например, храня пользовательские данные, добавьте ID пользователя с user: или user-.

Использование пространства имен или префиксов только управляет ключами. Нет никакой безопасности в пределах memcached, и поэтому никакого способа провести в жизнь, что особый клиент имеет доступ к особому пространству имен. Пространства имен полезны только как метод идентификации данных и предотвращения повреждения пар "ключ/значение".

18.2.2.4. Истечение данных

Есть два типа истечения данных в memcached. Первый тип применен, когда Вы сохраняете новую пару ключ/значения в memcached. Если недостаточно места в пределах подходящего блока, чтобы сохранить значение, то существующий объект, использованный последним (LRU) удален из кэша, чтобы создать место для нового элемента.

Алгоритм LRU гарантирует, что объект, который удален, больше не используется или это использовалось так давно, что его данные потенциально устаревшие. Однако, в системе, где память, выделенная memcached меньше числа регулярно используемых объектов в кэше, много элементов с истекшим сроком может быть удалено из кэша даже при том, что они еще в активном употреблении. Вы используете механизм статистики, чтобы получить лучшее представление об уровне удалений. Для получения дополнительной информации см. раздел 18.2.4.

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

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

Типичный сценарий для того, чтобы явно установить время истечения мог бы включать данные о сеансе кэширования для пользователя, получая доступ к Веб-сайту. memcached использует ленивый механизм истечения, где явное время истечения, которое было установлено, сравнивается с текущим временем, когда объект требуют. Только объекты, которые не истекли, возвращены.

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

18.2.2.5. Типы хэширования и распределения в memcached

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

Вы можете думать об этом процессе следующим образом. Учитывая массив серверов (a, b и c), клиент использует хеширующий алгоритм, который возвращает целое число, основанное на ключе, сохраненном или полученном. Получающееся значение используется, чтобы выбрать сервер из списка серверов, сконфигурированных в клиенте. Самый стандартный клиент, хеширующий в memcache, использует простое вычисление модуля на значении числа сконфигурированных memcached серверов. Вы можете суммировать процесс в псевдокоде как:

@memcservers = ['a.memc','b.memc','c.memc'];
$value = hash($key);
$chosen = $value % length(@memcservers);

Замените вышеупомянутое со значениями: Replacing the above with values:

@memcservers = ['a.memc','b.memc','c.memc'];
$value = hash('myid');
$chosen = 7009 % 3;

В вышеупомянутом примере клиентский хеширующий алгоритм выбирает сервер с индексом (7009 % 3 = 1), сохраняет или получаете ключ и значение с его помощью.

Этот выбор и хеширующий процесс обработан автоматически клиентом memcached, которого Вы используете: Вы должны только обеспечить список серверов memcached.

Рис. 18.3. Выбор хеша memcached.

То же самое хеширование и процесс выбора имеет место во время любой работы на указанном ключе в пределах клиента memcached .

Использование этого метода обеспечивает много преимуществ:

  • Хеширование и выбор сервера обработаны полностью в пределах клиента. Это избавляет от необходимости выполнять сетевые коммуникации, чтобы определить правильную машину.

  • Поскольку определение сервера memcached происходит полностью в пределах клиента, сервер может быть выбран автоматически, независимо от выполняемой работы.
  • Поскольку определение обработано в пределах клиента, хеширующий алгоритм возвращает то же самое значение для данного ключа, значения не затронуты или сброшены различиями в окружающей среде сервера.
  • Выбор очень быстр. Хеширующий алгоритм на значении ключа быстр, как и получающийся выбор сервера из простого массива доступных машин.
  • Использование хеширование на стороне клиента упрощает распределение данных по каждому серверу memcached. Естественное распределение значений, возвращенных хеширующим алгоритмом, означает, что ключи автоматически распространены по доступным серверам.

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

Однако, если Вы не используете тот же самый хеширующий механизм, те же самые данные могут быть зарегистрированы на различных серверах различными интерфейсами, тратящими впустую пространство на Вашем memcached и приводящими к разнобою.

Один способ использовать многоинтерфейсный совместимый хеширующий механизм состоит в том, чтобы использовать библиотеку libmemcached и и связанные интерфейсы. Поскольку интерфейсы для различных языков (включая C, Ruby, Perl и Python) используют тот же самый интерфейс библиотеки клиента, они всегда производят тот же самый код хеша из ID.

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

  • Новый сервер memcached был добавлен к списку доступных хостов.

  • Сервер memcached был удален из списка доступных машин.
  • Порядок серверов поменялся.

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

Если новый сервер добавлен в список серверов, как new.memc как в примере ниже, то операция GET используя тот же самый ключ myid, может привести к сбою кэша. Это потому, что то же самое значение вычислено от ключа, который выбирает тот же самый индекс в массиве серверов, но индекс теперь указывает на другую машину, а не на c.memc, где данные первоначально хранились. Это привело бы к сбою даже при том, что ключ существует в пределах кэша на другом сервере.

Рис. 18.4. Выбор хеша с новым сервером memcached

Это означает, что серверы c.memc и new.memc содержат информацию для ключа myid, но информация на каждой машине может отличаться в каждом случае. Более существенная проблема: намного более высокое число промахов кэша, получая данные, поскольку добавление нового сервера изменяет распределение ключей, а это в свою очередь требует восстановления кэшируемых данных, вызывая увеличение чтений базы данных.

Тот же самый эффект может произойти, если Вы активно управляете списком серверов, сконфигурированных в Ваших клиентах, добавляя и удаляя сконфигурированные memcached машины, поскольку каждый сервер идентифицирован как доступный. Например, удаление хоста, когда клиент замечает, что с ним больше нельзя связаться, может заставить выбор сервера потерпеть неудачу как описано здесь.

Чтобы предотвратить эти существенные проблемы и лишение законной силы Вашего кэша, Вы можете выбрать хеширующий алгоритм, используемый, чтобы выбрать сервер. Есть два общих типа алгоритма хеширования, последовательный и modula.

С последовательными хеширующими алгоритмами тот же самый ключ, когда применяется к списку серверов всегда использует тот же самый сервер, чтобы сохранить или получить ключи, даже если список сконфигурированных серверов изменяется. Это означает, что Вы можете добавить и удалить серверы из списка и всегда использовать тот же самый сервер для данного ключа. Есть два типа последовательных хеширующих доступных алгоритмов Ketama и Wheel. Оба типа поддержаны libmemcached и выполнение доступно для PHP и Java.

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

С хеширующим алгоритмом modula клиент выбирает сервер первыми вычислениями хеша, а затем выбором сервера из списка сконфигурированных серверов. Если список серверов изменен, выбранный сервер, используя хеширующий алгоритм modula, также изменяется. Результат: поведение, описанное выше. Изменения списка серверов означают, что различные серверы выбраны при получении данных, приводя к промахам кэша и увеличению нагрузки базы данных, поскольку кэш повторно наполняется информацией.

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

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

18.2.2.6. Применение memcached и DTrace

memcached включает много различных исследований DTrace, которые могут использоваться, чтобы контролировать работу сервера. Включенные исследования могут контролировать отдельные соединения, распределения памяти и модификации хэш-таблицы, когда пара ключа/значения добавлена, обновлена или удалена.

Для получения дополнительной информации о DTrace и написании скриптов DTrace читайте DTrace User Guide.

Поддержка исследований DTrace была добавлена к memcached 1.2.6, включая много исследований DTrace, которые могут использоваться, чтобы помочь контролировать Ваше приложение. DTrace поддержан на Solaris 10, OpenSolaris, OS X 10.5 и FreeBSD. Чтобы включить исследования DTrace в memcached, создайте из пакет из исходных текстов и используйте опцию --enable-dtrace.

Исследования, поддержанные memcached:

  • conn-allocate(connid)

    Запущено, когда объект соединения выделен из бассейна соединения.

    Параметры:

    • connid: ID соединения.

  • conn-release(connid)

    Запущен, когда объект соединения выпущен назад в бассейн соединения.

    Параметры:

    • connid: ID соединения.

  • conn-create(ptr)

    Запущен, когда новый объект соединения создается (то есть, нет никаких свободных объектов подключения в бассейне соединения).

    Параметры:

    • ptr: Указатель на объект соединения.

  • conn-destroy(ptr)

    Запущен, когда объект соединения разрушается.

    Параметры:

    • ptr: Указатель на объект соединения.

  • conn-dispatch(connid, threadid)

    Запущен, когда соединение послано от основного потока или потока управления соединения рабочему потоку.

    Параметры:

    • connid: ID соединения.

    • threadid: ID потока.

  • slabs-allocate(size, slabclass, slabsize, ptr)

    Выделить память от имени распределителя памяти.

    Параметры:

    • size: Требуемый размер.

    • slabclass: Распределение выполнено в этом классе.
    • slabsize: Размер каждого элемента в этом классе.
    • ptr: Указатель на выделенную память.

  • slabs-allocate-failed(size, slabclass)

    Сбой выделения памяти (мало памяти).

    Параметры:

    • size: Требуемый размер.

    • slabclass: Класс, который был не в состоянии выполнить запрос.

  • slabs-slabclass-allocate(slabclass)

    Запущен, когда класс памяти нуждается в большем количестве места.

    Параметры:

    • slabclass: Класс, который нуждается в большей памяти.

  • slabs-slabclass-allocate-failed(slabclass)

    Ошибка выделения памяти (out of memory).

    Параметры:

    • slabclass: Класс, который был не в состоянии получить больше памяти.

  • slabs-free(size, slabclass, ptr)

    Память освобождена.

    Параметры:

    • size: Объем памяти в байтах.

    • slabclass: Класс, которому память принадлежит.
    • ptr: Указатель на память.

  • assoc-find(key, depth)

    Запущен при поиске в хэш-таблице ключа. Эти два элемента обеспечивают понимание, как хорошо функция хеша работает. Пересечения знак менее оптимальной функции, тратящей впустую способность центрального процессора.

    Параметры:

    • key: Искомый ключ.

    • depth: Глубина в списке хэш-таблицы.

  • assoc-insert(key, nokeys)

    Запущен, когда новый элемент был вставлен.

    Параметры:

    • key: Ключ, который вставили.

    • nokeys: Общее количество ключей, в настоящее время сохраненных, включая ключ, для которого вызвали вставку.

  • assoc-delete(key, nokeys)

    Запущен, когда новый элемент был удален.

    Параметры:

    • key: Ключ, который удален.

    • nokeys: Общее количество ключей, в настоящее время сохраненных, исключая ключ, для которого удаление вызвано.

  • item-link(key, size)

    Запущен, когда элемент соединяется в кэше.

    Параметры:

    • key: Ключ элемента.

    • size: Размер данных.

  • item-unlink(key, size)

    Запущен, когда элемент удаляется.

    Параметры:

    • key: Ключ элемента.

    • size: Размер данных.

  • item-remove(key, size)

    Запущен, когда refcount для элемента уменьшен.

    Параметры:

    • key: Ключ элемента.

    • size: Размер данных.

  • item-update(key, size)

    Запущенный, когда время последней ссылки обновлено.

    Параметры:

    • key: Ключ элемента.

    • size: Размер данных.

  • item-replace(oldkey, oldsize, newkey, newsize)

    Запущен, когда элемент заменяется другим элементом.

    Параметры:

    • oldkey: Ключ старого элемента.

    • oldsize: Размер старого элемента.
    • newkey: Ключ нового элемента.
    • newsize: Размер нового элемента.

  • process-command-start(connid, request, size)

    Запущен, когда обработка команды запускается.

    Параметры:

    • connid: ID соединения.

    • request: Входящий запрос.
    • size: Размер запроса.

  • process-command-end(connid, response, size)

    Запущен, когда обработка команды сделана.

    Параметры:

    • connid: ID соединения.

    • response: Ответ, чтобы отослать назад клиенту.
    • size: Размер ответа.

  • command-get(connid, key, size)

    Запущен для команды get.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Размер данных ключа (или -1, если не найден).

  • command-gets(connid, key, size, casid)

    Запущен для команды gets.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Размер данных ключа (или -1, если не найден).
    • casid: casid для элемента.

  • command-add(connid, key, size)

    Запущен для команды add.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).

  • command-set(connid, key, size)

    Запущен для команды set.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).

  • command-replace(connid, key, size)

    Запущен для команды replace.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).

  • command-prepend(connid, key, size)

    Запущен для команды prepend.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).

  • command-append(connid, key, size)

    Запущен для команды append.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).

  • command-cas(connid, key, size, casid)

    Запущен для команды cas.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • size: Новый размер данных ключа (или -1, если не найден).
    • casid: cas ID.

  • command-incr(connid, key, val)

    Запущен для команды incr.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • val: Новое значение.

  • command-decr(connid, key, val)

    Запущен для команды decr.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • val: Новое значение.

  • command-delete(connid, key, exptime)

    Запущен для команды delete.

    Параметры:

    • connid: ID соединения.

    • key: Требуемый ключ.
    • exptime: Время истечения.

18.2.2.7. Распределение памяти в memcached

Когда Вы сначала запускаете memcached, память, которую Вы сконфигурировали, автоматически не выделена. Вместо этого memcached начинает выделять и резервировать физическую память, как только Вы начинаете сохранять информацию в кэш.

Когда Вы начинаете хранить данные в кэше, memcached не выделяет памяти для данных на основе элемента. Вместо этого распределение плиты используется, чтобы оптимизировать использование памяти и предотвратить фрагментацию памяти, когда информация удаляется из кэша.

С распределением куска память сохранена в блоках по 1 МБ. Кусок разделен на много блоков равного размера. Когда Вы пытаетесь сохранить значение в кэш, memcached проверяет размер значения, которое Вы добавляете к кэшу, и определяет, какой кусок содержит распределение правильного размера для элемента. Если кусок с размером элемента уже существует, элемент записан в блок в его пределах.

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

Например, размер значения по умолчанию для самого маленького блока составляет 88 байтов (40 байт значение и по умолчанию 48 байт для ключа и данных о флаге). Если размер первого элемента, который Вы храните в кэше, составляет меньше 40 байтов, то кусок с размером блока 88 байтов создается, и значение сохранено.

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

Рис. 18.5. Распределение памяти в memcached

Результат состоит в том, что Вам выделили много страниц в пределах диапазона памяти, выделенной memcached. Каждая страница составляет 1 МБ (по умолчанию) и разделена на различное число кусков, согласно размеру куска, требуемому, чтобы сохранить пары ключа/значения. Каждому экземпляру выделили много страниц, и страница всегда создается, когда новый элемент должен быть создан, требуя куска особого размера. Кусок может состоять из многих страниц, и каждая страница в пределах куска содержит равное количество блоков.

Размер куска определен основным размером куска, объединенным с фактором роста размера куска. Например, если начальные куски составляют 104 байта в размере, и фактор роста размера куска по умолчанию используется (1.25), то следующий выделенный размер куска был бы 104*1.25 или 136 байт.

Выделение страниц таким образом гарантирует, что память не становится фрагментированной. Однако, в зависимости от распределения объектов, которые Вы храните, это может привести к неэффективному распределению кусков, если у Вас есть существенно отличающиеся размером элементы. Например, имея относительно небольшое количество элементов в пределах каждого размера куска можно потратить впустую большую память только с немногими кусками в каждой выделенной странице.

Вы можете настроить фактор роста, чтобы уменьшить этот эффект при использовании параметра командной строки -f, который приспосабливает фактор роста, чтобы сделать более эффективное использование кусков. Для информации о том, как определить текущую статистику распределения см. раздел 18.2.4.2.

Если Ваша операционная система поддерживает это, Вы можете также запустить memcached с параметром командной строки -L. Эта опция предварительно выделяет всю память во время запуска, используя большие страницы памяти. Это может улучшить работу, сокращая количество промахов в кэш-памяти центрального процессора.

18.2.2.8. Поддержка потоков в memcached

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

Когда включено, выполнение поточной обработки работает следующим образом:

  • Поток обработан, обертывая функции в пределах кода, чтобы обеспечить основную защиту от обновления тех же самых глобальных структур в то же самое время.

  • Каждый поток использует свой собственный экземпляр libevent, чтобы помочь улучшить работу.
  • Соединения TCP/IP обработаны единственным потоком, слушающим на сокете TCP/IP. Каждое соединение распределено одному из активных потоков на простой круговой основе. Каждое соединение работает исключительно в пределах этого потока, в то время как соединение остается открытым.
  • Для соединений UDP все потоки слушают единственный сокет UDP для входящих запросов. Потоки, которые в настоящее время не имеют дело с другим запросом, игнорируют поступающий пакет. Один из остающихся, незанятых, потоков читает запрос и посылает ответ. Это выполнение может привести к увеличенной загрузке центрального процессора, поскольку потоки просыпаются от сна, чтобы потенциально обработать запрос.

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

18.2.2.9. Журналы memcached

Если Вы включаете многословный режим, используя опции -v, -vv или -vvv, вывод информации memcached включает детали выполняемых операций.

Без многословных опций memcached обычно не производит вывода во время нормального действия.

  • Вывод, используя -v.

    Самый низкий уровень многословия показывает Вам:

    • Ошибки и предупреждения

    • Переходные ошибки
    • Ошибки протокола и сокета, включая истощение доступных соединений
    • Каждое зарегистрированное соединение клиента, включая дескрипторное число сокета и используемый протокол.

      Например:

      32: Client using the ascii protocol
      33: Client using the ascii protocol
      

      Описатель сокета допустим только в то время, как клиент остается соединенным. Нестойкие соединения не могут быть эффективно представлены.

    Примеры вывода сообщений об ошибках на этом уровне:

    <%d send buffer was %d, now %d
    Can't listen for events on fd %d
    Can't read from libevent pipe
    Catastrophic: event fd doesn't match conn fd!
    Couldn't build response
    Couldn't realloc input buffer
    Couldn't update event
    Failed to build UDP headers
    Failed to read, and not due to blocking
    Too many open connections
    Unexpected state %d
    
  • Вывод, используя -vv

    Используя второй уровень многословия, Вы получаете более подробную информацию об операциях протокола, обновленные ключи и детали.

    Во время начального запуска memcached с этим уровнем Вам показывают размеры отдельных классов, размеры куска и число записей. Они не показывают распределение кусков, только куски, которые были бы созданы, когда данные добавлены. Вам также дают информацию о сетевых очередях. Образец вывода, произведенного для TCP/IP-системы с памятью по умолчанию дан ниже:

    shell> memcached -vv
    slab class   1: chunk size 80 perslab 13107
    slab class   2: chunk size104 perslab 10082
    slab class   3: chunk size136 perslab  7710
    slab class   4: chunk size176 perslab  5957
    slab class   5: chunk size224 perslab  4681
    slab class   6: chunk size280 perslab  3744
    slab class   7: chunk size352 perslab  2978
    slab class   8: chunk size440 perslab  2383
    slab class   9: chunk size552 perslab  1899
    slab class  10: chunk size696 perslab  1506
    slab class  11: chunk size872 perslab  1202
    slab class  12: chunk size   1096 perslab   956
    slab class  13: chunk size   1376 perslab   762
    slab class  14: chunk size   1720 perslab   609
    slab class  15: chunk size   2152 perslab   487
    slab class  16: chunk size   2696 perslab   388
    slab class  17: chunk size   3376 perslab   310
    slab class  18: chunk size   4224 perslab   248
    slab class  19: chunk size   5280 perslab   198
    slab class  20: chunk size   6600 perslab   158
    slab class  21: chunk size   8256 perslab   127
    slab class  22: chunk size  10320 perslab   101
    slab class  23: chunk size  12904 perslab81
    slab class  24: chunk size  16136 perslab64
    slab class  25: chunk size  20176 perslab51
    slab class  26: chunk size  25224 perslab41
    slab class  27: chunk size  31536 perslab33
    slab class  28: chunk size  39424 perslab26
    slab class  29: chunk size  49280 perslab21
    slab class  30: chunk size  61600 perslab17
    slab class  31: chunk size  77000 perslab13
    slab class  32: chunk size  96256 perslab10
    slab class  33: chunk size 120320 perslab 8
    slab class  34: chunk size 150400 perslab 6
    slab class  35: chunk size 188000 perslab 5
    slab class  36: chunk size 235000 perslab 4
    slab class  37: chunk size 293752 perslab 3
    slab class  38: chunk size 367192 perslab 2
    slab class  39: chunk size 458992 perslab 2
    <26 server listening (auto-negotiate)
    <29 server listening (auto-negotiate)
    <30 send buffer was 57344, now 2097152
    <31 send buffer was 57344, now 2097152
    <30 server listening (udp)
    <30 server listening (udp)
    <31 server listening (udp)
    <30 server listening (udp)
    <30 server listening (udp)
    <31 server listening (udp)
    <31 server listening (udp)
    <31 server listening (udp)
    

    Использование этого уровня может быть полезным способом проверить эффекты фактора роста, используемого на кусках с различными распределениями памяти, которые в свою очередь могут использоваться, чтобы лучше настроить фактор роста, чтобы удовлетворить данным, которые Вы храните в кэше. Например, если Вы устанавливаете фактор роста в 4 (увеличение вчетверо размера каждого куска):

    shell> memcached -f 4 -m 1g -vv
    slab class   1: chunk size 80 perslab 13107
    slab class   2: chunk size320 perslab  3276
    slab class   3: chunk size   1280 perslab   819
    slab class   4: chunk size   5120 perslab   204
    slab class   5: chunk size  20480 perslab51
    slab class   6: chunk size  81920 perslab12
    slab class   7: chunk size 327680 perslab 3
    ...
    

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

    32: Client using the ascii protocol
    <32 set my_key 0 0 10
    >32 STORED
    <32 set object_key 1 0 36
    >32 STORED
    <32 get my_key
    >32 sending key my_key
    >32 END
    <32 get object_key
    >32 sending key object_key
    >32 END
    <32 set key 0 0 6
    >32 STORED
    <32 incr key 1
    >32 789544
    <32 decr key 1
    >32 789543
    <32 incr key 2
    >32 789545
    <32 set my_key 0 0 10
    >32 STORED
    <32 set object_key 1 0 36
    >32 STORED
    <32 get my_key
    >32 sending key my_key
    >32 END
    <32 get object_key
    >32 sending key object_key1 1 36
    >32 END
    <32 set key 0 0 6
    >32 STORED
    <32 incr key 1
    >32 789544
    <32 decr key 1
    >32 789543
    <32 incr key 2
    >32 789545
    

    Во время коммуникации клиента, для каждой строки, начальный символ показывает направление потока информации. <Для коммуникации от клиента к memcached серверу и > для коммуникации назад клиенту. Число это числовой описатель сокета для соединения.

  • Вывод, используя -vvv

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

    <32 new auto-negotiating client connection
    32: going from conn_new_cmd to conn_waiting
    32: going from conn_waiting to conn_read
    32: going from conn_read to conn_parse_cmd
    32: Client using the ascii protocol
    <32 set my_key 0 0 10
    32: going from conn_parse_cmd to conn_nread
    > NOT FOUND my_key
    >32 STORED
    32: going from conn_nread to conn_write
    32: going from conn_write to conn_new_cmd
    32: going from conn_new_cmd to conn_waiting
    32: going from conn_waiting to conn_read
    32: going from conn_read to conn_closing
    <32 connection closed.
    

Все уровни в memcached разработаны, чтобы использоваться во время отладки или экспертизы проблем. Количество произведенной информации, особенно используя -vvv, является существенным, особенно на занятом сервере. Также знайте, что запись информации об ошибке, особенно на диск, может сильно снизить прирост производительности, которого Вы достигаете при использовании memcached. Поэтому, использование в рабочей среде не рекомендуется.

18.2.3. Разработка приложений memcached

Много языковых интерфейсов позволяют приложениям хранить и получать информацию с memcached. Вы можете написать приложения для memcached на популярных языках, таких как Perl, PHP, Python, Ruby, C и Java.

Данные, хранимые сервером memcached, упомянуты единственной строкой (ключом) с хранением в кэше и извлечением из кэша, используя ключ в качестве ссылки. Кэш поэтому работает как многочисленный ассоциативный массив или хэш-таблица. Невозможно структурировать или иначе организовать информацию, хранимую в кэше. Чтобы подражать понятиям базы данных, таким как многие таблицы или сложные значения ключа, Вы должны закодировать дополнительную информацию в строки, используемые в качестве ключей. Например, чтобы сохранить или искать адрес, соответствующий определенной широте и долготе, Вы могли бы превратить те два числовых значения в единственную разделенную запятыми строку, чтобы использовать в качестве ключа.

18.2.3.1. Основные действия memcached

Интерфейс к memcached поддерживает следующие методы для хранения и получения информации в кэше, и они одинаковы для всех API, хотя специфика языка отличается:

  • get(key): Получает информацию из кэша. Возвращает значение, связанное с ключом, если указанный ключ существует. Возвращает NULL, nil, undefined или самый близкий эквивалент на соответствующем языке, если указанный ключ не существует.

  • set(key, value [, expiry]): Устанавливает элемент, связанный с ключом в кэше к указанному значению. Это обновляет существующий элемент, если ключ уже существует, или добавляет новую пару ключа/значения, если ключ не существует. Если время истечения определено, то элемент истекает (и будет удален), когда время истечения достигнуто. Время определено в секундах и учтено в качестве относительного времени, если значение составляет меньше 30 дней (30*24*60*60), или абсолютного времени (epoch), если больше, чем это значение.
  • add(key, value [, expiry]): Добавляет ключ и связанное значение к кэшу, если указанный ключ не существует.
  • replace(key, value [, expiry]): Заменяет элемент, связанный с указанным key, только если ключ уже существует. Новое значение дано параметром value.
  • delete(key [, time]): Удаляет key и его связанный элемент из кэша. Если Вы указали time, тогда добавление другого элемента с указанным key заблокировано в течение установленного периода.
  • incr(key, value): Увеличивает элемент, связанный с key на указанное value.
  • decr(key, value): Уменьшает элемент, связанный с key на указанное value.
  • flush_all: Лишает законной силы (или истекает), все текущие элементы в кэше. Технически они все еще существуют (они не удалены), но будут тихо разрушены в следующий раз, когда Вы попытаетесь получить доступ к ним.

Во всех реализациях большая часть или все эти функции дублированы через соответствующий интерфейс языка.

Сложные структуры данных не могут быть сохранены непосредственно. Большинство интерфейсов преобразовывает в последовательную форму данные для Вас, то есть, поместите их в текстовую форму, которая может восстановить оригинальные указатели и вложение. Использование Perl Storable, PHP serialize, Python cPickle (или Pickle), Java Serializable интерфейсов предназначено как раз для этого. В большинстве случаев используемый интерфейс преобразования в последовательную форму настраиваем. Чтобы совместно использовать данные, хранимые в memcached между различными языковыми интерфейсами, рассмотрите использование общего решения для преобразования в последовательную форму, такого как JSON (Javascript Object Notation).

18.2.3.2. Применение memcached как кэширующего уровня MySQL

Когда memcached используется, чтобы кэшировать данные MySQL, Ваше приложение должно получить данные от базы данных и загрузить соответствующие пары значения ключа в кэш. Тогда последующие поиски могут быть сделаны непосредственно в кэш.

Поскольку у MySQL есть свои собственные механизмы кэширования в памяти для запрашиваемых данных, такие как InnoDB и кэш запроса MySQL, ищите возможности вне загрузки отдельных значений столбцов или строк в кэш. Предпочтите кэшировать сложные значения, такие как полученные от многих таблиц до запроса соединения или наборов результатов, собранных из многих строк.

Ограничьте информацию в кэше несекретными данными, потому что нет никакой безопасности, требуемой, чтобы получить доступ или обновить информацию в пределах memcached. У любого с доступом к машине есть способность считать, рассмотреть и потенциально обновить информацию. Чтобы сохранить данные безопасными, зашифруйте информацию прежде, чем кэшировать. Чтобы ограничить пользователей, способных к соединению с сервером, отключите сетевой доступ или используйте IPTables или подобные методы, чтобы ограничить доступ к портам memcached избранным набором хостов.

Вы можете ввести memcached в существующее приложение, даже если кэширование не было частью оригинального проекта. На многих языках изменения приложения будут только несколькими строками, чтобы попытаться сначала читать из кэша, загружая данные, и отступить к старому методу, если информация не будет кэшироваться, и обновить кэш с информацией, как только данные были считаны.

Общая последовательность для того, чтобы использовать memcached на любом языке как кэширующее решение для MySQL следующяя:

  1. Запросите элемент от кэша.

  2. Если он там есть, используйте данные.
  3. Если его там нет, загрузите данные из MySQL и сохраните значение в кэше. Это означает, что значение доступно следующему клиенту, который запросит это из кэша.

Рис. 18.6. Типичная блок-схема приложения memcached

Лучшие методы приспосабливания базы данных к memcached

Самый прямой способ кэшировать данные MySQL состоит в том, чтобы использовать таблицу на 2 столбца, где первый столбец первичный ключ. Из-за требований уникальности для ключей memcached удостоверьтесь, что Ваша схема базы данных делает соответствующее использование первичных ключей и уникальных ограничений.

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

Запросы, которые отображаются наиболее легко на memcached это поиски с одним WHERE, использующие оператор = или IN. Для сложного WHERE или запросов, которые используют такой оператор, как <, >, BETWEEN или LIKE, memcached не обеспечивает простой или эффективный способ фильтровать ключи или связанные значения, так что, как правило, Вы выполняете те операции как запросы SQL в основной базе данных.

18.2.3.3. Использование libmemcached с C и C++

Библиотека libmemcached обеспечивает интерфейсы C и C++ к memcached и является также основанием для различных дополнительных API, включая Perl, Python и Ruby. Понимание ядра libmemcached может помочь, используя эти другие интерфейсы.

Библиотека C самая всесторонняя библиотека интерфейса для memcached обеспечивает функции и операционные системы, не всегда выставляемые в интерфейсах, не основанных на библиотеке libmemcached.

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

Чтобы собрать и установить libmemcached, скачайте пакет libmemcached, запустите configure, соберите и затем поставьте:

shell> tar xjf libmemcached-0.21.tar.gz
shell> cd libmemcached-0.21
shell> ./configure
shell> make
shell> make install

На многих операционных системах Linux Вы можете установить пакет libmemcached через обычный менеджер пакетов yum, apt-get или подобное приложение.

Чтобы создать приложение, которое пользуется библиотекой, сначала устанавливается список серверов. Любое непосредственно управление сконфигурированными серверами выполняется в пределах основной структуры memcached_st или отдельно заполняется список серверов, а затем этот список добавляется к структуре memcached_st. Последний метод используется в следующем примере. Как только список серверов был установлен, Вы можете вызвать функции, чтобы сохранить или получить данные. Простое приложение для того, чтобы установить заданное значение в localhost обеспечено здесь:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libmemcached/memcached.h>

int main(int argc, char *argv[])
{
  memcached_server_st *servers = NULL;
  memcached_st *memc;
  memcached_return rc;
  char *key= "keystring";
  char *value= "keyvalue";

  memcached_server_st *memcached_servers_parse (char *server_strings);
  memc= memcached_create(NULL);
  servers= memcached_server_list_append(servers, "localhost", 11211, &rc);
  rc= memcached_server_push(memc, servers);
  if (rc == MEMCACHED_SUCCESS)
     fprintf(stderr,"Added server successfully\n");
  else fprintf(stderr,"Couldn't add server: %s\n",
               memcached_strerror(memc, rc));
  rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0,
                    (uint32_t)0);
  if (rc == MEMCACHED_SUCCESS) fprintf(stderr,"Key stored successfully\n");
  else fprintf(stderr,"Couldn't store key: %s\n",memcached_strerror(memc,
               rc));
  return 0;
}

Чтобы проверить успех работы, используйте возвращаемое значение или заполненный код результата для данной функции. Значение всегда устанавливается в MEMCACHED_SUCCESS, если работа успешна. В случае отказа используйте функцию memcached_strerror(), чтобы преобразовать код результата в пригодную для печати строку.

Чтобы создать приложение, определите библиотеку memcached:

shell> gcc -o memc_basic memc_basic.c -lmemcached

Выполнение вышеупомянутого примера приложения, после запуска сервера memcached должно возвратить сообщение успеха:

shell> memc_basic
Added server successfully
Key stored successfully
18.2.3.3.1. Основные функции libmemcached

Основные функции позволяют Вам создавать, разрушать и клонировать основную структуру memcached_st, которая используется, чтобы взаимодействовать через интерфейс с серверами memcached. Основные функции определены ниже:

memcached_st *memcached_create (memcached_st *ptr);

Создает новую структуру memcached_st для использования с другими функциями API libmemcached. Вы можете поставлять существующую, статическую, структуру memcached_st или NULL, чтобы иметь новую структуру. Возвращает указатель на создаваемую структуру или NULL при отказе или сбое.

void memcached_free (memcached_st *ptr);

Освобождает структуру и память, выделенную ранее создаваемой структурой memcached_st.

memcached_st *memcached_clone(memcached_st *clone, memcached_st *source);

Клонирует существующую структуру memcached_st из указанной source, копируя значения по умолчанию и список серверов, определенные в структуре.

18.2.3.3.2. Функции сервера libmemcached

API libmemcached использует список серверов, сохраненный в пределах структуры memcached_server_st, чтобы действовать как список серверов, используемых остальной частью функций. Используя memcached, Вы сначала создаете список серверов и затем применяете его к допустимому объекту libmemcached.

Поскольку список серверов и список серверов в пределах активного объекта libmemcached могут управляться отдельно, Вы можете обновить и управлять списками в то время, как активный интерфейс libmemcached работает.

Функции для того, чтобы управлять списком серверов в структуре memcached_st:

memcached_return memcached_server_add(memcached_st *ptr,
                                      char *hostname, unsigned int port);

Добавляет сервер, используя данные hostname и port в структуру memcached_st, указанную через ptr.

memcached_return memcached_server_add_unix_socket(memcached_st *ptr,
                                                  char *socket);

Добавляет Unix-сокет к списку серверов, сконфигурированных в структуре memcached_st.

unsigned int memcached_server_count (memcached_st *ptr);

Возвращает количество сконфигурированных серверов в пределах структуры memcached_st.

memcached_server_st * memcached_server_list (memcached_st *ptr);

Возвращает массив всех определенных узлов в memcached_st.

memcached_return memcached_server_push(memcached_st *ptr,
                                       memcached_server_st *list);

Продвигает существующий список серверов в список серверов, сконфигурированных для текущей структуры memcached_st. Это добавляет серверы в конец существующего списка и дубликаты не проверяет.

Структура memcached_server_st может использоваться, чтобы создать список серверов memcached, которые могут быть применены индивидуально к разным копиям memcached_st.

memcached_server_st * memcached_server_list_append(memcached_server_st *ptr,
                      char *hostname, unsigned int port,
                      memcached_return *error);

Добавляет сервер с hostname и port в список серверов в ptr. Код результата обработан параметром error, который должен указать на существующую переменную memcached_return. Функция возвращает указатель на возвращенный список.

unsigned int memcached_server_list_count (memcached_server_st *ptr);

Возвращает число серверов в списке.

void memcached_server_list_free (memcached_server_st *ptr);

Освобождает память, связанную со списком серверов.

memcached_server_st *memcached_servers_parse (char *server_strings);

Разбирает строку, содержащую список серверов, где отдельные серверы отделены запятой, пробелом или тем и другим сразу, и где отдельные серверы имеют форму server[:port] . Возвращаемое значение структура списка серверов.

18.2.3.3.3. Функции множества libmemcached

Связанные с набором функции libmemcached обеспечивают ту же самую функциональность как основные функции, поддержанные протоколом memcached. Полное определение то же самое для всех основных функций (add, replace, prepend, append). Например, функциональное определение для memcached_set():

memcached_return memcached_set(memcached_st *ptr, const char *key,
                               size_t key_length, const char *value,
                               size_t value_length, time_t expiration,
                               uint32_t flags);

ptr структура memcached_st. key и key_length определяют ключевое имя и длину, а value и value_length соответствующее значение и его длину. Вы можете также установить время истечения и дополнительные флаги. Для получения дополнительной информации см. раздел 18.2.3.3.5.

Эта таблица обрисовывает в общих чертах функции libmemcached и эквивалентные функции, поддержанные протоколом memcached .

Функция libmemcached EЭквивалентная основная функция
memcached_set(memc, key, key_length, value, value_length, expiration, flags) set().
memcached_add(memc, key, key_length, value, value_length, expiration, flags) add().
memcached_replace(memc, key, key_length, value, value_length, expiration, flags) replace().
memcached_prepend(memc, key, key_length, value, value_length, expiration, flags) Предварительно выбирает указанное value перед текущим значением указанного key.
memcached_append(memc, key, key_length, value, value_length, expiration, flags) Добавляет указанное value после текущего значения key.
memcached_cas(memc, key, key_length, value, value_length, expiration, flags, cas) Перезаписывает данные для данного ключа, пока cas все еще то же самое в пределах сервера.
memcached_set_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно set(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.
memcached_add_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно add(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.
memcached_replace_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно replace(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.
memcached_prepend_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно memcached_prepend(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.
memcached_append_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно memcached_append(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.
memcached_cas_by_key(memc, master_key, master_key_length, key, key_length, value, value_length, expiration, flags) Подобно memcached_cas(), но имеет опцию дополнительного главного ключа, который может использоваться, чтобы идентифицировать сервер.

Методы by_key добавляют два параметра, которые определяют главный ключ, чтобы использовать во время хеширующего этапа для того, чтобы выбрать серверы. Вы можете видеть это в следующем определении:

memcached_return memcached_set_by_key(memcached_st *ptr,
                 const char *master_key, size_t master_key_length,
                 const char *key, size_t key_length, const char *value,
                 size_t value_length, time_t expiration, uint32_t flags);

Все функции возвращают значение типа memcached_return, которое Вы можете сравнить с постоянной MEMCACHED_SUCCESS.

18.2.3.3.4. Функции Get libmemcached

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

Основная функция get-стиля, которая эквивалентна get(), memcached_get(). Эта функция возвращает указатель строки, указывая на значение, связанное с указанным ключом.

char *memcached_get(memcached_st *ptr, const char *key, size_t key_length,
                    size_t *value_length, uint32_t *flags,
                    memcached_return *error);

Мультиключевое получение, memcached_mget(), тоже есть. Используя многоключевое получение, работа намного более быстра. Чтобы запустить этот вариант, вызовите memcached_mget():

memcached_return memcached_mget(memcached_st *ptr,
                                char **keys, size_t *key_length,
                                unsigned int number_of_keys);

Возвращаемое значение успех работы. Параметр keys должен быть массивом строк, содержащих ключи, а key_length массив, содержащий длину каждого соответствующего ключа. number_of_keys число ключей, поставляемых в массиве.

Чтобы принести отдельные значения, надо использовать memcached_fetch(), чтобы получить каждое соответствующее значение.

char *memcached_fetch(memcached_st *ptr, const char *key,
                      size_t *key_length, size_t *value_length,
                      uint32_t *flags, memcached_return *error);

Функция возвращает значение ключа с параметрами key, key_length и value_length заполняемыми соответствующим ключом и информацией о длине. Функция вернет NULL, когда нет больше значений, которые будут возвращены. Полный пример, включая заполнение ключевых данных и возвращение информации обеспечен здесь.

#include <stdio.h>
#include <sstring.h>
#include <unistd.h>
#include <libmemcached/memcached.h>

int main(int argc, char *argv[])
{
  memcached_server_st *servers = NULL;
  memcached_st *memc;
  memcached_return rc;
  char *keys[]= {"huey", "dewey", "louie"};
  size_t key_length[3];
  char *values[]= {"red", "blue", "green"};
  size_t value_length[3];
  unsigned int x;
  uint32_t flags;

  char return_key[MEMCACHED_MAX_KEY];
  size_t return_key_length;
  char *return_value;
  size_t return_value_length;
  memc= memcached_create(NULL);
  servers= memcached_server_list_append(servers, "localhost", 11211, &rc);
  rc= memcached_server_push(memc, servers);
  if (rc == MEMCACHED_SUCCESS) fprintf(stderr,"Added server successfully\n");
  else fprintf(stderr,"Couldn't add server: %s\n",memcached_strerror(memc, rc));
  for (x= 0; x < 3; x++) {
    key_length[x] = strlen(keys[x]);
    value_length[x] = strlen(values[x]);
    rc= memcached_set(memc, keys[x], key_length[x], values[x],
    value_length[x], (time_t)0, (uint32_t)0);
    if (rc == MEMCACHED_SUCCESS)
       fprintf(stderr,"Key %s stored successfully\n",keys[x]);
    else fprintf(stderr,"Couldn't store key: %s\n",
                 memcached_strerror(memc, rc));
  }
  rc= memcached_mget(memc, keys, key_length, 3);
  if (rc == MEMCACHED_SUCCESS) {
     while ((return_value= memcached_fetch(memc, return_key,
             &return_key_length, &return_value_length, &flags,
             &rc)) != NULL) {
       if (rc == MEMCACHED_SUCCESS) {
          fprintf(stderr,"Key %s returned %s\n",return_key, return_value);
       }
     }
  }
  return 0;
}

Выполнение вышеупомянутого приложения производит следующий вывод:

shell> memc_multi_fetch
Added server successfully
Key huey stored successfully
Key dewey stored successfully
Key louie stored successfully
Key huey returned red
Key dewey returned blue
Key louie returned green
18.2.3.3.5. Управление поведением libmemcached

Поведение libmemcached может быть изменено, устанавливая один или более флагов поведения. Они могут быть установлены глобально или применены во время вызова отдельных функций. Некоторые параметры поведения также принимают дополнительную установку, такую как хеширующий механизм, используемый для выбора серверов.

Установить глобальные настройки поведения:

memcached_return memcached_behavior_set(memcached_st *ptr,
                                        memcached_behavior flag,
                                        uint64_t data);

Получить текущую установку поведения:

uint64_t memcached_behavior_get(memcached_st *ptr, memcached_behavior flag);

Следующая таблица описывает флаги поведения libmemcached.

ПоведениеОписание
MEMCACHED_BEHAVIOR_NO_BLOCK Предписывает libmemcached использовать асинхронный ввод/вывод.
MEMCACHED_BEHAVIOR_TCP_NODELAY Включает режим без задержек для сетевых сокетов.
MEMCACHED_BEHAVIOR_HASH Без значения устанавливает алгоритм хеширования по умолчанию для ключей в MD5. Другие допустимые значения включают MEMCACHED_HASH_DEFAULT, MEMCACHED_HASH_MD5, MEMCACHED_HASH_CRC, MEMCACHED_HASH_FNV1_64, MEMCACHED_HASH_FNV1A_64, MEMCACHED_HASH_FNV1_32 и MEMCACHED_HASH_FNV1A_32.
MEMCACHED_BEHAVIOR_DISTRIBUTION Изменяет метод выбора сервера, чтобы хранить данное значение. Метод по умолчанию MEMCACHED_DISTRIBUTION_MODULA. Вы можете включить последовательное хеширование, устанавливая MEMCACHED_DISTRIBUTION_CONSISTENT. MEMCACHED_DISTRIBUTION_CONSISTENT псевдоним для MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA.
MEMCACHED_BEHAVIOR_CACHE_LOOKUPS Кэшировать поиски, сделанные службой DNS. Это может улучшить работу, если Вы используете имена вместо IP-адресов для отдельных узлов.
MEMCACHED_BEHAVIOR_SUPPORT_CAS Операции CAS. По умолчанию это отключено, потому что имеет накладные расходы.
MEMCACHED_BEHAVIOR_KETAMA Устанавливает распределение по умолчанию в MEMCACHED_DISTRIBUTION_CONSISTENT_KETAMA и хеш в MEMCACHED_HASH_MD5.
MEMCACHED_BEHAVIOR_POLL_TIMEOUT Изменяет значение тайм-аута, используемое poll(). Задает signed int указатель для значения тайм-аута.
MEMCACHED_BEHAVIOR_BUFFER_REQUESTS Буферизация запросов IO. Действие get или закрытие соединения заставляет сбросить данные.
MEMCACHED_BEHAVIOR_VERIFY_KEY Предписывает libmemcached проверить, что указанный ключ допустим.
MEMCACHED_BEHAVIOR_SORT_HOSTS Если установлено, узлы, добавленные к списку сконфигурированных узлов структуры memcached_st помещены в список узла в сортированном порядке. Это ломает последовательное хеширование, если то поведение было включено.
MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT В неблокированном режиме это изменяет значение тайм-аута во время сокетного соединения.
18.2.3.3.6. Утилиты командной строки libmemcached

В дополнение к основному интерфейсу библиотеки C, libmemcached также включает много утилит командной строки, которые могут быть полезными, работая с приложениями memcached .

Все инструменты командной строки принимают много параметров, самый критический из которых servers, определяет список серверов, с которыми соединиться, возвращая информацию.

Основные инструменты:

  • memcat: Вывести на экран значение для каждого ID, данного в командной строке:

    shell> memcat --servers=localhost hwkey
    Hello world
    
  • memcp: Скопирует содержание файла в кэш, используя имя файла в качестве ключа:
    shell> echo "Hello World" > hwkey
    shell> memcp --servers=localhost hwkey
    shell> memcat --servers=localhost hwkey
    Hello world
    
  • memrm: Удалит элемент из кэша:
    shell> memcat --servers=localhost hwkey
    Hello world
    shell> memrm --servers=localhost hwkey
    shell> memcat --servers=localhost hwkey
    
  • memslap: Проверит загрузку на одном или более серверов memcached, моделируя get/set и многократные операции клиента. Например, Вы можете моделировать загрузку 100 клиентов:
    shell> memslap --servers=localhost --concurrency=100 --flush --test=get
    memslap --servers=localhost --concurrency=100 --flush --test=get
    Threads connecting to servers 100
    Took 13.571 seconds to read data
    
  • memflush: Сбрасывает содержание кэша.
    shell> memflush --servers=localhost
    

18.2.3.4. Применение MySQL и memcached с Perl

Модуль Cache::Memcached обеспечивает интерфейс к протоколу Memcache и оказывает поддержку для основных функций, предлагаемых memcached. Установите модуль, используя систему управления пакетами Вашей операционной системы или CPAN:

root-shell> perl -MCPAN -e 'install Cache::Memcached'

Для использования memcached из Perl через модуль Cache::Memcached, сначала создайте новый объект Cache::Memcached, который определяет список серверов и других параметров для соединения. Единственный параметр хеш, содержащий опции для интерфейса кэша. Например, чтобы создать новый экземпляр, который использует три сервера memcached:

use Cache::Memcached;

my $cache = new Cache::Memcached {
   'servers' => [
   '192.168.0.100:11211',
   '192.168.0.101:11211',
   '192.168.0.102:11211',],};

Используя интерфейс Cache::Memcached с многими серверами, API автоматически выполняет определенные операции через все серверы в группе. Например, получая статистическую информацию через Cache::Memcached возвращает хеш, который содержит данные по всем хостам, так же как и обобщенную статистику для всех серверов в группе.

Вы можете установить дополнительные свойства объекта кэша, когда он создается, определяя опцию как часть хеша опции. Альтернативно, Вы можете использовать соответствующий метод:

2507
  • servers или метод set_servers(): Определяет список серверов, которые будут использоваться. Список серверов должен быть ссылкой на массив серверов, каждый элемент которого комбинация адреса и номера порта (отделенные двоеточием). Вы можете также определить местное соединение через сокет Unix (например, /tmp/sock/memcached). Чтобы определить сервер с весом (указание, сколь часто сервер должен использоваться во время хеширования), определите ссылку массива с экземпляром сервера и числом веса. Более высокие числа дают более высокий приоритет.

  • compress_threshold или метод set_compress_threshold(): Определяет порог, когда значения сжаты. Значения больше, чем это количество, автоматически сжаты (используя zlib) во время сохранения.
  • no_rehash или метод set_norehash(): Отключает обнаружение нового сервера, если оригинальный недоступен.
  • readonly или метод set_readonly(): Отключает запись на серверы memcached.

Когда объект Cache::Memcached был сконфигурирован, Вы можете использовать методы set() и get(), чтобы сохранить и получить информацию от серверов memcached. Объекты, хранящиеся в кэше, автоматически преобразованы в последовательную форму силами модуля Storable.

Интерфейс Cache::Memcached поддерживает следующие методы для того, чтобы сохранить/получить данные:

Функция Cache::Memcached Эквивалентный нативный метод
get()get().
get_multi(keys) Получает несколько keys из memcache, используя только один запрос. Возвращает ссылку хеша пар ключа/значения.
set()set().
add()add().
replace()replace().
delete()delete().
incr()incr().
decr()decr().

Ниже приведен полный пример для того, чтобы использовать memcached с Perl и модулем Cache::Memcached

#!/usr/bin/perl

use Cache::Memcached;
use DBI;
use Data::Dumper;

# Configure the memcached server

my $cache = new Cache::Memcached {
   'servers' => ['localhost:11211',],};

# Get the film name from the command line
# memcached keys must not contain spaces, so create
# a key name by replacing spaces with underscores

my $filmname = shift or die "Must specify the film name\n";
my $filmkey = $filmname;
$filmkey =~ s/ /_/;

# Load the data from the cache
my $filmdata = $cache->get($filmkey);

# If the data wasn't in the cache, then we load it from the database
if (!defined($filmdata)) {
   $filmdata = load_filmdata($filmname);
   if (defined($filmdata)) {
      # Set the data into the cache, using the key
      if ($cache->set($filmkey,$filmdata)) {
         print STDERR "Film data loaded from database and cached\n";
      }
      else {
        print STDERR "Couldn't store to cache\n";
      }
   }
   else {
     die "Couldn't find $filmname\n";
   }
}
else {
  print STDERR "Film data loaded from Memcached\n";
}

sub load_filmdata
{
  my ($filmname) = @_;
  my $dsn = "DBI:mysql:database=sakila;host=localhost;port=3306";
  $dbh = DBI->connect($dsn, 'sakila','password');
  my ($filmbase) = $dbh->selectrow_hashref(sprintf('select * from
                                              film where title = %s',
                                              $dbh->quote($filmname)));
  if (!defined($filmname)) {
     return (undef);
  }
  $filmbase->{stars} = $dbh->selectall_arrayref(sprintf(
                          'select concat(first_name," ",last_name) ' .
                          'from film_actor left join (actor) ' .
                          'on (film_actor.actor_id = actor.actor_id) ' .
                          ' where film_id=%s',
                          $dbh->quote($filmbase->{film_id})));
  return($filmbase);
}

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

shell> memcached-sakila.pl "ROCK INSTINCT"
Film data loaded from database and cached

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

shell> memcached-sakila.pl "ROCK INSTINCT"
Film data loaded from Memcached

18.2.3.5. Использование MySQL и memcached с Python

Модуль Python memcache взаимодействует через интерфейс с серверами memcached и написан на чистом Python (то есть, не используя C API). Вы можете загрузить и установить копию с Python Memcached.

Чтобы установить, загрузите пакет и затем выполните установщик Python:

python setup.py install
running install
running bdist_egg
running egg_info
creating python_memcached.egg-info
...
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing python_memcached-1.43-py2.4.egg
creating /usr/lib64/python2.4/site-packages/python_memcached-1.43-py2.4.egg
Extracting python_memcached-1.43-py2.4.egg to /usr/lib64/python2.4/site-packages
Adding python-memcached 1.43 to easy-install.pth file

Installed /usr/lib64/python2.4/site-packages/python_memcached-1.43-py2.4.egg
Processing dependencies for python-memcached==1.43
Finished processing dependencies for python-memcached==1.43

После того, как установлен, модуль memcache обеспечивает основанный на классе интерфейс к серверам memcached. Когда Вы храните структуры данных Python как элементы memcached, они автоматически преобразованы в последовательную форму (превратились в строковые значения) с помощью модулей Python cPickle или pickle.

Чтобы создать новый интерфейс memcache, импортируйте модуль memcache и создайте новый экземпляр класса memcache.Client. Например, если демон memcached выполняется на localhost с использованием порта по умолчанию:

import memcache
memc = memcache.Client(['127.0.0.1:11211'])

Первый параметр массив строк, содержащих сервер и номер порта для каждого используемого экземпляра memcached. Чтобы позволить отладку, установите дополнительный параметр debug в 1.

По умолчанию, хеширующий механизм делит элементы среди многих серверов. Чтобы изменить используемую функцию, установите значение memcache.serverHashFunction к дополнительной функции, которую использовать. Например:

from zlib import adler32
memcache.serverHashFunction = adler32

Как только Вы определили серверы, чтобы использовать в пределах memcache, основные функции обеспечивают ту же самую функциональность как в исходной спецификации интерфейса. Следующая таблица обеспечивает обзор поддержанных функций:

Функция Python memcache Эквивалентная нативная функция
get()get().
get_multi(keys) Получает много значений из массива keys. Возвращает ссылку хеша пар ключа/значения.
set()set().
set_multi(dict [, expiry [, key_prefix]]) Устанавливает много пар ключа/значения из dict.
add()add().
replace()replace().
prepend(key, value [, expiry]) Предварительно ожидает заданное value к значению существующего key.
append(key, value [, expiry[) Добавляет value к значению существующего key.
delete()delete().
delete_multi(keys [, expiry [, key_prefix]] ) Удаляет все ключи из хеша, соответствующего каждой строке в массиве keys.
incr()incr().
decr()decr().

В пределах модуля Python memcache все функции *_multi() поддерживают дополнительный параметр key_prefix. Если задан, то строка используется в качестве префикса ко всем ключевым поискам. Например, если Вы вызываете:

memc.get_multi(['a','b'], key_prefix='users:')

Функция получает ключи users:a и users:b с серверов.

Вот пример, показывающий сохранение и извлечение информации с memcache, загружая необработанные данные из MySQL:

import sys
import MySQLdb
import memcache

memc = memcache.Client(['127.0.0.1:11211'], debug=1);
try:
  conn = MySQLdb.connect (host = "localhost",
  user = "sakila",
  passwd = "password",
  db = "sakila")
except MySQLdb.Error, e:
  print "Error %d: %s" % (e.args[0], e.args[1])
  sys.exit (1)
popularfilms = memc.get('top5films')
if not popularfilms:
   cursor = conn.cursor()
   cursor.execute('select film_id,title from film order by rental_rate desc limit 5')
   rows = cursor.fetchall()
   memc.set('top5films',rows,60)
   print "Updated memcached with MySQL data"
else:
  print "Loaded data from memcached"
for row in popularfilms:
  print "%s, %s" % (row[0], row[1])

Когда выполнено впервые, данные загружены из базы данных MySQL и хранятся в memcached.

shell> python memc_python.py
Updated memcached with MySQL data

Поскольку данные автоматически преобразованы в последовательную форму, используя cPickle/pickle, когда Вы загружаете данные назад из memcached, Вы можете использовать объект непосредственно. В примере выше информация, сохраненная в memcached, находится в форме строк курсора Python DB. При получении доступа к информации (в пределах 60 секунд), данные загружены из memcached:

shell> python memc_python.py
Loaded data from memcached
2, ACE GOLDFINGER
7, AIRPLANE SIERRA
8, AIRPORT POLLOCK
10, ALADDIN CALENDAR
13, ALI FOREVER

Преобразование в последовательную форму и наоборот происходят автоматически. Поскольку преобразование в последовательную форму данных Python может быть несовместимым с другими интерфейсами и языками, Вы можете изменить модуль преобразования в последовательную форму, используемый во время инициализации. Например, Вы могли бы использовать формат JSON, когда Вы храните сложные структуры данных, используя скрипт, написанный на одном языке, и получаете доступ к ним в скрипте, написанном на ином языке.

18.2.3.6. Использование MySQL и memcached с PHP

PHP оказывает поддержку для функций Memcache посредством расширения PECL. Чтобы включить расширение PHP memcache, соберите PHP с опцией --enable-memcache для configure, собирая из исходных текстов.

Если Вы устанавливаете сервере Red Hat, Вы можете установить php-pecl-memcache RPM:

root-shell> yum --install php-pecl-memcache

На Debian используйте пакет php-memcache.

Чтобы установить глобальные параметры конфигурации во время выполнения, определите значения параметра конфигурации в пределах Вашего файла php.ini. Следующая таблица обеспечивает имя, значение по умолчанию и описание для каждого глобального параметра конфигурации во время выполнения.

Параметр конфигурации Значение по умолчаниюОписание
memcache.allow_failover1 Определяет, должен ли другой сервер в списке быть запрошен, если первый выбранный сервер терпит неудачу.
memcache.max_failover_attempts20 Определяет число серверов, которые попробовать прежде, чем возвратить отказ.
memcache.chunk_size8192 Определяет размер сетевых пакетов, используемых, чтобы обменяться информациями с сервером memcached.
memcache.default_port11211 Определяет порт по умолчанию, чтобы использовать, общаясь с серверами memcached.
memcache.hash_strategystandard Определяет, которую стратегию хеша использовать. Установите в consistent, чтобы позволить серверам быть добавленными или удаленными из объединения, не заставляя ключи быть повторно отображенными на другие серверы. Когда установлено в standard, используется более старая стратегия (modula), которая потенциально использует различные серверы для хранения.
memcache.hash_functioncrc32 Определяет, которую функцию использовать, отображая ключи на серверы. crc32 использует стандартный хеш CRC32. fnv использует хеш FNV-1a.

Чтобы создать соединение с сервером memcached , создайте новый объект Memcache и затем определите опции соединения. Например:

<?php
   $cache = new Memcache;
   $cache->connect('localhost',11211);
?>

Это открывает непосредственное соединение с указанным сервером.

Чтобы использовать много серверов memcached, Вы должны добавить серверы к объекту с использованием addServer():

bool Memcache::addServer ( string $host [, int $port [, bool $persistent
     [, int $weight [, int $timeout [, int $retry_interval
     [, bool $status [, callback $failure_callback]]]]]]] )

Управленческий механизм сервера в пределах модуля php-memcache это критическая часть интерфейса, поскольку это управляет основным интерфейсом к memcached и тем, как различные варианты выбраны через хеширующий механизм.

Создать простое соединение с двумя экземплярами memcached можно так:

<?php
   $cache = new Memcache;
   $cache->addServer('192.168.0.100',11211);
   $cache->addServer('192.168.0.101',11211);
?>

В этом сценарии соединение открыто только, когда Вы попытаетесь сохранить или получить значение. Чтобы включить постоянное соединение с memcached, установите $persistent в true. Это настройка по умолчанию, заставляет соединения оставаться открытыми.

Чтобы помочь управлять распределением ключей к различным серверам, используйте глобальную настройку memcache.hash_strategy. Это устанавливает хеширующий механизм, используемый, чтобы выбрать сервер. Вы можете также добавить другой вес к каждому серверу, который эффективно увеличивает число раз, которое запись о сервере появляется в списке, увеличивая вероятность его выбора. Чтобы установить вес, установите значение параметра $weight больше 1.

Функции для установки и получения информации идентичны базовому функциональному интерфейсу, предлагаемому memcached, как показано в этой таблице:

Функция PECL memcache Базовая функция
get()get().
set()set().
add()add().
replace()replace().
delete()delete().
increment()incr().
decrement()decr().

Полный пример интерфейса PECL memcache обеспечен ниже. Код загружает данные о фильме из базы данных Sakila, когда пользователь обеспечивает имя фильма. Данные, хранимые в memcached , записаны как строка результата mysqli, API автоматически преобразовывает в последовательную форму информацию для Вас.

<?php
$memc = new Memcache;
$memc->addServer('localhost','11211');
if (empty($_POST['film'])) {
   ?>
   <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
   <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <title>Simple Memcache Lookup</title>
   </head>
   <body>
   <form method="post">
   <p><b>Film</b>: <input type="text" size="20" name="film"></p>
   <input type="submit">
   </form>
   <hr/>
   <?php
} else {
  echo "Loading data...\n";
  $film   = htmlspecialchars($_POST['film'], ENT_QUOTES, 'UTF-8');
  $mfilms = $memc->get($film);
  if ($mfilms) {
     printf("<p>Film data for %s loaded from memcache</p>", $mfilms['title']);
     foreach (array_keys($mfilms) as $key) {
       printf("<p><b>%s</b>: %s</p>",
              $key, $mfilms[$key]);
     }
  } else {
    $mysqli = mysqli('localhost','sakila','password','sakila');
    if (mysqli_connect_error()) {
       sprintf("Database error: (%d) %s", mysqli_connect_errno(),
               mysqli_connect_error());
       exit;
    }
    $sql = sprintf('SELECT * FROM film WHERE title="%s"',
                   $mysqli->real_escape_string($film));
    $result = $mysqli->query($sql);
    if (!$result) {
       sprintf("Database error: (%d) %s", $mysqli->errno, $mysqli->error);
       exit;
    }
    $row = $result->fetch_assoc();
    $memc->set($row['title'], $row);
    printf("<p>Loaded (%s) from MySQL</p>",
           htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8');
  }
}
?>
  </body>
</html>

С PHP соединения с memcached сохранены открытыми пока PHP и связанная копия Apache остаются работать. Добавляя или удаляя серверы из списка в рабочем экземпляре (например, запуская другой скрипт, который упоминает дополнительные серверы), соединения совместно использованы, но скрипт выбирает только среди серверов, явно сконфигурированных в своих пределах.

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

18.2.3.7. Использование MySQL и memcached с Ruby

Есть много различных модулей для того, чтобы взаимодействовать через интерфейс memcached с Ruby. Библиотека клиента Ruby-MemCache обеспечивает нативный интерфейс memcached, который не требует никаких внешних библиотек таких, как libmemcached. Вы можете получить пакет установщика с http://www.deveiate.org/projects/RMemCache.

Чтобы установить, извлеките пакет и затем выполните install.rb:

shell> install.rb

Если у Вас есть RubyGems, Вы можете установить Ruby-MemCache gem:

shell> gem install Ruby-MemCache
Bulk updating Gem source index for: http://gems.rubyforge.org
Install required dependency io-reactor? [Yn]  y
Successfully installed Ruby-MemCache-0.0.1
Successfully installed io-reactor-0.05
Installing ri documentation for io-reactor-0.05...
Installing RDoc documentation for io-reactor-0.05...

Чтобы использовать memcached в Ruby, создайте новый экземпляр объекта MemCache.

require 'memcache'
memc = MemCache::new '192.168.0.100:11211'

Вы можете добавить вес к каждому серверу, чтобы увеличить вероятность выбора этого сервера, прилагая количество веса к строке имени хоста сервера/номеру порта:

require 'memcache'
memc = MemCache::new '192.168.0.100:11211:3'

Чтобы добавить серверы к существующему списку, Вы можете добавить их непосредственно в объект MemCache:

memc += ["192.168.0.101:11211"]

Чтобы установить данные в кэш, Вы можете только назначить значение ключу в пределах нового объекта кэша, который работает точно так же как стандартный объект хеша Ruby:

memc["key"] = "value"

Или получить значение:

print memc["key"]

Для более явных действий Вы можете использовать интерфейс метода, который подражает основному API memcached, как показано в следующей таблице:

Метод Ruby MemCache Эквивалентная функция API memcached
get()get().
get_hash(keys) Получает значения многих keys, возвращая информацию как хеш ключей и их значений.
set()set().
set_many(pairs)Устанавливает ключи и значения в хеше pairs.
add()add().
replace()replace().
delete()delete().
incr()incr().
decr()decr().

18.2.3.8. Использование MySQL и memcached с Java

Класс com.danga.MemCached в Java обеспечивает интерфейс memcached. Вы можете получить клиент с https://github.com/gwhalin/Memcached-Java-Client/downloads. Класс Java использует хеши, которые совместимы с libmemcached, таким образом, Вы можете смешивать приложения Java и libmemcached, получающие доступ к тем же самым экземплярам memcached. Преобразование в последовательную форму между Java и другими интерфейсами не совместимо. Если это проблема, используйте JSON или подобный недвоичный формат преобразования в последовательную форму.

На большинстве систем Вы можете загрузить пакет и использовать непосредственно jar.

Чтобы использовать интерфейс com.danga.MemCached, Вы создаете экземпляр MemCachedClient и затем конфигурируете список серверов, настраивая SockIOPool. Через спецификацию бассейна Вы настраиваете список сервера, веса и параметры соединения между Вашим клиентом и экземпляром memcached, которые Вы конфигурируете.

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

Например, чтобы создать основной интерфейс, сначала сконфигурируйте MemCachedClient и основные настройки SockIOPool:

public class MyClass {protected static MemCachedClient mcc = new MemCachedClient();
static {String[] servers = {"localhost:11211",};
Integer[] weights = { 1 };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers( servers );
pool.setWeights( weights );

В вышеупомянутом образце список серверов сконфигурирован, создавая массив memcached. Вы можете тогда же сконфигурировать и отдельные веса для каждого сервера.

Остаток свойств для соединения является дополнительным, но Вы можете определить соединения (начальные соединения, минимальные соединения, максимальные соединения и тайм-аут), устанавливая параметры бассейна:

pool.setInitConn( 5 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
pool.setMaxIdle( 1000 * 60 * 60 * 6

Как только параметры были сконфигурированы, инициализируйте бассейн соединения:

pool.initialize();

Бассейн и соединение с Вашими серверами memcached должны теперь быть готовы.

Установить хеширующий алгоритм можно через pool.setHashingAlg():

pool.setHashingAlg( SockIOPool.NEW_COMPAT_HASH );

Допустимые значения NEW_COMPAT_HASH, OLD_COMPAT_HASH и NATIVE_HASH, основной хеширующий алгоритм modula. Для последовательного хеширующего алгоритма надо использовать CONSISTENT_HASH. Эти константы эквивалентны соответствующим настройкам хеша в libmemcached.

Следующая таблица обрисовывает в общих чертах методы Java com.danga.MemCached и эквивалентные методы в спецификации интерфейса memcached.

Метод Java com.danga.MemCached Эквивалентный нативный метод
get()get().
getMulti(keys) Получает значения многих keys, возвращая информацию, используя отображение хэша через java.lang.String для ключей и java.lang.Object для соответствующих значений.
set()set().
add()add().
replace()replace().
delete()delete().
incr()incr().
decr()decr().

18.2.3.9. Использование memcached TCP Text Protocol

Сообщение с сервером memcached может быть достигнуто через TCP или через протоколы UDP. Используя протокол TCP, Вы можете использовать простой текстовый интерфейс для обмена информацией.

Общаясь с memcached, Вы можете соединиться с сервером, используя порт, сконфигурированный для сервера. Вы можете открыть соединение с сервером, не требуя разрешения или входа в систему. Как только Вы соединились, Вы можете начать посылать команды серверу. Когда Вы закончили, Вы можете закончить соединение, не посылая определенной команды разъединения. Клиенты спроектированы сохранить свои соединения открытыми, чтобы уменьшить время ожидания и улучшить работу.

Данные посылают на сервер memcached в двух формах:

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

  • Неструктурированные данные, которые используются, чтобы получить или послать информацию о значении данного ключа. Данные возвращены клиенту точно в том формате, в каком переданы.

Текстовые строки (команды и ответы) и неструктурированные данные всегда заканчиваются строкой \r\n. Поскольку данные могут содержать эту последовательность, длина данных (возвращенная клиентом прежде, чем неструктурированные данные будут переданы) должна использоваться, чтобы определить конец данных.

Команды к серверу структурированы согласно их работе:

  • Команды хранения: set, add, replace, append, prepend, cas.

    Команды хранения серверу принимают форму:

    command key [flags] [exptime] length [noreply]
    

    Или когда использование сравнивает и переставляет (cas):

    cas key [flags] [exptime] length [casunique] [noreply]
    

    Где:

    • command: Название команды.

      • set: Сохранить значение для ключа.

      • add: Сохранить это значение для ключа, если ключ еще не существует.
      • replace: Сохранить это значение для ключа, если ключ существует.
      • append: Добавить поставляемое значение в конец значения для указанного ключа. Параметры flags и exptime не должны использоваться.
      • prepend: Добавить значение, которое в настоящее время в кэше, в конец поставляемого значения для указанного ключа. Параметры flags и exptime не должны использоваться.
      • cas: Установить указанный ключ к поставляемому значению, только если поставляемый casunique совпадает. Это эффективный эквивалент изменения информация, если никто ее не обновил.

    • key: Ключ. Все данные хранятся, используя определенный ключ. Ключ не может содержать символы управления или пробелы и может быть до 250 символов в размере.

    • flags: Флаги для работы (как целое число). Флаги в memcached прозрачны. Сервер игнорирует содержание флагов. Они могут использоваться клиентом, чтобы указать на любой тип информации. В memcached 1.2.0 и ниже значение 16-битовое целочисленное. В memcached 1.2.1 и выше значение 32-битовое целое число.
    • exptime: Время истечения или ноль для отсутствия истечения.
    • length: Длина поставляемого значения блока в байтах, исключая завершение \r\n.
    • casunique: Уникальное 64-битовое значение существующего входа. Это используется, чтобы сравнить с существующим значением. Используйте значение, возвращенное командой gets для обновления cas.
    • noreply: Говорит серверу не отвечать на команду.

    Например, чтобы сохранить значение abcdef в ключе xyzkey, Вы использовали бы:

    set xyzkey 0 0 6\r\nabcdef\r\n
    

    Возвращаемое значение от сервера одна строка, определяющая информацию о состоянии или ошибке. Для получения дополнительной информации см. таблицу 18.3.

  • Команды извлечения: get, gets

    Команды извлечения принимают форму:

    get key1 [key2 .... keyn]
    gets key1 [key2 ... keyn]
    

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

    Сервер отвечает информационной строкой формы:

    VALUE key flags bytes [casunique]
    

    Где:

    • key: Имя ключа.

    • flags: Значение целого числа флага, поставляемого memcached серверу, когда значение было сохранено.
    • bytes: Размер (исключая завершение \r\n) хранимого значения.
    • casunique: Уникальное 64-битовое целое число, которое идентифицирует элемент.

    Информационная строка немедленно сопровождается блоком данных значения. Например:

    get xyzkey\r\n
    VALUE xyzkey 0 6\r\n
    abcdef\r\n
    

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

  • Команда удаления: delete

    Команда удаления имеет такой вид:

    delete key [time] [noreply]
    

    Где:

    • key: Имя ключа.

    • time: Время в секундах (или определенное время Unix), после которого клиент хочет, чтобы сервер отказался от команд add или replace на этом ключе. Все команды add, replace, get и gets терпят неудачу во время этого периода. set работает успешно. После этого периода ключ удален и все команды приняты.

      Если не задано, значение, как предполагается, является нолем (удалить сейчас).

    • noreply: Говорит серверу не отвечать на команду.

    Ответы на команду DELETED, чтобы указать, что ключ был успешно удален, или NOT_FOUND, чтобы указать, что указанный ключ не мог быть найден.

  • Increment/Decrement: incr, decr

    Эти команды изменяют значение ключа в пределах сервера, не выполняя отдельную последовательность get/set. Операции предполагают, что в настоящее время хранимое значение 64-битовое целое число. Если хранимое значение не 64-bit integer, то значение, как предполагается, является нолем.

    Команды принимают форму:

    incr key value [noreply]
    decr key value [noreply]
    

    Где:

    • key: Имя ключа.

    • value: Целое число, которое будет использоваться в качестве значения инкремента или декремента.
    • noreply: Говорит серверу не отвечать на команду.

    Ответ:

    • NOT_FOUND: Указанный ключ не мог быть найден.

    • value: Новое значение связалось с указанным ключом.

    Значения, как предполагается, без знака. Для операции decr значение никогда не уменьшается ниже 0. Для операции incr значение имеет макусимум 64-bit.

  • Команды статистики: stats

    Команда stats предоставляет детализированную статистическую информацию о текущем статусе memcached и данных, которые это хранит.

    Команды статистики принимают форму:

    STAT [name] [value]
    

    Где:

    • name: Дополнительное название статистики для возврата. Если не определено, общие статистические данные возвращены.

    • value: Определенное значение, которое будет использоваться, выполняя определенные операции статистики.

    Возвращаемое значение список данных статистики, отформатированных следующим образом:

    STAT name value
    

    Статистические данные закончены строкой END.

Таблица 18.2. Команды memcached

CommandФормат команды
set set key flags exptime length, set key flags exptime length noreply
add add key flags exptime length, add key flags exptime length noreply
replace replace key flags exptime length, replace key flags exptime length noreply
append append key length, append key length noreply
prependprepend key length , prepend key length noreply
cas cas key flags exptime length casunique, cas key flags exptime length casunique noreply
getget key1 [key2 ... keyn]
gets
deletedelete key, delete key noreply, delete key expiry, delete key expiry noreply
incrincr key, incr key noreply, incr key value, incr key value noreply
decrdecr key, decr key noreply, decr key value, decr key value noreply
statstat, stat name, stat name value
Посылая команду серверу, Вы получите ответ от сервера: одно из значений в следующей таблице. Все значения ответа сервера закончены \r\n:

Таблица 18.3. Ответы протокола memcached

< td>Требуемый ключ был удален с сервера.
СтрокаОписание
STORED Значение было успешно сохранено.
NOT_STORED Значение не было сохранено, но не из-за ошибки. Для команд, где Вы добавляете или обновляете значение, если оно существует (add и replace), или где элемент удален, если он уже был установлен.
EXISTS Используя команду cas, элемент, который Вы пытаетесь сохранить, уже существует и был изменен.
NOT_FOUND Элемент, который Вы пытаетесь сохранить, обновить или удалить, не существует или был уже удален.
ERROR Вы представили несуществующее название команды.
CLIENT_ERROR errorstring Была ошибка во входной строке, детали содержатся в errorstring.
SERVER_ERROR errorstring Была ошибка в сервере, которая препятствует тому, чтобы он возвратил информацию. В экстремальных условиях сервер может отсоединить клиента после того, как эта ошибка происходит.
VALUE keys flags length Требуемый ключ был найден, и сохраненные key, flags и блок данных возвращены с указанной длиной length.
DELETED
STAT name value Строка данных о статистике.
ENDКонец данных о статистике.

18.2.4. Получение статистики memcached

У memcached есть встроенная система статистики, которая собирает информацию о данных, сохраненных в кэше, коэффициент совпадения кэша и подробную информацию об использовании памяти и распределении информации. Статистические данные обеспечены на базовом уровне, который обеспечивает основную статистику, и более определенную статистику для определенных областей memcached.

Эта информация может быть полезной, чтобы гарантировать, что Вы получаете правильный уровень кэша и использования памяти, и что Ваши свойства конфигурации установлены на оптимальном уровне.

Интерфейс stats доступен через стандартный протокол memcached, таким образом, к отчетам можно получить доступ при использовании telnet. Пакет memcached-tool включает поддержку получения статистическоой информации (см. разделы 18.2.4.2 и 18.2.4.1).

Альтернативно, большая часть интерфейсов API обеспечивают функцию для того, чтобы она получила статистику с сервера.

Например, чтобы получить основную статистику через telnet:

shell> telnet localhost 11211
Trying ::1...
Connected to localhost.
Escape character is '^]'.
stats
STAT pid 23599
STAT uptime 675
STAT time 1211439587
STAT version 1.2.5
STAT pointer_size 32
STAT rusage_user 1.404992
STAT rusage_system 4.694685
STAT curr_items 32
STAT total_items 56361
STAT bytes 2642
STAT curr_connections 53
STAT total_connections 438
STAT connection_structures 55
STAT cmd_get 113482
STAT cmd_set 80519
STAT get_hits 78926
STAT get_misses 34556
STAT evictions 0
STAT bytes_read 6379783
STAT bytes_written 4860179
STAT limit_maxbytes 67108864
STAT threads 1
END

Используя Perl и модуль Cache::Memcached, функция stats() предоставит информацию обо всех серверах, в настоящее время сконфигурированных в объекте соединения, и полную статистику для всех серверов memcached в целом.

Например, следующий скрипт на Perl получает статистику и выводит ссылку хеша, которая возвращена:

use Cache::Memcached;
use Data::Dumper;

my $memc = new Cache::Memcached;
$memc->set_servers(\@ARGV);
print Dumper($memc->stats());

Когда выполнено на том же самом memcached, который использовался в примере с Telnet выше, мы получаем ссылку хеша с хостами и полной статистикой:

$VAR1 = {
  'hosts' => {
    'localhost:11211' => {
      'misc' => {
        'bytes' => '2421', 'curr_connections' => '3',
        'connection_structures' => '56', 'pointer_size' => '32',
        'time' => '1211440166', 'total_items' => '410956',
        'cmd_set' => '588167', 'bytes_written' => '35715151',
        'evictions' => '0', 'curr_items' => '31', 'pid' => '23599',
        'limit_maxbytes' => '67108864', 'uptime' => '1254',
        'rusage_user' => '9.857805', 'cmd_get' => '838451',
        'rusage_system' => '34.096988', 'version' => '1.2.5',
        'get_hits' => '581511', 'bytes_read' => '46665716',
        'threads' => '1', 'total_connections' => '3104',
        'get_misses' => '256940'},
      'sizes' => {
        '128' => '16', '64' => '15'}}
  },
  'self' => {},
  'total' => {'cmd_get' => 838451, 'bytes' => 2421,
    'get_hits' => 581511, 'connection_structures' => 56,
    'bytes_read' => 46665716, 'total_items' => 410956,
    'total_connections' => 3104, 'cmd_set' => 588167,
    'bytes_written' => 35715151, 'curr_items' => 31,
    'get_misses' => 256940}
};

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

18.2.4.1. Основная статистика memcached

Вывод общей статистики обеспечивает краткий обзор работы и использования memcached. Статистику, возвращенную командой и ее значения, показывают в следующей таблице.

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

  • 32u: 32-bit unsigned integer.

  • 64u: 64-bit unsigned integer.
  • 32u:32u: Два числа 32-bit unsigned integer, разделенных двоеточием.
  • String: Строка символов.

СтаистикаТип данных ОписаниеВерсия
pid32u ID процесса memcached.
uptime32u Продолжительность работы (в секундах) для этого экземпляра memcached.
time32u Текущее время (как epoch).
versionstring Строка версии.
pointer_sizestring Размер указателей для этого узла в битах (32 или 64).
rusage_user32u:32u Полное пользовательское время (seconds:microseconds).
rusage_system32u:32u Полное системное время (seconds:microseconds).
curr_items32u Текущее число элементов сохраненных сервером
total_items32u Общее количество элементов, сохраненных за время жизни этого экземпляра.
bytes64u Текущее число байтов, используемых этим сервером, чтобы сохранить элементы.
curr_connections32u Текущее число открытых соединений.
total_connections32u Общее количество соединений, открытых начиная с начала работы сервера.
connection_structures 32uЧисло структур соединения, выделенных сервером.
cmd_get64u Общее количество запросов извлечения (get).
cmd_set64u Общее количество запросов хранения (set).
get_hits64u Число ключей, которые запрошены и найдены.
get_misses64u Число элементов, которые запрошены и не найдены.
delete_hits64u Число ключей, которые были удалены.1.3.x
delete_misses64u Число элементов, которые надо было удалить, но не нашли. 1.3.x
incr_hits64u Число ключей, которые были постепенно увеличены и сочтены существующими. 1.3.x
incr_misses64u Число элементов, которые были постепенно увеличены и не найдены. 1.3.x
decr_hits64u Число ключей, которые были уменьшены.1.3.x
decr_misses64u Число элементов, которые были уменьшены.1.3.x
cas_hits64u Число ключей, которые были сравнены и сочтены существующими. 1.3.x
cas_misses64u Число элементов, которые были сравнены и не найдены. 1.3.x
cas_badvalue64u Число ключей, которые были сравнены, но сравниваемое (оригинальное) значение не соответствовало поставляемому значению.1.3.x
evictions64u Число допустимых элементов, удаленных из кэша для новых элементов.
bytes_read64u Общее количество байтов, прочитанных этим сервером из сети.
bytes_written64u Общее количество байтов, посланных этим сервером в сеть.
limit_maxbytes32u Число байтов, которое этот сервер разрешает использовать для хранения.
threads32u Число рабочих потоков.
conn_yields64u Число соединений (связано с опцией -R).1.4.0

Самыми полезными статистическими данными здесь являются число хитов кэша, промахов и очищений

Большое количество get_misses может быть только признаком, что кэш все еще заполняется информацией. Число должно в течение долгого времени уменьшиться по сравнению с числом get_hits. Если у Вас есть большое количество промахов по кэшу по сравнению с хитами кэша после длительного периода выполнения, это может быть признаком, что размер кэша является слишком маленьким и Вы должны увеличить полный размер памяти или число серверов memcached, чтобы улучшить коэффициент совпадения.

Большое количество evictions, особенно по сравнению с числом сохраненных элементов, знак того, что Ваш кэш является слишком маленьким, чтобы держать количество информации, которую Вы регулярно хотите хранить кэшированной. Вместо элементов, сохраняемых в кэше, элементы сбрасываются, чтобы пробиться новым элементам, сохраняющих оборот элементов в кэше высоким и уменьшая эффективность кэша.

18.2.4.2. Статистика memcached Slabs

Чтобы получить эту статистику, используйте команду stats slabs или эквивалент API.

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

STAT 1:chunk_size 104
STAT 1:chunks_per_page 10082
STAT 1:total_pages 1
STAT 1:total_chunks 10082
STAT 1:used_chunks 10081
STAT 1:free_chunks 1
STAT 1:free_chunks_end 10079
STAT 9:chunk_size 696
STAT 9:chunks_per_page 1506
STAT 9:total_pages 63
STAT 9:total_chunks 94878
STAT 9:used_chunks 94878
STAT 9:free_chunks 0
STAT 9:free_chunks_end 0
STAT active_slabs 2
STAT total_malloced 67083616
END
3527

Отдельные отчеты для каждого класса имеют префикс ID куска. Уникальный ID дан каждому выделенному куску от самого маленького размера до самого большого. Число в префиксе указывает на классификационный индекс относительно расчетного куска от указанного фактора роста. Следовательно, в примере, 1 размер первого куска, и 9 выделенный размер девятого куска.

Параметры возвращены для каждого размера куска, описание каждого параметра обеспечено в следующей таблице.

Статистическая величина ОписаниеВерсия
chunk_size Место, выделенное каждому куску в пределах этого класса.
chunks_per_page Число кусков в пределах единственной страницы для этого класса.
total_pages Число страниц, выделенных этому классу.
total_chunks Число кусков, выделенных классу.
used_chunks Число кусков, выделенных элементу.
free_chunks Число кусков, еще выделенных элементам.
free_chunks_end Число свободных кусков в конце последней выделенной страницы.
get_hits Число хитов get к этому куску.1.3.x
cmd_set Число команд set на этом куске.1.3.x
delete_hits Число хитов удаления на этом куске.1.3.x
incr_hits Число хитов increment на этом куске.1.3.x
decr_hits Число хитов decrement на этом куске.1.3.x
cas_hits Число хитов CAS на этом куске.1.3.x
cas_badval Число хитов CAS на этом куске, где существующее значение не соответствовало. 1.3.x
mem_requested Истинный объем памяти памяти, запрошенный в пределах этого куска. 1.4.1

Следующие дополнительные статистические данные покрывают информацию для всего сервера, а не на основании куска:

Статистическая величина ОписаниеВерсия
active_slabs Общее количество классов, которое выделено.
total_malloced Общая сумма памяти, выделенной страницам.

Ключевые значения в статистике параметры chunk_size, total_chunks и used_chunks. Они дают признаки использования размера кусков в пределах системы. Помните, что одна пара ключ/значения размещена в кусок подходящего размера.

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

18.2.4.3. Статистика элемента memcached

Чтобы получить статистику, используйте команду stats items или эквивалент API.

Статистические данные дают информацию об отдельных элементах, выделенных в пределах данного класса.

STAT items:2:number 1
STAT items:2:age 452
STAT items:2:evicted 0
STAT items:2:evicted_nonzero 0
STAT items:2:evicted_time 2
STAT items:2:outofmemory 0
STAT items:2:tailrepairs 0
...
STAT items:27:number 1
STAT items:27:age 452
STAT items:27:evicted 0
STAT items:27:evicted_nonzero 0
STAT items:27:evicted_time 2
STAT items:27:outofmemory 0
STAT items:27:tailrepairs 0

Число префикса против каждой статистики касается соответствующего размера куска, как возвращено stats slabs. Результат отображает числа элементов, сохраненных в пределах каждого куска каждого размера и определенную статистику об их возрасте, количестве удалений и памяти. Резюме статистики дано в следующей таблице.

Статистическая величина ОписаниеВерсия
number Число элементов, в настоящее время сохраненных в этом классе.
age Возраст самого старого элемента в пределах класса в секундах.
evicted Число элементов, удаленных для новых записей.
evicted_time Время последней удаленной записи.
evicted_nonzero Время последней удаленной записи, отличной от нуля.1.4.0
outofmemory Число элементов для этого класса, которые вызвали из ошибки памяти (значение имеет смысл, только когда параметр командной строки -M указан).
tailrepairs Число раз записи для особого восстановления ID.

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

18.2.4.4. Статистика размера memcached

Чтобы получить этот вид статистики, используйте команду stats sizes или эквивалент API.

Статистические данные размера предоставляют информацию о размерах и числе элементов каждого размера в пределах кэша. Информация возвращена как два столбца, первый столбец передает размер элемента (округленный к самой близкой 32-байтовой границе), второй столбец показывает количество числа элементов этого размера в пределах кэша:

96 35
128 38
160 807
192 804
224 410
256 222
288 83
320 39
352 53
384 33
416 64
448 51
480 30
512 54
544 39
576 10065

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

Статистические данные размера элемента полезны только, чтобы определить размеры объектов, которые Вы храните. Так как фактическое распределение памяти релевантно только с точки зрения размера куска и размера страницы, информация полезна только во время осторожной отладки или диагностического сеанса.

18.2.4.5. Статистика memcached детали

Для memcached 1.3.x и выше Вы можете включить и получить детализированную статистику об операциях get, set и del на отдельных ключах, сохраненных в кэше, и определить, нашли ли ключ. Эти операции зарегистрированы только в то время, как подробный анализ включен.

Чтобы включить детализированную статистику, Вы должны послать серверу memcached команду stats detail on:

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to tiger.
Escape character is '^]'.
stats detail on
OK

Отдельные статистические данные зарегистрированы для каждой операции get, set и del, включая ключи, которые в настоящее время не сохранены в сервере. Например, если предпринята попытка получить значение ключа abckey, и это не существует, get на указанном ключе зарегистрирована, даже если ключ в настоящее время не сохранен. hits, то есть, число get или del для ключа, который существует на сервере, также посчитаны.

Чтобы выключить детализированную статистику, пошлите серверу команду stats detail off:

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to tiger.
Escape character is '^]'.
stats detail on
OK

Чтобы получить подробную статистику, зарегистрированную во время процесса, пошлите команду stats detail dump:

stats detail dump
PREFIX hykkey get 0 hit 0 set 1 del 0
PREFIX xyzkey get 0 hit 0 set 1 del 0
PREFIX yukkey get 1 hit 0 set 0 del 0
PREFIX abckey get 3 hit 3 set 1 del 0
END

Вы можете использовать подробную информацию о статистике, чтобы определить, используют ли Ваши клиенты большое количество ключей, которые не существуют на сервере, сравнивая количество hit и get и del. Поскольку информация зарегистрирована ключом, Вы можете также определить, кластеризируются ли отказы или операции вокруг определенных ключей.

18.2.4.6. Использование memcached-tool

memcached-tool расположен в подкаталоге scripts каталога исходных текстов memcached. Инструмент обеспечивает удобный доступ к некоторым отчетам и статистике от любого сервера memcached.

Основной формат команды:

shell> ./memcached-tool hostname:port [command]

Вывод по умолчанию производит список распределений кусков и использования. Например:

shell> memcached-tool localhost:11211 display
  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
  1     80B       93s       1       20      no       0      0        0
  2    104B       93s       1       16      no       0      0        0
  3    136B     1335s       1       28      no       0      0        0
  4    176B     1335s       1       24      no       0      0        0
  5    224B     1335s       1       32      no       0      0        0
  6    280B     1335s       1       34      no       0      0        0
  7    352B     1335s       1       36      no       0      0        0
  8    440B     1335s       1       46      no       0      0        0
  9    552B     1335s       1       58      no       0      0        0
 10    696B     1335s       1       66      no       0      0        0
 11    872B     1335s       1       89      no       0      0        0
 12    1.1K     1335s       1      112      no       0      0        0
 13    1.3K     1335s       1      145      no       0      0        0
 14    1.7K     1335s       1      123      no       0      0        0
 15    2.1K     1335s       1      198      no       0      0        0
 16    2.6K     1335s       1      199      no       0      0        0
 17    3.3K     1335s       1      229      no       0      0        0
 18    4.1K     1335s       1      248     yes      36      2        0
 19    5.2K     1335s       2      328      no       0      0        0
 20    6.4K     1335s       2      316     yes     387      1        0
 21    8.1K     1335s       3      381     yes     492      1        0
 22   10.1K     1335s       3      303     yes     598      2        0
 23   12.6K     1335s       5      405     yes     605      1        0
 24   15.8K     1335s       6      384     yes     766      2        0
 25   19.7K     1335s       7      357     yes     908    170        0
 26   24.6K     1336s       7      287     yes    1012      1        0
 27   30.8K     1336s       7      231     yes    1193    169        0
 28   38.5K     1336s       4      104     yes    1323    169        0
 29   48.1K     1336s       1       21     yes    1287      1        0
 30   60.2K     1336s       1       17     yes    1093    169        0
 31   75.2K     1337s       1       13     yes     713    168        0
 32   94.0K     1337s       1       10     yes     278    168        0
 33  117.5K     1336s       1        3      no       0      0        0

Этот вывод то же самое, если Вы определяете command как display:

shell> memcached-tool localhost:11211 display
  #  Item_Size  Max_age   Pages   Count   Full?  Evicted Evict_Time OOM
  1     80B       93s       1       20      no      0       0        0
  2    104B       93s       1       16      no      0       0        0
...

Вывод показывает полученную в итоге версию вывода статистики. Столбцы, обеспеченные в выводе, показывают:

  • #: Номер куска.

  • Item_Size: Размер куска.
  • Max_age: Возраст самого старого элемента.
  • Pages: Число страниц, выделенных куску.
  • Count: Число элементов в этом куске.
  • Full?: Заполнен ли кусок полностью.
  • Evicted: Число объектов, удаленных из этого куска.
  • Evict_Time: Время (в секундах), начиная с последнего удаления.
  • OOM: Число элементов, которые вызвали ошибки памяти.

Вы можете также получить дамп общей статистики для сервера, используя команду stats:

shell> memcached-tool localhost:11211 stats
#localhost:11211   Field Value
         accepting_conns   1
                   bytes 162
              bytes_read 485
           bytes_written 6820
              cas_badval   0
                cas_hits   0
              cas_misses   0
               cmd_flush   0
                 cmd_get   4
                 cmd_set   2
             conn_yields   0
   connection_structures  11
        curr_connections  10
              curr_items   2
               decr_hits   0
             decr_misses   1
             delete_hits   0
           delete_misses   0
               evictions   0
                get_hits   4
              get_misses   0
               incr_hits   0
             incr_misses   2
          limit_maxbytes 67108864
     listen_disabled_num   0
                     pid 12981
            pointer_size  32
           rusage_system 0.013911
             rusage_user 0.011876
                 threads   4
                    time 1255518565
       total_connections  20
             total_items   2
                  uptime 880
                 version 1.4.2

18.2.5. memcached FAQ

18.2.5.1.

memcached может быть выполнен в Windows?

Нет. В настоящее время memcached доступен только на платформе Unix/Linux. Есть неофициальный доступный порт, см. http://www.codeplex.com/memcachedproviders.

18.2.5.2.

Каков максимальный размер объекта, который Вы можете хранить в memcached? Это конфигурируемо?

Максимум размера объекта по умолчанию составляет 1 МБ. В memcached 1.4.2 и позже Вы можете изменить максимальный размер объекта, используя параметр командной строки -I.

Для версий перед этой, чтобы увеличить этот размер, Вы должны повторно собрать memcached. Вы можете изменить значение POWER_BLOCK в файле slabs.c.

В memcached 1.4.2 Вы можете сконфигурировать максимальный поддержанный размер объекта при использовании параметра командной строки -I. Например, чтобы увеличить максимальный размер объекта до 5 МБ:

$ memcached -I 5m

Если объект больше, чем максимальный размер объекта, Вы должны вручную разделить его. memcached очень прост: Вы даете ключ и некоторые данные, он пытается кэшировать это в RAM. Если Вы пытаетесь сохранить больше, чем максимальный размер, значение усекается по причинам скорости.

18.2.5.3.

Правда ли, что memcached более полезен с базами данных с интенсивным чтением, чем с интенсивной записью?

Да. memcached не играет роли в записи в базу данных, это метод кэширования прочитанных данных в RAM.

18.2.5.4.

Есть ли накладные расходы от неиспользования постоянных соединений? Если постоянные всегда рекомендуются, каковы проблемы (например, блокировки)?

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

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

18.2.5.5.

Как падение одного из серверов memcached обрабатывается клиентом?

Нет никакой автоматической обработки этого. Если Ваш клиент не в состоянии получить ответ от сервера, сделайте механизм отступления, чтобы загрузить данные из базы данных MySQL.

Все API обеспечивают способность добавить и удалить серверы memcached на лету. Если в пределах Вашего приложения Вы замечаете, что сервер memcached больше не отвечает, Вы можете удалить сервер из списка серверов, и ключи будут автоматически перераспределены к другому серверу в списке. Если сохранение контента кэша на всех Ваших серверах важно, удостоверьтесь, что Вы используете API, который поддерживает последовательный хеширующий алгоритм. Для получения дополнительной информации см. раздел 18.2.2.5.

18.2.5.6.

Какова рекомендуемая конфигурация аппаратных средств для memcached сервера?

У memcached очень низкие накладные расходы. Все, что требуется, это побольше свободной RAM. Сервер memcached не требует специализированной машины. Если у Вас есть сеть, приложение или серверы базы данных, у которых есть запасная RAM, то используйте их с memcached.

Чтобы создать и развернуть специализированный сервер memcached, используйте относительно слабый центральный процессор, много RAM и один или больше интерфейсов Gigabit Ethernet.

18.2.5.7.

Действительно ли memcached более эффективен для видео и аудио в противоположность текстовым данным?

memcached работает одинаково хорошо на всех видах данных. Любое значение, которое Вы храните, является только потоком данных. Помните, тем не менее, что максимальный размер объекта, который Вы можете хранить в memcached, составляет 1 МБ, но может быть сконфигурирован, чтобы размер был больше при использовании опции -I в memcached 1.4.2 и позже, или изменяя исходный текст в версиях до 1.4.2. Если Вы запланируете использование memcached с аудио и видеоконтентом, то Вы будете, вероятно, хотеть увеличить максимальный размер объекта. Также помните, что memcached решение для того, чтобы кэшировать информацию для того, чтобы читать. Это не должно использоваться для записи, кроме тех случаев, когда, обновляется информация в кэше.

18.2.5.8.

Может memcached работать с ASPX?

Есть порты и интерфейсы для многих языков. ASPX полагается на основной язык, такой как C# или VisualBasic, и если Вы используете ASP.NET, есть библиотека C# memcached. Для получения дополнительной информации см. https://sourceforge.net/projects/memcacheddotnet/.

18.2.5.9.

Как накладно установить соединение memcache? Соединения должны быть объединены?

Открытие соединения относительно недорого, потому что нет никакой безопасности, аутентификации или другого квитирования, имеющего место прежде, чем Вы сможете начать посылать запросы и получать результаты. Большинство API поддерживает постоянное соединение с memcached , чтобы уменьшить время ожидания. Объединение соединений зависит от API, который Вы используете, но если Вы общаетесь непосредственно по TCP/IP, тогда объединение соединений обеспечило бы некоторую небольшую исполнительную выгоду.

18.2.5.10.

Как данные обработаны, когда сервер memcached падает?

Поведение полностью зависит от приложения. Большинство приложений переходят к загрузке из базы данных (так же, как если бы они обновляли данные в memcached). Если Вы используете много копий memcached, Вы могли бы также удалить именно этот сервер из списка, чтобы это не затронуло работу. Иначе клиент все еще попытается общаться с сервером memcached, который соответствует ключу, который Вы пытаетесь загрузить.

18.2.5.11.

Как столбцы auto-increment в базе данных MySQL, скоординированы с учетом нескольких серверов memcached?

Никак. Нет никаких отношений между MySQL и memcached , если Ваше приложение не создает их.

Если Вы храните информацию, основанную на ключе auto-increment на нескольких серверах memcached, информация хранится только на одном из экземпляров memcached . Клиент использует значение ключа, чтобы определить, который сервер хранит информацию. Это не хранит ту же самую информацию на всех серверах, это было бы тратой кэш-памяти.

18.2.5.12.

Действительно ли сжатие доступно?

Да. Большая часть API клиента поддерживает своего рода сжатие, и некоторые даже позволяют Вам определять порог, в котором значение считают подходящим для сжатия во время хранения.

18.2.5.13.

Мы можем осуществить различные типы memcached как различные узлы в том же самом сервере?

Да. Вы можете выполнить много копий memcached на единственном сервере, и в Вашей конфигурации клиента Вы выбираете список серверов, которые Вы хотите использовать.

18.2.5.14.

Каковы лучшие методы для того, чтобы проверить выполнение, гарантировать, что это улучшает работу, и измерить воздействие изменений конфигурации memcached? Вы рекомендовали бы сохранить конфигурацию очень простой?

Лучший способ проверить работу состоит в том, чтобы запустить memcached. Во-первых, измените свое приложение так, чтобы оно сохранило данные непосредственно перед тем, как данные собираются использоваться. Начиная с дескриптора API и преобразования в последовательную форму данных, это должна быть только короткая модификация Вашего кода. Измените процесс, который обычно загружал бы эту информацию из MySQL, чтобы он запрашивал данные из memcached. Если данные не могут быть загружены из memcached , должен произойти возврат к MySQL.

Все требуемые изменения, вероятно, составят только несколько строк кода. Чтобы извлечь лучшую пользу, удостоверьтесь, что Вы кэшируете все объекты (например, все компоненты веб-страницы, сообщения в блоге и так далее), вместо того, чтобы использовать memcached в качестве простого кэша отдельных строк таблиц MySQL.

Как только у Вас есть базовая структура, часто единственное изменение, которое Вы должны потом сделать, это добавить больше серверов в список серверов, используемых Вашими приложениями. Вы не должны управлять серверами memcached и нет никакой сложной конфигурации. Только добавьте больше серверов к списку и позвольте клиенту, API и memcached принимать решения.

Поиск

 

Найди своих коллег!

Вы можете направить письмо администратору этой странички, Алексею Паутову. mailto:alexey.v.pautov@mail.ru