프로그래밍 114

[쿠버네티스] 2. 쿠버네티스로 배포하기

이제 쿠버네티스를 사용해서 배포해보자. 일단 배포하기 위한 도커 이미지가 있어야 한다. 간단하게 하나 만들어보자. 도커 이미지 생성 # main.py from fastapi import FastAPI import uvicorn app = FastAPI() @app.get("/") async def root(): return {"message": "Hello World"} if __name__ == "__main__": uvicorn.run(app, port=8000, host="0.0.0.0") # Dockerfile FROM python:3.11 WORKDIR /app COPY . . RUN pip install -r requirements.txt EXPOSE 8000 CMD ["python", "ma..

[쿠버네티스] 1. 쿠버네티스 시작하기

쿠버네티스 쿠버네티스는 컨테이너환경으로 배포할 때 자동으로 관리해주는 컨테이너 오케스트레이션 도구이다. 여기에서 컨테이너는 도커에서 사용하는 그 컨테이너를 의미한다. 컨테이너는 도커만 있는것이 아니기 때문에 다른 도구에도 활용할 수 있다. 쿠버네티스의 편리한 점은 컨테이너가 어떠한 이유로 종료되면 자동으로 복구해주고, 트래픽이 많아지면 오토스케일링도 해주고, 현재 컨테이너들의 상태를 보여주는 대시보드도 보여주는 등 다양한 기능을 제공하기 때문이다. 배포할 때 일일히 사람이 확인해야 하는 작업을 자동으로 해준다. 쿠버네티스 설치하기 학습용으로 쿠버네티스를 사용할때 미니큐브를 자주 사용하곤 한다. 그래서 미니큐브를 사용할 예정이다. (2코어 이상의 cpu가 필요하다.) curl -Lo minikube htt..

[개발] 샤딩이란 것을 해보자! (3)

샤딩 1 샤딩 2 조건이 포함된 조회 쿼리 특정 이름이 들어간 유저를 찾고싶다고 하자. # datasource.py class DataSource: ... def select_by_name_exact(self, name): ix = insert_route(name) query = f"SELECT * FROM user WHERE name = '{name}'" cursor = self.cursors[ix] cursor.execute(query) result = cursor.fetchall() return result 삽입과 유사하게 사용하면 된다. 범위 조건이 포함된 조회 쿼리 이제 살짝 복잡해지기 시작한다. aa ~ bb를 찾는다고하면 1번 인스턴스에서 끝나지만 aa ~ zz를 찾는다면 1~4번 인스턴스를..

[개발] 샤딩이란 것을 해보자! (2)

지난시간에 이어 샤딩을 사용해보자. 라우터 생성 우리는 이름을 기준으로 라우팅을 할 것이다. 영어 소문자만 들어온다고 가정하자. 데이터베이스가 4개이니까 a~g로 시작하는건 1번, h~n은 2번, o~u는 3번, v~z는 4번 데이터베이스에 넣도록 하자. # router.py def insert_route(name: str): assert len(name) > 0 ch = name[0] return (ord(ch) - ord('a')) // 7 정말 간단하다. 위 라우터는 삽입할 때 사용하는 라우터이다. 삽입쿼리 추가 # datasource.py from router import insert_route class DataSource: ... def insert(self, name: str, age: in..

[개발] 샤딩이란 것을 해보자! (1)

데이터베이스 샤딩(Sharding)이란 동일한 스키마의 데이터베이스를 여러 인스턴스에 나누어 저장하는 것을 말한다. 이중화와는 다른 개념이다. 이중화는 하나의 데이터를 여러 곳에 저장하지만 샤딩은 하나의 데이터를 하나의 인스턴스에 골라서 저장을 한다. 보통은 잘 사용하지 않고 데이터가 억수로 많은 경우에 사용한다. 샤딩을 사용하면 데이터가 많은 경우에 단일 인스턴스보다 성능이 빨라지고 단일 인스턴스에 저장할 수 없는 만큼의 데이터를 가지고 있다면 샤딩을 사용해야만 할 것이다. 샤딩에는 여러 종류가 있지만 여기에서는 Range Sharding이란 것을 사용해 볼 예정이다. Range Sharding 유저테이블을 샤딩한다고 생각하자. 인스턴스를 4개(개발자가 정하면 된다.) 두고 1~3월 생일은 1번, 4~..

[알고리즘] smaller to larger를 사용해서 분리집합을 구현하자!

이 글에는 지극히 주관적인 내용이 많이 들어있습니다. 분리집합을 구현할 때 보통 가리키는 포인터를 옮기는 방식으로 구현하곤 한다. 하지만 이런 방법은 경로압축도 해야 하고 개인적으로 비직관적이었다. 사실 나는 재귀적인 코드와 작동 과정이 아직 완벽히 이해가 되지 않는다. 그래서 상대적으로 직관적인 smaller to larger(a.k.a 작은거 큰거)를 사용한 분리집합 구현을 소개하고자 한다. (물론 기존 방식보다 느리고 공간도 많이 사용한다.) smaller to larger라는게 애초에 집합을 합치기 위한 연산을 최적화하기 위한 기법이기 때문에 분리집합에도 사용할 수 있다. 기초적인 구조 class DisjointSet { public: vector p; vector ix; int n; } 우선 멤..

[알고리즘] Mo's 알고리즘

Mo's 알고리즘은 중국 알고리즘 대회에서 Mo Tao라는 사람이 사용한 기법으로 유명해졌다. 그래서 컴퓨터공학 다른 곳에서는 찾기 힘든 알고리즘이고 Competitive Programming에서 볼 수 있는 알고리즘이다. 어떤 알고리즘인지 알아보자. 오프라인 쿼리 mo's 알고리즘을 알기 위해 오프라인 쿼리를 알아야 한다. 무방향 가중 그래프가 주어지고 쿼리마다 a, b를 연결하는 간선을 끊고 u, v번 노드가 서로 연결돼 있는지 판정하시오. 위와 같은 문제는 주어지는 쿼리마다 해결하려고 하면 굉장히 어렵다. 하지만 간선을 연결하는 문제라면 분리집합으로 쉽게 해결할 수 있다. 그래서 처음에 쿼리를 모두 저장하고 뒤에서부터 역순으로 쿼리를 수행하면 쉬울 것이다. 이런식으로 여러 개의 쿼리를 주어진 순서대..

[알고리즘] 제곱근 분할법 (Sqrt decomposition)

Q : N개의 정수 배열에서 a~b까지 합을 구하려면 어떻게 하나요? A : for문을 돌면서 더해요! $O(N)$ Q : 그럼 Q개의 쿼리형식으로 들어온다면요? A : 누적합배열을 사용해요! $O(N+Q)$ Q : 그럼 여기에 업데이트도 있다면 있다면 어떻게 할까요? A : 세그먼트 트리를 쓰면 되죠! $O(Q \log N)$ 위의 모든 답변은 실제로 정답이고 더 어려운 알고리즘이 하위 문제를 해결할 수 있다. 예를들어 누적합으로 1번 문제를 해결할 수 있고 세그먼트 트리로 1, 2번 문제를 해결할 수 있다. 하지만 위 문제들을 제곱근 분할법(a.k.a. 루트질)을 사용해서 해결할 수도 있다! 물론 쉬운 알고리즘을 사용할 수 있다면 그걸 사용하는게 좋겠지만 연습용으로 풀기 좋다. 어떻게 해결할 지 알아..

[개발] nginx에서 https 적용하기

지난시간 nginx설정한 도메인으로 들어가보면 http연결이라고 뜨면서 주의요함이라는 메시지를 받는다. https연결을 사용하지 않았기 때문이다. 그리고 mixed content문제라고 해서 프론트 접속할 때 https를 쓰고 백엔드 접속할 때 http를 사용하면 불러오지 못하는 문제가 생긴다. 특히 기본 https를 제공하는 gh-pages랑 http로 설정한 백엔드로 접속하려고 할 때 의문도 모른채 생기는 오류를 접할 수 있다. 그래서 요즘은 모두 https를 사용하는게 좋다. nginx에서 https를 적용하는 법을 알아보자. nginx 파일 # /etc/nginx/sites-available/aaa.riroan.com server { listen 80; server_name aaa.riroan.c..

[개발] Nginx에서 여러 도메인 적용하기

최근 진행하는 프로젝트가 꽤 많아져서 배포를 위해 인스턴스 한대를 혹사시키고 있다. Oracle Cloud에 있는 인스턴스 한 대에 백엔드서버 3개와 프론트엔드 페이지를 2개 배포중이다. 그러다보니 서로 다른 프로젝트의 도메인들이 같은 서버를 가리키고 있다. 현재, aaa.riroan.com, bbb.riroan.com이 하나의 서버 ip를 가리키고 있는 상태이다. 이를 위한 nginx 설정이 필요했다. riroan1.com, riroan2.com같이 도메인이 통채로 다른 경우도 가능하고 aaa.riroan.com, bbb.riroan.com처럼 접두어(prefix)만 다른 경우도 가능하다. (어떻게 생각해보면 당연하다.) 파일 작성 기본적으로 nginx설정을 하기 위해 /etc/nginx/sites-a..