# Solid Queue та Solid Cache у Rails 8: Повний посібник для підготовки до технічної співбесіди 2026 > Solid Queue та Solid Cache замінюють Redis у Rails 8. Повний посібник з архітектури, налаштування, контролю конкурентності та ключових питань на технічних співбесідах 2026 року. - Published: 2026-05-13 - Updated: 2026-05-13 - Author: Anthony Fillion-Maillet - Tags: ruby-on-rails, solid-queue, solid-cache, rails-8, технічна-співбесіда - Reading time: 12 min --- Rails 8 приносить найзначнішу інфраструктурну трансформацію за всю історію фреймворку. Solid Queue та Solid Cache постачаються як компоненти за замовчуванням, замінюючи Redis для фонових завдань та кешування рішеннями на основі бази даних. Ця зміна усуває цілий рівень операційної складності, який раніше вимагав окремого обслуговування in-memory сховища. > **Solid-трійка** > > Rails 8 за замовчуванням використовує три компоненти на основі бази даних: Solid Queue (фонові завдання), Solid Cache (кешування) та Solid Cable (WebSocket). Разом вони знімають залежність від Redis для більшості Rails-застосунків. Це питання регулярно з'являється на технічних співбесідах щодо Rails 8. ## Як Solid Queue замінює Redis-бекенди для черг завдань Solid Queue — це бекенд Active Job на основі бази даних, що зберігає завдання безпосередньо у PostgreSQL, MySQL або SQLite. Ключовий механізм — SQL-конструкція `FOR UPDATE SKIP LOCKED`, доступна у PostgreSQL 9.5+ та MySQL 8+, яка перетворює звичайну таблицю бази даних на конкурентну чергу завдань без блокування. Архітектура складається з трьох компонентів: - **Workers** — опитують таблицю `solid_queue_ready_executions` та захоплюють завдання за допомогою `SKIP LOCKED` - **Dispatchers** — переміщують заплановані завдання з `solid_queue_scheduled_executions` до таблиці готових, коли настає час їх виконання - **Schedulers** — керують повторюваними завданнями, визначеними у конфігурації ```ruby # config/solid_queue.yml production: dispatchers: - polling_interval: 1 batch_size: 500 workers: - queues: "*" threads: 5 polling_interval: 0.1 processes: 2 ``` Ця конфігурація запускає два процеси воркерів по 5 потоків кожен, які опитують базу кожні 100 мс. Диспетчер перевіряє заплановані завдання щосекунди пакетами по 500 записів. ## Транзакційне додавання завдань до черги у Rails 8 Один із найвагоміших аргументів на користь Solid Queue — транзакційне додавання завдань. Коли завдання ставиться в чергу всередині транзакції бази даних, воно стає видимим лише після успішного коміту цієї транзакції. Redis-бекенди не здатні надати таку гарантію — завдання може виконатися до завершення транзакції, що його створила, посилаючись на записи, яких ще не існує. ```ruby # app/jobs/send_welcome_email_job.rb class SendWelcomeEmailJob < ApplicationJob self.enqueue_after_transaction_commit = true queue_as :default def perform(user_id) user = User.find(user_id) UserMailer.welcome(user).deliver_now end end # app/models/user.rb class User < ApplicationRecord after_create do SendWelcomeEmailJob.perform_later(id) # Job only enqueued after the CREATE transaction commits # No risk of the job running before the user record exists end end ``` З увімкненою опцією `enqueue_after_transaction_commit` завдання потрапляє до черги лише після успішного коміту транзакції. Якщо транзакція відкочується, завдання ніколи не буде додано. Це усуває цілий клас race conditions, які постійно виникають у системах на базі Redis. ## Контроль конкурентності та пріоритетні черги Solid Queue надає вбудовані механізми контролю конкурентності — функціональність, яку Sidekiq пропонує лише у платній версії Enterprise. Опція `limits_concurrency` обмежує кількість завдань певного типу, що виконуються одночасно. ```ruby # app/jobs/api_sync_job.rb class ApiSyncJob < ApplicationJob limits_concurrency to: 3, key: ->(account_id) { "api_sync_#{account_id}" } def perform(account_id) account = Account.find(account_id) ExternalApi.sync(account) end end ``` Цей код гарантує, що для кожного облікового запису одночасно виконуватимуться максимум 3 завдання синхронізації з API. Заблоковані завдання зберігаються у таблиці `solid_queue_blocked_executions` та автоматично вивільняються, коли з'являється вільний слот. Пріоритизація працює на двох рівнях: числовий пріоритет окремого завдання (менше число = вищий пріоритет) та порядок черг у конфігурації воркера. Обидва механізми можна комбінувати для точного контролю над порядком виконання завдань. > **Порада для співбесіди** > > Типове питання на співбесіді щодо Rails 8 стосується порівняння Solid Queue та Sidekiq. Ключова відмінність: Solid Queue пропонує транзакційні гарантії та вбудований контроль конкурентності безкоштовно. Sidekiq перемагає у сирій пропускній здатності для великих навантажень (10 000+ завдань на хвилину), оскільки Redis працює в оперативній пам'яті. Для 95% застосунків продуктивності Solid Queue цілком достатньо. ## Повторювані завдання без cron Solid Queue замінює cron-планування вбудованим планувальником. Повторювані завдання визначаються у YAML-файлі конфігурації та керуються процесом планувальника. ```ruby # config/recurring.yml production: cleanup_expired_sessions: class: CleanupExpiredSessionsJob schedule: every 6 hours daily_report: class: DailyReportJob schedule: every day at 6am queue: reports weekly_digest: class: WeeklyDigestJob schedule: every Monday at 9am ``` Процес планувальника зчитує цей файл та додає відповідні завдання до черги у визначених інтервалах. На відміну від cron, він працює в межах того самого процесу-супервізора та використовує спільне з'єднання з базою даних. ## Розгортання з інтеграцією Puma Rails 8 із [Kamal](https://kamal-deploy.org/) забезпечує розгортання Solid Queue без додаткового налаштування. Встановлення змінної `SOLID_QUEUE_IN_PUMA=1` вказує серверу Puma запускати та контролювати процеси Solid Queue паралельно з веб-сервером. ```ruby # config/puma.rb (Rails 8 default) plugin :solid_queue if ENV["SOLID_QUEUE_IN_PUMA"] ``` Ця модель розгортання в одному процесі спрощує оркестрацію контейнерів. Один Docker-образ обслуговує як веб-сервер, так і обробку завдань — оптимальне рішення для малих і середніх застосунків. ## Solid Cache: кешування на базі даних, що масштабується завдяки SSD Solid Cache — це реалізація `ActiveSupport::Cache::Store` на основі бази даних, яка використовує продуктивність сучасних SSD-накопичувачів для заміни Redis та Memcached як сховища кешу за замовчуванням. Базове припущення: SSD лише незначно повільніші за оперативну пам'ять при операціях читання, проте забезпечують на порядки більший обсяг зберігання за значно меншу ціну. Solid Cache використовує стратегію витіснення FIFO (First In, First Out) замість LRU (Least Recently Used). Хоча FIFO теоретично менш ефективна, значно більша ємність диска компенсує цю різницю — записи залишаються у кеші набагато довше, що загалом зменшує кількість промахів. ```ruby # config/environments/production.rb config.cache_store = :solid_cache_store # config/solid_cache.yml production: databases: - cache store_options: max_age: 604800 # 1 week in seconds max_size: 256 # Max entry size in KB namespace: "app_v1" expiry_batch_size: 100 # Entries cleaned per expiry cycle ``` ## Архітектура кешу та механізм закінчення терміну дії Solid Cache відстежує операції запису за допомогою внутрішнього лічильника. Коли лічильник досягає 50% налаштованого значення `expiry_batch_size`, запускається фонове завдання для очищення прострочених записів. Такий амортизований підхід дозволяє уникнути пауз типу stop-the-world, які можуть виникати при LRU-витісненні в Redis-інстансах з обмеженою пам'яттю. Таблиця `solid_cache_entries` зберігає всі дані кешу: ```ruby # db/cache_schema.rb (generated by installer) create_table :solid_cache_entries do |t| t.binary :key, null: false, limit: 1024 t.binary :value, null: false, limit: 262144 # 256 KB default t.datetime :created_at, null: false t.index :key, unique: true t.index :created_at # For FIFO expiry end ``` За замовчуванням читання та запис у цю таблицю використовують той самий пул з'єднань, що й решта застосунку. Для високонавантажених застосунків рекомендується налаштувати окрему базу даних для даних кешу, щоб операції кешування не впливали на продуктивність основної бази. ## Окрема база даних для кешу у продакшені Ізоляція Solid Cache на виділеній базі даних є простою та рекомендованою для продакшен-навантажень, що генерують значний трафік кешування. ```yaml # config/database.yml production: primary: <<: *default database: myapp_production cache: <<: *default database: myapp_cache_production migrations_paths: db/cache_migrate ``` Такий поділ гарантує, що мільйони операцій запису кешу не роздують WAL (Write-Ahead Log) основної бази даних та не конкуруватимуть за слоти пулу з'єднань із запитами застосунку. > **Важливо для продакшену** > > Без окремої бази даних операції читання та запису Solid Cache беруть участь у будь-якій зовнішній транзакції ActiveRecord. Це означає, що тривала транзакція утримує записи кешу у незакоміченому стані. Для продакшен-застосунків завжди необхідно налаштовувати виділену базу даних для кешу. ## Шардинг та шифрування Solid Cache підтримує розподіл даних кешу між кількома базами даних (шардинг) для балансування навантаження. Також підтримуються [зашифровані атрибути](https://guides.rubyonrails.org/active_record_encryption.html) — дані кешу залишаються зашифрованими у стані спокою, що є вимогою відповідності для застосунків, які обробляють конфіденційну інформацію. ```ruby # config/solid_cache.yml production: databases: - cache_shard_1 - cache_shard_2 - cache_shard_3 store_options: max_age: 1209600 # 2 weeks ``` Записи розподіляються між шардами за допомогою консистентного хешування (consistent hashing) ключа кешу. Додавання або видалення шарда спричиняє тимчасове збільшення промахів кешу під час перерозподілу, але не призводить до втрати даних. ## Моніторинг за допомогою Mission Control Jobs [Mission Control Jobs](https://github.com/rails/mission_control-jobs) надає веб-панель для інспекції та керування завданнями Solid Queue. Через монтований Rails-рушій відображаються воркери, черги та стани завдань (в обробці, завершені, заблоковані, невдалі). ```ruby # config/routes.rb Rails.application.routes.draw do mount MissionControl::Jobs::Engine, at: "/jobs" end # Gemfile gem "mission_control-jobs", ">= 1.0.1" ``` Mission Control також надає консольний API для масових операцій над невдалими завданнями: ```ruby # Rails console ActiveJob.jobs.failed.where(job_class: "ApiSyncJob").retry_all ActiveJob.jobs.failed.where(job_class: "BrokenJob").discard_all ``` Програмний доступ до завдань є незамінним для обробки масштабних збоїв без ручного клікання по інтерфейсу панелі. ## Ключові питання для технічних співбесід Співбесіди з Rails 8 дедалі частіше фокусуються на стеку Solid. Нижче наведено питання, які зустрічаються найчастіше, разом з очікуваною глибиною відповіді. **З: Як Solid Queue забезпечує конкурентну обробку завдань без Redis?** Solid Queue використовує SQL-конструкцію `FOR UPDATE SKIP LOCKED`, яка дозволяє кільком воркерам одночасно опитувати одну й ту саму таблицю без взаємного блокування. Кожен воркер блокує пакет рядків, обробляє їх та видаляє записи виконання. Інші воркери пропускають вже заблоковані рядки та захоплюють інші завдання. **З: Яку проблему вирішує транзакційне додавання до черги?** Воно запобігає виконанню завдань до завершення транзакції бази даних, яка їх ініціювала. Без цього механізму завдання може посилатися на запис, який було відкочено, що спричиняє помилку `ActiveRecord::RecordNotFound`. **З: Чому Solid Cache використовує FIFO замість LRU?** FIFO простіше реалізувати у базі даних, і цей підхід усуває навантаження запису, пов'язане з оновленням часових міток доступу при кожному читанні. Цей компроміс компенсується ємністю SSD — записи живуть довше, тому коефіцієнт влучень залишається високим попри менш оптимальну стратегію витіснення. **З: Коли застосунку варто використовувати Redis замість стеку Solid?** Redis залишається кращим вибором для застосунків, що обробляють понад 10 000 завдань на хвилину, навантажень, які потребують читання кешу за субмілісекунди, або застосунків, які вже використовують Redis для інших цілей (Pub/Sub, rate limiting, зберігання сесій). Стек Solid орієнтований на простоту, а не на пікову пропускну здатність. Більше питань та практичних завдань доступно у модулях [ActiveJob та фонові завдання](/technologies/ruby-on-rails/interview-questions/active-job-background-jobs) та [Стратегії кешування](/technologies/ruby-on-rails/interview-questions/caching-strategies) на платформі SharpSkill. ## Висновки - Solid Queue замінює черги завдань на базі Redis рішенням на основі бази даних, використовуючи `FOR UPDATE SKIP LOCKED` для конкурентної обробки - Транзакційне додавання до черги усуває race conditions між записом у базу та виконанням завдання — гарантія, яку Redis не здатен забезпечити - Вбудований контроль конкурентності, повторювані завдання та інтеграція з Puma постачаються з Solid Queue без додаткової оплати - Solid Cache використовує FIFO-кешування на основі SSD з опціональним шардингом та шифруванням, видаляючи Memcached та Redis з інфраструктурного стеку - Окрема конфігурація бази даних для Solid Cache запобігає впливу операцій кешування на продуктивність основної бази - Mission Control Jobs забезпечує моніторинг у продакшені та масове керування завданнями через веб-панель та консольний API - Для більшості застосунків Rails 8 у 2026 році стек Solid є рекомендованим вибором за замовчуванням — Redis залишається доцільним лише для граничних випадків з пропускною здатністю понад 10 000 завдань на хвилину --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/uk/blog/ruby-on-rails/solid-queue-solid-cache-rails-8-guide