php - 如何在 laravel 中同时拥有集群和非集群 redis 连接

标签 php laravel redis redis-cluster predis

背景

在过去,我可以像这样在我的配置中使用非集群的 redis:

'redis' => [

    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port'     => 6379,
        'database' => 0,
        'cluster' => true,
    ]
],

但是由于我们的 redis 服务器上的负载,我必须对我的 redis 进行集群,当我拥有的 only redis 连接被集群时,这个配置工作正常(在很多 work 之后弄清楚) :

'redis' => [
    'client' => 'predis',
    'cluster' => true,
    'options' => [
        'cluster' => 'redis',
        'parameters' => [
            'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_DEFAULT_PORT', 6379),
            'database' => 0,
            ],
        ],
    'clusters' => [
        'default' => [
            'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_SHARD_1_PORT', 6379),
            'database' => 0,
        ],
        'shard2' => [
            'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_SHARD_2_PORT', 6379),
            'database' => 0,
        ],
        'shard3' => [
            'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_SHARD_3_PORT', 6379),
            'database' => 0,
        ],
        'options' => [
            'cluster' => 'redis'
        ],
    ]
]

我的任何 env 文件都像这样(无论如何对于我的本地主机):

QUEUE_DRIVER=redis      // cluster compatible
BROADCAST_DRIVER=redis  // cluster compatible
CACHE_CONNECTION=redis  // cluster incompatible 

REDIS_CLUSTER=true
REDIS_HOST=localhost

REDIS_DEFAULT_PORT=7000

REDIS_SHARD_1_HOST=localhost
REDIS_SHARD_2_HOST=localhost
REDIS_SHARD_3_HOST=localhost

REDIS_SHARD_1_PORT=7000
REDIS_SHARD_2_PORT=7001
REDIS_SHARD_3_PORT=7002

问题

事实是,目前,我们使用非集群redis用于以下方面:

  • 缓存:支持redis集群
  • Queue/Jobs:支持redis集群
  • 广播(即websockets):支持redis集群吗

这就是为什么我们需要同时拥有两个 redis 连接,这样我们就可以将集群连接用于缓存/队列,将非集群连接用于 websockets。

但这行不通:

'redis' => [
    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port'     => 6379,
        'database' => 0,
        'cluster' => true,
    ],
    'clustered' => [
        'client' => 'predis',
        'cluster' => true,
        'options' => [
            'cluster' => 'redis',
            'parameters' => [
                'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_DEFAULT_PORT', 6379),
                'database' => 0,
                ],
            ],
        'clusters' => [
            'default' => [
                'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_SHARD_1_PORT', 6379),
                'database' => 0,
            ],
            'shard2' => [
                'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_SHARD_2_PORT', 6379),
                'database' => 0,
            ],
            'shard3' => [
                'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
                'password' => env('REDIS_PASSWORD', null),
                'port' => env('REDIS_SHARD_3_PORT', 6379),
                'database' => 0,
            ],
            'options' => [
                'cluster' => 'redis'
            ],
        ]

此外,一些用户 state 认为这样的任务对于 redis 来说根本不可能。是真的吗?

更新

我试过了

Cache.php

    'redis' => [
        'driver' => 'redis',
        'connection' => 'clustered',
    ],

注意:在上面的连接中,我不能简单地复制/粘贴集群选项,因为如果我不放置驱动程序选项它会崩溃

database.php 中,我受到这个 answer 的启发,并简单地将不同的连接放在 redis 键下:(即`database.redis.connection-1,database.redis.connection-2 等)

'redis' => [
    'clustered' => [
         // clustered settings copied from above
        ],
    ], 

    'default' => [
         // non clustered settings
    ],
]

为了测试,我运行了以下修补程序

>>> use Illuminate\Support\Facades\Cache;
>>> Cache::put('foo','bar',1);
Predis/Response/ServerException with message 'MOVED 7837 127.0.0.1:7001'

移动错误是一个已知错误,它只是 saying,我正在处理一个非集群的 redis 连接。

想法?

最佳答案

我能够用这个 PR 解决这个问题.

这是我现在的配置:

'redis' => [

    'clustered' => [
        'client' => 'predis',
        'cluster' => true,
        'options' => [ 'cluster' => 'redis' ],
        'clusters' => [
                    [
                        'host' => env('REDIS_SHARD_1_HOST', '127.0.01'),
                        'password' => env('REDIS_PASSWORD', null),
                        'port' => env('REDIS_SHARD_1_PORT', 6379),
                        'database' => 0,
                    ],
                    [
                        'host' => env('REDIS_SHARD_2_HOST', '127.0.01'),
                        'password' => env('REDIS_PASSWORD', null),
                        'port' => env('REDIS_SHARD_2_PORT', 6379),
                        'database' => 0,
                    ],
                    [
                        'host' => env('REDIS_SHARD_3_HOST', '127.0.01'),
                        'password' => env('REDIS_PASSWORD', null),
                        'port' => env('REDIS_SHARD_3_PORT', 6379),
                        'database' => 0,
                    ],
        ],
    ], 

    'default' => [
        'host' => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port'     => 6379,
        'database' => 0,
        'cluster' => false,
    ],
]

很快就会将 PR 发送给 Laravel 本身。

关于php - 如何在 laravel 中同时拥有集群和非集群 redis 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57722659/

相关文章:

php - Symfony/PHP - 存储单个值的最佳方式

php - 获取两列中具有相同值的行数据

php - 如何通过redbeanphp查询同一个表中的多对多关系?

caching - Redis 作为缓存 - 重置过期

spring-boot - Spring Boot应用程序中如何在Java中为Redis Cache设置硬编码 key ?

asp.net-mvc - Azure Redis 缓存动态 applicationName 或 key 名称

php - Joomla 网站 View 没有 "read more"

php - Laravel 5.3 使用单个 SQL 查询和缓存需要 1.9 秒

php - Laravel Socialite 名字和姓氏

php - 事件不会在 laravel 的 redis 中发布