Elasticache와 AWS Lambda 연결하기 (연결 안되는 에러 해결기)

Lambda 만들기

기본 정보는 위와 같이 작성

역할은 이렇게 주었는데 해당 역할에는

이렇게 정책이 지정되어 있다.

추가 구성에서 VPC 활성화 체크를 하고

Elasticache가 위치할 곳의 서브넷을 선택한다.

 

보안그룹의 경우 별도의 설정없이 인바운드 규칙 X, 아웃바운드 규칙 모두 허용 상태로 지정했다.

 

Elasticache 만들기

이번엔 Elasticache를 만들어 보겠다.

Redis OSS캐시를 사용했고 클러스터 모드를 활성화한 캐시로 사용했다.

아까 람다가 위치한 곳과 같은 서브넷으로 서브넷 그룹을 생성하였다.

그외에 설정은 그냥 기본 상태로 설정

 

Lambda 코드 작성하기

우선 레디스 연결 테스트를 위해 다음과 같은 코드를 작성해서 테스트 해보았다.

import redis
from redis.cluster import RedisCluster

redis_host = {endpoint}
redis_port = 6379 

def get_redis_client():
  # RedisCluster 클라이언트로 연결
  redis_client = RedisCluster(
    host=redis_host,
    port=redis_port,
    ssl=True, 
    decode_responses=True,
  )
  return redis_client

def lambda_handler(event, context):
  print("Lambda 실행 - Redis 연결 및 쿠폰 발급 처리 시작")
  redis_client = get_redis_client()

 

참고로 import 할 redis 패키지를 같이 업로드 해주어야 한다.

근데 에러가남

No module named 'distutils' 에러

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'distutils'
Traceback (most recent call last):

 

distutils이 대체 뭐시란 말이냐...

필요한 모듈들 모두 포함시켜서 업로드 했는데도 정체를 알 수 없는 에러가 계속 발생했다.

안해본짓이 없는거 같음

 

가상환경 만들어서 zip으로 업로드하기

reids, reidscluster 버전 다르게 해서 업로드하기

등등

 

아무튼 결론은 람다의 파이썬 버전을 조정하니까 해결됐다;;

 

디폴트 값으로 생성하면 파이썬 3.13을 사용하는데

3.10으로 변경하니 멀쩡히 잘 연결됐다.

파이썬이 주 언어가 아니다보니 버전별 차이를 잘 모르겠어서 일어난 일인거 같다.

 

3.10으로 버전을 낮추면 impor문도 수정해주어야한다.

from rediscluster import RedisCluster

 

 

근데 이번엔 새로운 에러가 나왔다.

'config get cluster-require-full-coverage' command to redis server 에러

[ERROR] RedisClusterException: ERROR sending 'config get cluster-require-full-coverage' command to redis server: {'host': 'prod-elasticache-cluster-0001-001.prod-elasticache-cluster.lbkn6z.apn2.cache.amazonaws.com', 'port': 6379, 'name': 'prod-elasticache-cluster-0001-001.prod-elasticache-cluster.lbkn6z.apn2.cache.amazonaws.com:6379', 'server_type': 'master'}
Traceback (most recent call last):
  File "/var/task/lambda_function.py", line 18, in lambda_handler
    redis_client = get_redis_client()
  File "/var/task/lambda_function.py", line 9, in get_redis_client
    redis_client = RedisCluster(
  File "/var/task/rediscluster/client.py", line 368, in __init__
    pool = connection_pool_cls(
  File "/var/task/rediscluster/connection.py", line 160, in __init__
    self.nodes.initialize()
  File "/var/task/rediscluster/nodemanager.py", line 288, in initialize
    need_full_slots_coverage = self.cluster_require_full_coverage(nodes_cache)
  File "/var/task/rediscluster/nodemanager.py", line 378, in cluster_require_full_coverage
    return any(node_require_full_coverage(node) for node in nodes.values())
  File "/var/task/rediscluster/nodemanager.py", line 378, in <genexpr>
    return any(node_require_full_coverage(node) for node in nodes.values())
  File "/var/task/rediscluster/nodemanager.py", line 375, in node_require_full_coverage
    raise RedisClusterException("ERROR sending 'config get cluster-require-full-coverage' command to redis server: {0}".format(node))

다행스럽게도 이 에러의 경우 검색하니 해결법이 많이 나왔다.

아래 글을 참고하여 파이썬 코드를 수정했다.

https://github.com/Grokzen/redis-py-cluster/issues/303

 

ERROR sending 'config get cluster-require-full-coverage · Issue #303 · Grokzen/redis-py-cluster

Hi @Grokzen, I am currently seeing many occurences of ERROR sending 'config get cluster-require-full-coverage while starting an application which used this redis-py-cluster driver. When checked her...

github.com

레디스 클라이언트를 연결할때

skip_full_coverage_check=True

이 옵션을 추가해주면 된다.

def get_redis_client():
    # RedisCluster 클라이언트로 연결
    redis_client = RedisCluster(
        host=redis_host,
        port=redis_port,
        ssl=True,  # TLS 연결 활성화
        skip_full_coverage_check=True
    )
    return redis_client

기본적으로 Redis Cluster는 “전체 슬롯(0~16383)“을 커버해야 정상 작동하는데 이걸 트루로 하면 

클러스터의 일부노드만 연결된 상태에서도 연결이 가능하게 해준다는거 같다.

 

3일동안 고생한 에러들인데 막상 적으니 굉장히 적어졌다..

아무튼 이제 람다에서 엘라스틱캐시에 접근이 매우 잘된다!