Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 20 серпня 2026

Laravel Read-Through Filesystem: ледаче перенесення сховища

Перенесення кількох мільйонів файлів з одного бакета в інший - це та частина міграції сховища, на яку ніхто не закладає бюджет. Масове aws s3 sync між провайдерами займає дні, коштує реальних грошей на передачу даних і копіює кожен застарілий аватар та осиротілий експорт разом із файлами, які люди дійсно відкривають. Альтернатива - код застосунку, який вручну перевіряє два диски, розсіює Storage::disk('old') фолбеки по всіх шляхах читання і ніколи не видаляється повністю.

Laravel 13.26 постачається з драйвером файлової системи read-through, який виконує танець з двома дисками всередині самого диска. Ви вказуєте йому основний та запасний диск, і читання спочатку перевіряють основний, потім повертаються до старого диска, коли файл ще не там, і копіюють файл на основний під час проходження. Гарячі файли мігрують самі при першому зверненні до них, а холодні залишаються там, де вони є, поки ви не вирішите, що з ними робити. Драйвер потрапив у фреймворк через #61140 від @taylorotwell.

Налаштування диска

Диск read-through складається з двох інших дисків у config/filesystems.php. Посилайтеся на них за назвою:

'disks' => [
    'r2' => [
        'driver' => 's3',
        // облікові дані Cloudflare R2...
    ],
    'legacy-s3' => [
        'driver' => 's3',
        // бакет, який ви покидаєте...
    ],
    'assets' => [
        'driver' => 'read-through',
        'primary' => 'r2',
        'fallback' => 'legacy-s3',
    ],
],

Код застосунку використовує Storage::disk('assets') як будь-який інший диск, і в цьому суть: контролери та завдання не знають, що існує два бакети. Обидва primary та fallback також приймають масив конфігурації замість назви диска, коли ви не хочете реєструвати базові диски окремо. Менеджер валідує пару під час резолюції, тому відсутня сторона, той самий диск з обох сторін або диск, який посилається на себе, викидає InvalidArgumentException замість того, щоб зазнати невдачі при першому використанні.

Що куди йде

Правила маршрутизації варто засвоїти перед тим, як розміщувати це перед продакшн трафіком:

  • Читання (get(), readStream()) перевіряють основний диск, потім запасний. Попадання в запасний копіює файл на основний, а потім повертає вміст. Потокові читання буферизуються через потік php://temp, а не завантажують файл у пам'ять
  • Запис, видалення, переміщення та копіювання спрямовані тільки на основний диск
  • Списки директорій надходять тільки з основного диска, тому files() показує лише те, що було просунуто або записано після переключення
  • Перевірки існування та метадані (exists(), size(), mimeType(), lastModified(), url(), temporaryUrl()) звертаються до того диска, який містить файл, без запуску копіювання

Два з цих правил є гострими краями. Списки відображають тільки основний диск, тому все, що ітерує директорію для пошуку файлів, не побачить непросунутий контент на запасному диску. А видалення торкається тільки основного диска, тому видалення файлу, який все ще існує на запасному, воскрешає його при наступному читанні. Під час міграції це зазвичай нормально, запасний диск все одно зникає, але delete(), за яким слідує exists(), що повертає true, здивує вперше, коли ви на це натрапите.

Просування навмисно зроблено за принципом "найкращих зусиль". Якщо копіювання на основний диск не вдається, читання все одно успішне з запасного, і виняток проковтується, виходячи з теорії, що повний основний диск не повинен відключати ваші завантаження. Змініть це за допомогою 'throw_on_promotion_failure' => true, коли ви хочете знати про це негайно.

Читання без копіювання

Іноді вам потрібне шарування без міграції. #61155 від @jimbojsb додав опцію copy саме для цього:

'assets' => [
    'driver' => 'read-through',
    'primary' => 'local-assets',
    'fallback' => 'production-s3',
    'copy' => false,
],

З copy => false попадання в запасний обслуговуються безпосередньо, і нічого не просувається. Випадок використання, викладений у PR, - це середовище розробки, заповнене знімком продакшн бази даних: рядки посилаються на файли, які існують тільки в продакшн бакеті, і це налаштування дозволяє цим файлам рендеритися локально без повільного дзеркалювання бакета на ваш ноутбук. Це також підходить для обережної першої фази реальної міграції, коли ви переключаєте читання на новий макет і спостерігаєте за частотою помилок перед тим, як дозволити просуванню почати запис у новий бакет.

План міграції

Підсумовуючи, переміщення зі старого S3 бакета на R2 виглядає так:

  1. Створіть новий бакет і додайте його конфігурацію диска поряд зі старим
  2. Перенаправте назву диска, яку ваш застосунок вже використовує (assets вище), на пару read-through: новий бакет як primary, старий бакет як fallback. Нові завантаження тепер потрапляють у R2, і кожен запитуваний файл просувається сам при першому читанні
  3. Після того як шаблони доступу, які вас цікавлять, змінилися, найбільш читаний контент живе в основному диску. Заповніть довгий хвіст одноразовою синхронізацією або пакетною фоновою операцією, яка тепер має переміщувати лише те, про що ніхто не питав
  4. Замініть конфігурацію диска read-through на звичайний диск, що вказує на новий бакет, і виведіть старий з експлуатації

Між кроками 2 і 4 немає деплою, який перемикає весь трафік одразу, і відкат - це зміна конфігурації, оскільки старий бакет ніколи не переставав бути повним.

Додаткове читання

0

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

PayZephyr
Новини 12 вересня 2026

PayZephyr: Єдиний API для роботи з Stripe, Paystack та PayPal

PayZephyr - Laravel-пакет від Nwaneri Chukwunyere Kenneth, який об'єднує вісім платіжних провайдерів під одним зручним API. Підтримує автоматичне перемикання, захист від подвійної оплати, підписки та повернення коштів.

2
Laravel Telescope
Новини 11 вересня 2026

Artisan-команди для дебагу в Laravel Telescope 5.24.0

Laravel Telescope 5.24.0 додає дві нові Artisan-команди для роботи із записами із терміналу. Тепер можна переглядати запити, винятки, джоби та запити до бази даних без відкриття веб-інтерфейсу, а також отримувати дані у форматі JSON для скриптів та AI-агентів.

3

Пакети за темою

Laravel Medialibrary

spatie/laravel-medialibrary

Пакет для асоціювання файлів з Eloquent-моделями. Надає зручний інтерфейс для управління медіа-файлами, пов'язаними з вашими моделями бази даних.

6,163 11.23.7 13 8

Laravel Backup

spatie/laravel-backup

Пакет для створення резервних копій вашого Laravel-додатку.

6,018 10.3.2 13 10