Laravel + predis + Redis 集群 - 移动/没有连接到 127.0.0.1:6379 [英] Laravel + predis + Redis cluster - MOVED / no connection to 127.0.0.1:6379

查看:21
本文介绍了Laravel + predis + Redis 集群 - 移动/没有连接到 127.0.0.1:6379的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a laravel (5.3) app with redis used for sessions (using predis). Everything works as long as I use a single redis node (using default approach from config/database.php). As soon as I switch to a Redis cluster though I am starting to get MOVED error like 50% of the time (based on googling I understand that this should be managed by predis, but somehow isn't).

我尝试将集群参数更改为 true,但随后出现奇怪的错误

I tried changing the cluster parameter to true, but then I get a weird error

No connection could be made because the target machine actively refused it. [tcp://127.0.0.1:6379] 

虽然我用的redis集群是部署在Azure上的(通过.env文件配置的),在使用单节点的情况下,参数是可以接受的.

Although the redis cluster that I use is deployed in Azure (and is configured via .env file) and the parameters are accepted without any problem when a single node is used.

配置

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

Here is the laravel configuration that I have (as mentioned earlier, it's the standard default)

'redis' => [

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

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

    ],

对于 Redis,我使用 Azure Redis 缓存集群高级 P1、2 个分片(如 此处).

For Redis, I use Azure Redis Cache Cluster Premium P1, 2 shards (as described here).

更新 2

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

So far I also tried the following variations of the config:

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

我一直收到 MOVED 错误...

All the time I am getting MOVED error...

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

My Redis version is 3.2, predis/predis package 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)],
        ],
    ],

非常感谢您的帮助:)

推荐答案

TL;DR:

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

    • 'cluster' => true should be true to create one aggregate client that handles multiple nodes.
    • 'options' => ['cluster' => 'redis'] needs to be added to the configuration as a sibling of default (not a child) in order to tell Predis to handle the server-side clustering provided by Azure.
    • if using auth with server-side clustering, 'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ] will be needed to auth newly discovered cluster nodes.
    • 在redis配置中,可以设置多个连接到多个redis实例.cluster 选项告诉 Laravel 如何处理这些多个定义的连接.

      In the redis configuration, you can set up multiple connections to multiple redis instances. The cluster option tells Laravel how to handle those multiple defined connections.

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

      If cluster is set to false, Laravel will create individual PredisClient instances for each connection. Each connection can be accessed individually, and will not have any relation to another connection.

      如果 cluster 设置为 true,Laravel 将使用所有定义的连接创建聚合 PredisClient 实例.没有其他配置,这有点假"簇.它使用客户端分片来分配密钥空间,并且可能需要外部监控和维护以确保适当的密钥负载平衡.

      If cluster is set to true, Laravel will create an aggregate PredisClient instance using all the defined connections. With no other configuration, this is kind of a "fake" cluster. It uses client-side sharding to distribute the keyspace and may require external monitoring and maintenance to ensure a proper key load balance.

      然而,您遇到的问题是 Azure 实现(大概)一个真正的服务器端 Redis 集群,它处理密钥空间的自动分片.在这种情况下,节点相互了解并相互交谈,并且可以上下移动.这是 MOVEDASK 响应的来源.

      The issue you're running into, however, is that Azure implements (presumably) a real server-side Redis cluster, which handles automatic sharding of the keyspace. In this instance, the nodes know about each other and talk to each other, and may go up and down. This is where MOVED and ASK responses come from.

      Predis 库可以自动处理这些响应,但前提是您告诉它需要这样做.在这种情况下,你需要告诉 Predis 客户端它需要处理集群,这是由 Laravel 通过 redis 上的 options 数组完成的代码> 配置.

      The Predis library can automatically handle these responses, but only when you tell it that it needs to. In this case, you need to tell the Predis client that it needs to handle clustering, and this is done by Laravel through the options array on the redis configuration.

      redis 配置中,options 键应该是连接的兄弟(即 default),而不是子项.此外,选项应指定为 key =>;值对.

      On the redis configuration, the options key should be a sibling of your connections (i.e. default), not a child. Additionally, the options should be specified as key => value pairs.

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

      So, your configuration should look like:

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

      redis 配置下的 cluster 键会告诉 Laravel 创建一个可以处理多个节点的聚合 PredisClient 实例,并且options 数组下的 cluster 键将告诉该实例它需要处理服务器端集群,而不是客户端集群.

      The cluster key under the redis config will tell Laravel to create an aggregate PredisClient instance that may handle multiple nodes, and the cluster key under the options array will tell that instance that it needs to handle server-side clustering, not client-side clustering.

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

      The original connection parameters (including authentication) are not shared with connections to new nodes discovered via -MOVED and -ASK responses. So, any errors you previously got from -MOVED responses will now just convert to NOAUTH errors. However, the server-side 'cluster' configuration allows for a 'parameters' sibling which defines a list of parameters to use with newly discovered nodes. This is where you can put your auth parameters to use with new nodes.

      我相信这看起来像:

      '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)],
          ],
      ],
      


      公平警告,这是我刚刚从研究和代码潜水中获得的所有信息.虽然我已经在 Laravel 中使用了 Redis,但我还没有使用过服务器端集群(还没有),所以这仍然可能不起作用.


      Fair warning, this is all information I just got from research and code diving. While I have used Redis with Laravel, I have not used server side clustering (yet), so this still may not work.

      我在研究这个时发现了一些有用的信息:

      Some useful pieces of information I came across while looking into this:

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

      Predis issue discussing connecting to a redis-cluster:
      https://github.com/nrk/predis/issues/259#issuecomment-117339028

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

      It looks like you did not configure Predis to use redis-cluster but instead you are using it with the plain old client-side sharding logic (which is also the default behaviour). You should configure the client setting the option cluster with the value redis to let the client know it must play along with redis-cluster. Quick example:

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

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

      Doing so will make it possible for the client to automatically handle -MOVED or -ASK responses coming from Redis nodes.

      MS 文章讨论了 redis 缓存上的集群:
      https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect-to-my-cache-when-clustering-is-enabled

      MS article discussing clustering on redis cache:
      https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect-to-my-cache-when-clustering-is-enabled

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

      You can connect to your cache using the same endpoints, ports, and keys that you use when connecting to a cache that does not have clustering enabled. Redis manages the clustering on the backend so you don't have to manage it from your client.

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

      Laravel code for creating PredisClient instances:
      https://github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66

      这篇关于Laravel + predis + Redis 集群 - 移动/没有连接到 127.0.0.1:6379的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆