Laravel + predis + Redis集群 - MOVED /无连接到127.0.0.1:6379

Lec*_*dal 5 redis laravel azure-caching

我有一个laravel(5.3)应用程序,redis用于会话(使用predis).只要我使用单个redis节点(使用config/database.php中的默认方法),一切正常.一旦我切换到Redis群集,虽然我开始得到MOVED错误,如50%的时间(基于谷歌搜索我明白这应该由predis管理,但不知何故不是).

我尝试将cluster参数更改为true,但后来我得到了一个奇怪的错误

No connection could be made because the target machine actively refused it. [tcp://127.0.0.1:6379] 
Run Code Online (Sandbox Code Playgroud)

虽然我使用的redis群集部署在Azure中(并通过.env文件配置),但在使用单个节点时接受参数时没有任何问题.

组态

这是我的laravel配置(如前所述,它是标准默认值)

'redis' => [

        'client' => 'predis',
        'cluster' => false,

        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ],

    ],
Run Code Online (Sandbox Code Playgroud)

对于Redis的,我使用的Redis天青缓存集群高级P1,2个碎片(如所描述的在这里).

更新2

到目前为止,我还尝试了以下配置的变体:

  1. 将群集设置为true
  2. 将群集设置为redis
  3. 添加默认值 - >集群设置为redis
  4. 添加默认 - >选项设置为数组('cluster','redis')

我一直得到MOVED错误...

我的Redis版本是3.2,predis/predis包1.1.1

适用于predis 1.1+的工作配置

'redis' => [
        'cluster' => true,

        'default' => [
            'host' => env('REDIS_HOST', 'localhost'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_PORT', 6379),
            'database' => 0,
        ] ,
        'options' => [
            'cluster' => 'redis',
             'parameters' => ['password' => env('REDIS_PASSWORD', null)],
        ],
    ],
Run Code Online (Sandbox Code Playgroud)

非常感谢你的帮助:)

pat*_*cus 11

TL; DR:

  • 'cluster' => true 应该是真的创建一个处理多个节点的聚合客户端.
  • 'options' => ['cluster' => 'redis']需要将其作为default(不是子)的兄弟添加到配置中,以便告诉Predis处理Azure提供的服务器端集群.
  • 如果将auth与服务器端群集一起使用,'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ]则需要对新发现的群集节点进行身份验证.

全文

在redis配置中,您可以设置多个redis实例的多个连接.该cluster选项告诉Laravel如何处理这些多个已定义的连接.

如果cluster设置为false,Laravel将为\Predis\Client每个连接创建单个实例.每个连接都可以单独访问,与其他连接没有任何关系.

如果cluster设置为true,Laravel将\Predis\Client使用所有已定义的连接创建聚合实例.没有其他配置,这是一种"假"集群.它使用客户端分片来分配密钥空间,并且可能需要外部监视和维护以确保正确的密钥负载平衡.

但是,您遇到的问题是Azure(可能是)实现了一个真正的服务器端Redis集群,该集群处理密钥空间的自动分片.在这种情况下,节点彼此了解并且彼此交谈,并且可以上下移动.这是MOVEDASK反应从何而来.

Predis库可以自动处理这些响应,但只有当您告诉它需要时才会这样.在这种情况下,您需要告诉Predis客户端它需要处理群集,这是由Laravel通过配置options上的数组完成的redis.

redis配置上,options密钥应该是您的连接的兄弟(即default),而不是孩子.此外,应将选项指定为key => value对.

因此,您的配置应如下所示:

'redis' => [
    'cluster' => true,

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

    'options' => [
        'cluster' => 'redis',
    ],
],
Run Code Online (Sandbox Code Playgroud)

cluster下键redis配置会告诉Laravel来创建聚合Predis\Client可以处理多个节点的实例,而cluster下键options阵列会告诉实例它需要处理服务器端集群,而不是客户端集群.

验证

原始连接参数(包括身份验证)不会与通过-MOVED-ASK响应发现的新节点的连接共享.因此,您之前从-MOVED响应中获得的任何错误现在只会转换为NOAUTH错误.但是,服务器端'cluster'配置允许'parameters'兄弟节点定义用于新发现节点的参数列表.您可以在此处将auth参数用于新节点.

我相信这看起来像:

'redis' => [
    'cluster' => true,

    'default' => [
        'host' => env('REDIS_HOST', 'localhost'),
        'password' => env('REDIS_PASSWORD', null),
        'port' => env('REDIS_PORT', 6379),
        'database' => 0,
    ],

    'options' => [
        'cluster' => 'redis',
        'parameters' => ['password' => env('REDIS_PASSWORD', null)],
    ],
],
Run Code Online (Sandbox Code Playgroud)

公平的警告,这是我刚从研究和代码潜水中得到的所有信息.虽然我使用Redis和Laravel,但我还没有使用服务器端集群,所以这仍然可能无法正常工作.

我在调查时发现了一些有用的信息:

Predis问题讨论连接到redis-cluster:https:
//github.com/nrk/predis/issues/259#issuecomment-117339028

看起来您没有将Predis配置为使用redis-cluster,而是使用普通的旧客户端分片逻辑(这也是默认行为).您应该使用值redis配置客户端设置选项集群,让客户端知道它必须与redis-cluster一起使用.快速举例:

$client = new Predis\Client([$node1, $node2, ...], ['cluster' => 'redis']);

这样做可以使客户端自动处理来自Redis节点的-MOVED或-ASK响应.

MS文章讨论了在redis缓存上的集群:https:
//docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect-to-my-在启用缓存时,聚类,

您可以使用连接到未启用群集的缓存时使用的相同端点,端口和密钥连接到缓存.Redis管理后端的群集,因此您无需从客户端进行管理.

用于创建Predis\Client实例的Laravel代码:https:
//github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66