【问题标题】:How to have both clustered and non-clustered redis connections in laravel如何在 laravel 中同时拥有集群和非集群 Redis 连接
【发布时间】:2020-01-03 11:12:49
【问题描述】:

背景

过去,我可以在我的配置中使用非集群的 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 连接被集群时,此配置工作正常(经过大量 @987654321 后想通了@):

'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集群
  • 队列/作业:支持 redis 集群
  • 广播(即websockets):支持redis集群

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

但这不起作用:

'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 连接。

想法?

【问题讨论】:

  • 我会这样处理它:我会在cache.php 中创建额外的redis 配置,我称之为redis_nonclustered。在database.php 中,我将创建额外的redis 配置,同时将键命名为redis_nonclustered。这应该让您使用两个 redis 连接,一个是集群的,另一个是非集群的,彼此不同。
  • @N.B.你以前试过吗?
  • 我没有尝试使用 redis 本身,但我使用这种方法添加了与其他类似数据库的服务的各种额外的多个连接。您想要做的是通过在 Laravel 中使用单个服务提供者来使用集群和非集群的 redis,而您不能这样做,您必须创建两个不同的连接 - 所以只需这样做,配置两个不同的连接就可以了。跨度>
  • @N.B.如果您可以向我展示如何创建两个不同的连接(用于redis 或其他)的示例,我将不胜感激(如果它有效,足以得到正确的答案)。在我的 config/cache.php 中,我有 'redis' => [ 'driver' => 'redis', 'connection' => 'default', ], ,其中连接指向 default,这又在我的 config/database.php 中定义,所以不是确定如何添加另一个连接。
  • @N.B.我听从了你上面的建议,但仍然没有用。这就是你的想法吗?

标签: php laravel redis redis-cluster predis


【解决方案1】:

我可以用这个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。

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 2020-08-23
    • 2018-07-12
    • 2015-10-13
    • 2015-11-12
    • 2018-12-04
    • 2016-06-06
    • 2018-03-09
    • 2021-03-26
    相关资源
    最近更新 更多