我有一个运行.NET Core应用程序的Lambda函数,我尝试使用StackExchange.Redis与ElastiCache Redis集群进行交互。集群是单个节点。Lambda配置在与ElastiCache Redis集群相同的VPC和安全组中。安全组为端口6379的VPC中的所有子网设置了入站规则。所有这些子网都连接到Lambda。
当我的代码尝试连接到Redis集群时,我不断收到以下错误:
{
"errorType": "RedisConnectionException",
"errorMessage": "No connection is active/available to service this operation: GET <REDACTED-KEY>; UnableToConnect on <REDACTED-PRIMARY-ENDPOINT-NAME>:6379/Interactive, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 5s ago, v: 2.2.50.36290, mc: 1/1/0, mgr: 10 of 10 available, clientName: 169, IOCP: (Busy=0,Free=1000,Min=2,Max=1000), WORKER: (Busy=0,Free=32767,Min=2,Max=32767), v: 2.2.50.36290",
"stackTrace": [
"at StackExchange.Redis.ConnectionMultiplexer.ThrowFailed[T](TaskCompletionSource`1 source, Exception unthrownException) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2799",
"--- End of stack trace from previous location where exception was thrown ---",
"at <REDACTED-STACK-TRACE>"
"at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
],
"cause": {
"errorType": "RedisConnectionException",
"errorMessage": "UnableToConnect on <REDACTED-PRIMARY-ENDPOINT-NAME>:6379/Interactive, Initializing/NotStarted, last: NONE, origin: BeginConnectAsync, outstanding: 0, last-read: 5s ago, last-write: 5s ago, keep-alive: 60s, state: Connecting, mgr: 10 of 10 available, last-heartbeat: never, global: 5s ago, v: 2.2.50.36290"
}
}
注意:abortConnect=false
设置在Redis配置上
我已经尝试过的东西:
- 将
elasticache:*
操作添加到Lambda权限的Terraform IAM策略中。完整政策:
data "aws_iam_policy_document" "iam_policy_document_mylambda" {
statement {
actions = [
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface",
"ec2:DescribeInstances",
"ec2:AttachNetworkInterface",
"elasticache:*",
"execute-api:ManageConnections"
]
resources = ["*"]
effect = "Allow"
}
}
- 将
resolveDns=true
添加到Redis配置中。Redis集群的IP地址显示在上面的错误中,而不是主要端点名称,我可以确认它在为Lambda配置的其中一个子网(eu-west-1a上的子网(的IP范围内 - 显式添加
ssl=false
,因为Redis集群上已禁用传输中的加密(目前(。还尝试了ssl=true,sslProtocols=tls12
,这在GitHub的一个问题中提到过,只是为了确保 - 删除
abortConnect=false
,则会失败,并出现以下错误:
{
"errorType": "RedisConnectionException",
"errorMessage": "It was not possible to connect to the redis server(s). Error connecting right now. To allow this multiplexer to continue retrying until it's able to connect, use abortConnect=false in your connection string or AbortOnConnectFail=false; in your code.",
"stackTrace": [
"at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(ConfigurationOptions configuration, TextWriter log) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1164",
"at StackExchange.Redis.ConnectionMultiplexer.Connect(ConfigurationOptions configuration, TextWriter log) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 1032",
"at ...",
"at lambda_method(Closure , Stream , Stream , LambdaContextInternal )"
]
}
我对此束手无策,每次网上搜索似乎都指向同一个方向;确保你的Lambda和ElastiCache Redis集群在同一个VPC和安全组中运行,并在Redis配置上设置abortConnect=false
,这对我的情况来说似乎还不够。有人知道我还能尝试什么吗?
我想明白了。问题出在我的基础设施上,而不是StackExchange.RRedis如何连接到集群的问题。我必须为我的Lambda函数创建一个安全组,并将该安全组添加到我的Redis Terraform模块上的allow_connections_from_security_groups
中,该模块依赖于Grunnetwork模块,而不是将Redis安全组分配给我的Lamb达。