재택근무, 클라우드 전환, 해외 지사 확대로 "회사 네트워크의 경계"가 흐려지고 있습니다. 이 글에서는 최근 자주 등장하는 SASE 와 국내 기업 환경에서 널리 쓰이는 Tgate(티게이트) 를 비교하며, 두 기술이 각각 어떤 문제를 풀고 어떻게 함께 쓰이는지 쉽게 정리합니다. 1. 먼저 용어부터 정리 1-1. SASE (Secure Access Service Edge) SASE(샘사이, "sassy"로 발음) 는 네트워크와 보안 기능을 클라우드에서 하나로 묶어 제공하는 아키텍처 입니다. 2019년 가트너가 제시한 개념이에요. "사용자가 어디에 있든, 어떤 기기를 쓰든, 클라우드에 있는 보안 게이트웨이를 거쳐 안전하게 접속하게 하자" 1-2. Tgate (티게이트) Tgate 는 국내에서 만든 보안 솔루션 브랜드로, 크게 두 가지 제품군이 있습니다. ▶ 표 1. Tgate 제품군 제품 풀어 쓰면 한 줄 설명 Tgate NAC Network Access Control (네트워크 접근통제) 네트워크에 붙는 유·무선 단말의 보안 상태를 검사하고, 통과한 기기만 내부망에 접속시킴 Tgate SDP Software Defined Perimeter (소프트웨어 정의 경계) 사용자 신원 중심으로 접근을 통제하는 제로트러스트 계열 원격 접속 솔루션 이 글에서는 Tgate NAC와 Tgate SDP를 모두 다루되 , 회사 내부망을 지키는 NAC를 중심으로 SASE와 비교합니다. 2. SASE, 무엇으로 구성될까? SASE는 하나의 제품이라기보다 여러 기능의 묶음 입니다. ▶ 표 2. SASE를 구성하는 핵심 기능 구성 요소 풀어 쓰면 하는 일 SD-WAN Software-Defined WAN 지사·본사·클라우드를 효율적으로 연결하는 네트워크 SWG Secure Web Gateway 웹 접속 시 악성 사이트를 차단하고 URL을 필터링 CASB Cloud Access Security Broker SaaS 이용 현황을 가시화하고 데이터 유출을 통제 FWaaS Firewall as a Service 클라우드로 제공되는 방화벽 ZTNA Zero Trust Network Access 사용자·기기를 검증하고 필요한 앱에만 접근 허용 이 중 보안 기능(SWG, CASB, FWaaS, ZTNA)만 따로 묶은 것 을 SSE(Security Service Edge) 라고 부릅니다. SASE는 여기에 SD-WAN 같은 네트워크 기능까지 더한 개념이에요. SASE의 핵심 발상 ▶ 그림 1. 전통 방식 vs SASE 방식의 트래픽 흐름 [전통 방식: 본사 중심] 재택 직원 ──VPN──▶ 본사 데이터센터 ──▶ 방화벽 ──▶ 인터넷/SaaS (모든 트래픽이 본사를 경유 → 병목, 느림) [SASE 방식: 클라우드 중심] 재택 직원 ──┐ 해외 지사 ──┼──▶ SASE 클라우드 (보안 검사 + 정책 적용) ──▶ 사내 앱 / SaaS / 인터넷 사무실 ──┘ (가까운 접점(PoP)에서 검사 → 빠르고 일관된 정책) 3. Tgate는 어떻게 동작할까? 3-1. Tgate NAC: "내부망의 출입 게이트" NAC는 기기가 내부망에 붙으려 할 때 검문하는 시스템 입니다. 공항 보안검색대를 떠올리면 쉬워요. ▶ 그림 2. Tgate NAC 동작 흐름 [단말이 사내 네트워크에 연결] │ ▼ 1 인증 (누구인가?) - 사용자 인증 (AD, LDAP, SSO 등 연동) │ ▼ 2 검역 (기기 상태는 안전한가?) - 백신 설치·동작 여부 - 필수 SW 설치 여부 - 금지 SW(P2P 등) 설치 여부 │ ┌──────┴──────┐ 통과 실패 │ │ ▼ ▼ 내부망 접속 허용 격리망(완충지대)으로 이동 → 조치 후 재검사 │ ▼ 3 접속 후에도 주기적 재검사 - 백신 프로세스 중지 등 정책 위반 시 즉시 격리 주요 기능 접속 전(Pre-admission) 검사 : 필수 보안 프로그램 설치를 강제하고, 위험한 프로그램은 제거를 강제합니다. 접속 후(Post-admission) 검사 : 이미 접속한 기기도 주기적으로 점검해서 정책 위반 시 격리합니다. 단말 정보 자동 수집 : IP/MAC, 단말 종류, 운영체제, 하드웨어·소프트웨어 정보를 수집합니다. IP 관리 : 누가 어떤 IP를 쓰는지 매핑하고(IP 실명제), IP 충돌을 방지합니다. 논리적 망분리 : 사내망을 안전한 내부망과 완충지대 역할의 외부망으로 나눕니다. 3-2. Tgate SDP: "보이지 않는 사내 서버" SDP는 "인증되기 전에는 서버의 존재 자체를 숨기는" 방식입니다. 사내 서버를 인터넷에서 아예 보이지 않게 만들어 공격 표면을 줄이죠. 블랙 클라우드 : 인증 전에는 접속 대상이 외부에 노출되지 않습니다. Dynamic Firewall : 화이트리스트 기반으로 접속·차단 정책이 상황에 따라 실시간 변경됩니다. App Binding : 사용자와 애플리케이션을 묶어서 통제합니다. 클라우드형(SaaS) 제공 : 에이전트 설치 없이 사내 서버 쪽에 커넥터만 설치하는 방식도 제공됩니다. 4. 비유로 한 번에 이해하기: 건물 보안 비유 Tgate NAC 회사 정문 출입 게이트 . 사원증(인증)을 찍고, 가방 검사(검역)를 통과해야 건물에 들어갈 수 있다. 들어온 뒤에도 순찰(주기 점검)한다. Tgate SDP 비밀 금고실 . 인증받은 사람에게만 문이 나타난다. 그 외에는 문이 있는지조차 모른다. SASE 전 세계 어디서나 따라다니는 경호팀 . 출장지, 카페, 집 어디에 있든 같은 보안 수준을 제공한다. 5. SASE vs Tgate 한눈에 비교 ▶ 표 3. SASE와 Tgate 비교 구분 SASE Tgate NAC Tgate SDP 핵심 질문 "어디서 접속하든 안전한가?" "이 기기를 내부망에 들여도 되는가?" "이 사용자에게 이 앱을 열어줘도 되는가?" 성격 클라우드 기반 네트워크+보안 통합 아키텍처 내부망 접근통제 솔루션 신원 중심 원격 접속 솔루션 주된 보호 영역 사용자의 인터넷·SaaS·사내 앱 접속 전반 사내 네트워크에 연결되는 단말 사내 서버·앱에 대한 원격 접근 통제 지점 클라우드 PoP(접속 지점) 사내망 내 (스위치·에이전트 등) 인증 게이트웨이/커넥터 단말 상태 점검 접속 시 기기 상태(Posture) 확인 핵심 기능 (설치 SW, 백신, 금지 SW 등) 사용자·기기 인증 중심 인터넷/SaaS 통제 핵심 (SWG, CASB) 해당 없음 해당 없음 망 구조 경계 없는 분산 환경 사내망 중심 경계 없는 원격 환경 대표 도입 목적 클라우드·재택·해외지사 보안 통합 내부 단말 보안 정책 준수 강제, IP·자산 관리 VPN 대체, 재택·원격 접속 보안 겹치는 부분과 다른 부분 ┌──────────────── SASE ────────────────┐ │ SD-WAN SWG CASB FWaaS │ │ ┌────────────┐ │ │ │ ZTNA │◀┼─ Tgate SDP와 목적이 유사 │ └────────────┘ │ (신원 중심 접근통제) └────────────────────────────────────────┘ Tgate NAC : 사내망에 붙는 단말의 "상태 검사·격리" → SASE가 직접 다루지 않는 내부망 단말 통제 영역 Tgate SDP ↔ SASE의 ZTNA : 둘 다 "신원 기반으로 필요한 앱에만 접근 허용"이라는 제로트러스트 원칙을 따르므로 역할이 겹칩니다. Tgate NAC ↔ SASE : 풀고 있는 문제의 층이 다릅니다. NAC는 사내망에 연결된 단말의 상태와 정책 준수 , SASE는 어디서든 접속하는 트래픽의 보호 에 초점이 있어요. 6. 시나리오로 보는 역할 차이 ▶ 표 4. 상황별 어떤 기술이 활약할까? 상황 문제 적합한 기술 사무실 PC에 백신이 꺼져 있다 감염된 PC가 내부망에서 확산될 수 있음 Tgate NAC (즉시 격리) 직원이 개인 노트북을 사내 와이파이에 연결한다 미등록·미검증 기기의 내부망 접근 Tgate NAC (인증·검역 후 허용) 재택 직원이 사내 시스템에 접속해야 한다 VPN은 접속 후 내부망 전체가 노출되는 구조 Tgate SDP / SASE(ZTNA) 직원이 승인되지 않은 SaaS에 파일을 올린다 데이터 유출, 섀도 IT SASE (CASB) 해외 지사 직원이 본사 앱을 느리게 쓴다 모든 트래픽이 본사를 경유 SASE (SD-WAN + 클라우드 PoP) 카페에서 인터넷 서핑 중 악성 사이트 접속 사용자 단말이 인터넷에 직접 노출 SASE (SWG) 7. 경쟁 관계일까, 보완 관계일까? 결론부터 말하면 대체가 아니라 보완 관계 인 경우가 많습니다. ▶ 그림 3. 계층별 보안 구성 예시 [ 밖 (인터넷 · 재택 · 지사) ] │ │ SASE / SDP : 어디서 오든 신원과 기기를 검증하고, │ 필요한 앱에만 연결 ▼ [ 경계 ] │ ▼ [ 사내망 ] │ NAC : 내부망에 붙은 단말이 정책을 지키는지 계속 확인, │ 위반 단말은 격리 ▼ [ 서버 · 데이터 ] 재택·해외 접속은 SASE나 SDP 로 보호하고, 사내에 연결된 단말은 NAC 로 상태를 통제하는 식으로 층층이(Defense in Depth) 구성할 수 있습니다. 8. 어떤 환경에서 무엇을 먼저 검토할까? ▶ 표 5. 환경별 검토 우선순위 우리 회사는... 먼저 살펴볼 기술 사내 PC·노트북 관리, 금지 SW 통제, IP 관리가 숙제 Tgate NAC VPN을 줄이고 재택·원격 접속을 제로트러스트로 바꾸고 싶다 Tgate SDP 또는 SASE의 ZTNA SaaS 사용이 급증했고 데이터 유출이 걱정된다 SASE (CASB, SWG) 해외 지사가 많고 네트워크 품질·보안 정책을 통일하고 싶다 SASE (SD-WAN + SSE) 위 문제가 다 있다 단계적 도입: 우선순위를 정해 SASE와 NAC를 병행 9. 도입 시 체크 포인트 SASE는 벤더마다 구성이 다릅니다. SD-WAN, SWG, CASB, FWaaS, ZTNA를 모두 제공하는 벤더는 많지 않으므로, 필요한 기능이 포함되어 있는지 확인해야 합니다. NAC는 단말 에이전트와 네트워크 구성에 영향을 줍니다. 도입 전에 OS·기기 종류, 네트워크 구조, 예외 단말(프린터, IoT 등)을 파악해야 합니다. 사용자 경험 을 반드시 고려하세요. 지나치게 엄격한 정책은 현업의 우회를 부르고, 오히려 보안이 약해집니다. 한 번에 다 바꾸지 마세요. 파일럿 부서 → 단계 확대 순서가 안전합니다. 제품 기능과 라이선스는 버전과 구성에 따라 달라지므로 각 벤더의 최신 자료를 꼭 확인 하세요. 10. 정리 ▶ 표 6. 핵심 요약 키워드 한 줄 요약 SASE 네트워크+보안을 클라우드로 통합한 아키텍처. 어디서든 같은 보안 ZTNA 신원과 기기를 검증해 필요한 앱에만 접근을 허용하는 방식 Tgate NAC 내부망에 붙는 단말을 인증·검역하고 위반 시 격리 Tgate SDP 인증 전에는 서버를 숨기는 신원 중심 원격 접속 관계 대체가 아니라 계층별로 보완하는 경우가 많음 "경계가 사라진 시대에는, 경계 대신 사람과 기기를 믿을 수 있는지 계속 확인해야 한다." SASE, SDP, NAC는 모두 이 질문에 답하는 서로 다른 방법입니다. 다음 글 예고 제로트러스트란 무엇인가? VPN이 위험해진 이유 ZTNA와 SDP의 차이 자세히 보기 엔드포인트 보안(EDR, MDM, NAC) 역할 구분하기 읽어주셔서 감사합니다. 궁금한 점은 댓글로 남겨주세요! 🙌
코딩테스트를 공부하다 보면 분수의 약분, 최소공배수, 배열의 공통 주기처럼 최대공약수(GCD, Greatest Common Divisor) 를 구해야 하는 문제를 자주 만나게 된다. GCD를 구하는 방법은 여러 가지가 있지만, 코딩테스트에서는 모든 알고리즘을 깊게 공부할 필요는 없다. 가장 중요한 것은 유클리드 호제법(Euclidean Algorithm) 이다. 이번 글에서는 GCD를 구하는 여러 방법을 살펴보고, 코딩테스트에서 어느 정도까지 알고 있으면 좋은지 정리해본다. 1. 최대공약수란? 두 정수 a , b 가 있을 때 두 수를 모두 나누어떨어지게 하는 수를 공약수 라고 한다. 예를 들어 12와 18의 공약수를 구해보면, 12의 약수: 1, 2, 3, 4, 6, 12 18의 약수: 1, 2, 3, 6, 9, 18 공약수는 1, 2, 3, 6 이고, 그중 가장 큰 값인 6 이 최대공약수이다. 따라서 gcd(12, 18) = 6 이다. 2. 모든 약수를 탐색하는 방법 가장 쉽게 생각할 수 있는 방법은 1 부터 두 수 중 작은 값까지 모두 확인하는 것이다. public int gcdBruteForce(int a, int b) { int gcd = 1; for (int i = 1; i <= Math.min(a, b); i++) { if (a % i == 0 && b % i == 0) { gcd = i; } } return gcd; } 두 수를 모두 나눌 수 있는 값을 발견할 때마다 gcd 를 갱신하고, 마지막에 발견한 가장 큰 공약수를 반환한다. 시간 복잡도 두 수 중 작은 값을 N 이라고 하면, O(N) 의 시간이 필요하다. 구현은 간단하지만 입력값이 커지면 비효율적이다. 따라서 이 방법은 GCD의 개념을 이해하기 위한 방법 으로는 좋지만, 실제 코딩테스트에서는 유클리드 호제법을 사용하는 것이 일반적이다. 3. 유클리드 호제법 GCD를 구할 때 가장 중요한 알고리즘은 유클리드 호제법 이다. 다음 성질을 이용한다. gcd(a, b) = gcd(b, a % b) 두 수의 최대공약수는 작은 수 b a 를 b 로 나눈 나머지 의 최대공약수와 동일하다. 이를 나머지가 0 이 될 때까지 반복한다. 예제 gcd(48, 18) 을 계산해보자. gcd(48, 18) | 48 % 18 = 12 gcd(18, 12) | 18 % 12 = 6 gcd(12, 6) | 12 % 6 = 0 따라서 최대공약수는 6 이다. 4. 반복문으로 구현한 유클리드 호제법 코딩테스트에서 가장 사용하기 좋은 형태이다. public int gcd(int a, int b) { while (b != 0) { int remainder = a % b; a = b; b = remainder; } return a; } 처음에는 a = 48 b = 18 이라고 해보자. 반복 과정은 다음과 같다. 48, 18 18, 12 12, 6 6, 0 b 가 0 이 되면 현재 a 가 최대공약수이다. 시간 복잡도 유클리드 호제법은 대략 O(log(min(a, b))) 의 시간 복잡도를 가진다. 단순하게 모든 약수를 확인하는 방법보다 훨씬 빠르다. 5. 재귀로 구현하기 유클리드 호제법은 재귀 호출로도 자연스럽게 표현할 수 있다. public int gcd(int a, int b) { if (b == 0) { return a; } return gcd(b, a % b); } 더 줄이면 다음처럼 작성할 수도 있다. public int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } 알고리즘의 정의 자체와 코드가 거의 동일하다는 장점이 있다. gcd(a, b) → gcd(b, a % b) → ... → gcd(gcd, 0) 코딩테스트 풀이에서도 자주 볼 수 있는 형태이다. 다만 처음 공부할 때는 값이 어떻게 변하는지 확인하기 쉬운 반복문 버전도 함께 이해하는 것이 좋다. 6. 여러 수의 GCD 구하기 유클리드 호제법은 두 수뿐만 아니라 여러 수에도 사용할 수 있다. 다음 성질을 이용한다. gcd(a, b, c) = gcd(gcd(a, b), c) 예를 들어 24, 36, 60 의 최대공약수를 구한다고 해보자. 먼저 gcd(24, 36) = 12 이고, 다음으로 gcd(12, 60) = 12 이므로 최종 최대공약수는 12 이다. 배열에 적용하면 다음과 같이 작성할 수 있다. public int gcd(int a, int b) { while (b != 0) { int remainder = a % b; a = b; b = remainder; } return a; } public int gcd(int[] numbers) { int result = numbers[0]; for (int i = 1; i < numbers.length; i++) { result = gcd(result, numbers[i]); } return result; } 이러한 형태는 배열 전체의 공통 간격이나 비율을 구하는 문제에서 활용할 수 있다. 7. GCD와 LCM GCD를 공부할 때는 최소공배수(LCM, Least Common Multiple) 도 함께 알아두는 것이 좋다. 두 수 a , b 에 대해서 다음 관계가 성립한다. a × b = gcd(a, b) × lcm(a, b) 따라서 최소공배수는 lcm(a, b) = a × b / gcd(a, b) 로 구할 수 있다. Java에서는 다음과 같이 작성할 수 있다. public long lcm(int a, int b) { return (long) a / gcd(a, b) * b; } 여기에서 a * b / gcd(a, b) 가 아니라 a / gcd(a, b) * b 순서로 계산하는 이유는 곱셈 과정에서 발생할 수 있는 overflow 위험을 줄이기 위해서 이다. 또한 계산 결과가 int 의 범위를 넘어갈 수 있으므로 long 을 사용하는 것이 안전하다. 8. Binary GCD GCD를 구하는 또 다른 알고리즘으로 Binary GCD , 또는 Stein's Algorithm 이 있다. 이 알고리즘은 % 연산 대신 주로 다음 연산을 이용한다. 비트 연산 2로 나누기 뺄셈 다음 성질들을 이용한다. gcd(2a, 2b) = 2 × gcd(a, b) // 둘 다 짝수라면 공통으로 2를 꺼냄 gcd(2a, b) = gcd(a, b) // b가 홀수이면 2를 제거 gcd(a, b) = gcd(|a - b|, min(a, b)) // 두 수가 홀수라면 두 수의 차이를 이용 과거에는 나눗셈 연산이 상대적으로 비싼 환경에서 의미가 있었지만, 일반적인 코딩테스트에서는 직접 구현할 일이 많지 않다. 따라서 Binary GCD라는 알고리즘도 존재한다. 정도만 알고 있어도 충분하다. 9. 확장 유클리드 알고리즘 유클리드 호제법을 확장하면 단순히 GCD만 구하는 것이 아니라 다음 식을 만족하는 x , y 까지 구할 수 있다. ax + by = gcd(a, b) 이를 확장 유클리드 알고리즘(Extended Euclidean Algorithm) 이라고 한다. 예를 들어, gcd(30, 18) = 6 이고 30 × (-1) + 18 × 2 = 6 이므로 x = -1 y = 2 가 하나의 해가 된다. 확장 유클리드 알고리즘은 다음과 같은 정수론 문제에서 사용된다. 모듈러 역원 선형 디오판토스 방정식 중국인의 나머지 정리 모듈러 연산 기본적인 코딩테스트에서는 자주 등장하지 않지만, 정수론 문제를 공부하기 시작하면 중요해진다. 10. 코딩테스트에서는 어디까지 공부해야 할까? GCD 관련 알고리즘을 모두 같은 수준으로 외울 필요는 없다. 알고리즘 중요도 학습 목적 모든 약수 탐색 ★ GCD 개념 이해 유클리드 호제법 ★★★★★ 반드시 숙지 재귀 유클리드 호제법 ★★★★★ 간결한 구현 여러 수의 GCD ★★★★ 배열 문제 응용 Binary GCD ★ 존재 정도 알아두기 확장 유클리드 ★★★ 정수론 심화 일반적인 코딩테스트를 준비한다면 다음 코드는 바로 작성할 수 있을 정도로 익혀두는 것이 좋다. public int gcd(int a, int b) { while (b != 0) { int remainder = a % b; a = b; b = remainder; } return a; } 그리고 함께 기억할 공식은 다음과 같다. gcd(a, b) = gcd(b, a % b) lcm(a, b) = a / gcd(a, b) × b 이 두 가지를 알고 있으면 상당수의 GCD/LCM 문제를 해결할 수 있다. 정리 GCD를 구하는 가장 단순한 방법은 모든 약수를 검사하는 것이지만 시간 복잡도가 O(N) 이기 때문에 큰 입력에는 적합하지 않다. 코딩테스트에서는 대부분 유클리드 호제법 을 사용한다. 유클리드 호제법의 핵심은 다음 한 줄이다. gcd(a, b) = gcd(b, a % b) 이를 나머지가 0 이 될 때까지 반복하면 최대공약수를 빠르게 구할 수 있다. GCD를 이해하면 자연스럽게 최소공배수, 분수의 약분, 배열의 공통 주기와 같은 문제에도 적용할 수 있다. 따라서 코딩테스트를 준비한다면 여러 GCD 알고리즘을 모두 외우기보다는 유클리드 호제법의 원리를 이해하고 직접 구현할 수 있는 수준까지 익히는 것 이 가장 중요하다.
하트 HP, 장애물, 그리고 벽을 못 지나가던 돌진형 기간: 2026-09-28 ~ 2026-09-30 트릭컬 리바이브 IP로 만드는 아이작류 로그라이크 팬게임 개발 기록입니다. 이번에 한 일 요약 플레이어 HP를 반 칸 단위 하트 로 전환, 적 HP 10배 스케일 탐색 자원 엘리프(골드)·열쇠·폭탄 과 체력 회복 픽업, 전투방 클리어 드롭 파괴 가능한 장애물 과 장애물 Layout 3종 장애물에 막힌 적을 위한 A* 우회 이동 돌진형 적의 벽 스침 처리 (이게 제일 길었다) SpawnPoint 배치 역할 지정 1. 체력을 하트 칸으로 바꾸다 기존 HP는 게이지였다. 아이작류인데 체력이 막대기라 피격 한 번의 무게가 잘 안 느껴졌고, 회복이나 방어막 수치도 소수점이 섞여서 설명하기 애매했다. 그래서 아이작처럼 하트 칸으로 바꿨다. 시작 HP 5칸. 내부적으로는 반 칸 = 1단위 정수 (5칸 = 10) 적에게 받는 피해는 최소 반 칸이 아니라 최소 1칸 층 배율 대신 약·중·강·치명 피해 등급표 . 3층 약공격은 1.5칸 HUD는 반 칸 하트 아이콘 줄, 방어막은 파란 하트로 이어서 표시 보스 대형 패턴도 등급을 매겼다. 새마음금고 착지는 중, 크레용사용 내려찍기는 강, 황금 3방향 내려찍기는 치명. 그런데 왜 적 HP를 10배로? HP를 정수로 바꾸고 나니 "최대 HP의 N%" 같은 효과를 계산할 때 공격력 1 기준 수치로는 해상도가 너무 낮았다. 그래서 플레이어 쪽 칸 수는 그대로 두고, 적 쪽 숫자만 10배 로 키웠다. 플레이어 기본 공격력 1 → 10 적·보스·장애물 HP ×10 새마음금고 보물 회복 15 → 150 체감 난이도는 그대로인데 이후 화상 같은 도트 피해나 % 효과를 넣을 여유가 생겼다. 비율 계산 결과는 내림하되 최소 1단위를 보장하는 공통 함수로 통일했다. 기존 아이템도 하트 규칙에 맞춰 손봤다. 코미의 베개는 "N킬마다 회복", 광기의 가면은 "주변 적에게 공격력 기반 오라 피해"로 바꿨고, 풍선 갑옷은 +1칸. 2. 탐색 자원: 엘리프, 열쇠, 폭탄 보스방으로 직행하는 것과 방을 뒤지는 것 사이에 선택이 있으려면, 뒤졌을 때 얻는 게 있어야 한다. 그래서 아이작의 동전·열쇠·폭탄에 해당하는 자원을 넣었다. 셋 다 보유 한도 99. 픽업 하나에 1개 가득 차 있으면 줍지 않고 바닥에 남는다. 대신 밀 수 있는 충돌체라 발에 채인다 체력 회복 픽업(1칸)도 같은 규칙. 회복량이 전부 들어갈 때만 줍는다 (반 칸만 비었으면 안 주움) Pickup 레이어는 플레이어·환경·다른 픽업과만 충돌해서, 적과 투사체는 하트를 통과한다 일반 전투방은 클리어할 때 한 번만 드롭을 추첨한다. 확률 결과 (가중치) 33% 하트 30 · SP 30 · 엘리프 20 · 열쇠 12 · 폭탄 8 67% 없음 방 seed로 재현되고, 재방문하거나 층을 다시 불러와도 재추첨하지 않는다. 그리고 기존의 "클리어 시 SP 확정 지급"과 "적 처치 시 25% SP 드롭"은 삭제 했다. 에르핀 저학년 스킬이 너무 자주 돌아서 SP 공급을 줄일 필요가 있었다. 폭탄은 이번엔 얻고 들고 다니는 것까지만 만들었다. 던지고 터뜨리는 건 비밀방과 함께 다음 주차. 3. 파괴 가능한 장애물과 Layout 방 크기(Small·Basic·Wide·Tall·Large)는 다양해졌지만, 같은 크기의 방은 결국 비어 있거나 기둥 하나뿐이라 다 비슷하게 느껴졌다. 그래서 1 × 1 파괴 가능 장애물을 만들고, 이걸 배치한 Layout을 수작업으로 설계했다. 플레이어, 적, 투사체, 돌진 모두 막는다 플레이어 공격 5타 에 파괴 (공격력과 무관하게 공격 1회 = 1타) 아티팩트 부가 피해(광기의 가면 오라, 번개)나 적 공격은 타수에 안 센다 기본 3% 확률로 드롭. 장애물 ID + 방 seed로 결정되고, 파괴 상태는 방 상태에 남아서 재방문해도 부서진 그대로 "공격력과 무관하게 5타"로 정한 이유는, 딜 빌드일수록 장애물이 휴지처럼 녹는 걸 막고 싶어서였다. 장애물은 엄폐물이기도 하니까. Layout은 Large 방 기준으로 엄폐물 블록형 등 3종을 만들었다. 대신 사람이 만든 Layout은 실수가 나기 쉬워서, 검증기가 이런 걸 잡아서 명시적으로 실패 하게 했다. 장애물끼리 겹침 문과 필수 통로가 막힘 모든 영역에 도달 가능한지 원거리 적 스폰 위치에서 사선이 나오는지 4. 막힌 적에게 길을 알려주기 (A*) 장애물을 놓자마자 예상대로 적이 장애물에 코를 박고 멈췄다. 기존 적들은 플레이어를 향해 직선으로만 움직였으니까. 규칙은 단순하게 잡았다. 목표까지 몸통 크기의 직선 이 비어 있으면 그냥 직선 이동 막혔으면 적 주변을 0.5유닛 격자로 나눈 A* 경로 로 우회하고, 보이는 가장 먼 경로점을 향해 이동 경로는 0.25초마다 재계산. 같은 배치면 같은 경로 적 타입별로는 이렇게 다르게 반응한다. 적 사선/경로가 막혔을 때 원거리형 사거리 안이어도 쏘지 않고 우회 저격형 조준을 시작하지 않음. 조준이 끝난 순간 막혀 있으면 발사 취소 후 재배치 돌진형 직선이 뚫려 있을 때만 예고 시작. 예고를 시작한 뒤엔 막혀도 그대로 돌진 기둥에 등을 붙인 원거리형 seed 1~10으로 장애물 방 20개를 돌리는 Play Mode 테스트를 하다가 재밌는 사례가 나왔다. 원거리형이 기둥에 등을 붙인 채 이동도 사격도 안 하고 멈춰 있었다. 원인은 후퇴 로직이었다. 플레이어가 최소 사거리 안으로 들어오면 뒤로 물러나는데, 뒤가 기둥이라 못 물러나고, 물러나는 중이라 쏘지도 않았다. 그래서 직선 후퇴가 막히면 좌우 45°를 확인해서 빈 쪽으로 물러나고, 셋 다 막혔으면 그냥 제자리에서 쏘게 했다. 궁지에 몰린 적이 반격하는 게 오히려 자연스럽다. 5. 돌진형이 벽을 스치면 멈추는 버그 — 네 번 고친 이야기 이번 기간의 하이라이트. 수정 → 피드백 → 재수정이 네 번 반복됐다. 1차: 스치기만 해도 정지 돌진형은 벽에 부딪히면 멈추고 잠깐 빈틈을 보인다. 그런데 벽을 살짝 스치기만 해도 정면 충돌처럼 멈췄다. 장애물이 생기니 이게 훨씬 자주 보였다. 충돌 법선과 진행 방향의 각도로 나눴다. 얕게 스친 건 벽을 따라 미끄러지고, 정면에 가까우면 멈춘다. 문과 플레이어에 부딪힌 건 항상 멈춘다. // 개념만 단순화한 예시 float dot = Vector2.Dot(chargeDir, contactNormal); bool isGlancing = /* 입사각이 기준 이상 */; if (isGlancing) SlideAlong(contactNormal); else EnterRecovery(); 2차: 벽에 붙은 채 다시 돌진하면 또 멈춤 미끄러짐은 잘 됐는데, 첫 충돌 뒤 벽에 붙은 상태에서 다음 돌진 을 시작하면 또 막혔다. 원인은 Unity 물리 콜백이었다. 이미 접촉 중인 충돌 쌍에는 OnCollisionEnter2D 가 다시 오지 않는다. 판정을 Enter에만 걸어놨으니 두 번째 돌진에선 판정 자체가 안 돌고 그냥 물리에 막힌 거다. OnCollisionStay2D 에도 같은 판정을 연결했다. 3차: 벽에서 멀어지는 돌진도 정면 충돌 이번엔 벽에 붙어 있다가 벽 반대쪽으로 돌진해도 멈췄다. 내적에 절댓값을 씌운 게 문제였다. |dot| 으로 각도를 보면 벽으로 들어가는 방향이든 벽에서 나오는 방향이든 똑같이 "정면"으로 판정된다. 벽으로 접근하는 접촉일 때만 각도를 판정하고, 이탈하거나 평행하게 움직일 땐 원래 방향을 유지하도록 바꿨다. 접촉점이 여러 개면 벽 쪽으로 가장 강하게 들어가는 법선을 쓴다. 4차: 미끄러진 뒤 원래 방향으로 안 돌아옴 마지막으로, 미끄러짐이 조준 방향 자체를 덮어써서 벽을 벗어나도 벽 접선 방향으로 계속 가버렸다. 조준 방향은 그대로 보존하고, 벽 접촉이 유지되는 동안만 조준 방향을 벽 접선에 투영해서 이동하도록 바꿨다. 접촉이 끝나면 원래 돌진 방향으로 복귀한다. 덤: 스케일 연출이 충돌체를 키우고 있었다 추적하다 보니 돌진형의 예고·돌진·회복 연출이 루트 Transform 스케일 을 바꾸고 있었다. 보이는 건 살짝 커지는 연출인데 Collider도 같이 커져서, 판정 범위가 상태마다 달라지고 있었다. 1편에서 새마음금고 탄성 연출을 시각용 자식에만 걸었던 것과 같은 문제다. 돌진형뿐 아니라 일반 적·소환몹 전부 상태 배율을 1로 맞췄다. 추가로 정한 것 미끄러짐 허용 범위는 벽면 기준 30°까지로 조정 예고 시작 전 플레이어와의 여유 거리, 첫 장애물까지의 거리가 모두 최소 1유닛이어야 돌진 (코앞에서 돌진 시작하는 어색함 방지) 예고선은 첫 벽 접촉 지점까지만 그린다. 미끄러질 경로까지 예측해서 그리진 않는다 매 단계마다 자동 검증에 케이스를 추가했더니(80° 경계, 진입/유지 콜백, 이탈 방향 보존, 접촉 종료 후 복귀...) 나중엔 돌진형 검증만 꽤 두꺼워졌다. 그래도 수동 피드백이 올 때마다 "이건 이미 테스트로 막혀 있다"고 확인할 수 있어서 마음은 편했다. 6. SpawnPoint에 역할 붙이기 장애물 Layout이 생기니 "적이 어디서 나오느냐"도 중요해졌다. 원거리형이 플레이어 코앞에서 나오면 의미가 없고, 돌진형이 기둥 바로 앞에서 나오면 돌진을 못 한다. 그래서 SpawnPoint에 배치 역할을 붙였다. 역할 어울리는 적 근접 압박 추적형, 고속형 후방 사격 원거리형, 저격형 돌진 경로 돌진형 역할이 안 맞는 배치는 검증 단계에서 거부한다. 다음 단계는 이 위에 위협 점수와 방 난이도 를 얹어서, 층 안에서 쉬운 방과 어려운 방의 흐름을 설계하는 것. 다음 목표 엘리프·열쇠·폭탄 HUD (미니맵·아티팩트 HUD 재배치와 같이) 폭탄 사용과 비밀방 방 난이도와 층 규모 확장, 특수방 추가
클라우드, 가상화, 컨테이너 같은 용어의 밑바닥에는 결국 서버 가 있습니다. 이 글에서는 IT 인프라의 가장 기본 단위인 서버가 무엇이고, 어떻게 구성되며, 어떻게 안정적으로 운영되는지 쉽게 정리합니다. 1. 서버란 무엇일까? "요청(Request)을 받아서 처리한 뒤 응답(Response)을 돌려주는 컴퓨터(또는 프로그램)" 우리가 웹사이트에 접속하면, 내 PC( 클라이언트 )가 요청을 보내고 어딘가의 컴퓨터( 서버 )가 응답을 돌려줍니다. ▶ 그림 1. 클라이언트-서버 구조 [클라이언트] [서버] 내 PC / 스마트폰 웹 서버, DB 서버 ... │ │ │ 1 "메인 페이지 보여주세요" (요청) │ │ ─────────────────────────────────▶ │ │ │ 2 처리 │ 3 페이지 데이터 (응답) │ │ ◀───────────────────────────────── │ 서버라는 말은 두 가지 의미로 쓰입니다. 하드웨어 서버 : 서비스를 제공하기 위해 설계된 컴퓨터 장비 소프트웨어 서버 : 요청을 처리하는 프로그램 (예: Apache, Nginx, MySQL) 한 대의 하드웨어 서버 위에서 여러 소프트웨어 서버가 동작하기도 합니다. 식당에 비유하면? 🍽️ 식당 IT 손님 클라이언트 (사용자 PC, 앱) 주문 요청 (Request) 주방 서버 요리 응답 (Response) 주방 규모, 요리사 수 서버 사양, 서버 대수 손님이 많아지면 주방을 넓히거나(사양 증설) 주방을 하나 더 만들어야(서버 증설) 하죠. 서버 인프라의 고민이 바로 이겁니다. 2. 서버와 일반 PC는 뭐가 다를까? 서버도 결국 컴퓨터지만, 목적이 다르기 때문에 설계가 다릅니다. ▶ 표 1. 서버 vs 일반 PC 구분 일반 PC 서버 목적 한 사람이 사용 여러 사용자·시스템의 요청 처리 가동 시간 필요할 때만 켬 24시간 365일 가동 전제 안정성 고장 나면 교체 부품 이중화로 고장에도 계속 동작 메모리 일반 메모리 오류 정정 기능이 있는 ECC 메모리 사용이 일반적 전원 단일 전원 이중 전원(Redundant PSU) 구성이 일반적 디스크 단일 디스크 RAID 구성, 교체 가능한 핫스왑 디스크 관리 화면 앞에서 직접 조작 원격 관리 전용 포트(BMC) 제공 설치 형태 책상 위 랙(Rack)에 장착, 전용 공간(전산실·데이터센터) 핵심 차이는 "멈추면 안 된다" 는 것입니다. 그래서 서버는 성능 못지않게 안정성과 관리 편의성 에 투자합니다. 3. 서버의 하드웨어 구성 ▶ 그림 2. 서버 하드웨어 구성 요소 ┌──────────────────────── 서버 ────────────────────────┐ │ │ │ CPU ◀──▶ 메모리(RAM) : 연산과 작업 공간 │ │ │ │ │ ├──▶ 스토리지 (SSD/HDD, RAID) : 데이터 저장 │ │ │ │ │ ├──▶ 네트워크 카드(NIC) : 외부와 통신 │ │ │ │ │ └──▶ 전원 공급 장치(PSU) x 2 : 전력 공급 (이중화) │ │ │ │ BMC (원격 관리 칩) : 서버가 꺼져 있어도 원격 제어 │ └────────────────────────────────────────────────────────┘ ▶ 표 2. 구성 요소별 역할 구성 요소 역할 서버에서 중요한 포인트 CPU 연산 처리 코어 수, 동시 처리 능력 메모리 (RAM) 작업 중인 데이터를 임시 보관 용량, ECC 지원 여부 스토리지 데이터 영구 저장 SSD/HDD, 속도와 용량, RAID 구성 NIC 네트워크 연결 대역폭(1G, 10G, 25G 등), 이중화 PSU 전력 공급 이중화 구성 BMC 원격 관리 (전원 제어, 콘솔 접속, 상태 확인) 장애 시 현장에 가지 않고 대응 서버 폼팩터 (생김새) ▶ 표 3. 서버 형태 비교 형태 특징 주로 쓰이는 곳 타워형 일반 PC 본체처럼 생김 소규모 사무실, 지사 랙 마운트형 표준 랙에 차곡차곡 장착 (높이는 U 단위) 전산실, 데이터센터의 표준 블레이드형 얇은 서버 여러 장을 섀시에 꽂는 방식 고밀도 환경, 공간 절약 4. 서버 OS 서버 운영체제는 크게 두 계열이 많이 쓰입니다. ▶ 표 4. 대표적인 서버 OS 계열 예시 특징 Windows Server Windows Server 2019, 2022 등 GUI 관리가 편하고 Active Directory 등 Microsoft 환경과 궁합이 좋음 Linux RHEL, Ubuntu Server, Rocky Linux 등 웹·클라우드·컨테이너 환경에서 널리 사용, 명령줄(CLI) 중심 유닉스 계열 AIX, HP-UX, Solaris 등 기존 대형 시스템에서 사용, 점차 축소되는 추세 서버는 화면을 붙여놓고 쓰는 경우가 드물어서 SSH(리눅스)나 RDP(윈도우) 로 원격 접속해서 관리하는 것이 일반적입니다. 5. 서버는 어떤 역할을 할까? (역할별 서버 종류) 서버는 "무엇을 제공하느냐"에 따라 이름이 붙습니다. ▶ 표 5. 역할별 서버 종류 서버 종류 하는 일 대표 예시 웹 서버 웹 페이지 요청 처리, 정적 콘텐츠 제공 Apache, Nginx, IIS WAS (Web Application Server) 비즈니스 로직 실행, 동적 처리 Tomcat, JBoss DB 서버 데이터 저장·조회·관리 MySQL, PostgreSQL, Oracle, MSSQL 파일 서버 파일 공유 및 저장 Windows 파일 서버, NAS 메일 서버 이메일 송수신 Exchange, Postfix DNS 서버 도메인 이름을 IP 주소로 변환 BIND, Windows DNS DHCP 서버 단말에 IP 주소 자동 할당 Windows DHCP 인증 서버 사용자 인증과 계정·권한 관리 Active Directory, LDAP 백업 서버 데이터 백업과 복구 각종 백업 솔루션 실제 서비스는 서버를 "층"으로 나눕니다 (3-Tier) ▶ 그림 3. 웹 서비스의 3계층 구조 사용자 │ ▼ [ 웹 서버 ] ── 화면·정적 파일 제공, 요청 전달 │ ▼ [ WAS ] ── 로직 처리 (로그인, 주문, 결제 등) │ ▼ [ DB 서버 ] ── 데이터 저장·조회 왜 나눌까요? 역할 분리 : 각 서버가 잘하는 일에 집중 독립적 확장 : 요청이 몰리는 계층만 서버를 늘릴 수 있음 보안 강화 : DB 서버는 외부에 직접 노출하지 않고 내부망에 배치 6. 서버를 쪼개고 나누는 기술: 물리 → 가상 → 컨테이너 ▶ 그림 4. 서버 운영 방식의 진화 [물리 서버] [가상화] [컨테이너] 서버 1대 = 앱 1개 서버 1대 = VM 여러 개 서버 1대 = 컨테이너 수십 개 ┌────────┐ ┌─────────────────┐ ┌──────────────────┐ │ 앱 │ │ VM1 VM2 VM3 │ │ C1 C2 C3 C4 C5 │ │ OS │ │ (각자 OS 보유) │ │ (OS 커널 공유) │ │ 하드웨어│ │ 하이퍼바이저 │ │ 컨테이너 런타임 │ └────────┘ │ 하드웨어 │ │ OS / 하드웨어 │ └─────────────────┘ └──────────────────┘ 자원 낭비 큼 자원 효율↑, 격리↑ 더 가볍고 빠름 ▶ 표 6. 세 가지 방식 비교 구분 물리 서버 가상 서버 (VM) 컨테이너 단위 하드웨어 1대 가상머신 프로세스 격리 단위 OS 서버당 1개 VM마다 별도 OS 호스트 OS 커널 공유 기동 속도 느림 분 단위 초 단위 자원 효율 낮음 중간 높음 격리 수준 완전 분리 높음 VM보다 낮음 대표 기술 - VMware, Hyper-V, KVM Docker, Kubernetes 이 흐름의 끝에 클라우드 가 있습니다. 클라우드의 가상 서버(예: AWS EC2)도 결국 누군가의 물리 서버 위에서 돌아가는 가상머신입니다. 7. 서버 스토리지: 데이터는 어디에 저장할까? ▶ 표 7. 스토리지 연결 방식 방식 설명 특징 DAS (Direct Attached Storage) 서버에 직접 연결된 디스크 단순하고 빠르지만 다른 서버와 공유 어려움 NAS (Network Attached Storage) 네트워크로 접근하는 파일 공유 저장소 파일 단위 공유에 적합 SAN (Storage Area Network) 전용 고속 네트워크로 서버와 연결된 스토리지 블록 단위, 대규모·고성능 환경에 사용 RAID: 디스크가 죽어도 데이터를 지키는 기술 여러 디스크를 묶어 성능을 높이거나 장애에 대비 하는 기술입니다. ▶ 표 8. 주요 RAID 레벨 RAID 방식 최소 디스크 특징 RAID 0 데이터를 나눠서 저장 (스트라이핑) 2 빠르지만 디스크 1개만 고장 나도 전체 손실 RAID 1 똑같이 복사 (미러링) 2 1개가 고장 나도 유지, 용량은 절반 RAID 5 데이터 + 패리티 분산 3 디스크 1개 고장까지 견딤 RAID 6 패리티 2개 분산 4 디스크 2개 고장까지 견딤 RAID 10 미러링 + 스트라이핑 4 성능과 안정성이 좋지만 용량 효율은 낮음 ⚠️ RAID는 백업이 아닙니다. RAID는 디스크 고장에 대비하는 기술이고, 실수로 삭제한 파일이나 랜섬웨어 피해는 막아주지 못합니다. 별도의 백업 이 반드시 필요합니다. 8. 서버는 왜 "이중화"에 집착할까? (가용성) 서버가 멈추면 서비스도 멈춥니다. 그래서 가용성(Availability) 이 핵심 지표입니다. ▶ 표 9. 가용률별 연간 허용 중단 시간 가용률 연간 허용 중단 시간 (대략) 99% 약 3.65일 99.9% 약 8.76시간 99.99% 약 52분 99.999% 약 5분 숫자 하나 늘릴 때마다 필요한 비용과 복잡도가 크게 올라갑니다. 이중화(Redundancy) 구성 예 ▶ 그림 5. 로드밸런서와 서버 이중화 사용자 │ ┌──────▼──────┐ │ 로드밸런서 │ ← 요청을 여러 서버에 분산, 죽은 서버는 제외 │ (이중화) │ └──┬───┬───┬──┘ │ │ │ 서버1 서버2 서버3 ← 하나가 죽어도 나머지가 처리 └───┼───┘ │ ┌──────▼──────┐ │ DB (Active) │◀──복제──▶ DB (Standby) └──────────────┘ ← 장애 시 대기 서버로 자동 전환(Failover) ▶ 표 10. 이중화 대상별 대응 방법 대상 이중화 방법 전원 이중 PSU, UPS(무정전 전원장치) 디스크 RAID 네트워크 NIC 이중화(티밍/본딩), 스위치 이중화 서버 로드밸런싱, 클러스터링 데이터센터 재해 복구(DR) 센터 구축 9. 서버 운영에서 꼭 챙길 것들 서버는 설치보다 운영이 훨씬 오래 갑니다. ▶ 표 11. 서버 운영 체크리스트 영역 해야 할 일 모니터링 CPU, 메모리, 디스크 사용량, 네트워크, 서비스 상태를 상시 감시하고 임계치 알람 설정 패치 관리 OS와 소프트웨어 보안 패치를 정기적으로 적용 (테스트 후 적용) 백업과 복구 정기 백업 + 복구 테스트 까지 확인 계정·권한 관리 최소 권한 원칙, 퇴사자·미사용 계정 정리 로그 관리 접속·변경 이력 보관, 이상 징후 분석 용량 관리 디스크·메모리 증가 추세를 파악해 사전에 증설 문서화 서버 목록(자산 대장), 구성도, 장애 대응 절차 정리 서버 보안 기본기 불필요한 서비스와 포트는 끄기 관리자 계정 기본 이름·비밀번호 변경 , 다중 인증 적용 방화벽으로 필요한 통신만 허용 원격 접속(SSH, RDP)은 접근 IP 제한 , VPN·제로트러스트 경유 취약점 점검과 패치를 주기적으로 수행 로그를 중앙에 수집 하고 이상 행위를 탐지 서버 침해 사고의 상당수는 고도의 해킹이 아니라 패치 누락, 약한 비밀번호, 불필요하게 열린 포트 같은 기본기 부족에서 시작됩니다. 10. 온프레미스 서버 vs 클라우드 서버 ▶ 표 12. 서버 운영 방식 비교 구분 온프레미스 (자체 서버) 클라우드 장비 소유 회사가 직접 구매 사용료를 내고 빌려 씀 초기 비용 큼 작음 확장 구매 → 설치로 시간 소요 몇 분 내 확장 물리 관리 전산실, 전력, 냉각 직접 관리 클라우드 업체가 담당 통제권 높음 업체 정책 범위 내 적합한 경우 규제·보안 요건, 안정적이고 예측 가능한 부하 변동이 큰 부하, 빠른 서비스 출시 실무에서는 하나만 쓰기보다 온프레미스와 클라우드를 함께 쓰는 하이브리드 구성이 흔합니다. 11. 정리 ▶ 표 13. 핵심 키워드 요약 키워드 한 줄 요약 서버 요청을 받아 처리하고 응답하는 컴퓨터 또는 프로그램 서버 vs PC 서버는 24시간 안정 가동을 위해 이중화와 원격 관리를 갖춤 서버 종류 웹, WAS, DB, 파일, 메일, DNS, 인증 등 역할에 따라 구분 3-Tier 웹 - WAS - DB로 나눠 역할 분리와 독립 확장 가상화·컨테이너 서버 한 대를 효율적으로 나눠 쓰는 기술 RAID 디스크 장애 대비 기술 (백업이 아님!) 가용성 서비스가 얼마나 끊기지 않고 제공되는가 운영 모니터링, 패치, 백업, 권한 관리가 핵심 "서버는 만드는 것보다 안 죽게 오래 운영하는 것이 진짜 실력이다." 다음 글 예고 가상화 기술 자세히 보기: 하이퍼바이저와 VM의 원리 서버 모니터링, 무엇을 어떻게 볼까? 백업 전략: 3-2-1 원칙과 복구 테스트 읽어주셔서 감사합니다. 궁금한 점은 댓글로 남겨주세요! 🙌
정규화 1. 이상현상과 정규화의 목적 잘못 설계된 테이블에서 데이터를 조작할 때 발생하는 무결성 저해 현상을 방지하고, 데이터 중복을 최소화하여 구조의 안정성을 확보하는 과정이다. 삽입 이상 : 새 데이터를 넣을 때 불필요한 속성값까지 억지로 함께 입력해야 하거나, 특정 데이터 없이는 삽입 자체가 불가능한 현상 갱신 이상 : 중복 저장된 튜플 중 일부만 수정되어 데이터 불일치 및 불연속이 발생하는 현상 삭제 이상 : 특정 정보를 삭제할 때 연쇄 작용으로 유지해야 할 유용한 정보까지 함께 삭제되는 현상 2. 정규화 단계 요약 (1NF ~ 5NF) 단계 제거해야 할 요소 / 조건 분해 핵심 원리 제1정규형 (1NF) 도메인이 원자값이 아닌 경우 한 속성에 여러 값이 들어가지 않도록 단일 원자값으로 분리 제2정규형 (2NF) 부분 함수 종속성 복합 기본키의 일부에만 종속되는 속성을 별도 테이블로 분리 (완전 함수 종속화) 제3정규형 (3NF) 이행적 함수 종속성 ($X \rightarrow Y \rightarrow Z$) 기본키가 아닌 일반 속성에 종속되는 일반 속성을 별도 테이블로 분리 BCNF (보이스-코드) 후보키가 아닌 결정자 모든 결정자가 후보키 역할을 하도록 테이블 분리 제4정규형 (4NF) 다치 종속성 (Multi-valued Dependency) 독립적인 1:N 관계가 2개 이상 얽혀 있을 때 각각 1:N 테이블로 분리 제5정규형 (5NF) 조인 종속성 (Join Dependency) 분해된 릴레이션들을 무손실 조인으로 복원할 수 있도록 분해 반정규화 (역정규화) 잦은 조인으로 인해 조회 성능이 심각하게 저하될 때, 시스템 처리 속도 향상을 목적으로 의도적으로 중복·통합을 허용하는 최적화 기법 3. 병행 제어(Concurrency Control) & 잠금(Locking) 여러 트랜잭션이 동시에 실행될 때 데이터베이스의 일관성과 무결성을 보장하기 위한 메커니즘이다. 잠금 단위(Granularity)의 트레이드오프 잠금 단위가 크면 (DB, 테이블 단위): 제어와 관리가 단순하고 오버헤드가 적으나, 동시성(병행성) 수준이 낮아진다. 잠금 단위가 작으면 (레코드, 필드 단위): 동시성(병행성) 수준이 매우 높아지나, 락 관리 오버헤드가 증가하고 복잡해진다. 2단계 잠금 규약 (2PL: Two-Phase Locking) 확장 단계 (Growing Phase) : 락을 획득하기만 하고 해제할 수 없는 단계 축소 단계 (Shrinking Phase) : 락을 해제하기만 하고 새 락을 획득할 수 없는 단계 직렬 가능성을 보장하지만 교착 상태(Deadlock) 가 발생할 수 있다. 4. 장애 회복(Recovery) 기법 로그 기반 회복 즉시 갱신 (Immediate Update) : 트랜잭션 수행 중 변경 결과를 즉시 DB에 반영. 장애 발생 시 미완료 트랜잭션은 UNDO , 완료된 트랜잭션은 REDO 수행 지연 갱신 (Deferred Update) : 트랜잭션 완료( COMMIT ) 전까지 로그에만 기록하고 DB 반영을 지연. 장애 시 UNDO 불필요, REDO 만 수행 체크포인트(Check Point) 회복 : 주기적으로 검사점을 두어, 장애 발생 시 가장 최근 체크포인트 이후의 로그만 분석하여 복구 시간을 단축
선형변환 T: Rn → Rm에서 정의역은 입력이 속한 Rn, 공역은 출력이 속할 수 있는 Rm 전체이다 치역은 T를 통해 실제로 나오는 출력 벡터의 집합이며, 항상 공역의 부분집합이다 전사와 일대일은 치역이 공역을 얼마나 채우는지, 입력과 출력이 어떻게 대응되는지를 구분하는 개념이다 1. Onto(전사) Onto(전사)란 공역의 모든 벡터 b가 적어도 하나의 입력 x의 결과일 때의 T이다 즉 치역이 공역과 같다 R2가 R3 안의 평면 하나로만 보내진다면 공역 전체를 채우지 못하므로 전사가 아니다 공역을 전부 채우려면 정의역의 차원이 공역의 차원 이상이어야 한다 따라서 R2 → R3 변환은 어떤 행렬을 쓰더라도 전사가 될 수 없다 반대로 R3 → R2는 일반적으로 전사가 될 수 있지만 항상 그런 것은 아니다 열벡터가 서로 겹쳐서 R2를 다 펼치지 못하면 전사가 아니기 때문이다 1-1) Onto(전사)의 판정 T(x) = Ax는 A의 열벡터를 x의 성분만큼 선형결합한 것이므로 출력은 항상 열벡터들의 선형결합이다 따라서 공역의 모든 b를 열벡터의 선형결합으로 만들 수 있으면 T는 전사이고 그 역 또한 성립한다 Ax = b의 해가 항상 존재한다는 뜻이다. 이를 열벡터가 Rm을 span한다고도 표현한다 예를 들어 [[2, 0], [−1, 1], [1, 2]]는 열이 2개뿐이다 벡터 2개의 선형결합으로는 R3 전체를 만들 수 없으므로 전사가 아니다 또한 A = [[1, 4, 5], [2, 3, 6]]는 첫째, 둘째 열 (1, 2)와 (4, 3)이 선형독립이다 R2 안에서 독립인 벡터 2개의 선형결합으로 R2 전체를 만들 수 있으므로 전사이다 2.One-to-One 공역의 각 벡터 b가 많아야 하나의 입력 x의 결과일 때 T는 One-to-One이다 치역의 각 벡터를 가리키는 입력이 하나뿐이고 서로 다른 입력은 서로 다른 출력을 만든다. 여러 입력이 같은 점으로 모여버리면 일대일이 아니다 2-1)One-to-One의 판정 A의 열벡터가 선형독립이면 T는 One-to-One이고 그 역 또한 성립한다 열벡터가 선형독립이면 Ax = 0의 해가 x = 0뿐이라서 서로 다른 입력이 같은 출력을 만들 수 없기 때문이다 R2 안의 벡터 3개는 항상 선형종속이므로 정의역의 차원이 공역보다 크면(n > m) One-to-One이 될 수 없다 예를 들어 A = [[2, 0], [−1, 1], [1, 2]]의 두 열 (2, −1, 1)과 (0, 1, 2)는 서로의 상수배가 아니므로 선형독립이다. 따라서 One-to-One이다 하지만 A = [[1, 4, 5], [2, 3, 6]]는 R2 안의 열벡터가 3개라서 선형종속이다. 실제로 셋째 열은 첫째 열의 9/5배와 둘째 열의 4/5배를 더한 것과 같다 따라서 One-to-One이 아니다 3.두 성질의 관계 One-to-One이라고 해서 전사일 필요는 없다 치역이 공역 안의 평면 하나여도, 각 출력을 만드는 입력이 하나뿐이면 일대일이다 반대로 전사라고 해서 일대일인 것도 아니다 두 조건은 서로를 보장하지 않으므로 따로 확인해야 한다 또한 One-to-One이면서 전사가 되려면 입력과 출력의 차원이 같아야 한다 4. 신경망과의 관계 신경망의 fully-connected 층은 입력 벡터에 T(x) = Ax를 적용하는 선형변환이다 예를 들어 (몸무게, 키, 흡연 여부)인 R3를 (과체중 여부, 키 큰 흡연자 여부)인 R2로 바꾸는 층을 생각할 수 있다 4-1) One-to-One 관점: 3차원에서 2차원으로 줄어들므로 One-to-One일 수 없다 서로 다른 사람이 같은 값으로 묶이면서 원래 정보가 일부 사라진다 4-2) 전사 관점: 만들어질 수 없는 (과체중, 키 큰 흡연자) 조합이 없는지를 묻는 것이다 열벡터의 선형결합으로 R2 전체를 만들 수 있는지로 판단한다
기존 프로젝트의 CI/CD 파일을 볼 때는 설정이 너무 많아서 어디서부터 이해해야 할지 막막했다. 이번에는 구조가 단순한 todo-app 에서 CI부터 직접 구성하고, Docker 이미지를 만들어 GitHub Container Registry(GHCR)에 게시하는 데까지 진행했다. 아직 서버 배포는 하지 않았다. 지금까지 확인한 범위는 PR 테스트 자동화 → 로컬 Docker 실행 → GHCR 이미지 수동 게시 다. 1. 먼저 CI가 언제 무엇을 할지 정했다 todo-app 은 Java 17을 사용하는 단일 Gradle 프로젝트다. 처음부터 여러 작업을 넣기보다, PR을 올렸을 때 테스트가 통과하는지만 확인하기로 했다. name: CI on: pull_request: branches: [main, develop] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-java@v6 with: distribution: temurin java-version: '17' cache: gradle - run: ./gradlew test 여기서 branches: [main, develop] 은 PR의 대상 브랜치 를 뜻한다. develop 이나 main 에 직접 푸시했을 때 실행한다는 뜻은 아니다. 기능 브랜치에서 작업한 뒤 develop 을 대상으로 PR을 만들면 CI가 실행된다. main 은 나중에 실제 배포할 변경을 병합하는 브랜치로 사용할 계획이다. GitHub Actions 워크플로 문법 (https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax) ./gradlew test 를 사용한 이유는 저장소에 포함된 Gradle Wrapper로 이 프로젝트의 테스트를 실행하기 위해서다. gradlew 만 실행하면 어떤 작업을 할지 지정되지 않는다. 현재 워크플로는 저장소 루트에서 실행되므로 별도의 프로젝트 경로도 필요하지 않다. 처음에는 PR이 저절로 생성되는 줄 알았는데, 푸시와 PR 생성은 별개였다. 작업 브랜치를 푸시하고 develop 으로 PR을 만들어야 이 흐름을 확인할 수 있었다. 2. 테스트가 느려서 Gradle 캐시를 추가했다 처음 CI를 실행했을 때는 테스트 코드가 간단한데도 시간이 꽤 걸렸다. CI는 내 컴퓨터가 아닌 새 실행 환경에서 시작하므로, Gradle 실행 준비와 의존성 다운로드에도 시간이 든다. 그래서 actions/setup-java 에 cache: gradle 을 추가했다. 관찰한 실행 기록에서는 첫 실행보다 캐시를 복원한 재실행이 빨랐다. 다만 캐시를 추가했다고 모든 PR이 항상 같은 속도로 빨라지는 것은 아니다. PR에서 만든 캐시는 해당 PR의 merge ref에 묶여 다른 PR에서 그대로 재사용되지 않을 수 있다. GitHub Actions 캐시 범위 설명 (https://docs.github.com/en/actions/reference/workflows-and-actions/dependency-caching#restrictions-for-accessing-a-cache) 관찰한 실행 대략적인 전체 시간 해석 캐시 추가 전 PR 실행 82초 Gradle 준비와 테스트를 처음부터 수행 캐시 추가 후 첫 실행 비슷한 수준 저장된 캐시가 없어 즉시 빨라지지는 않음 같은 PR 재실행 43초 캐시 복원 효과를 확인 새로운 PR 실행 100초 PR이 바뀌면 캐시를 다시 받지 못할 수 있음 develop 에 푸시할 때도 CI를 실행해 공유 캐시를 만드는 방법을 검토했지만, 지금은 PR마다 테스트한다는 원래 목적을 유지하기로 했다. 캐시를 넣었다는 사실과 실제 실행시간 개선은 구분해서 봐야 한다는 점을 배웠다. 3. Docker 이미지로 로컬 실행을 확인했다 다음으로 Dockerfile 과 .dockerignore 를 만들었다. Dockerfile은 두 단계로 구성했다. 단계 하는 일 빌드 단계 JDK 17 환경에서 ./gradlew bootJar 로 실행 가능한 JAR 생성 실행 단계 JRE 17 환경에 생성된 JAR만 복사해 애플리케이션 실행 WORKDIR /app 은 컨테이너 내부 에서 이후 명령을 실행할 작업 폴더다. 내 Mac의 /app 폴더를 뜻하지 않는다. COPY 로 빌드에 필요한 파일을 컨테이너에 가져오는 이유는 이미지 빌드가 내 로컬 프로젝트 폴더에서 직접 실행되는 방식이 아니기 때문이다. 처음에는 Docker 엔진이 실행되지 않아 소켓 연결 오류가 났다. Docker Desktop을 실행한 뒤 다음 명령으로 이미지 빌드와 접속을 확인했다. docker build -t todo-app:local . docker run --rm -p 127.0.0.1:18080:8080 todo-app:local 브라우저에서는 http://127.0.0.1:18080 으로 접속했다. 18080 은 내 컴퓨터에서 접속하는 포트, 8080 은 컨테이너 안의 애플리케이션 포트다. 127.0.0.1 을 붙여 내 컴퓨터에서만 접근하도록 했다. IntelliJ에서 애플리케이션을 실행하는 것과 비슷하게 로컬에서 접속하지만, 이번에는 컨테이너 안에서 실행된 앱 에 접속한 것이다. 4. GHCR에 이미지를 게시했다 로컬에서 이미지를 실행한 다음에는 GitHub Actions가 이미지를 빌드해 GHCR에 게시하는 워크플로를 추가했다. on: workflow_dispatch: permissions: contents: read packages: write workflow_dispatch 를 사용했으므로 PR 병합만으로 이미지를 게시하지는 않는다. GitHub Actions 화면에서 직접 실행해야 한다. 워크플로는 GitHub 실행 환경에서 저장소의 Dockerfile로 새 이미지를 빌드 하고, ghcr.io 에 게시한다. 로컬에서 만들었던 todo-app:local 이미지를 그대로 업로드하는 것은 아니다. 이미지 태그에는 커밋 SHA를 사용해 어느 코드로 만든 이미지인지 구분한다. 게시 워크플로의 성공을 확인했고, GitHub의 Packages 화면에서도 이미지가 보이는 것을 확인했다. 여기까지는 이미지 저장소에 게시한 것 이지, EC2 서버에 배포한 것은 아니다. GitHub Container Registry 문서 (https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry) 기존 프로젝트와 무엇이 달랐나 프로젝트 CI 구성 이미지와 배포 구성 todo-app 단일 Gradle 프로젝트에서 PR 대상이 develop / main 일 때 ./gradlew test Docker 이미지 로컬 실행 확인, GHCR에 수동 게시까지 완료. 서버 배포는 아직 없음 PARUT 여러 서비스 중 변경된 서비스를 감지해 빌드, 테스트용 PostgreSQL/Redis도 사용 워크플로 설정상 ECR에 이미지를 저장하고 SSM 명령으로 EC2 배포 bonae-dream-logistics 여러 모듈을 빌드하고 지정된 모듈의 테스트를 실행 워크플로 설정상 GHCR에 이미지를 저장하고 SSH/SCP로 EC2 배포 두 기존 프로젝트는 서비스나 모듈이 여러 개라 변경 감지, matrix, 서비스별 경로, 테스트용 외부 서비스가 필요하다. 반면 todo-app 은 단일 애플리케이션이라 처음부터 그 구조를 가져올 이유가 없었다. 기존 프로젝트의 설정을 복사하기보다 현재 프로젝트에서 필요한 단계가 무엇인지 판단하는 연습 이 되었다. 위 비교는 각 저장소의 워크플로 설정을 기준으로 한 것이다. 기존 프로젝트의 실제 서버 배포 성공 여부까지 이번에 검증한 것은 아니다. 다음 작업: 같은 앱을 두 방식으로 배포해보기 다음에는 EC2에 실제로 배포해볼 예정이다. 비교하려는 방식은 두 가지다. 방식 이미지 저장소 서버에서 배포 명령을 실행하는 방법 배우려는 점 1안 GHCR SSH 이미 게시한 이미지를 서버에서 받아 실행하는 전체 흐름 2안 AWS ECR AWS Systems Manager(SSM) AWS의 이미지 저장소와 원격 명령 방식, 권한 설정 이는 Todo 앱을 두 버전으로 개발한다는 뜻이 아니다. 같은 앱과 같은 서버를 기준으로 이미지 저장소와 원격 실행 방식만 바꿔 비교 해보려는 것이다. 그래야 어떤 설정과 권한이 추가되는지, 운영 방식이 어떻게 달라지는지 직접 이해할 수 있다. 먼저 GHCR + SSH로 배포를 완성하고, 이후 ECR + SSM을 실습할 계획이다. 두 배포 워크플로를 동시에 자동 실행해 같은 서버의 컨테이너를 서로 덮어쓰게 하지는 않을 것이다. 실제 배포 전에는 EC2 비용과 보안 설정, 이미지 접근 권한부터 확인해야 한다. 최종적으로는 develop 에서 개발하고, 검증한 변경을 main 에 병합할 때 배포하는 흐름을 목표로 한다. 이번 실습에서 가장 크게 배운 점은 CI 성공, Docker 실행, 이미지 게시, 서버 배포는 각각 다른 완료 단계 라는 것이다. 지금은 앞의 세 단계까지 확인했다. 다음 TIL에는 실제 EC2 배포 결과와 두 방식의 차이를 기록해보려 한다.
클라우드 컴퓨팅을 처음 접하는 분들을 위한 입문 글입니다. 개념부터 동작 원리까지, 비유와 그림으로 쉽게 풀어봅니다. 1. 클라우드, 한 줄로 정의하면? "내가 직접 서버를 사지 않고, 인터넷을 통해 컴퓨팅 자원을 빌려 쓰고, 쓴 만큼만 비용을 내는 방식" 전기에 비유해볼게요. 전기를 쓸 때 발전소가 어떻게 돌아가는지 몰라도 되듯이, 클라우드를 쓸 때도 데이터센터의 전원, 냉각, 하드웨어 교체를 신경 쓰지 않아도 됩니다. ▶ 표 1. 온프레미스 vs 클라우드 비교 구분 온프레미스 (직접 구축) 클라우드 비유 내 집에 발전소를 짓는다 한전에서 전기를 끌어다 쓴다 초기 비용 매우 큼 거의 없음 비용 방식 구매 (CAPEX) 사용량 과금 (OPEX) 확장 속도 주문 → 배송 → 설치 (몇 주) 클릭 몇 번 (몇 분) 관리 책임 전부 내 책임 일부는 클라우드 업체가 담당 2. 왜 클라우드가 필요해졌을까? 2-1. 온프레미스 시절의 고민 서비스가 갑자기 인기를 얻으면? → 서버가 모자라서 장애 발생 반대로 서버를 넉넉히 사두면? → 평소엔 놀고 있는 자원에 돈 낭비 서버 구매, 설치, 네트워크 연결까지 수 주~수 개월 소요 하드웨어 고장, 전원, 냉각, 물리 보안까지 전부 직접 관리 2-2. 클라우드가 준 해결책 필요할 때 바로 서버를 만들고 안 쓰면 바로 지우고 쓴 만큼만 비용을 냅니다 이 세 가지가 클라우드의 핵심 가치입니다. 3. 클라우드의 5가지 핵심 특성 (NIST 정의) 미국 국립표준기술연구소(NIST)는 클라우드의 조건을 다섯 가지로 정리했습니다. ▶ 표 2. NIST가 정의한 클라우드의 5대 특성 특성 설명 온디맨드 셀프서비스 담당자에게 요청하지 않아도 사용자가 직접 콘솔이나 API로 자원을 만듭니다. 광범위한 네트워크 접근 인터넷만 되면 어디서든 접속할 수 있습니다. 자원 풀링 여러 고객이 거대한 자원 풀을 나눠 씁니다. (멀티 테넌시) 빠른 탄력성 트래픽이 늘면 자동으로 늘리고, 줄면 자동으로 줄입니다. 측정 가능한 서비스 사용량이 측정되고, 그에 따라 과금됩니다. 4. 클라우드는 어떻게 가능할까? (핵심 원리) 4-1. 가상화 (Virtualization) 클라우드의 가장 밑바닥 기술입니다. 물리 서버 1대를 논리적으로 여러 대의 "가상 서버"로 쪼개는 기술 ▶ 그림 1. 가상화 전후 비교 [가상화 이전] [가상화 이후] 물리 서버 1대 물리 서버 1대 └─ OS 1개 ├─ 가상머신 A (Linux) └─ 앱 1개 ├─ 가상머신 B (Windows) (CPU 10%만 사용...) └─ 가상머신 C (Linux) (자원 활용률 대폭 상승) 하이퍼바이저 라는 소프트웨어가 물리 자원(CPU, 메모리, 디스크)을 나눠서 각 가상머신에 배분합니다. 아파트 한 동(물리 서버)을 여러 세대(가상머신)로 나눠 각자 독립된 집처럼 쓰는 것과 비슷해요. 4-2. 자원 풀링과 규모의 경제 클라우드 업체는 전 세계에 거대한 데이터센터를 운영하며 서버를 대량으로 구매합니다. 이렇게 확보한 자원을 여러 고객이 나눠 쓰기 때문에, 개별 기업이 직접 구축하는 것보다 단가가 낮아집니다. 4-3. 자동화와 API 클라우드의 모든 기능은 API 로 제어됩니다. 콘솔에서 버튼을 누르는 것도 내부적으로는 API를 호출하는 것이죠. 그래서 코드로 인프라를 만드는 IaC(Infrastructure as Code) 가 가능해집니다. ▶ 코드 1. Terraform으로 서버 1대 생성하기 resource "aws_instance" "web" { ami = "ami-0abcdef1234567890" instance_type = "t3.micro" tags = { Name = "my-first-server" } } 이 코드를 실행하면 서버가 만들어지고, 코드를 삭제하고 적용하면 서버가 사라집니다. 인프라가 "손으로 하는 작업"에서 "버전 관리되는 코드"로 바뀌는 거죠. 5. 서비스 모델: IaaS, PaaS, SaaS 클라우드 입문에서 가장 자주 나오는 개념입니다. 핵심은 "내가 어디까지 관리하느냐" 의 차이예요. 5-1. 피자로 이해하기 🍕 ▶ 표 3. 피자 비유로 보는 서비스 모델 모델 비유 설명 온프레미스 집에서 직접 만들기 재료, 도구, 조리 전부 내가 IaaS 재료와 주방 빌리기 서버·네트워크는 빌리고 나머지는 내가 PaaS 피자 배달 (토핑만 고르기) 실행 환경까지 제공, 앱만 올리면 됨 SaaS 피자 가게에서 먹기 완성품을 그냥 사용 5-2. 관리 책임 비교 ▶ 그림 2. 모델별 관리 주체 (내가 관리 / 업체가 관리) 온프레미스 IaaS PaaS SaaS 애플리케이션 내가 내가 내가 업체 데이터 내가 내가 내가 내가 런타임/미들웨어 내가 내가 업체 업체 OS 내가 내가 업체 업체 가상화 내가 업체 업체 업체 서버/스토리지 내가 업체 업체 업체 네트워크 내가 업체 업체 업체 SaaS에서도 내가 입력한 데이터의 관리와 접근 권한 설정 은 사용자 몫입니다. 5-3. 실제 서비스 예시 ▶ 표 4. 서비스 모델별 대표 서비스 모델 대표 서비스 IaaS AWS EC2, Azure Virtual Machines, Google Compute Engine PaaS AWS Elastic Beanstalk, Azure App Service, Heroku SaaS Microsoft 365, Google Workspace, Slack, Salesforce 6. 배포 모델: 퍼블릭 / 프라이빗 / 하이브리드 ▶ 표 5. 클라우드 배포 모델 비교 모델 설명 예시 퍼블릭 클라우드 업체가 운영하는 자원을 여러 고객이 공유 AWS, Azure, GCP 프라이빗 클라우드 한 조직 전용으로 구축한 클라우드 사내 VMware 기반 환경 하이브리드 클라우드 온프레미스(또는 프라이빗)와 퍼블릭을 연결 민감 데이터는 사내, 웹 서비스는 퍼블릭 멀티 클라우드 여러 퍼블릭 클라우드를 함께 사용 AWS + Azure 병행 실무에서는 규제, 보안, 비용, 기존 자산 때문에 하이브리드 나 멀티 클라우드 를 택하는 경우가 매우 많습니다. 7. 클라우드의 구조: 리전과 가용 영역 퍼블릭 클라우드는 다음과 같은 계층으로 구성되어 있습니다. ▶ 그림 3. 클라우드 인프라 계층 구조 클라우드 (예: AWS) └─ 리전 (Region): 지리적 지역 (예: 서울, 도쿄, 버지니아) └─ 가용 영역 (AZ): 리전 안의 독립된 데이터센터 묶음 └─ 데이터센터: 실제 서버가 있는 건물 왜 이렇게 나눌까? 장애 격리 : 한 데이터센터에 화재나 정전이 나도 다른 AZ는 멀쩡합니다. 고가용성 : 서버를 여러 AZ에 분산 배치하면 한 곳이 죽어도 서비스가 유지됩니다. 지연 시간(Latency) : 사용자와 가까운 리전을 쓰면 응답이 빨라집니다. 데이터 주권 : 법적으로 데이터를 특정 국가 안에 둬야 할 때 리전을 선택합니다. 8. 탄력성: 오토스케일링 클라우드의 꽃이라 할 수 있는 기능입니다. 트래픽에 맞춰 서버 수가 자동으로 늘고 줄어듭니다. ▶ 그림 4. 트래픽에 따른 서버 자동 증감 트래픽 ▲ │ ╱╲ ← 이벤트 시간대 (서버 자동 증가) │ ╱ ╲ │ ___╱ ╲___ ← 평상시 (서버 자동 감소) └──────────────────▶ 시간 ▶ 표 6. 확장 방식 비교 방식 의미 특징 Scale Up / Down (수직 확장) 서버 한 대의 사양을 키우거나 줄임 간단하지만 한계가 있고, 서버 1대가 죽으면 끝 Scale Out / In (수평 확장) 서버 대수를 늘리거나 줄임 한 대가 죽어도 나머지가 버팀 클라우드에서는 보통 수평 확장 을 선호합니다. 9. 공동 책임 모델 (Shared Responsibility Model) "클라우드에 올렸으니 보안도 업체가 알아서 해주겠지?" 는 위험한 착각입니다. ▶ 표 7. 클라우드 업체와 고객의 보안 책임 구분 영역 책임 주체 데이터센터 물리 보안, 하드웨어, 네트워크 인프라 ☁️ 클라우드 업체 OS 패치, 방화벽 설정, 접근 권한(IAM), 데이터 암호화 👤 고객 업체는 "클라우드 자체의 보안" 을, 고객은 "클라우드 안에 올린 것들의 보안" 을 책임집니다. 실제로 클라우드 보안 사고의 상당수는 업체의 해킹이 아니라 고객의 설정 실수 (공개 상태로 열린 스토리지 버킷, 과도한 권한 부여 등)에서 발생합니다. 10. 클라우드의 장점과 주의할 점 장점 ✅ 초기 투자 비용 절감 빠른 도입과 확장 글로벌 서비스 용이 고가용성, 재해 복구 구성이 쉬움 인프라 운영 부담 감소 주의할 점 ⚠️ 비용 관리 : 켜놓고 잊어버린 리소스가 청구서 폭탄으로 돌아옵니다. (FinOps의 필요성) 벤더 종속(Lock-in) : 특정 업체 전용 서비스에 깊이 의존하면 이전이 어렵습니다. 보안 설정 책임 : 공동 책임 모델의 이해가 필수입니다. 네트워크 의존 : 인터넷 연결 품질이 곧 서비스 품질입니다. 11. 정리 ▶ 표 8. 핵심 키워드 요약 키워드 한 줄 요약 클라우드 인터넷으로 빌려 쓰는 컴퓨팅 자원, 종량제 가상화 물리 서버를 논리적으로 쪼개는 기반 기술 IaaS / PaaS / SaaS 내가 어디까지 관리하느냐의 차이 리전 / AZ 장애 격리와 고가용성을 위한 물리적 구조 탄력성 수요에 따라 자원을 자동으로 늘리고 줄임 공동 책임 모델 업체와 고객이 보안 책임을 나눠 가짐 다음 글 예고 컨테이너와 쿠버네티스는 왜 클라우드와 함께 언급될까? 클라우드 네트워크(VPC) 쉽게 이해하기 IAM: 클라우드 보안의 시작점 읽어주셔서 감사합니다. 궁금한 점은 댓글로 남겨주세요! 🙌
최근 주문현황을 고객 이름과 상품명을 포함해서 보고서로 만들어줘!! USERS , PRODUCTS , ORDERS 테이블만 있는 상황 ORDERS 에서는 id 만있느 고객이름, 상품명이 없다. 만약 모든 데이터를 하나의 테이블에 저장한다면? 고객이 주문하지 않은 상품은 어떻게 관리 할래 주문하지 않은 고객은 어떻게 관리 할래 모든 주문거의 상품 마다 저장하면 얼마나 많은 커다란 데이터가 있을까 데이터 중복(Redundancy) : 고객이 100번 주문하면, 이름, 이메일, 주소 정보가 100번이나 불필요하게 저장 갱신 이상(Update Anomaly) : 100번 주문한 고객의 주소가 변경되면 1개라도 누락되면 어떻게할래 삽입 이상, 삭제 이상 우리는 데이터베이스를 설계할 때 정규화(Normalization) 라는 과정을 거친다. 데이터 중복을 최소화하고 일관성을 유지하기 위해 데이터를 논리적인 단위로 분리하는 과정 이래서 조인이 필요하다 여러가지 이유로 데이터를 왜 분리해서 저장하는지 이해했다. 데이터의 중복을 막고 일관성을 지키기 위함 즉, 데이터를 잘 관리 하기 위해서 이다. 하지만 반대로 의미있는 정보를 얻기 위해서는 흩어진 조각을 합쳐야하는데 이게 조인 데이터 정규화()뿐리)를 통해 얻는 일관성과 효율성의 장점은 그대로 유지하면서, 우리가 원하는 통합된 정보를 얻을수 있게 해주는 기술이다. 내부 조인 두 테이블을 연결할때, 양쪽 테이블에 모두 공통으로 존재하는 데이터만을 결과 로 보여줌 주문이 완료된( COMPLETED ) 모든 주문에 대해, 어떤 고객이 주문했는지 고객 ID, 고객 이름과 주문 날짜를 함께 보고 싶네 SELECT * FROM orders INNER JOIN users ON orders.user_id = users.user_id; SELECT orders.user_id, users.name, orders.order_date FROM orders INNER JOIN users ON orders.user_id = users.user_id WHERE orders.status = 'COMPLETED' 논리적인 순서 FROM / JOIN 을 통해 가상 테이블을 만든다. WHERE join을 통해 생성된 가상 테이블에서 WHERE 절의 조건이 만족하는 행들만 필터링 SELECT 필터링된 가상 테이블에서 SELECT 로 최종 결과 정리 물론 쿼리 최적화기를 통해 효율적으로 실행하는 순서는 달라질수 있다. 일단은 SQL 자체에 집중 내부 조인의 순서는 언제 중요할까? 내부 조인은 결과가 같으므로 어떤 순서로 작성해도 무방하다. 어떤 데이터가 중심이 되는가 에 집중하면 가독성이 높아진다. 주문 목록을 중심 으로 고객 정보를 추가 FROM orders JOIN users 고객 목록을 중심 으로 주문 정보를 조회 FROM users JOIN orders 외부조인은 순서가 결과에 매우 큰 영향을 미친다 다행이 문제는 그냥 원트에 풀었따
회귀 함수를 기반으로 최적 회귀 함수를 도출하지 않고 결정 트리를 기반으로 하는 회귀 방식을 소개하겠습니다. 회귀 트리는 분류 트리와 달리 리프 노드에 속한 데이터 값의 평균값을 구해 회귀 예측값을 계산합니다. 데이터 세트의 X 피처를 결정 트리 기반으로 분할하면 X값의 균일도를 반영한 지니계수에 따라 다음 그림의 왼쪽과 같이 분할할 수 있습니다. 루트 노드를 Split 0을 기준으로 분할하고 이렇게 분할된 규칙노드에서 다시 Split1과 Split2 규칙 노드로 분할할 수 있습니다. 그리고 Split 2는 다시 재귀적으로 Split3 규칙 노드로 다음 그림의 오른쪽과 같이 트리 규칙으로 변환될 수 있습니다. 리프 노드 생성 기준에 부합하는 트리 분할이 완료됐다면 리프 노드에 소속된 데이터 값의 평균값을 구해서 최종적으로 리프 노드에 결정 값으로 할당합니다. 결정트리, 랜덤 포레스트,GBM,XGBoost,LightGBM 등의 앞 4장의 분류에서 소개한 모든 트리 기반의 알고리즘은 분류뿐만 아니라 회귀도 가능합니다. 트리 생성이 CART(Classification and Regression Trees)는 이름에서도 알 수 있듯이 분류뿐만 아니라 회구도 가능하게 해주는 트리 생성 알고리즘입니다. 사이킷런에서는 결정트리, 랜덤 포레스트, GBM에서 CART 기반의 회귀 수행을 할 수 있는 Estimator 클래스를 제공합니다. 또한 XGBoost,LightGBM도 사이킷런 래퍼 클래스를 통해 이를 제공합니다. 회귀 트리 Regressor 클래스는 선형 회귀와 다른 처리 방식이므로 회귀 계수를 제공하는 $coef_$ 속성이 없습니다. 대신 $feature_importance_$를 이용해 피처별 중요도를 알 수 있습니다.
참고자료 https://publications.aston.ac.uk/id/eprint/373/1/NCRG_94_004.pdf 1. 기존 딥러닝 일반적인 회귀 신경망은 입력 벡터 $\mathbf{x}$를 받아 목표 벡터 $\mathbf{t}$의 각 성분에 해당하는 출력 $f_k(\mathbf{x};\mathbf{w})$를 계산합니다. MSE로 학습할 때의 오차 함수는 다음과 같습니다. $$ \frac{1}{2} \sum_{q=1}^{n}\sum_{k=1}^{c} \left[ f_k(\mathbf{x}^{q};\mathbf{w})-t_k^{q} \right]^2 $$ 데이터가 충분히 많고 모델이 데이터를 잘 표현할 수 있을 때 데이터에 대한 합을 결합확률밀도 $p(\mathbf{t},\mathbf{x})$를 이용한 적분으로 나타낼 수 있습니다. $$ \begin{aligned} E &= \lim_{n\to\infty} \frac{1}{2n}\sum_{q=1}^{n}\sum_{k=1}^{c}[f_k(\mathbf{x}^q;\mathbf{w})-t_k^q]^2 \ &= \frac{1}{2}\sum_{k=1}^{c}\iint [f_k(\mathbf{x};\mathbf{w})-t_k]^2, p(\mathbf{t},\mathbf{x}),d\mathbf{t},d\mathbf{x} \end{aligned} $$ 고정된 입력 $\mathbf{x}$에서 이 오차를 최소화하는 출력값을 구해보면 $p(\mathbf{t},\mathbf{x})=p(\mathbf{t}\mid\mathbf{x})p(\mathbf{x})$를 이용하고 $f_k(\mathbf{x};\mathbf{w})$에 대해 미분하면 다음과 같습니다. $$ \int \left[ f_k(\mathbf{x};\mathbf{w})-t_k \right] p(\mathbf{t}\mid\mathbf{x})d\mathbf{t} =0 $$ 조건부 확률밀도의 적분값은 1입니다. 따라서 출력값은 $$ \langle t_k\mid\mathbf{x}\rangle = \int t_k,p(\mathbf{t}\mid\mathbf{x}),d\mathbf{t} $$ MSE로 학습한 신경망의 $k$번째 출력은 입력 $\mathbf{x}$가 주어졌을 때 목표값 $t_k$의 조건부 평균입니다. 하지만 하나의 입력에 대해 목표값이 여러개라면 어떻게 될까요? 2. inverse problem 어떤 과정에서는 같은 결과가 서로 다른 원인에서 나올 수도 있습니다. 이렇게 관측된 결과로부터 그 결과를 만들어 낸 원인을 추정하는 문제를 inverse problem(역문제)이라고 합니다. 결과가 같더라도 가능한 원인이 여러 개라면, 하나의 입력에 여러 목표값이 대응하게 됩니다 이제 관측된 결과를 신경망의 입력 $\mathbf{x}$ 추정할 원인을 목표값 $\mathbf{t}$라고 두겠습니다. 어떤 입력 $\mathbf{x}_0$에 대해 서로 다른 두 목표값 $\mathbf{t}_1$, $\mathbf{t}_2$가 모두 가능하다고 하였을 때 MSE 회귀 신경망은 하나의 출력값만 예측합니다. 두 목표값이 비슷한 빈도로 나타난다면 $k$번째 출력은 대략 다음과 같습니다. $$ \langle t_k\mid\mathbf{x}0\rangle \approx \frac{t_{1,k}+t_{2,k}}{2} $$ 이 출력의 문제점은 출력값이 두 개의 원인 모두와 값이 달라 어느 쪽에도 해당하지 않을 수 있다는 점입니다. 이와 같은 역문제에서는 평균값 하나를 예측하는 것보다 주어진 입력에서 어떤 목표값들이 얼마나 가능한지를 나타내는 조건부 분포 $p(\mathbf{t}\mid\mathbf{x})$를 모델링할 필요가 있습니다. 이것이 다음 절에서 살펴볼 MDN의 출발점입니다. 3. MDN 문제는 신경망이 입력 $\mathbf{x}$에 대해 목표값 하나만 출력한다는 데 있습니다. Mixture Density Network(MDN) 는 목표값 하나 대신 조건부 확률밀도 $p(\mathbf{t}\mid\mathbf{x})$를 모델링합니다. 따라서 같은 입력에서 여러 목표값이 가능한 상황도 표현할 수 있습니다. MDN은 신경망과 혼합모형으로 구성됩니다. 신경망은 입력 $\mathbf{x}$를 받아 혼합모형의 파라미터를 출력하고 혼합모형은 이 파라미터를 사용해 목표값 $\mathbf{t}$의 확률밀도를 만듭니다. 가우시안 성분을 $m$개 사용하면 다음과 같습니다. $$ \sum_{i=1}^{m} \alpha_i(\mathbf{x}) \phi_i(\mathbf{t}\mid\mathbf{x}) $$ $\phi_i(\mathbf{t}\mid\mathbf{x})$는 $i$번째 가우시안의 확률밀도이고 $\alpha_i(\mathbf{x})$는 그 성분의 혼합계수입니다. 각 성분은 입력에 따라 다음 세 가지 값을 가집니다. $\alpha_i(\mathbf{x})$: 해당 성분이 차지하는 비중 $\boldsymbol{\mu}_i(\mathbf{x})$: 해당 성분의 중심 $\sigma_i(\mathbf{x})$: 해당 성분의 퍼짐 정도 목표 벡터 $\mathbf{t}$의 차원이 $c$일 때 자료에서 사용한 가우시안 성분은 다음과 같습니다. $$ \frac{1}{(2\pi)^{c/2}\sigma_i(\mathbf{x})^c} \exp\left( -\frac{|\mathbf{t}-\boldsymbol{\mu}_i(\mathbf{x})|^2} {2\sigma_i(\mathbf{x})^2} \right) $$ 혼합계수는 확률의 비중이어서 $\alpha_i(\mathbf{x})\geq 0$, $\sum_{i=1}^{m}\alpha_i(\mathbf{x})=1$이어야 합니다. 이를 위해 신경망의 혼합계수 출력을 softmax에 통과시킵니다. 이 구조에서는 한 입력에 대해 가능한 목표값이 두 군데에 모여 있을 때 두 가우시안의 중심을 각각의 목표값 근처에 둘 수 있습니다. 기존 MSE 회귀 모델은 두 값 사이의 평균을 하나의 답으로 출력하지만 MDN은 두 영역 모두에서 목표값이 나올 수 있음을 분포로 표현합니다. 각 영역의 비중과 퍼짐 정도도 함께 나타낼 수 있습니다. 4. software implementation Mixture Density Network도 일반적인 신경망과 같은 방법으로 학습합니다. 신경망이 혼합분포의 파라미터를 출력하면 오차 함수가 그 파라미터와 목표값을 이용해 손실 및 출력층의 기울기를 계산합니다. 이후에는 이 기울기를 신경망에 역전파하여 가중치를 조정합니다. MSE 회귀에서는 예측값과 목표값의 차이 제곱을 오차로 사용했습니다. MDN은 입력 $\mathbf{x}^{q}$가 주어졌을 때 실제 목표값 $\mathbf{t}^{q}$에 모델이 얼마나 높은 확률밀도를 부여하는지 평가합니다. $q$번째 데이터의 손실은 음의 로그 가능도입니다. $$ E^q = -\ln p(\mathbf{t}^q|\mathbf{x}^q) = -\ln\left[\sum_{i=1}^{m}\alpha_i(\mathbf{x}^q)\phi_i(\mathbf{t}^q|\mathbf{x}^q)\right] $$ 신경망의 출력 벡터를 $\mathbf{z}^{q}$라고 하겠습니다. 이 출력으로부터 혼합계수 $\alpha_i$ 평균 $\boldsymbol{\mu}_i$ 표준편차 $\sigma_i$를 계산합니다. 오차 함수는 $\mathbf{z}^{q}$와 목표값 $\mathbf{t}^{q}$를 받아 손실 $E^q$ 및 출력에 대한 기울기 $\boldsymbol{\delta}^{q}=\nabla{\mathbf{z}^{q}}E^q$를 반환합니다. 가중치를 조정하려면 먼저 실제 목표값 $\mathbf{t}^{q}$에 대해 각 가우시안 성분이 얼마나 기여했는지 계산합니다. 이를 $i$번째 성분의 책임도라고 합니다. $$ \frac{ \alpha_i(\mathbf{x}^{q}) \phi_i(\mathbf{t}^{q}\mid\mathbf{x}^{q}) }{ \sum_{j=1}^{m} \alpha_j(\mathbf{x}^{q}) \phi_j(\mathbf{t}^{q}\mid\mathbf{x}^{q}) } $$ 책임도를 이용하면 손실을 신경망의 출력인 혼합계수, 평균, 표준편차에 대해 미분할 수 있습니다. 이렇게 구한 출력층의 기울기를 일반적인 역전파 알고리즘과 동일하게 사용하면 됩니다. $$ \sum_j \frac{\partial E^q}{\partial z_j^q} \frac{\partial z_j^q}{\partial w} $$
Opus 5.5 发布后,网友都抢着试用。一刷就是好几个作品,从网页、动画到游戏等等。这些都比 benchmark 的数值直观,有的还能自己上手试试。一位名为 MiaAI Lab 的创作者直接让 Opus 5.5「做 100 个 HTML 文件」,附带三条要求:好看、设计不要重复、充分发挥创意。做出来的成品十分惊人。 阅读全文