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 script, который больше не отвечает, а статические ресурсы все еще доставляются Apache. Это действительно не сбой, нет segfault. Мы пробовали последнюю стабильную и последнюю бета-версию APC, мы пробовали pthreads, spin locks, каждый раз с той же проблемой. Мы предоставили APC гораздо больше памяти, которую он может когда-либо потреблять, за 1 минуту до крушения у нас есть 2% фрагментации и около 90% памяти бесплатно. Когда он "сбой", мы не находим ничего в журналах ошибок, только перезапуск Apache помогает. Только со спин-замками мы получаем ошибку php, которая:

PHP Неустранимая ошибка: Неизвестно: Застрял спин-блокировка (0x7fcbae9fe068), обнаруженная в Неизвестно в строке 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 (ее устаревшим приложением, Ive слышал, что эта версия PHP тоже может быть проблемой?), Linux 64bit.

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

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

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

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

С наилучшими пожеланиями, Andreas

Ответ 1

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Надеюсь, вы доберетесь до конца:)

Ответ 2

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