我有一个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]
虽然我使用的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,
],
],
对于Redis,我使用Azure Redis缓存集群高级P1,2碎片(如here所述)。
更新2
到目前为止,我还尝试了以下配置变体:
1.将cluster设置为true
1.将群集设置为redis
1.正在将default -〉cluster集添加到redis
1.将default -〉选项集添加到数组('cluster','redis')
所有的时间我都得到移动错误...
我的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)],
],
],
非常感谢你们的帮助:)
7条答案
按热度按时间ufj5ltwl1#
注意
此处指定的信息和配置适用于Laravel 5.3及更低版本。Redis配置结构在Laravel 5.4+中已更改。
TL;DR的名称
'cluster' => true
应为true,以创建一个处理多个节点的聚合客户端。'options' => ['cluster' => 'redis']
作为default
的同级(而不是子级)添加到配置中,以便告知Predis处理Azure提供的服务器端集群。'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集群,它处理密钥空间的自动分片。在这个例子中,节点彼此知道,彼此交谈,可能会上升和下降。这就是
MOVED
和ASK
响应的来源。Predis
库可以自动处理这些响应,但只有当您告诉它需要这样做时才可以。在这种情况下,您需要告诉Predis
客户端它需要处理集群,这是由Laravel通过redis
配置上的options
数组完成的。在
redis
配置中,options
键应该是连接的同级(即default
),而不是子项。此外,选项应该指定为key => value
对。因此,您的配置应如下所示:
redis
配置下的cluster
键将告诉Laravel创建一个可以处理多个节点的聚合Predis\Client
示例,而options
数组下的cluster
键将告诉该示例它需要处理服务器端群集,而不是客户端群集。验证
原始连接参数(包括验证)不会与通过
-MOVED
和-ASK
响应发现的新节点的连接共享。因此,以前从-MOVED
响应获得的任何错误现在都将转换为NOAUTH
错误。但是,服务器端'cluster'
配置允许使用'parameters'
同级节点,该同级节点定义了一个参数列表,以便用于新发现的节点。您可以在此放置身份验证参数,以便用于新节点。我相信这看起来像这样:
公平的警告,这是我刚刚从研究和代码潜水中得到的所有信息。虽然我已经在Laravel上使用过Redis,但我还没有使用服务器端集群(还没有),所以这仍然可能不起作用。
我在调查这件事时发现了一些有用的信息:
Predis讨论连接到redis集群的问题:
https://github.com/nrk/predis/issues/259#issuecomment-117339028
看起来你并没有配置Predis使用redis-cluster,而是使用了普通的客户端分片逻辑(这也是默认行为)。你应该配置客户端的cluster选项为redis,让客户端知道它必须沿着redis-cluster。举个例子:
x1米32英寸
这样客户端就可以自动处理来自Redis节点的-MOVED或-ASK响应。
讨论Redis缓存集群的MS文章:
https://learn.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect-to-my-cache-when-clustering-is-enabled
您可以使用与连接未启用集群的缓存时相同的端点、端口和键来连接缓存。Redis在后端管理集群,因此您不必从客户端进行管理。
用于创建
Predis\Client
示例的Laravel代码:https://github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66
ep6jt1vc2#
相关:Laravel + Redis通过SSL缓存?
我在这里回答:https://stackoverflow.com/a/48876398/663058
相关详情如下:
如果您有集群 * 和 * TLS,则需要以下配置(使用AWS Elasticache进行测试):
解释上述内容:
'client' => 'predis'
:指定要使用的PHP库Redis驱动程序(predis)。'cluster' => 'redis'
:这告诉Predis假设服务器端集群。这只是意味着“跟随重定向”(例如-MOVED
响应)。当与集群一起运行时,节点将使用-MOVED
响应您必须请求特定键的节点。-MOVED
异常1/n 次,n 是Redis集群中的节点数(它会很幸运地每隔一段时间询问正确的节点)'clusters' => [...]
:指定一个节点列表,但只设置一个“default”并将其指向AWS的“Configuration endpoint”将允许它动态地查找任何/所有其他节点(建议用于Elasticache,因为您不知道节点何时到来或离开)。'options'
:对于Laravel,可以在顶层、集群级和节点选项中指定。(它们在传递到Predis之前在Illuminate中组合)'parameters'
:这些“覆盖”Predis用于新连接的默认连接设置/假设。由于我们为“默认”连接明确设置了这些设置,因此不会使用这些设置。但对于集群设置,它们是至关重要的。"主“节点可能会发回重定向(-MOVED
),除非为password
和scheme
设置了参数,否则它将采用默认值,并且到新节点的新连接将失败。jutyujz03#
在应用了很多建议之后,我终于找到了使用phpredis而不是Redis的解决方案。使用下面的代码:
使用官方文档更好地理解Laravel Redis集群
oknwwptz4#
对于AWS elasticcache redis集群,上述配置不起作用,但以下配置对我来说是有效的。文档中也提到:https://laravel.com/docs/5.4/redis#configuration
arknldoa5#
请参阅[ https://laravel.com/docs/5.5/redis ]。
请确保您有正确的库
在config/database.php和config/queue.php中[如果你的队列也使用集群reddis]
kpbpu0086#
这对我很有效:
要了解我是如何做到这一点的,请参阅我的答案here
bbuxkriu7#
这个结果出现在Google的predis+redis-cluster(没有laravel)上。我和我的团队为这个问题纠结了几个小时,所以我把这个答案放在这里,给那些在试图直接连接到Redis集群时发现这个页面出现错误的人: