为什么我的lambda无法与Elasticache说话?

时间:2018-08-28 16:00:49

标签: amazon-web-services redis .net-core aws-lambda stackexchange.redis

我有一个Redis ElastiCache集群,该集群的主节点的FQDN格式为master.clustername.x.euw1.cache.amazonaws.com。我也有一个Route53记录,其中CNAME指向该FQDN。

我在与群集相同的VPC中具有.net核心lambda,可以通过安全组访问群集。 Lambda使用由Stack Overflow(Github repo here for reference)开发的Redis库与集群进行对话。

如果我给lambda主机名作为Redis集群(以master开头的集群)的FQDN,则可以连接,保存数据并读取它。

如果我给Lambda提供了CNAME(并且当我从本地计算机ping CNAME时,该CNAME提供了与FQDN相同的IP地址,并且如果我在Lambda中使用了Dns.GetHostEntry),它也不会连接并且我收到以下错误消息:

One or more errors occurred. (It was not possible to connect to the redis server(s); to create a disconnected multiplexer, disable AbortOnConnectFail. SocketFailure on PING): AggregateException
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at lambda_method(Closure , Stream , Stream , LambdaContextInternal )

at StackExchange.Redis.ConnectionMultiplexer.ConnectImpl(Func`1 multiplexerFactory, TextWriter log) in c:\code\StackExchange.Redis\StackExchange.Redis\StackExchange\Redis\ConnectionMultiplexer.cs:line 890
at lambda.Redis.RedisClientBuilder.Build(String redisHost, String redisPort, Int32 redisDbId) in C:\BuildAgent\work\91d24911506461d0\src\Lambda\Redis\RedisClientBuilder.cs:line 9
at lambda.Ioc.ServiceBuilder.GetRedisClient() in C:\BuildAgent\work\91d24911506461d0\src\Lambda\IoC\ServiceBuilder.cs:line 18
at lambda.Ioc.ServiceBuilder.GetServices() in C:\BuildAgent\work\91d24911506461d0\src\Lambda\IoC\ServiceBuilder.cs:line 11
at Handlers.OrderHandler.Run(SNSEvent request, ILambdaContext context) in C:\BuildAgent\work\91d24911506461d0\src\Lambda\Handlers\OrderHandler.cs:line 26

有人看见过类似的东西吗?

2 个答案:

答案 0 :(得分:0)

可能的解决方法是将问题与客户端库隔离开来-按照AWS' tutorial并将Lambda重写为类似于下面的代码(例如Python)。

from __future__ import print_function
import time
import uuid
import sys
import socket
import elasticache_auto_discovery
from pymemcache.client.hash import HashClient

#elasticache settings
elasticache_config_endpoint = "your-elasticache-cluster-endpoint:port"
nodes = elasticache_auto_discovery.discover(elasticache_config_endpoint)
nodes = map(lambda x: (x[1], int(x[2])), nodes)
memcache_client = HashClient(nodes)

def handler(event, context):
    """
    This function puts into memcache and get from it.
    Memcache is hosted using elasticache
    """

    #Create a random UUID... this will the sample element we add to the cache.
    uuid_inserted = uuid.uuid4().hex
    #Put the UUID to the cache.
    memcache_client.set('uuid', uuid_inserted)
    #Get item (UUID) from the cache.
    uuid_obtained = memcache_client.get('uuid')
    if uuid_obtained.decode("utf-8") == uuid_inserted:
        # this print should go to the CloudWatch Logs and Lambda console.
        print ("Success: Fetched value %s from memcache" %(uuid_inserted))
    else:
        raise Exception("Value is not the same as we put :(. Expected %s got %s" %(uuid_inserted, uuid_obtained))

    return "Fetched value from memcache: " + uuid_obtained.decode("utf-8")

参考:https://docs.aws.amazon.com/lambda/latest/dg/vpc-ec-deployment-pkg.html

答案 1 :(得分:0)

事实证明,由于我在Elasticache群集上使用SSL证书,并且SSL证书已绑定到master.端点,而我试图连接到CNAME,因此证书验证失败。

所以我最终在代码中查询Route53记录以获取master端点,并且它起作用了。