왜 이렇게 안 쓸까?
방학에 만들었던 iOS 앱도 기간 내에 딱 맞춰서 작동될 정도로 만들었는데 배포를 안 하고 있고
공부한 거나 궁금한 건 많은데 정리를 안 하고 있고..
반성 좀 하자.
아무튼 요즘 나는 4학년 1학기를 보내며 취업을 준비하는 대학생 겸 취준생인 상태이다.
근데 문제는 프론트엔드로 취업 준비를 해야 하는데 다른 것에 관심을 갖고 있다.
예전에는 보이는 게 재밌어서 Figma를 배우고 프론트엔드에서도 더 나은 animation / transition을 고민했다면
요즘은 서버나 DB 쪽에 관심을 갖게 되었다.
그 이유는 간단한 프로젝트나 서비스를 만들 때, 서버나 DB는 그저 테이블을 만들고, API를 만드는 수준이라고 생각했었지만
"대규모"라는 단어가 들어가는 순간 고민을 해야 할 것들이 확 늘어나기 때문이다.
이런 고민과 답을 얻는 과정이 너무 재밌는데 4학년 1학기라서 너무 부담을 느끼고 있다.
지금까지 해온 게 프론트엔드인데, 프론트엔드 공부를 더 해도 모자랄 판에 다른 것에 관심을 갖고 있으니까
그렇지만 컴퓨터과학부를 졸업하는 학생인 만큼 조금 더 CS적인 지식도 쌓고 싶고,
4학년 1학기는 아직 지원서 받는 곳도 별로 없는데 너무 조급 한 건 아닌가 싶기도 하고(작년에 여자친구가 취업을 해서 조급하기는 하다.)
이래저래 고민이 많은 하루하루를 보내고 있다.
위에 적었듯, 요즘 나는 고민과 의문을 품는 것에 재미를 느끼고 있다.
특히 주변인과의 대화에서 계속적으로 의문을 자아내는데, 이 방식의 문제는 다양한 주제를 이끌어내기가 어렵고 답을 알지 못하고 있는 경우도 허다하다.
근데 마침 github Home에 대학교 선배님의 블로그가 떠서 별생각 없이 구경하러 들어갔다.
Unknownpgr's Blog
Hi, I'm Unknownpgr, A software engineer who loves to build things. and working as a tech lead at The Form. I'm interested in web development, embedded systems, and machine learning. Click here to learn more about me. Scroll down to see my posts. This blog
unknownpgr.com
예전부터 블로그를 운영하셨고, 다양한 경험과 깊이 있는 지식 및 생각이 정리되어 있는 것을 보고 존경심을 느끼게 되었고 자극을 받게 되었다.
작년에 SW Maestro 연수생 때 기회가 되어 만나 뵈었고 대화를 나눈 경험이 있는데
그때 느꼈던 감정이 아직까지도 선명히 남아있다.
진짜 천재라고 느껴졌기 때문이다.
그래서 나는 이 선배님의 어깨까지는 아니어도 무릎정도에 올라타보려고 한다.(몰래)
가장 과거에 작성하신 글부터 하나씩 정독해 가며 나의 세계를 확장해보고자 한다.
----
평소에 Docker에 대해 컨테이너나 이미지 등 듣긴 들었지만 사실 정확한 개념까지는 잘 이해를 못하고 있었다.
오늘 알게된 것을 간단하게만 적자면
"컨테이너는 종료되면 내부 데이터가 전부 날라간다. 따라서 외부 디렉토리를 마운트하여 사용해야 한다."
이걸 알고나니 첫번째로는 어제 수업을 같이 듣던 누나가 "컨테이너 안에서 생성한 데이터가 저장이 되지 않을 수도 있다"라는 말이 떠올랐고
오늘 홈서버에 도커를 띄운 A형한테 "형 지금 컨테이너 띄운거는 로컬에 마운트 한거야?"를 묻기도 했고
B형으로부터 "Stateful한건 컨테이너에 띄우면 안된다"라는 것을 듣기도 했다.
그래서 일단 Stateful과 Stateless를 알기 위해 inpa님의 블로그를 정독했다.
🌐 아주 쉽게 이해하는 Stateful / Stateless 차이
Stateful 과 Stateless 차이점 웹 공부를 하다보면 클라이언트(Client)와 서버(Server)간의 통신을 상태유지(Stateful) 하느냐, 상태유지하지않음(Stateless) 으로 하느냐 라는 말귀를 한번쯤은 들어본 적이 있
inpa.tistory.com
Stateful: 서버가 클라이언트 상태를 기억한다.
Stateless: 서버가 클라이언트 상태를 보존하지 않는다 -> 클라이언트에게 책임을 떠맡긴다.
Stateful한 프로토콜로는 TCP의 3-way handshaking이 있고 그 이유는 클라이언트와 서버간의 요청과 응답이 이루어질때마다 상태가 SYN-SENT, Established 등 변경되기 때문이다.
그러면 Stateful의 장점은 무엇인가? 클라이언트가 서버에게 요청을 할 때 데이터의 용량이 적어지는 것도 있고(서버가 기억하고 있으니)...
또 어떤게 있을진 모르겠다.
그래서 GPT한테 물어보니 SessionID를 받으니 Token기반 인증보다 간단한 식별자이고 매 요청마다 재검증할 필요가 없다 정도일 것 같다.
근데 이게 보안쪽으로는 결국 SessionID나, Token이나 클라이언트가 서버한테 보내야 하는건데 그러면 보안쪽으로는 관련이 없나?라고 생각이 들어서 아래와 같이 질문했다.
이거 자체는 관련이 없나보다.
그냥 요청할 때 데이터의 양이 줄어든다 정도의 이점을 누릴 수 있는 것 같다.
그러면 단점으로는 뭐가 있을까?
서버를 하나만 쓰는 간단한 프로젝트라면 상상할 필요도 없겠지만
만약에 여러개를 쓴다면? 서버간에는 상태를 공유하고 있지 않으니까
사용자 상태를 기억하는 A서버가 죽어버리면 B서버가 대응할텐데 사용자를 모르니 다시 로그인을 해야한다는 경우가 생긴다.
근데 블로그 작성자분이 다음과 같이 남겼는데
따라서 현업에서는 이러한 클라이언트의 상태 데이터를 따로 캐시 서버(Redis)에 저장하여 이용한다.
아 이걸 보고 왜 Redis라고 하는지 알 것 같다. 근데 얘도 죽으면 끝아닌가? 그러면 Redis는 단일로 두는게 아니라 무조건 2개 이상을 사용하는건가? 이런 궁금증이 생겼고
보통 서비스는 Redis 복제로, Redis Master가 중단되면 Replica가 자동으로 Master로 변경되며
[Redis Master] ─── 복제 ───▶ [Redis Replica(slave)]
이밖에도 Redis Node를 여러개 배치하는 방식인 Redis 클러스터 방식이나
Redis Sentinel 방식도 있다고 한다.
이 부분은 Docker를 배우는 것에서 너무 멀리 왔으니 여기까지만 일단은 알아둘 것이다.
그러면 반대로 Stateless는 뭘까?
먼저 Stateless 프로토콜로는 UDP나 HTTP가 있다.
데이터를 전송할 때마다 연결하고 바로 끊는 방식이다.
따라서 요청할 때마다 사용자는 "나 방금 걔였어요"를 하더라도 서버는 "걔가 누군데?"가 되어버리니까
사용자는 "나는 누구고 무엇을 하고싶고 ~~"라는 모든 정보를 넘겨야 한다.
그러면 이 방식은 요청마다 많은 값을 보내야하니 되게 복잡하고 비효율적인 것 같단 생각이 든다.
하지만 서버가 고장나거나 트래픽이 몰려서 늘려야하는 경우에도 문제없이 작동할 수 있다.
그럼 로그인같은걸 서버가 기억을 못한다면 어떻게 구현할 수 있을까?
그래서 stateless 특징을 유지하면서 로그인 상태 유지도 가능하게 하는 기술이 JWT라고 한다.
(요즘따라 JWT에도 궁금한게 많았는데 이렇게 하나 더 알게 되었다. 나중에 세션인증, 토큰인증도 다뤄볼 생각이다.)
일단은 딱 여기까지만 공부했다.
다시 돌아와서,
B형이 말한 Stateful한건 컨테이너에 저장하면 안된다라는 말을 이해할 수 있다.
컨테이너 종료 시 내부 데이터가 날라가는데 Stateful한건 상태를 저장해야하니까 적절하지 않은 것이다.
그리고 나서 내가 했던 질문은 "그러면 실제 서비스에서는 여러 컨테이너를 띄울텐데, 하나의 DB를 공유하나?" 였고
답으로 "첨엔 그렇게 했다가 요즘엔 레플리카나 파티셔닝을 한다"고 했다.
그래서 다음으로는 이 글을 봤다.
글의 시작은 스타트업에 적합한 인프라는 무엇일까?이고 간단한 서비스 아키텍처도 나타난다.
여기선 간단한 서비스 아키텍처 LB 2개, API Server 2개, DBMS Primary, DBMS Replica로 구성된다는 것을 배웠다.
이정도 구성이면 어느정도의 장애를 대응할 수 있다고 적혀있다.
그리고 서비스 인프라는 모니터링이 중요하다고 하는데 여기서 프로메테우스, 그라파나, 클라우드워치, 데이터 독, 센트리 등 자주 들어보던 용어를 접하게 되었다. 이부분도 공부해서 지금 진행하는 OpenAloc에 적용해보고 싶다는 생각이 들었다.
다시 돌아와서, 지금 알고자 하는건 레플리카에 대한 지식이다.
DBMS가 장애가 났을 때 데이터를 한곳에서만 관리했다면 모두 날라갔을 것이다.
그래서 Primary 내용을 Replica에 복제하는 작업이 필요하며, 이는 Redis 복제와 비슷한 것 같다. 데이터를 다루는 방식은 이게 기본인가 보다.
Primary에 문제가 생겨 Replica로 바뀌는걸 Failover(페일오버)라고 한다는 것도 알게 됐다.
(추가적으로 대부분 서비스는 Read가 80% 이고 Write은 아무리 많아도 50%를 안넘어간다고도 했는데 이런 정보도 더 자세하게 알고있다면 추후에 서비스를 운영할 때 확실히 도움이 될 것이라고 생각한다. 아니 그전에 나는 왜 이런생각을 못했을까? 그동안 AWS EC2로 서버띄우고 DB연결하고 좋다~정도로 끝냈는데, 이게 얼마만큼의 트래픽을 감당하는지 그런거도 궁금함을 못느끼고 말이야. 세상은 똑똑한 사람들이 이끌어 간다는게 어떤 느낌인지 와닿았다.)
또한, 데이터를 분리하는 방식은 수직 분리, 수평 분리가 있는데 수직 분리는 테이블을 Column단위로 쪼개는거다. 많이 쓰는 컬럼만 모아서 테이블을 만들면 접근속도가 빨라진다고 한다.
수평 분리는 스키마는 똑같은데 특정 key를 기준으로 분리한다고 한다.
그리고 샤딩(Sharding)은 이러한 수평 분리를 말한다.
샤딩은 데이터를 여러 조각으로 나눈다고 하는데, 왜 나누는걸까?
그러면 특정 데이터와 키를 편하게 찾을 수 있기 때문이라고 한다. 예를들면 김씨 성을 가진 사람들끼리 나누고, 이씨 성을 가진 사람들끼리 나누어 저장한다면 찾을 때 모든 DB를 다 찾을 필요가 없으니 더 빠르게 찾을 수 있다.
아무튼 이 부분도 딱 여기까지만 공부하자.
(아 그리고 구름 블로그에서 온프레미스라는 단어가 있어서 이것도 GPT한테 물어봤는데 사실은 On-Premise가 아니라 On-Premises라고 한다. 발음도 온프레미시즈가 된다는데 이건 이미 개발자사이에서 굳어진 것 같으니 넘어가자.)
다시 돌아와서 "첨엔 그렇게 했다가 요즘엔 레플리카나 파티셔닝을 한다"는 말도 이해가 간다.
하나의 DB만을 쓰면 상태가 날라갈 수 있기 때문에 레플리카를 통해 안정성을 확보하고
성능을 위해 파티셔닝을 사용한다.
이것도 역시 대규모적인 생각을 하면 이렇게 되는게 맞다는 생각도 들고, "누가 이런 생각을 했을까?"라는 의문도 생긴다. 누군진 몰라도 대단하시다.
자 다시 한번더 돌아와서, 선배님 블로그에서 아직 첫문단을 다 읽지도 못했다.
다음으로는 이미지다.
이미지는 OS이미지의 그 이미지랑 같다고 적혀있어서, OS이미지에 대해 GPT에게 물어봤다.
윈도우 설치같은거 할때 자주보단 .iso 확장자가 그 이미지였구나! 싶으면서 두 이미지의 차이점도 설명해주니 이해가 됐다.
도커는 운영체제의 커널을 공유하는 방식이라는 것을 알게 됐다.
따라서 이미지는 환경 변수나 설정, 파일 등, 컨테이너에 대한 정보를 모두 담고 있다.
그리고 이 이미지를 실행하면 컨테이너가 된다.
(이미지 = 클래스, 컨테이너 = 인스턴스라고 비유를 들어주셨다. 근데 이걸 보니 예전에 객체지향을 배울 때 붕어빵과 붕어빵 틀이 떠올라서 검색해봤는데 이러한 글이 있어서 재밌게 보았다)
돌아와서, 그러면 이미지는 어떻게 만들까?
Dockerfile이라는 text 파일을 이용해서 만드는데 여기서 흥미로운 점은 도커파일을 빌드 할때 도커 이미지가 만들어지는데,
1. 임시 컨테이너 생성
2. 임시 컨테이너에서 Dockerfile 한 줄 명령어 실행
3. 임시 컨테이너의 상태 자체를 이미지로 저장
4. 1로 돌아감.
이게 반복된다는 것이다.
그래서 도커 이미지는 레이어를 쌓는 식으로 생성이 된다.
따라서 Dockerfile을 수정하면 해당 행부터 다시 레이어를 쌓는 과정이 수행되어 효율적이다.
(그러니 자주 변경안될것 같은것을 맨위에 적는다고 한다. <- 이걸 봤을때 감탄했다.)
또한 도커는 가상화인데, 가상머신과는 다르다고 한다.
가상머신은 커널과 프로세스를 모두 가상화한다면, 도커가 커널은 호스트 것을 그대로 사용하고 프로세스만 가상화를 하여서, 컨테이너 자체는 얇은 가상화 계층으로 싸여있는 프로세스라고 한다.
그래서 OS를 가상화 하지 않으니 빠르고 가볍고 부담도 없다고 한다.
여기까지의 내용이 첫번째 글이었다.
근데 두번째글도 도커의 글이라 이어서 읽었다.
선배님이 도커를 쓰게 된 이유는 프로젝트를 진행할 때 팀원들이 모든 설정을 동일하게 하기에는 복잡하고 어려우니, 이 환경을 도커로 만들어서 한다고 하셨다.
(근데 이때 궁금한게 생겼다.
위에서 설명은 안했지만 사실 Dockerfile을 작성할 때 베이스 이미지가 macOS일수도 있나?라는 생각이 들었다.
근데 macOS는 오픈소스가 아닌것도 있고, Darwin 커널 기반이기 때문에 도커는 리눅스 컨테이너 기술을 기반으로 해서 안된다고 한다.
그러면 도커는 호스트의 커널을 그대로 사용한다 했는데, 그럼 맥북에서는 어떻게 도커를 실행시키는거지?!라는 고민이 생긴거다.
그래서 Docker Desktop이라는 프로그램을 설치하는데, 이 프로그램이 Linux 기반 VM을 생성해준다는 것이다.
아... 그래서 이 프로그램을 설치한거구나. 왜 설치할 때는 궁금증을 느끼지 못했던 것일까?하고 반성하게 되었다.)
이후 도커의 글을 읽으면서 조금 더 세계를 확장할 수 있었으며 도커에 대해 이해도를 높일 수 있었다.
그럼에도 완전히 이해했다고 할 수는 없는 이유가 직접 써보지를 않았기 때문이다.
그래도 오늘 배운걸 정리해보자
1. 컨테이너는 종료되면 내부 데이터가 전부 날라간다. 따라서 외부 디렉토리를 마운트하여 사용해야 한다.
2. Stateful, Stateless 개념(+ JWT)
3. 레플리카, 파티셔닝 개념
4. On-Premises
5. 도커 이미지, 컨테이너 개념
6. Docker Desktop의 설치 이유
물론 깊게 판건 아니지만 자주 듣던 개념간의 연결고리를 이어볼 수 있었다.
이걸 대학교 2학년때 글을 작성하셨다는게 정말 대단하다는 것을 다시 느꼈고,
배울 것은 여전히 많은데 이 배우는 과정이 너무 재밌어서 다행이다.
아 근데 취업 준비도 해야하고... 프론트엔드도 부족한게 많은데 걱정이다...
'✏️나를 되돌아보는, 글 > 뻘글' 카테고리의 다른 글
생성형 AI와 완성된 세상 (0) | 2024.03.21 |
---|---|
| 소개글 | (0) | 2018.08.05 |
첫번째 글 (0) | 2018.08.05 |