Как разделить кеш приложения между несколькими экземплярами Symfony (общий пул кеша)?
У моего приложения symfony есть несколько экземпляров, которые работают в отдельных контейнерах докеров.
И я настроил свой
app.cache
использовать Redis:
framework:
cache:
app: cache.adapter.redis
У меня такая же
prefix_seed
:
framework:
cache:
prefix_seed: 'dev'
В результате я попадаю в redis примерно так:
1605259288.470950 [0 172.18.0.28:55044] "MGET" "HnMEIyUlZ+:workers.restart_requested_timestamp"
1605259288.471680 [0 172.18.0.28:55044] "SET" "HnMEIyUlZ+:workers.restart_requested_timestamp" "d:1605259288.471522;"
1605259314.483389 [0 172.18.0.29:42884] "MGET" "8TMgMtnOAG:workers.restart_requested_timestamp"
Как видно из приведенных выше двух разных экземпляров, они пытаются получить значение из Redis одним и тем же ключом.
workers.restart_requested_timestamp
но приставка разная даже у одинаковых
prefix_seed
.
В этом примере я использую компонент обмена сообщениями, и я хочу остановить выполнение рабочих повсюду с помощью
stop-workers
команда (через общий Redis). Но в целом это связано с настройкой кеша.
Как это преодолеть и указать обоим приложениям использовать один и тот же пул? Какая конфигурация для этого?
2 ответа
Наконец, я нашел решение. Есть возможность создать свой собственный кеш-пул с подключенным к нему адаптером. Основная хитрость здесь - передать тег с помощью
namespace
к вашему адаптеру (имя также должно быть
cache.pool
):
framework:
cache:
pools:
cache.redis_shared_pool:
adapter: app.cache_shared_redis_adapter
services:
app.cache_shared_redis_adapter:
parent: 'cache.adapter.redis'
tags:
- { name: 'cache.pool', namespace: 'shared' }
Это оно! Все ваши ключи в Redis будут иметь префикс
shared:
. Теперь вы должны передать
@cache.redis_shared_pool
на любую услугу, которую вы хотите.
А что касается компонента мессенджера, мы должны переопределить службы (но я не уверен, что это лучший способ):
console.command.messenger_stop_workers:
class: Symfony\Component\Messenger\Command\StopWorkersCommand
arguments:
$restartSignalCachePool: "@cache.redis_shared_pool"
messenger.listener.stop_worker_on_restart_signal_listener:
class: Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener
arguments:
$cachePool: "@cache.redis_shared_pool"
В определении конфигурации пакета фреймворка Symfony вы можете найти:
private function addCacheSection(ArrayNodeDefinition $rootNode)
{
$rootNode
->children()
->arrayNode('cache')
->info('Cache configuration')
->addDefaultsIfNotSet()
->fixXmlConfig('pool')
->children()
->scalarNode('prefix_seed')
->info('Used to namespace cache keys when using several apps with the same shared backend')
->example('my-application-name')
->end()
...
prefix_seed - это именно то, что вы ищете. Проверьте документацию здесь: https://symfony.com/doc/current/reference/configuration/framework.html#prefix-seed