2017-02-04 13 views
7

Я использую Laravel кэширование (remember() метод) на веб-сайте с помощью следующего кода:Laravel иногда не в состоянии прочитать кэш

$postedItems = Cache::remember('home_posted_items', $this->cacheTimes['postedItems'], function() { 

    /* the stuff that prepares data */ 

    return ['items' => $items, 'firstItemNumber' => $firstItem]; 
}); 

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

Вот часть стека ошибок, которые могут иметь отношение:

[2017-02-04 22:01:34] production.ERROR: ErrorException: unserialize(): Error at offset 131059 of 131062 bytes in /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php:78 
Stack trace: 
#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'unserialize(): ...', '/home/path/to/...', 78, Array) 
#1 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php(78): unserialize('a:2:{s:7:"item...') 
#2 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php(47): Illuminate\Cache\FileStore->getPayload('home_posted_ite...') 
#3 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(98): Illuminate\Cache\FileStore->get('home_posted_ite...') 
#4 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(202): Illuminate\Cache\Repository->get('home_posted_ite...') 
#5 [internal function]: Illuminate\Cache\Repository->remember('home_posted_ite...', 1, Object(Closure)) 
#6 /home/path/to/app/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php(318): call_user_func_array(Array, Array) 
#7 /home/path/to/app/bootstrap/cache/compiled.php(6089): Illuminate\Cache\CacheManager->__call('remember', Array) 
#8 /home/path/to/app/app/Http/Controllers/HomeController.php(197): Illuminate\Support\Facades\Facade::__callStatic('remember', Array) 

Как решить эту проблему?

Из опыта Я знаю, что очистка кеша решает проблему. Таким образом, кажется, что проблема связана с коррупцией в файлах. Я думаю, если бы я заметил, что «файл нечитабелен» и просто очистить кеш (Cache::forget(...)), он должен решить проблему.

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

if (!($postedItems = @Cache::get('home_posted_items')) 
{ 
    // prepare data 

    $postedItems = ['items' => $items, 'firstItemNumber' => $firstItem]; 

    Cache::put('home_posted_items', $postedItems, $this->cacheTimes['postedItems']); 
} 
+0

У меня была аналогичная проблема ранее с laravel 4.2, в то время по какой-то причине файлы кэша, которые ранее были удалены, а затем класс кеширования попытался получить кеш и завершился неудачей, потому что файл не читается (не существуют), и после очистки кеша все просто отлично работает. я хочу сказать, что даже если вы используете Cache :: put вместо того, чтобы помнить, что это ничего не изменит, единственный способ сделать это - сделать недействительным кеш раз в то время, когда вы знаете, что это должно произойти –

+0

Have вы дисковая квота или вы, возможно, исчерпаете место? Или есть какой-то неожиданный символ в строке, которую вы пытаетесь выполнить без арифметики? Лучший способ превзойти imho - это VarDump содержимое в строке 78 файла FileStore.php. Дайте мне знать, что вы найдете. – DonCallisto

+0

@DonCallisto нет проблем с пространством, я не иссякнут. Но кажется, что файлы почему-то порезались по какой-то причине. Я выбрал исключение и написал его в файл журнала - оказалось, что он был отрезан от нового конца.Это странно, потому что это происходит только иногда, и, похоже, не было достигнуто никаких ограничений на ресурсы. –

ответ

0

Это не кажется вопрос разрешения (вы можете увидеть # 1 в трассировки стека), как-то Laravel является переопределение (развращение) файлы кэша. Вам нужно узнать, какой контент у вас есть в конце файла.

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

И лучший способ отладки, который находится здесь. https://stackoverflow.com/a/10152996/3305978

1

У IMHO может быть проблема с файловым драйвером. Я думаю, что если у вас есть хороший веб-сервер, способный обрабатывать параллельные запросы, проблема в том, что файловый драйвер не способен обрабатывать параллелизм.

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

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

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

+0

Это не решение, которое я мог бы поставить на место, но я считаю, что вы указываете на правильные проблемы. Наверное, этого достаточно, потому что здесь нет никого лучше :) –

+0

Большое спасибо @ Džuris надеюсь, что этот ответ может быть полезен – dparoli