Solid Queue та Solid Cache у Rails 8: Повний посібник для підготовки до технічної співбесіди 2026

Solid Queue та Solid Cache замінюють Redis у Rails 8. Повний посібник з архітектури, налаштування, контролю конкурентності та ключових питань на технічних співбесідах 2026 року.

Solid Queue та Solid Cache у Rails 8 — технічний посібник

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 забезпечує розгортання 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-образ обслуговує як веб-сервер, так і обробку завдань — оптимальне рішення для малих і середніх застосунків.

Готовий до співбесід з Ruby on Rails?

Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.

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 підтримує розподіл даних кешу між кількома базами даних (шардинг) для балансування навантаження. Також підтримуються зашифровані атрибути — дані кешу залишаються зашифрованими у стані спокою, що є вимогою відповідності для застосунків, які обробляють конфіденційну інформацію.

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 надає веб-панель для інспекції та керування завданнями 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 та фонові завдання та Стратегії кешування на платформі SharpSkill.

Готовий до співбесід з Ruby on Rails?

Практикуйся з нашими інтерактивними симуляторами, flashcards та технічними тестами.

Висновки

  • 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 завдань на хвилину

Починай практикувати!

Перевір свої знання з нашими симуляторами співбесід та технічними тестами.

Теги

#ruby-on-rails
#solid-queue
#solid-cache
#rails-8
#технічна-співбесіда

Поділитися

Пов'язані статті