Skip to content

4. Redis + Gunicorn


1. Mission

001


  • 이미 번역한 내용이라면 캐시 서버에서 바로 반환


2. Redis

1) Redis 설정

  • Redis는 목적에 맞게 설정한다.


sudo vim /etc/redis/redis.conf
port 6379 (default)
maxmemory 2g
maxmemory-policy allkeys-lru


2) Redis 재시작 및 상태 확인

  • 다음과 같이 Redis를 재시작한다.


sudo systemctl restart redis-server.service


  • 다음과 같이 상태를 확인한다.


sudo systemctl status redis-server.service


  • Could not create server TCP listening socket 127.0.0.1:6379: bind: Address already in use와 같은 메시지가 로그에 찍힌다면 다음과 같이 해결한다.


ps aux | grep redis
redis       42  0.0  0.0  53372  5268 ?        Ssl  11:06   0:00 /usr/bin/redis-server 127.0.0.1:6379
sudo kill -9 42(PID)


  • 다시 재시작한다.


sudo systemctl restart redis-server.service


  • 상태를 확인한다.


sudo systemctl status redis-server.service
redis-server.service - Advanced key-value store
    Loaded: loaded (/usr/lib/systemd/system/redis-server.service, disabled)
    Active: active (running)


3) classifier.py 수정

  • 기존의 classifier.py를 다음과 같이 수정한다.


from flask import Flask, request
import requests
import json
import os
import hashlib
import redis

app = Flask(__name__)

class Classifier:
    def __init__(self):
        self.project_dir = os.path.dirname(os.path.abspath(__file__))
        self.json_name = "access_token.json"
        self.json_path = os.path.join(self.project_dir, self.json_name)
        self.PID = os.getpid()
        print(f"PID: {self.PID} / Loaded Classifier!")

        if not os.path.isfile(self.json_path):
            print(f"PID: {self.PID} / {self.json_path} does not exist!")

        self.load()

    def load(self):
        with open(self.json_path, "r") as json_file:
            self.json_data = json.load(json_file)

        print(f"PID: {self.PID} / JSON file loaded from {self.json_path}")

def request_text(URL: str, body: dict):
    response = requests.post(URL, data=json.dumps(body)).json()

    return response

classifier = Classifier()
access_tokens = classifier.json_data.values()
rd = redis.StrictRedis(host="localhost", port=6379, db=0)

@app.route("/", methods=["POST"])
def main():
    URL = "http://127.0.0.1:9999/predictions/test"
    headers = request.headers
    body = request.get_json(force=True)

    if headers["Authorization"] in access_tokens:
        src_lang = body["src_lang"]
        src_text = body["src_text"]
        tgt_lang = body["tgt_lang"]

        h = hashlib.new("sha256")
        h.update(src_lang.encode("utf-8"))
        h.update(src_text.encode("utf-8"))
        h.update(tgt_lang.encode("utf-8"))
        hashed_key = h.hexdigest()

        check_redis = rd.get(hashed_key)

        if check_redis is not None:
            translated = dict(json.loads(check_redis.decode("utf-8")))["tgt_text"]

            print(f"\nPID: {classifier.PID} \ URL: {URL}\nSrc_Lang: {src_lang} \ Src_text: {src_text}\nTgt_Lang: {tgt_lang} \ Translated: {translated['translated']}\nGet from DB")
        else:
            translated = request_text(URL, body)
            data_dict = {
                    "src_lang": src_lang,
                    "src_text": src_text,
                    "tgt_lang": tgt_lang,
                    "tgt_text": translated
                    }
            dict_value = json.dumps(data_dict, ensure_ascii=False).encode("utf-8")
            rd.set(hashed_key, dict_value)

            print(f"\nPID: {classifier.PID} \ URL: {URL}\nSrc_Lang: {src_lang} \ Src_text: {src_text}\nTgt_Lang: {tgt_lang} \ Translated: {translated['translated']}\nSet to DB")

        return translated
    else:
        return "Access Token Error!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port="80", debug=True)


4) Gunicorn 실행

  • Gunicorn을 실행한다.


$(base) gunicorn


3. 테스트

  • 처음 들어오는 내용은 번역기를 통과해야 하므로 시간이 걸린다.


002


  • 하지만 한 번 들어온 내용은 캐시 서버에서 바로 반환한다.


003