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

Мы пытаемся развернуть пользовательский кэш APC в среде высокой нагрузки в качестве локального 2-уровневого кэша на каждом сервере для нашей центральной службы кэширования (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-скрипт с only only больше не отвечает, в то время как статические ресурсы все еще поставляются Apache. На самом деле это не сбой, нет segfault. Мы пробовали последнюю стабильную и последнюю бета-версию APC, мы пробовали pthreads, спин-блокировки, каждый раз одну и ту же проблему. Мы предоставили 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 только в нашем центральном редисе).

Наши 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 работает намного быстрее. Но как сделать это стабильным?

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

2 ответа

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

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

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

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

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

Они используются ядром эффективно, потому что именно там они и предназначены для использования, блокируя крошечные крошечные крошечные секции, не сидят без дела и не ждут, пока вы скопируете свои ответы мыльной системы 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

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

Я надеюсь, что вы дошли до сути:)

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

Другие вопросы по тегам