Category: Develop

0

[PostgreSQL] 인증 및 보안 강화하기

🔐 PostgreSQL 인증 강화 가이드 — 비밀번호만으로는 부족하다PostgreSQL은 기본적으로 username + password 조합으로 인증하지만,그 외에도 여러 보안 강화 방법을 제공하여 MFA(다단계 인증) 수준의 보호를 구축할 수 있습니다.이 글에서는 PostgreSQL의 인증 강화 방안을 단계별로 정리합니다. 1️⃣ 비밀번호 보안 강화 (기본 강화)기본적인 로그인 방식을 유지하면서도 훨씬 안전하게 만드는 방법입니다. ✅ SCRAM-SHA-256 전환md5보다 훨씬 안전한 해시 알고리즘입니다. # postgresql.confpassword_encryption = scram-sha-256 # pg_hba.confhost all all 10.0.0.0/8 scram-sha-256 ✅ 채널 바인딩 (MITM 방어)

0

[JAVA] - Cold Start

목차 [JAVA] - 가비지 컬렉션 튜닝 [JAVA] - Garbage Collection(가비지 컬렉션) [JAVA] - JVM (자바 가상 머신) 🧊 Cold Start란?Cold Start는 JVM이 애플리케이션이 처음 실행될 때 초기화 과정 때문에 발생하는 지연(latency) 을 의미합니다. 마치 추운 겨울날 자동차 시동을 걸 때 엔진이 따뜻해질 때까지 시간이 걸리는 것과 비슷합니다. 일반적인 서버 환경에서는 애플리케이션이 한 번 시작되면 계속 실행되기 때문에 이 문제가 크게 부각되지 않았습니다. 하지만 MSA 는 인스턴스가 빈번히 생성 및 소멸되고 여러 서버가 긴밀히 통신하는 환경입니다. 이로 인해 특정 시스템이 재부팅되면 연결된 다른 시스템의 응답 속도까지 지연되는 문제가 발생했으며, 무중단 배포·잦은 배포·오토스케일링 등으로 인해 기존 아키텍처보다 성능 지연 현상이 더 빈번하게 나타나게 되었고, 전체적인 서비스 성능 이슈의 문제가 됐습니다. 🚦 Cold Start가 발생하는 이유Java 애플리케이션은 네이티브 코드가 아닌 JVM 위에서 바이트코드 실행 방식으로 동작하기 때문에, 첫 실행 시 다음과 같은 과정에서 오버헤드가 발생합니다. 1. JVM 초기화 과정의 복잡성Java 애플리케이션이 시작될 때 여러 단계의 초기화 과정을 거쳐야 합니다:

0

[Java] - 가비지 컬렉션 히스토리

목차 [JAVA] - 가비지 컬렉션 튜닝 [JAVA] - Garbage Collection(가비지 컬렉션) [JAVA] - JVM (자바 가상 머신) 초기 GC들 (JDK 1.0~1.4)Serial GC 가장 오래된 GC 단일 스레드로 동작 작은 애플리케이션이나 클라이언트 환경에 적합 Stop-the-World 시간이 길어서 현재는 제한적으로 사용 Parallel GC (Throughput Collector) JDK 1.4에서 도입 멀티코어 환경에서 여러 스레드를 사용해 처리량을 개선 JDK 6~8에서 기본 GC 여전히 긴 정지 시간이 단점 저지연 목표 GC들 (JDK 1.4~)Concurrent Mark Sweep (CMS) GC

0

[Docker] 이미지 history

목차 [Docker] 이미지 history [Docker] 이미지 레이어 [Docker] 이미지 Build 참고 Docker History 명령어 공식문서 📋 이미지 historyDocker 이미지를 받아서 사용하다보면 해당 이미지가 어떻게 생성 됐는지, 어떤 명령어를 사용했는지 확인해봐야 할때가 있습니다. Docker 에서는 history 명령어를 이용해 해당 이미지가 어떤 명령어를 이용해 이미지가 생성 됐는지 확인할 수 있는 기능을 제공합니다. 저 같은 경우는 제대로 작동되지 않는 빌드된 이미지에 대한 디버깅용으로 사용을 많이 했었습니다. ✅ docker history 명령어기본 명령어

0

[Docker] 이미지 레이어

목차 [Docker] 이미지 레이어 [Docker] 이미지 Build 참고 Docker 공식 문서 - 이미지 레이어 이해하기 Docker 공식 문서 - Storage drivers 🔍 이미지 레이어란?Docker 이미지의 핵심적인 특징 중 하나는 레이어 기반 구조 입니다. Docker 이미지는 빌드시 한번에 만들어 지는 것이 아닌 기존 이미지에 레이어를 하나씩 쌓는 방식으로 이미지를 만듭니다. 이미지 레이어는 Dockerfile 에 있는 명령어를 실행할때 각 명령어별로 생성됩니다.. 각 레이어들은 읽기 전용 (read-only) 속성을 가지며, 순서대로 쌓여서 하나의 완전한 이미지를 구성합니다. 최종적으로 생성되는 이미지는 여러개의 레이어들이 쌓여서 만들어진 결과물이라 생각하면 됩니다. ✅ 레이어의 특징

0

[Docker] 이미지 Build

🔍 Docker Build 란?Docker Build 는 서비스를 격리된 환경에서 실행할 수 있도록 운영체제 및 필요한 의존성과 설정, 실행 파일등을 하나의 이미지로 패키징하는 것을 의미합니다. 이미지 Build 는 Dockerfile 을 기반으로 수행되며, Dockerfile 에는 이미지 생성에 필요한 명령어들이 있으며, 순서대로 실행됩니다. ✅ Build 명령어# 현재 디렉토리 위치에 Dockerfile 가 있고 현재 위치에서 이미지를 생성할 경우docker build -t <만들 이미지 이름>:<만들 이미지 태그> .# Dockerfile 이 다른 경로에 있을 경우docker build -t <만들 이미지 이름>:<만들 이미지 태그> -f <파일 경로> <빌드 컨텍스트 경로># Dockerfile 명이 다를 경우우docker build -t <만들 이미지 이름>:<만들 이미지 태그> -f <파일 경로/파일 이름> <빌드 컨텍스트 경로> ✅ 이미지지 레이어Docker 는 Build 시 Dockerfile 의 베이스가 되는 이미지부터 시작해 각 명령어를 실행할 때마다 새로운 이미지를 생성합니다. 이것을 이미지 레이어를 생성한다고 이야기 합니다. 때문에 초기 명령어들이 같고 중간 단계 부터 달라지는 Dockerfile 의 경우 빌드시 각각 이미지 레이어를 생성하는게 아닌 기존에 만들어진 이미지 레이어를 바탕으로 새로운 이미지를 생성해 빌드시간과 저장공간을 절약할 수 있습니다. ✅ Dockerfile

0

[Docker] Network - 컨테이너간 통신

목차 [Docker] Volume - 컨테이너 데이터 관리 [Docker] Network - 컨테이너간 통신 [Docker] 📌 Docker Network 란?Docker Network는 컨테이너 간 통신을 가능하게 해주는 가상 네트워크입니다. 컨테이너는 독립적인 환경에서 실행되지만, 애플리케이션을 만들다 보면 서로 데이터를 주고받아야 하거나 외부 요청을 받아야 할 일이 많습니다. Docker 네트워크는 이러한 컨테이너간 통신을 가능하게 해주는 역할을 합니다. 🔍 Docker Network 의 종류Docker는 기본적으로 다음과 같은 네트워크 드라이버들을 제공합니다 드라이버 설명 bridge 기본 드라이버. 컨테이너 간 통신이 가능하며, 같은 호스트에서 작동합니다. host 컨테이너가 호스트의 네트워크를 그대로 사용합니다. 격리는 없지만 속도는 빠릅니다. none 네트워크를 사용하지 않도록 설정합니다. 완전한 격리가 필요할 때 사용합니다. overlay 여러 호스트 간 컨테이너를 연결할 수 있습니다. Docker Swarm에서 유용합니다. macvlan 컨테이너에 고유한 MAC 주소를 부여해 물리 네트워크처럼 동작시킵니다. ✅ Docker 네트워크 생성

0

[Docker] Volume - 컨테이너 데이터 관리

목차 [Docker] Volume - 컨테이너 데이터 관리 [Docker] Network - 컨테이너간 통신 [Docker] 🤔 Docker Volume 이 왜 필요한가? 컨테이너내 데이터는 휘발성입니다. Docker 와 컨테이너 기술이 막 떠오를때 PC 에 깔아서 개발을 하고 있는데 Docker 내에서 설정한 값들이 재실행할때 마다 초기화 되는 현상들을 겪었습니다. 당시 너무 화가나서 여러 책들을 읽어봤는데 생각해보니 컨테이너의 특성을 제대로 이해하지 못해 생기는 문제였었습니다. 컨테이너는 기본적으로 휘발성 이기 때문에 컨테이너가 종료되거나 삭제되면 내부 데이터도 함께 사라집니다. 쉽게 생각해서 격리돼 있는 컨테이너의 특성상 컨테이너가 생성한 모든 파일들은 결국 컨테이너내에서만 존재하고 컨테이너 삭제시에는 컨테이너와 함께 데이터도 삭제가 되는 것입니다. Docker 에서는 Docker Volume 을 통해 컨테이너 내에서의 데이터 휘발성 문제를 해결하고 영구적으로 저장할 수 있는 방법을 제공합니다. ✅ Docker Volume 이란?Docker Volume 은 컨테이너 외부 에 데이터를 저장할 수 있는 공간입니다. 컨테이너와는 별도로 존재하기 때문에, 컨테이너를 삭제하더라도 데이터는 유지되며 데이터 영속성이 보장됩니다.

0

Oracle - 파티셔닝 활용

Oracle 파티셔닝 활용 오라클 파티셔닝을 활용하여 대용량 테이블의 성능과 관리 효율성을 향상시키는 방법을 다룹니다. 파티셔닝은 대용량 테이블과 인덱스를 더 작고 관리하기 쉬운 조각으로 나누는 기법입니다. 쿼리 성능 향상, 데이터 관리 개선, 가용성 향상 등 다양한 이점을 제공합니다. Range 파티션날짜나 숫자 범위로 파티션을 나눕니다. -- Range 파티션 생성CREATE TABLE sales ( sale_id NUMBER, sale_date DATE, customer_id NUMBER, amount NUMBER)PARTITION BY RANGE (sale_date) ( PARTITION p_2024_q1 VALUES LESS THAN (TO_DATE('2024-04-01', 'YYYY-MM-DD')), PARTITION p_2024_q2 VALUES LESS THAN (TO_DATE('2024-07-01', 'YYYY-MM-DD')), PARTITION p_2024_q3 VALUES LESS THAN (TO_DATE('2024-10-01', 'YYYY-MM-DD')), PARTITION p_2024_q4 VALUES LESS THAN (TO_DATE('2025-01-01', 'YYYY-MM-DD')), PARTITION p_max VALUES LESS THAN (MAXVALUE));-- 월별 파티션CREATE TABLE orders ( order_id NUMBER, order_date DATE, customer_id NUMBER)PARTITION BY RANGE (order_date)INTERVAL (NUMTOYMINTERVAL(1, 'MONTH'))( PARTITION p_initial VALUES LESS THAN (TO_DATE('2024-01-01', 'YYYY-MM-DD'))); List 파티션특정 값 목록으로 파티션을 나눕니다. -- List 파티션CREATE TABLE employees_regional ( employee_id NUMBER, first_name VARCHAR2(50), last_name VARCHAR2(50), country_code VARCHAR2(2))PARTITION BY LIST (country_code) ( PARTITION p_asia VALUES ('KR', 'JP', 'CN', 'TH'), PARTITION p_europe VALUES ('UK', 'FR', 'DE', 'IT'), PARTITION p_america VALUES ('US', 'CA', 'MX', 'BR'), PARTITION p_other VALUES (DEFAULT));

0

Oracle - 힌트 사용 전략

Oracle 힌트 사용 전략 오라클 힌트를 효과적으로 사용하여 쿼리 실행 계획을 제어하는 방법을 다룹니다. 힌트는 옵티마이저에게 특정 실행 방법을 지시하는 강력한 도구입니다. 하지만 잘못 사용하면 오히려 성능을 저하시킬 수 있으므로 신중하게 사용해야 합니다. 자주 사용하는 힌트PARALLEL 힌트대용량 데이터 처리에 효과적입니다. -- PARALLEL 힌트 (대용량 처리)SELECT /*+ PARALLEL(e, 4) */ *FROM employees eWHERE hire_date >= DATE '2020-01-01';-- 테이블별 병렬도 지정SELECT /*+ PARALLEL(e, 4) PARALLEL(d, 2) */ e.employee_id, d.department_nameFROM employees e, departments dWHERE e.department_id = d.department_id;-- AUTO 병렬도SELECT /*+ PARALLEL(e, AUTO) */ *FROM employees e;-- 주의사항:-- - CPU 리소스 집약적-- - 배치 작업에 적합-- - OLTP 환경에서는 신중하게 사용 APPEND 힌트Direct Path Insert로 성능 향상.

0

Oracle - 성능 모니터링

Oracle 성능 모니터링 오라클 데이터베이스의 성능을 모니터링하고 문제를 진단하는 방법을 다룹니다. 성능 모니터링은 데이터베이스의 현재 상태를 파악하고 병목 지점을 찾아 개선하는 데 필수적입니다. 다양한 모니터링 도구와 기법을 활용하여 시스템 성능을 지속적으로 관리할 수 있습니다. AWR (Automatic Workload Repository)AWR 스냅샷 관리-- 수동 스냅샷 생성EXEC DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT;-- 스냅샷 목록 확인SELECT snap_id, begin_interval_time, end_interval_timeFROM dba_hist_snapshotORDER BY snap_id DESCFETCH FIRST 10 ROWS ONLY;-- AWR 리포트 생성 (SQL*Plus)@$ORACLE_HOME/rdbms/admin/awrrpt.sql-- AWR 리포트 생성 (PL/SQL)SELECT outputFROM TABLE(DBMS_WORKLOAD_REPOSITORY.AWR_REPORT_TEXT( l_dbid => (SELECT dbid FROM v$database), l_inst_num => 1, l_bid => 100, -- 시작 스냅샷 ID l_eid => 110 -- 종료 스냅샷 ID)); AWR 설정 변경-- AWR 수집 간격 및 보관 기간 변경EXEC DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS( retention => 43200, -- 30일 (분 단위) interval => 30 -- 30분 간격);-- 현재 설정 확인SELECT snap_interval, retentionFROM dba_hist_wr_control; 대기 이벤트 분석

0

Oracle - SQL 재작성 기법

Oracle SQL 재작성 기법 비효율적인 SQL을 효율적으로 재작성하여 성능을 개선하는 다양한 기법을 다룹니다. SQL 재작성은 동일한 결과를 얻으면서도 더 빠르게 실행되도록 쿼리를 변경하는 기법입니다. 옵티마이저가 최적화하기 어려운 경우 직접 SQL을 개선할 수 있습니다. UNION ALL vs UNION-- UNION ALL (중복 제거 불필요시)SELECT employee_id, last_name FROM employees WHERE department_id = 10UNION ALLSELECT employee_id, last_name FROM employees WHERE department_id = 20;-- UNION (중복 제거 필요시만)SELECT employee_id FROM employees WHERE department_id = 10UNIONSELECT employee_id FROM employees WHERE department_id = 20;-- 성능 차이:-- UNION ALL: 정렬 없음, 빠름-- UNION: 정렬 + 중복 제거, 느림 COUNT 최적화-- 나쁜 예: COUNT(*)에 불필요한 조건SELECT COUNT(*) FROM employees WHERE salary > 0;-- 문제: salary는 NOT NULL이므로 불필요한 조건-- 좋은 예: 필요한 조건만SELECT COUNT(*) FROM employees WHERE department_id = 10;-- 인덱스 활용SELECT COUNT(*) FROM employees;-- 인덱스가 있으면 테이블 스캔 없이 빠르게 계산-- 존재 여부만 확인할 때-- 나쁜 예SELECT COUNT(*) FROM employees WHERE department_id = 10;-- 좋은 예SELECT CASE WHEN EXISTS ( SELECT 1 FROM employees WHERE department_id = 10) THEN 1 ELSE 0 END FROM DUAL; DISTINCT 최적화-- 나쁜 예: 불필요한 DISTINCTSELECT DISTINCT e.employee_id, e.last_nameFROM employees e, departments dWHERE e.department_id = d.department_id;-- 문제: employee_id는 PK이므로 DISTINCT 불필요-- 좋은 예: DISTINCT 제거SELECT e.employee_id, e.last_nameFROM employees e, departments dWHERE e.department_id = d.department_id;-- EXISTS로 대체-- 나쁜 예: DISTINCT로 중복 제거SELECT DISTINCT e.employee_id, e.last_nameFROM employees e, job_history jhWHERE e.employee_id = jh.employee_id;-- 좋은 예: EXISTS 사용SELECT e.employee_id, e.last_nameFROM employees eWHERE EXISTS ( SELECT 1 FROM job_history jh WHERE jh.employee_id = e.employee_id);

0

Oracle - 통계 정보 관리

Oracle 통계 정보 관리 오라클 옵티마이저가 최적의 실행 계획을 수립할 수 있도록 통계 정보를 관리하는 방법을 다룹니다. 통계 정보는 옵티마이저가 실행 계획을 결정하는 데 사용하는 핵심 데이터입니다. 정확하고 최신의 통계 정보를 유지하는 것이 쿼리 성능 최적화의 기본입니다. 통계 수집테이블 통계 수집-- 테이블 통계 수집EXEC DBMS_STATS.GATHER_TABLE_STATS( ownname => 'HR', tabname => 'EMPLOYEES', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO', cascade => TRUE);-- 파라미터 설명:-- ownname: 스키마 이름-- tabname: 테이블 이름-- estimate_percent: 샘플링 비율 (AUTO_SAMPLE_SIZE 권장)-- method_opt: 히스토그램 수집 방법-- cascade: 인덱스 통계도 함께 수집 스키마 전체 통계 수집-- 스키마 전체 통계 수집EXEC DBMS_STATS.GATHER_SCHEMA_STATS( ownname => 'HR', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, cascade => TRUE, degree => 4 -- 병렬도);-- 데이터베이스 전체 통계 수집EXEC DBMS_STATS.GATHER_DATABASE_STATS( estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, cascade => TRUE, degree => DBMS_STATS.DEFAULT_DEGREE); 시스템 통계 수집

0

Oracle - 서브쿼리 최적화

Oracle 서브쿼리 최적화 오라클에서 서브쿼리를 효율적으로 작성하고 최적화하는 방법을 다룹니다. 서브쿼리는 SQL의 강력한 기능이지만, 잘못 사용하면 성능 문제를 일으킬 수 있습니다. 적절한 서브쿼리 유형과 최적화 기법을 선택하는 것이 중요합니다. EXISTS vs INEXISTS 사용외부 쿼리가 큰 경우 효과적입니다. -- EXISTS 사용 (외부 쿼리가 큰 경우)SELECT * FROM employees eWHERE EXISTS ( SELECT 1 FROM departments d WHERE d.department_id = e.department_id AND d.location_id = 1700);-- 특징:-- - 첫 번째 일치하는 행을 찾으면 즉시 반환-- - NULL 값 처리에 안전-- - Correlated 서브쿼리로 실행 IN 사용서브쿼리 결과가 작은 경우 효과적입니다.

0

Oracle - 조인 최적화

Oracle 조인 최적화 오라클에서 효율적인 조인 방법을 선택하고 최적화하는 방법을 다룹니다. 조인은 여러 테이블의 데이터를 결합하는 중요한 연산입니다. 적절한 조인 방식과 순서를 선택하면 쿼리 성능을 크게 향상시킬 수 있습니다. 조인 방식 선택Nested Loop Join작은 테이블과 인덱스가 있을 때 효과적입니다. -- NESTED LOOP JOIN (작은 테이블 + 인덱스)SELECT /*+ USE_NL(e d) */ e.*, d.department_nameFROM employees e, departments dWHERE e.department_id = d.department_id AND e.employee_id = 100;-- 특징:-- - 작은 결과 집합에 유리-- - 선행 테이블의 각 행마다 후행 테이블 인덱스 검색-- - OLTP 환경에 적합 Hash Join큰 테이블 간 조인에 효과적입니다.