AWS/실습 기록

AWS ElastiCache Redis 생성 및 Python 연동 방법 알아보기(feat. Pycharm)

daeunnniii 2021. 9. 24. 02:26
728x90
반응형

1. ElastiCache Redis 란?

ElastiCache는 클라우드에서 인메모리 데이터 스토어 또는 캐시를 손쉽게 배포, 운영 및 확장할 수 있게 해주는 웹 서비스이다. ElastiCache는 클러스터 엔진으로 Memcached와 Redis를 지원한다.

Redis는 인메모리 DB이다. RDBMS가 파일에 데이터를 저장하는 것에 비해 인메모리 DB는 메모리에 데이터를 저장하기 때문에 RDBMS에 비해 속도가 빠르다. RDBMS의 부하를 덜어주기 위해 Redis를 많이 사용한다. Redis는 String, Hash, List, Set, Sorted Set 등 다양한 데이터 형식을 제공하는 키-값(Key-Value) 데이터 저장소라고 할 수 있다.

 

2. Memcached와 Redis 비교

Memcached를 선택하는 경우

상대적으로 작고 정적인 데이터를 캐싱하는 경우

여러 코어 또는 스레드가 있는 멀티 스레드의 경우

메모리 관리가 redis만큼 정교하지는 않지만, 메타 데이터에 대한 메모리 리소스를 비교적 적게 소비하여 간단한 사용에 적합하다.

쉽게 확장할 수 있지만 해싱 사용 여부에 따라 캐시된 데이터의 일부 또는 전부를 잃는다.

Redis를 선택하는 경우

문자열, 해시, 목록, 세트, 정렬된 세트 및 비트맵과 같은 복잡한 데이터 유형이 필요한 경우

인 메모리 데이터 세트를 정렬하거나 순위를 지정해야 하는 경우

키 저장소의 속성을 원할 경우

읽기 집약적 애플리케이션을 위해 기본 항목에서 하나 이상의 읽기 전용 복제본으로 데이터를 복제해야 하는 경우

기본 노드가 실패할 때 자동 장애 조치가 필요한 경우

서버에 대한 이벤트를 클라이언트에 알리기 위해 게시 및 구독(게시/구독) 기능이 필요한 경우

백업 및 복원 기능이 필요한 경우

여러 데이터베이스를 지원해야 하는 경우

 

 

 

3. AWS ElastiCache Redis 생성

다른 서비스들은 생성할 때 보안 그룹을 같이 생성할 수 있는 반면에, ElastiCache는 생성하기 전에 먼저 보안 그룹을 생성해주어야한다. 먼저 VPC로 들어가서 아래와 같이 보안그룹을 생성해준다.

 

이제 ElastiCache로 가서 클러스터 생성을 클릭한다.

 

 

클러스터 엔진은 Redis를 선택하고, 위치는 Amazon 클라우드를 선택했다. 실제 운영 환경에서는 클러스터 모드 활성화까지 체크해주면 좋을 것이다.

노드 유형은 프리티어 스팩인 t2.micro를 선택한다. 다른 것으로 선택하면 요금이 발생할 수 있다.

복제본 개수는 0으로 조절하지 않도록 설정했다.

 

보안그룹은 위에서 생성했던 보안그룹으로 선택한다.

나머지 설정은 그대로 두어도 되고, 추가적으로 원하는 설정사항을 반영하여 "생성" 버튼을 클릭한다.

 

4. AWS ElastiCache Redis과 Python 연동

RDS와 달리 ElastiCache는 외부에서 접속이 되지 않도록 되어있다. 따라서 배포를 해서 같은 VPC 내의 인스턴스에서 확인해보아야한다. 내 컴퓨터에서는 접속할 수 없기 때문에 꼭 AWS 에 배포해서 정상작동을 테스트 해보아야 한다!

1) 백엔드 연동

테스트 코드는 다음과 같다. 라이브러리의 경우 터미널에 pip freeze > requirements.txt를 입력해서 추가해준다. 그리고 이전 게시글에서 EB에 MySQL 환경 변수를 추가해주는 것과 같은 방법으로 REDIS_HOST 환경변수도 추가해준다. (이전 게시글 환경변수 참고: https://daeunnniii.tistory.com/144)

import boto3
from flask import Flask, render_template, request, jsonify
from flask_cors import CORS
import os
from flaskext.mysql import MySQL
import redis

application = Flask(__name__)

# cors
cors = CORS(application, resources={r"/*": {"origins": "*"}})

# mysql
mysql = MySQL()
application.config['MYSQL_DATABASE_USER'] = os.environ["MYSQL_DATABASE_USER"]
application.config['MYSQL_DATABASE_PASSWORD'] = os.environ["MYSQL_DATABASE_PASSWORD"]
application.config['MYSQL_DATABASE_DB'] = os.environ["MYSQL_DATABASE_DB"]
application.config['MYSQL_DATABASE_HOST'] = os.environ["MYSQL_DATABASE_HOST"]
mysql.init_app(application)

# redis
db = redis.Redis(os.environ["REDIS_HOST"], decode_responses=True)


@application.route('/')
def main():
    return "핵심 쏙쏙 AWS"

@application.route('/fileupload', methods=['POST'])
def file_upload():
    file = request.files['file']
    s3 = boto3.client('s3',
                      aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
                      aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"]
                      )
    s3.put_object(
        ACL="public-read",
        Bucket=os.environ["BUCKET_NAME"],
        Body=file,
        Key=file.filename,
        ContentType=file.content_type
    )

    conn = mysql.connect()
    cursor = conn.cursor()
    cursor.execute("insert into file(file_name) value('" + file.filename + "')")
    conn.commit()


    cursor.execute("SELECT count(*) from file")
    data = cursor.fetchone()
    conn.close()
    db.set("fileCount", data[0])

    return jsonify({'result': 'success'})

@application.route('/files', methods=['GET'])
def files():
    conn = mysql.connect()
    cursor = conn.cursor()
    cursor.execute("SELECT file_name from file")
    data = cursor.fetchall()
    conn.close()

    return jsonify({'result': 'success', 'files':data})

@application.route('/file/count', methods=['GET'])
def file_count():
    return jsonify({'result': 'success', 'count':db.get("fileCount")})

if __name__ == '__main__':
    application.debug = True
    application.run()

 

2) 프론트 연동

{EB URL}에는 ElasticBeanstalk에 들어가서 엔드포인트 주소를 복사해서 넣는다. 아래 화면에서 url을 복사해서 넣으면 된다.

 

<!---------- 생략 ------------>
    <script>
        $(document).ready(function(){
            getCount();
            getFiles();
        })

        function save() {
            var form_data = new FormData($('#upload-file')[0]);
            $.ajax({
                type: 'POST',
                url: '{EB URL}/fileupload',
                data: form_data,
                processData: false,
                contentType: false,
                success: function (data) {
                    alert("파일이 업로드 되었습니다!!");
                    location.reload();
                },
            });
        }

        function getFiles() {
            $.ajax({
                type: 'GET',
                url: '{EB URL}/files',
                success: function (data) {
                    for(let i = 0 ; i < data['files'].length ; i++){
                        makeCard(data['files'][i]);
                    }
                },
            });
        }

        function makeCard(data){
            let card = ` <div class="card">
                                <div>
                                    <img class="card-img-top"
                                         src="http://djocwjyh5wkd4.cloudfront.net/${data}"
                                         alt="Card image cap">
                                    <p class="card-text comment">${data}</p>
                                </div>
                            </div>`;
            $("#cards-box").append(card);
        }

        function getCount() {
            $.ajax({
                type: 'GET',
                url: '{EB URL}/file/count',
                success: function (data) {
                    $("#count").html(data.count);
                },
            });
        }
    </script>
<!---------- 생략 ------------>

 

이제 AWS Cloudfront 도메인 네임을 브라우저에서 호출해서 잘 연동이 되었는지 확인해보면 된다!

 

 

 

 

 

 

참고: https://docs.aws.amazon.com/ko_kr/AmazonElastiCache/latest/mem-ug/SelectEngine.html
스파르타코딩클럽 핵심 쏙쏙 AWS

728x90
반응형