Laravel + 通过 SSL 的 Redis 缓存?

Laravel + Redis Cache via SSL?

我正在尝试使用信息 https://github.com/nrk/predis 通过 predis 1.1 和 SSL 连接到 Redis,示例中使用了以下配置:

// Named array of connection parameters:
$client = new Predis\Client([
  'scheme' => 'tls',
  'ssl'    => ['cafile' => 'private.pem', 'verify_peer' => true],
]);

我的 Laravel 配置如下所示:

'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),

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

不幸的是,我收到以下错误:

ConnectionException in AbstractConnection.php line 155:
Error while reading line from the server. [tcp://MY_REDIS_SERVER_URL:6380]

欢迎提出建议:)

我能够让它工作!

您需要将 'scheme' 从 'options' 移动到 'default':

我的工作配置:

'redis' => [
    'client' => 'predis',
    'cluster' => env('REDIS_CLUSTER', false),

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

    'options' => [
        'parameters' => ['password' => env('REDIS_PASSWORD', null)],
    ],
],

注意:我还从 'options' 中删除了 'cluster' 选项,但我不怀疑这是 make-or-break 有此问题的原因。

在我的 final-final 配置中,我将其更改为:'scheme' => env('REDIS_SCHEME', 'tcp'),,然后在我的 env 文件中定义了 REDIS_SCHEME=tls

已在启用 TLS 的情况下使用 AWS ElastiCache 进行测试。

编辑: 上面的配置只适用于 single-node redis。如果您碰巧启用了集群 TLS,那么您将需要完全不同的配置。

'redis' => [
        'client' => 'predis',
        'cluster' => env('REDIS_CLUSTER', false),

        // Note! for single redis nodes, the default is defined here.
        // keeping it here for clusters will actually prevent the cluster config
        // from being used, it'll assume single node only.
        //'default' => [
        //    ...
        //],

        // #pro-tip, you can use the Cluster config even for single instances!
        'clusters' => [
            'default' => [
                [
                    'scheme'   => env('REDIS_SCHEME', 'tcp'),
                    'host'     => env('REDIS_HOST', 'localhost'),
                    'password' => env('REDIS_PASSWORD', null),
                    'port'     => env('REDIS_PORT', 6379),
                    'database' => env('REDIS_DATABASE', 0),
                ],
            ],
            'options' => [ // Clustering specific options
                'cluster' => 'redis', // This tells Redis Client lib to follow redirects (from cluster)
            ]
        ],
        'options' => [
            'parameters' => [ // Parameters provide defaults for the Connection Factory
                'password' => env('REDIS_PASSWORD', null), // Redirects need PW for the other nodes
                'scheme'   => env('REDIS_SCHEME', 'tcp'),  // Redirects also must match scheme
            ],
        ]
    ]

解释以上内容:

  • 'client' => 'predis':指定要使用的 PHP 库 Redis 驱动程序 (predis)。
  • 'cluster' => 'redis':这告诉 Predis 假设 server-side 聚类。这只是意味着“跟随重定向”(例如 -MOVED 响应)。当 运行 一个集群时,一个节点将用 -MOVED 响应您必须要求特定密钥的节点。
  • 如果您没有为 Redis 集群启用此功能,Laravel 将抛出 -MOVED 异常 1/n 次,n 是 Redis 集群中的节点数(它会幸运地每隔一段时间询问正确的节点)
  • 'clusters' => [...] :指定一个节点列表,但是只设置一个'default'并将其指向AWS 'Configuration endpoint'将让它动态地找到any/all其他节点(推荐对于 Elasticache,因为您不知道节点何时进入或离开)。
  • 'options':对于Laravel,可以在top-level、cluster-level和节点选项中指定。 (在传递给 Predis 之前,它们在 Illuminate 中合并)
  • 'parameters':这些 'override' Predis 用于新连接的默认连接 settings/assumptions。由于我们为 'default' 连接明确设置了它们,因此未使用它们。但是对于集群设置,它们是至关重要的。 'master' 节点可能会发回重定向 (-MOVED),除非为 passwordscheme 设置了参数,否则它将采用默认值,并且新连接到新节点将失败。

谢谢CenterOrbit!!

我可以确认第一个解决方案确实允许 Laravel 通过 TLS 连接到 Redis 服务器 。使用 TLS 在 AWS ElastiCache 上使用 Redis 3.2.6 进行测试,配置为单节点和单分片。

我还可以确认第二种解决方案确实允许 Laravel 通过 TLS 连接到 Redis Cluster。使用 TLS 在 AWS ElastiCache 上使用 Redis 3.2.6 进行测试,配置 "Cluster Mode Enabled",1 个分片,每个分片 1 个副本。

我第一次尝试实施集群解决方案时收到以下错误:

Error: Unsupported operand types

当我将 "default" 设置移动到 "clusters" 数组时,我错过了额外的一组数组括号。

不正确

'clusters' => [
  'default' => [
    'scheme' ...
  ]
]

正确

'clusters' => [
  'default' => [
    [
      'scheme' ...
    ]
  ]
]

我希望这能为其他人节省一些故障排除时间。

CenterOrbit 接受的解决方案对我有用,因为我使用的是 AWS,所以我必须在我的 .env 中添加 tls:// Laravel