4. Redis + Gunicorn
1. Mission
- 이미 번역한 내용이라면 캐시 서버에서 바로 반환
2. Redis
1) Redis 설정
sudo vim /etc/redis/redis.conf
port 6379 (default)
maxmemory 2g
maxmemory-policy allkeys-lru
2) 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
와 같은 메시지가 로그에 찍힌다면 다음과 같이 해결한다.
redis 42 0.0 0.0 53372 5268 ? Ssl 11:06 0:00 /usr/bin/redis-server 127.0.0.1:6379
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 실행
3. 테스트
- 처음 들어오는 내용은 번역기를 통과해야 하므로 시간이 걸린다.
- 하지만 한 번 들어온 내용은 캐시 서버에서 바로 반환한다.