Проверьте, существует ли ключ в Memcache

Как проверить PHP, если значение хранится в Memcache без его получения? Мне не нравится получать его, потому что значения, которые я установил, имеют размер 1 МБ, и после того, как я его извлечу, я не использую его, поэтому я трачу ресурсы. Я использую это в скрипте, который проверяет, кэшируются ли определенные ключи в memcache, а если нет, он читает их из медленного источника данных и устанавливает их в memcache.

Изменить: что делать, если я использую Memcached::append для добавления NULL к ключу, который я проверяю? Возвращает TRUE при успешном FALSE или FALSE при сбое. Memcached::getResultCode вернет Memcached::RES_NOTSTORED если ключ не существует. Таким образом, я проверяю, существует ли ключ, и он должен правильно поставить ключ поверх списка LRU?

Спасибо.

Я не уверен, что это вам поможет, но вы можете использовать

 Memcache::add ( string $key , mixed $var) 

Он вернет false, если ключ уже существует.

В случае возврата истины вы можете использовать

 Memcache::delete ( string $key) 

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

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

 function has($key) { $m->get($key) return \Memcached::RES_NOTFOUND !== $m->getResultCode(); } 

В основном, что вы хотите сделать, это заполнить memcached вашими данными, не так ли?

Дело в том, что спрашивать, есть ли ключ с удаленным извлечением значения, не очень полезно. См. Этот сценарий:

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

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

Я решил это, используя Memcached :: append. Я пытаюсь добавить значение NULL, и если он возвращает TRUE, это означает, что ключ существует. Если он возвращает FALSE, значит, ключ не существует. Если ключ существует, он также будет помещен поверх списка LRU.

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

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

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

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

Реализация будет состоять из использования memcached append или prepend для поддержки вашего списка ключей, привязанных к некоторому главному ключу или мастер-ключу, который указывает на набор sub_keys, которые указывают на сами ключи 🙂

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

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

Просто невозможно, невозможно проверить, существует ли только ключ. Лучше вы создадите отдельный ключ с истинными / ложными значениями для проверки наличия ключей

Теперь memcached имеет команду cas. вы можете использовать его с cas уникальным как 0, чтобы получить ответы EXISTS или NOT_FOUND:

 $ telnet localhost 11211 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. set hello 0 0 5 12345 STORED gets hello VALUE hello 0 5 6743 12345 END cas hello 0 0 0 0 EXISTS cas foo 0 0 0 0 NOT_FOUND 

В вышеприведенном расшифровке я сначала использую команду set, чтобы установить ключ hello со значением 12345. Затем возвращает его, что также возвратило уникальный cas 6743. Затем я пытаюсь использовать команду cas для замены значения ничем, а потому, что cas unique я использовал 0, я получил ошибку EXISTS.

Наконец, я пытаюсь использовать cas для установки ключа foo, которого не существует, и получить ошибку NOT_FOUND.

Поскольку memcached использует глобальное значение incrementing для уникального cas, использование 0 безопасно, что оно недействительно для элемента, который вы пытаетесь установить, и вы вернете ошибку EXISTS, если она существует.

Извините, не знакомы с клиентом memcache php, чтобы поместить его в php-код.

Это не имеет смысла с точки зрения Memcached. Если вы хотите избежать медленного источника данных (по запланированному заданию, я полагаю?), Сохраните данные в более быстрый, но все же стабильный источник данных (например, файл) в запланированном задании. Когда вам нужны данные, попробуйте сначала прочитать Memcached, и если это не удается прочитать файл и сохранить его в Memcached.

Memcached не может дать вам хороший ответ, поскольку pakore уже ответил. Архитектура не должна быть стабильным источником данных.

Самый простой способ – получить данный ключ и применить его к логическому значению.

 (bool) Memcache::get(string $key) 

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

 $allSlabs = $memcache->getExtendedStats('slabs'); $items = $memcache->getExtendedStats('items'); foreach ($allSlabs as $server => $slabs) foreach ($slabs as $slabId => $slabMeta) foreach ($memcache->getExtendedStats('cachedump', (int) $slabId) as $entries) if (!empty($entries)) foreach ($entries as $key => $entry)