APC User-Cache подходит для сред с высокой нагрузкой?

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

http://www.slideshare.net/guoqing75/4069180-caching-performance-lessons-from-facebook http://www.slideshare.net/shire/php-tek-2007-apc-facebook

Он работает довольно хорошо в течение некоторого времени, но через несколько часов при высокой нагрузке APC сталкивается с проблемами, поэтому весь mod_php больше не выполняет никакого PHP. Даже простой скрипт PHP, который больше не отвечает, в то время как статические ресурсы все еще доставляются Apache. Это действительно не сбой, нет segfault. Мы пробовали последнюю стабильную и последнюю бета-версию APC, мы пробовали pthreads, spin locks, каждый раз с той же проблемой. Мы предоставили APC гораздо больше памяти, которую он может когда-либо потреблять, за 1 минуту до крушения у нас есть 2% фрагментации и около 90% памяти бесплатно. Когда он «сбой», мы ничего не обнаруживаем в журналах ошибок, только перезапуск Apache помогает. Только со спин-замками мы получаем ошибку php, которая:

PHP Неустранимая ошибка: Неизвестно: Застрял spinlock (0x7fcbae9fe068), обнаруженный в Unknown в строке 0

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

Вероятно, что-то вроде этого: http://notmysock.org/blog/php/user-cache-timebomb.html

Некоторые номера: сервер имеет около 400 APC-запросов в секунду в секунду и около 30 вставок в секунду (что, по-моему, много), один запрос содержит около 20-100 запросов пользователя. В пользовательском кеше имеется около 300 000 переменных, все с ttl (мы сохраняем без ttl только в нашем центральном redis).

Наши настройки APC:

apc.shm_segments=1 apc.shm_size=4096M apc.num_files_hint=1000 apc.user_entries_hint=500000 apc.max_file_size=2M apc.stat=0 

В настоящее время мы используем версию 3.1.13-бета, собранную со спин-блокировками, используемую со старым PHP 5.2.6 (это устаревшее приложение, я слышал, что эта версия PHP тоже может быть проблемой?), Linux 64bit.

Это очень сложно отладить, мы создали сценарии мониторинга, которые собирают столько данных, сколько мы можем получить каждую минуту от apc, системы и т. Д., Но мы не видим ничего необычного – даже за 1 минуту до сбоя.

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

http://webadvent.org/2010/share-and-enjoy-by-gopal-vijayaraghavan

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

с наилучшими пожеланиями, Андреас

Урок 1: https://www.kernel.org/doc/Documentation/spinlocks.txt

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

Это написано Линусом …

Замки спинов медленны; это утверждение не основано на какой-то статье, которую я читал в Интернете по facebook, но по фактическим фактам.

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

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

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

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

Прежде чем продолжить, ваша основная проблема заключается в том, что вы используете версию PHP из древности, о которой никто даже не помнит, как поддерживать , в общем, вы должны посмотреть на обновление, я знаю ограничения на OP, но это было бы безответственно чтобы отрицать, что это настоящая проблема, вы не хотите развертывать неподдерживаемое программное обеспечение. Кроме того, APC практически не поддерживается, ему суждено умереть. O + и APCu – это замена в современных версиях PHP.

Во всяком случае, я отвлекаюсь …

Синхронизация – это головная боль, когда вы программируете на уровне ядра, с винтовыми замками или что угодно. Когда вы удаляете несколько ядер из ядра, когда вы полагаетесь на 6 или 7 бит сложного программного обеспечения под вами, вы правильно синхронизируете, чтобы ваш код мог синхронизироваться правильно, синхронизация становится не только головной болью для программиста, но и для исполнителя; он может легко стать узким местом вашего блестящего веб-приложения, даже если в вашей реализации нет ошибок.

К счастью, это 2013 год, и Yahoo – это не единственные люди, которые могут реализовать пользовательские кэши в PHP 🙂

http://pecl.php.net/package/yac

Это чрезвычайно умный, незащищенный кеш для userland PHP, он отмечен как экспериментальный, но как только вы закончите, играйте с ним, может быть, еще через 7 лет мы не будем думать о проблемах синхронизации 🙂

Надеюсь, вы дойдете до конца 🙂

Если вы не используете операционную систему freebsd, то неплохо использовать винтовые блоки, это худший вид синхронизации на поверхности земли. Единственная причина, по которой вы должны использовать их в freebsd, состоит в том, что разработчик отказался включить поддержку PTHREAD_PROCESS_SHARED для мьютексов и rwlocks, поэтому у вас мало выбора, кроме как использовать блокировку спина pg-sql в этом случае.