1.삶은 풀어야 할 숙제가 아니라 겪어봐야 할 신비다
문제는 당신 안에 있다
나만의 고유한 삶을 살자
의미와가치는 평판에 달려 있지 않다


2.배움을 멈추지 않는 한 우리는 계속 성장할 것이다
앎을 실천함으로써 삶을 바꾸자
바꿀수 없는것에 매이지 말고, 바꿀 수있는것에 살아라


3.인생은 빗속에서 춤추는 법을 배우는 것
해결할 수 있는 일은 근심할 필요가 없다
해결할 수 없는 일 또한 근심할 필요가 없다.

반드시라는 마음을 내려놓고
물 흐르듯이

욕망, 두려움 을 초월한다면 자유롭다

'인문학' 카테고리의 다른 글

겸손(자신있게 고개숙일 수 있는 마음)  (3) 2025.08.29

[어떻게 어른이 되는가]-엄성우 지음 

 

1. 겸손이란 무엇일까.

신이 아니기에 모든면에서 완벽하지 않고,

그런 불완정성을 스스로 인지할 수 있기에 다른 동물과 구분이 된다.

자신의 가치와 남의 가치를 비교하지 않는 것으로 출발

 

2. 왜 겸손해야 할까.

남을 불쾌하게 하지 않고 자신도 미움받지 않는다.

자기평가에 연연하지 않고 진정으로 중요한 것을 추구한다.

귀한 배움을 얻기 위해서는 남의 잘난척 정도는 가볍게 받아줄수도 있는 여유로운 태도가 필요할수도 있다. (이것도 겸손)

겸손만큼 쉽고 안전한 덕목이 없다.

 

3. 겸손은 예의나 친절함과 어떻게 다를까

예의 바름은 대부분 겉으로 드러나는 것.

겸손은 친절과는 다르다. 친절하게 태도를 가질수는 있으나

겸손은 결국 스스로를 어떻게 여기는가에 내면에서 나오는 소리에 달려있음

내적겸손을 갖추어야 외적겸손이 자연스럽게 발현된다.

 

4. 겸손한 사람은 자신에 대해 잘 알까?

자신의 탁월함을 알고도 겸손할 수 있는가.

내가 뛰어나다고 해서 내가 남보다 가치가 있는 것은 아니다. 탁월성을 안다고 겸손하지 못한것은 아님.

오히려 자신이 가진 힘과 영향력을 제대로 알지 못해서 생기는 문제도 있다. (가진자의 횡포, 상처주는 막말)

자신이 가진 탁월함을 제대로 알아야 적절히 활용하며 그에 걸맞는 행동을 할 수 있다.

 

"너 자신을 알라"

"내가 모른다는 사실이라도 알면 지혜로울 수 있다"

 

5. 겸손한 사람은 스스로를 어떻게 의식할까?

지나치게 자신을 의식하면 겸손하지 못할 수 있다.

"겸손이란 자신을 하찮게 생각하는 것이 아니라 자신에 대해 너무 많은 생각을 하지 않는 것이다" - C.S. 루이스

자신의 가치를 알맞게 가늠하는 사람은 꼭 필요한 경우가 아니면 자신을 화제의 중심에 두지 않는다.

 

"우리는 우리에 대해 무슨 이야기를 하는지보다 우리에 대한 이야기 자체에 더 신경을 쓰고,

우리를 어떻게 부르는지와 상관없이 사람들 입에 오르내린다는 사실로 만족스러워 한다. " - 몽테뉴

쓸데없는 것에 기뻐하는 사람들

 

우리는 자신의 것이 아닌 것에 대해서 과시하지 않아야 한다.

 

6. 감사와 겸손, 겸손과 자기비하, 겸손과 오만

보통 겸손한 사람은 감사를  잘한다. 하지만 감사할 줄은 알지만 겸손하지 못한 사람도 있다. 

진짜 겸손한 사람은 자신을 중심에 두려는 성향이 적어서, 남을 돕거나 진리를 추구하는 등

인생의 중요하고 가치있는 일을 실천해 나가는 사람.

---------

겸손과 자기비하는 마치 비슷해보이지만 다르다.

자신을 스스로 깎아 내리려는 성향이 선의,용기 등 다른 덕목을 발휘하는데 방해가 되는를 기준으로 본다면

자기비하는 그 부정적인 태도로 자신과 그 주위에 악영향을 미친다.

 

예를 들어서 상을 받거나 축하를 받을때 스스로 깎아내린다면, 혹은 자신이 받은 상의 가치를 깎아 내린다면

그 상을 준사람, 받은 또 다른 사람, 또 그 상을 받지 못한사람과 그 상을 받도록 도와준 모든 사람에게 실례

 

겸손은 자신을 낮추는 태도가 아닙니다. 자신에게 엄격한 것도 아니며,

자신을 깎아 내린다는 것은 결국 자신과 비슷한 위치에 있는 사람도 깎아내리는 것이 되기 때문이다.

 

자신을 드러내는 행동이 반드시 오만한 것은 아니다.

자랑에도 이유가 있다면 겸손에 어긋나지 않으며

 

결국 겸손은 자기비하와 오만 사이의 중용이다.

"덕 이란 모자람과 지나침의 양 극단 사이의 중용" - 아리스토텔레스

 

** 자존감의 크기가 아니라 자존감의 근거에 달려있다.

겸손하지 못한 사람은 Better에 중점을 두고,

겸손한 사람은 Good에 중점을 둔다. 즉, 가치있고 의미있는 것을 추구하고 실현함으로써 높아진 자존감을 얻게 되는 것

 

'인문학' 카테고리의 다른 글

삶이 풍요로워지는 여덟번의 동양 고전수업 #1  (0) 2025.09.14

Flink State vs 외부 저장소를 활용한 값 관리: 어떤 선택이 더 합리적일까?

 

개요

실시간 데이터 처리 파이프라인에서 흔히 등장하는 과제 중 하나는 “사용자 피로도, Aggregation등” 값 관리입니다.
예를 들어, 마케팅 알림이나 이벤트 푸시 발송 시스템에서 동일 사용자에게 너무 많은 알림이 전달되지 않도록 시간/횟수 기반 제약을 두어야 할 필요도 있고, 일정 시간내의 이벤트 Aggregation등의 처리가 필요한 경우도 있습니다.
 
이를 구현하는 방법은 크게 두 가지로 나눌 수 있습니다.

  1. Flink State를 통한 관리
  2. Redis 등 외부 저장소를 통한 관리

 실제 운영 환경에서 이 두 가지 접근법을 모두 검토했으며, 각 방식의 장단점과 보완 방법을 정리해 보았습니다.
 


Flink State 기반 관리

 

동작 방식

  • Flink의 KeyedProcessFunction 또는 RichFlatMapFunction에서 ValueState, ListState, MapState 등을 활용.
  • 사용자별 키(userId)로 state를 유지하고, 이벤트 처리 시 조건을 체크.
  • checkpoint/restore 메커니즘을 통해 exactly-once 보장 가능.

 

장점

  • 일관성 보장: Flink state는 checkpoint와 함께 관리되어 장애 상황에서도 데이터 유실 최소화.
  • 처리 성능 최적화: 외부 호출 없이 JVM 내부 메모리/로컬 RocksDB로 state 접근 → 지연(latency) 최소화.
  • 운영 단순화: 외부 저장소 장애와 무관하게 파이프라인 내에서 관리 가능.

 

단점

  • 확장성 한계: State 크기가 커질수록 checkpoint 부하가 증가.
  • 비즈니스 연계성 부족: 파이프라인 외부 서비스(예: CRM, 백오피스)에서 동일 피로도 정책 확인 어려움.
  • 운영 가시성 부족: state는 Flink 내부에 있어 모니터링/조회가 불편.
  • 복원 불안정 : Operator나 내부 Class등의 변경이 생길경우 복원이 정상적으로 되지 않음

 

보완 방법

  • TTL(State Time-to-Live)을 활용해 불필요한 state 자동 정리.
  • State backend(RocksDB) 튜닝으로 대규모 데이터 관리 가능.
  • 필요 시 side-output 등으로 state snapshot을 외부 DB로 export하여 조회용 데이터 구축.

 


외부 저장소(Redis 등) 기반 관리

동작 방식

  • 이벤트 처리 시 Redis에 사용자별 카운터 / 타임스탬프를 저장.
  • 피로도 체크 시 Redis 조회 → 조건 충족 시 이벤트 처리, 아니면 drop.
  • Redis의 INCR, EXPIRE 등을 활용하여 TTL 기반 제어 가능.

 

장점

  • 외부 접근성 우수: CRM, 백오피스, API 등 다양한 외부 시스템에서 즉시 참조 가능.
  • 운영 유연성: Redis 데이터만 보면 전체 상태 확인 가능.  (Prefix 를 이용, 전체 Keys는 운영중 절대 안됨!)
  • 확장성: Redis Cluster 등으로 수평 확장 가능.
  • 안정성 : Flink App의 재부팅 / 결함으로부터 자유로움

 

단점

  • 일관성 취약: Flink 처리 중 실패/재처리 시 Redis 값이 중복 증가할 수 있음.
  • 성능 부담: 외부 I/O 호출로 인해 latency 증가 가능.
  • 운영 복잡성: Redis 장애 시 파이프라인도 영향 받을 수 있음.

 

보완 방법

  • 원자적 연산(GET+INCR) 사용 및 Lua Script 기반 트랜잭션 처리.
  • 배치 보정 파이프라인: 하루/주 단위로 Redis 카운트를 원천 이벤트 로그와 맞추어 정합성 보정.
  • 모니터링/알림 : Redis Replica/Cluster 구성을 통한 가용성 확보

 


보관하는 값의 종류에 따른 차이점

 

운영 중 겪었던 문제

처음에는 모든  데이터를 Flink state로 관리하려 했습니다.
하지만 장애 복구 시 state 복원 크기가 커지면서 문제가 발생했습니다.

  • 복원 사례: 수십 GB 단위 state를 가진 잡이 재시작될 때→ 그동안 KPU(Flink 작업 슬롯)를 넉넉하게 늘려야만 안정적인 복구 가능
  • → 운영 비용과 복잡성이 증가
  • → Checkpoint restore 시간이 수십 분 이상 소요

이 경험을 통해 모든 값을 state에 넣는 건 정답이 아님을 깨달았습니다.
 

State로 관리하면 좋은 값들

State는 Flink의 강력한 무기입니다. 특히 **“스트림 내에서 바로 계산되는 값”**에는 최적화되어 있습니다.

  • 누적 값 (counters): 예) 특정 키(userId)의 이벤트 누적 개수
  • 평균/합/통계치 (aggregation): 예) 지난 5분간 클릭률 평균
  • 세션/윈도우 기반 임시 상태: 예) 10분 세션 동안 발생한 이벤트 패턴
  • 비교적 작은 사이즈의 데이터: 예) 단일 사용자 최근 5개 이벤트 저장

➡️ 이런 값들은 Flink checkpoint/restore와 exactly-once 보장이 잘 맞아떨어집니다.
 

외부 저장소로 관리하면 좋은 값들

반면, **“외부에서 참조가 필요하거나, 중복 증가가 치명적이지 않은 값”**은 Redis 같은 외부 저장소가 더 적합합니다.

  • Fatigue (발송 제약):→ CRM/운영툴에서 실시간 확인 가능
    • 중복으로 값이 과증가해도 보수적으로 동작 (안 보내는 쪽으로 기울어 안전)
  • 장기 보존이 필요한 값:→ Redis/DB에 두면 조회와 보정(batch pipeline) 용이
    • Flink state에 두면 checkpoint 부하 ↑
  • 운영 가시성이 중요한 값:
    • 운영자가 즉시 확인하고 조정해야 하는 데이터 (예: 사용자별 발송 제한 카운터)

➡️ 이런 값들은 Flink state보다 외부 저장소 + 보정 파이프라인이 더 안정적입니다
 

결론 및 선택 가이드

  • Flink State 중심 전략: 성능과 일관성이 가장 중요할 때 선택.
    • 알림 피로도 관리가 파이프라인 내부 로직에 국한되고, 외부에서 별도 조회 필요성이 적을 경우 적합.
  • Redis 중심 전략: 운영 가시성, 보수적 동작, 외부 연계성
    • 단, 재처리/중복 처리 리스크를 줄이기 위한 보완책이 필수.

맺음말

결국, fatigue 관리의 초점이 “실시간 정확성”인지 “운영 편의성”인지에 따라 선택지가 달라집니다.
저의 고민과 정리를 바탕으로, 비슷한 고민을 하고 계신 분들께 도움이 되길 바랍니다.

AWS Managed Flink + Kinesis DataStream 실시간 데이터 처리 시스템 개요

 

1. 개요

 

최근 데이터 처리 환경은 “실시간”이라는 키워드가 핵심입니다.

대용량 이벤트 스트림을 빠르게 수집하고, 실시간으로 분석·가공한 뒤 다양한 시스템에 전달해야 하는 요구가 있어서

AWS에서 제공되고 있는 Amazon Kinesis DataStream와 **Amazon Managed Service for Apache Flink(이하 Managed Flink)**를 활용해봤습니다.

 

이번 글에서는 이 두 서비스를 활용해 실시간 데이터 파이프라인을 구축하는 기본 개념과 설계 포인트를 정리해봅니다.

 


 

2. 서비스 개요

 

2.1 Amazon Kinesis

Kinesis는 AWS의 완전관리형 스트리밍 데이터 서비스입니다. (Kafka 와 유사하다고 생각하시면 됩니다.)

이 중 **Kinesis Data Streams(KDS)**를 사용하면 초당 수백 MB~GB급 이벤트를 안정적으로 수집·버퍼링할 수 있습니다.

 

특징

  • 샤드(Shard) 단위로 처리량 확장 가능 -> 파티션 과 유사
  • 순서 보장 및 재처리 지원
  • 초당 수천 TPS 가능
  • SDK, Firehose, CLI 등 다양한 연동 방식

 


 

2.2 Amazon Managed Flink

 

Apache Flink를 완전관리형으로 제공하는 서비스입니다.

Managed Flink를 사용하면 클러스터 관리나 배포 인프라 고민 없이, Flink 애플리케이션 개발에 집중할 수 있습니다.

단, 기본 Flink와 다르게 조정할 수 없는 Configuration 들이 있으니 공식문서를 참조해야 합니다.

 

특징

  • Flink 버전 업그레이드 및 인프라 관리 자동화
  • Kinesis, S3, DynamoDB 등 AWS 서비스와 Native 연동
  • Checkpoint/Savepoint를 통한 상태(State) 복구 지원
  • Scaling 자동화(Parallelism 조정)

 

3. 시스템 아키텍처 개요

  1. Producer: 실시간 Event 수집 Platform
  2. Kinesis Data Streams: 실시간 데이터 Queue
  3. Managed Flink: 실시간 데이터 처리(Enrichment, Filtering, Aggregation)
  4. Sink: 결과 저장(S3)

 

4. 구현 시 주요 고려사항

4.1 데이터 모델 & 직렬화

  • Flink와 Kinesis 간 전송 데이터는 기본사용은 kryo사용(reflect방식)으로 성능이 떨어지기 때문에 추후 스키마 진화를 생각하면 Avro, Protobuf 등 직렬화 포맷 선택하는것이 유리하다.

4.2 상태 관리(State Management)

  • Flink는 Keyed StateOperator State를 제공
  • 상태 크기가 커질수록 Checkpoint 주기와 저장소 성능이 중요하다.
  • AWS에서는 기본적으로 S3에 Checkpoint/Savepoint 저장하며 사용자는 접근이 불가능하다.

4.3 Checkpoint / Savepoint 전략

  • Checkpoint: 장애 시 자동 복구
  • Savepoint: 버전 배포·롤백 시 수동 복구
  • 체크포인트 주기는 1분~5분 권장, 처리량과 지연 시간에 따라 조정

4.4 Source/Sink Connector

  • Source: KinesisStreamsSource 또는 Flink Kinesis Connector
  • Sink: S3 로 기본사용

4.5 확장성(Scaling)

  • Kinesis는 샤드 수로 확장
  • Flink는 parallelism 조정 
  • 병목 지점(Shard → Flink 병렬도) 일치 여부 체크 필요
  • Parallelism과 KPU가 자동으로 계산되는데  4.2의 상태관리와 연관되어 재기동시 backpressure , 지연이 발생하지 않도록 처리시간 + 복원시간을 고려해야 한다.

 


5. 운영 팁

  1. CloudWatch + Managed Flink Metrics로 레이턴시, 백프레셔(backpressure) 모니터링
  2. Kinesis 샤드 모니터링 → 샤드 split/merge 자동화 스크립트 준비
  3. Flink 애플리케이션 버전 관리 → Git + CI/CD (CodePipeline, CodeBuild) 연동 , Flink재기동은 자동보다는 수동을 추천
  4. Data retention: Kinesis는 최대 7일, 그 이상은 S3에 Raw Data 저장
  5. 배포 전 로컬 환경에서 Flink MiniCluster로 테스트
  6. Flink 내 ProecssFunction에 대해서는 Harness를 이용해서 최대한 Test Code를 작성해둔다.

 

6. 간단한 예제 플로우

  • Source: Kinesis에서 JSON 데이터 읽기
  • KeyBy: UserId 단위 처리
  • ProcessFunction: 룰 매핑, 데이터 보강
  • Sink: S3 저장
DataStream<Event> source = env
    .fromSource(kinesisSource, WatermarkStrategy.noWatermarks(), "Kinesis Source")
    .map(json -> parseJson(json));

source
    .keyBy(Event::getUserId)
    .process(new CustomEnrichmentFunction())
    .addSink(s3Sink);

 

7.  결론

AWS Managed Flink + Kinesis 조합은 실시간 데이터 분석 파이프라인을 빠르고 안정적으로 구축할 수 있는 강력한 도구입니다.

인프라 운영 부담을 줄이고, 비즈니스 로직에 집중할 수 있다는 점이 가장 큰 장점입니다.

 

다만, 체크포인트 전략, 상태 크기 관리, Kinesis 샤드 수 조정 등 운영 노하우가 중요하니, 충분히 검증 / 모니터링을 후 본격 도입하는 것을 추천드립니다.

OAuth 2.0 Resource Server에서 JWT 토큰을 검증하고 권한을 처리하는 방법에 대해 알아보겠습니다. Spring Security를 사용하여 Resource Server를 구성하고, JWT 토큰의 scope와 roles 클레임을 권한으로 변환하는 과정을 살펴볼 것입니다. 또한, 자주 발생하는 SSL 관련 오류와 그 해결 방법에 대해서도 다룰 예정입니다.

 

Authorization_code vs Client_credentials

OAuth 2.0의 Authorization Code 방식과 Client Credentials 방식은 서로 다른 사용 사례와 흐름을 가지고 있습니다. 두 방식의 주요 차이점은 다음과 같습니다:
  • Authorization Code 방식:
    • 사용자 개입이 필요한 인증 흐름
    • 웹 애플리케이션이나 모바일 앱에서 주로 사용
    • 리소스 소유자(사용자)의 동의를 얻어 액세스 토큰을 발급
    • 보안성이 높고 refresh token을 사용할 수 있음
  • Client Credentials 방식:
    • 클라이언트 애플리케이션이 직접 자신의 자격 증명으로 인증
    • 서버 간 통신이나 백그라운드 작업에 주로 사용
    • 사용자 컨텍스트 없이 클라이언트 자체의 권한으로 액세스 토큰을 얻음
    • 간단하지만 사용자 특정 데이터에 접근할 수 없음

 

OAuth2 Authorization Server Setup

Spring Boot와 Spring Security를 사용하여 OAuth 2.0 Authorization Server를 구현하기 위해서는 다음과 같은 핵심 설정이 필요합니다:
  • spring-boot-starter-oauth2-authorization-server 의존성을 추가합니다
  • @EnableAuthorizationServer 어노테이션을 사용하여 OAuth 2.0 권한 부여 서버 구성을 활성화합니다
  • AuthorizationServerConfigurerAdapter를 상속받는 구성 클래스를 생성하고, 클라이언트 세부 정보, 토큰 저장소, 보안 제약 조건 등을 설정합니다
  • ClientDetailsServiceConfigurer를 사용하여 클라이언트 ID, 시크릿, 권한 부여 유형, 스코프 등을 정의합니다
  • JWT 토큰을 사용하는 경우, JwtAccessTokenConverter TokenStore를 구성하여 토큰 생성 및 검증 로직을 커스터마이즈할 수 있습니다
  • 사용자 인증을 위해 UserDetailsService를 구현하고, 비밀번호 인코딩을 위한 PasswordEncoder를 설정합니다
이러한 설정을 통해 기본적인 OAuth 2.0 Authorization Server를 구현할 수 있으며, 필요에 따라 추가적인 커스터마이징이 가능합니다.

 

Configuring Resource Server with JWT

 
JWT를 사용하는 리소스 서버 구성은 Spring Security의 OAuth 2.0 지원을 통해 간단히 설정할 수 있습니다. 주요 단계는 다음과 같습니다:
  • application.yml 파일에 spring.security.oauth2.resourceserver.jwt.issuer-uri 속성을 설정하여 JWT 발급자 URI를 지정합니다
  • @EnableWebSecurity 어노테이션과 함께 SecurityFilterChain 빈을 구성하여 JWT 인증을 활성화합니다
  • JwtDecoder 빈을 커스터마이즈하여 토큰 유효성 검사 로직을 추가할 수 있습니다
  • 필요한 경우 JwtAuthenticationConverter를 구현하여 JWT 클레임을 Spring Security의 권한으로 매핑합니다
이러한 설정을 통해 리소스 서버는 Authorization Server에서 발급한 JWT를 검증하고, 토큰에 포함된 스코프나 역할에 따라 접근 제어를 수행할 수 있습니다
 
 
What is Scope and Role
OAuth 2.0에서 scope와 role은 접근 제어를 위한 중요한 개념이지만, 그 용도와 적용 방식에 차이가 있습니다:
  • Scope: 클라이언트 애플리케이션이 사용자 리소스에 접근할 수 있는 범위를 정의합니다. 예를 들어, 'read:profile', 'write:email' 등으로 세분화된 권한을 나타냅니다.
    • Scope는 OAuth 2.0 프로토콜의 표준 부분으로, 인증 서버에서 관리됩니다.
  • Role: 사용자의 조직 내 역할이나 권한 수준을 나타냅니다. 예를 들어, 'admin', 'user', 'manager' 등이 있을 수 있습니다
    • Role은 주로 애플리케이션 내부에서 정의되고 관리됩니다.
적절한 사용:
  • Scope는 클라이언트 애플리케이션의 권한을 제한하는 데 사용합니다. 예: 'read:books'
  • Role은 사용자의 전반적인 권한 수준을 정의하는 데 사용합니다. 예: 'librarian'
두 개념을 조합하여 더 세밀한 접근 제어를 구현할 수 있습니다. 예를 들어, 'librarian' 역할을 가진 사용자에게만 'write:books' 스코프를 허용하는 방식으로 사용할 수 있습니다
 
 

Handling Roles and Scopes in Tokens

OAuth 2.0 토큰에서 역할(roles)과 범위(scopes)를 처리하는 것은 리소스 서버의 중요한 기능입니다. Spring Security에서는 JwtAuthenticationConverter를 사용하여 이를 구현할 수 있습니다:
  • JWT 토큰의 'scope' 클레임을 Spring Security의 권한으로 자동 변환합니다.
  • 커스텀 'roles' 클레임을 처리하려면 JwtAuthenticationConverter를 확장하여 구현합니다.
  • GrantedAuthoritiesMapper를 사용하여 클레임을 세분화된 권한으로 매핑할 수 있습니다.
  • 보안 구성에서 @PreAuthorize 또는 hasRole() 메소드를 사용하여 엔드포인트별 권한을 설정합니다.
이러한 방식으로 토큰의 역할과 범위를 효과적으로 처리하여 세밀한 접근 제어를 구현할 수 있습니다.

Customizing Token Claims

JWT 토큰의 클레임을 커스터마이즈하는 것은 OAuth 2.0 인증 서버에서 중요한 기능입니다. Spring Security에서는 OAuth2TokenCustomizer 인터페이스를 구현하여 이를 수행할 수 있습니다
 
- @Bean 메서드를 통해 OAuth2TokenCustomizer를 구현합니다.
- customize 메서드 내에서 context.getClaims()를 사용하여 JWT 클레임에 접근합니다.
- claims.put() 메서드로 커스텀 클레임을 추가하거나 기존 클레임을 수정합니다.
- 사용자의 권한이나 역할을 클레임으로 추가하려면 context.getPrincipal()에서 정보를 추출합니다

 

이 방법을 통해 리소스 소유자의 추가 정보나 애플리케이션 특정 데이터를 토큰에 포함시킬 수 있어, 리소스 서버에서 더 세밀한 접근 제어가 가능해집니다.
 

Resolving Errors

OAuth 2.0 구현 시 JwtDecoder와 SSL 관련 오류를 해결하는 방법은 다음과 같습니다:
  • JwtDecoder 오류: NimbusJwtDecoder.withJwkSetUri()를 사용하여 JWK Set URI를 명시적으로 설정합니다.
    • 이때 URI가 올바른지 확인하고, 필요한 경우 커스텀 RestTemplate을 구성하여 추가적인 헤더나 인증을 처리할 수 있습니다.
  • SSL 인증서 오류: 개발 환경에서는 server.ssl.key-store-type=PKCS12 server.ssl.key-store=classpath:keystore.p12를 설정하여 자체 서명된 인증서를 사용할 수 있습니다.
  • 프로덕션 환경에서는 신뢰할 수 있는 인증 기관에서 발급한 유효한 SSL 인증서를 사용해야 합니다.
이러한 설정을 통해 대부분의 JwtDecoder 및 SSL 관련 오류를 해결할 수 있으며, 안전하고 신뢰할 수 있는 OAuth 2.0 인증 흐름을 구현할 수 있습니다.
 
 

Setting Up JWK URI for Validation

  • application.yml 파일에 spring.security.oauth2.resourceserver.jwt.jwk-set-uri 속성을 추가합니다.  이 URI는 일반적으로 https:///.well-known/jwks.json 형식을 따릅니다.
  • 보안 구성 클래스에서 JwtDecoder 빈을 커스터마이즈하여 JWK URI를 명시적으로 설정할 수 있습니다
    • JWT 토큰 검증을 위한 JWK (JSON Web Key) URI 설정은 OAuth 2.0 리소스 서버 구현의 중요한 부분입니다.
이러한 설정을 통해 리소스 서버는 Authorization Server에서 제공하는 공개 키를 사용하여 JWT 토큰의 서명을 검증할 수 있으며, 토큰의 무결성과 신뢰성을 보장할 수 있습니다.

 

개요


AWS RDS와 DynamoDB의 비용 및 성능 비교는 데이터베이스 선택 시 중요한 고려사항입니다. 이 분석에서는 두 서비스의 비용 구조, 성능 특성, 그리고 대규모 쓰기 작업 시나리오에서의 비용 효율성을 살펴보았습니다. 또한 고가용성을 위한 중복 구성 시의 비용과 Spring Boot와의 연동 방법에 대해서도 논의하였습니다.

 

AWS RDS vs DynamoDB 비용비교

 
AWS RDS와 DynamoDB의 비용 비교에서, 25백만 건의 500바이트 레코드(총 12.5GB)를 기준으로 분석한 결과, DynamoDB가 RDS보다 상당히 높은 비용을 보였습니다. DynamoDB의 월간 비용은 $937.5로 추정되며, 이는 주로 쓰기 작업에 따른 비용입니다. 반면 RDS의 월간 비용은 $198.24로, 인스턴스 비용과 쓰기 작업 비용을 포함합니다. 이러한 차이는 DynamoDB의 쓰기 중심 요금 체계와 RDS의 인스턴스 기반 요금 구조의 차이에서 비롯됩니다.
      • DynamoDB: 쓰기 작업당 $1.25/백만 건, 스토리지 비용 $0.25/GB/월
      • RDS: 인스턴스 비용(예: db.t3.medium) + 쓰기 작업 비용 $0.20/백만 건

고가용성 구성 시, DynamoDB의 비용은 $1,406.25로 증가하며, RDS Multi-AZ는 $297.36로 증가합니다

선택은 애플리케이션의 요구사항, 확장성 필요, 그리고 운영 팀의 역량을 고려하여 이루어져야 합니다. DynamoDB는 글로벌 확장성과 관리 용이성에서 우위를 보이며, RDS는 복잡한 쿼리와 트랜잭션 지원에 더 적합합니다.
 
 

추가적으로 비용에서 고려할 수 있는 부분

AWS 데이터베이스 서비스의 비용을 고려할 때, 다음과 같은 추가적인 요소들을 염두에 두어야 합니다:
  • 데이터 전송 비용: AWS 리전 간 또는 인터넷으로의 데이터 전송에 따른 추가 비용이 발생할 수 있습니다.
  • 백업 및 복구: RDS의 경우 자동 백업과 수동 스냅샷에 대한 추가 스토리지 비용이 발생할 수 있으며, DynamoDB는 온디맨드 백업과 특정 시점으로의 복구(PITR) 기능에 대한 비용이 추가될 수 있습니다.
  • 성능 최적화: RDS의 경우 쿼리 최적화를 통해 성능을 향상시키고 비용을 절감할 수 있습니다. 예를 들어, AI 기반 최적화 도구를 사용하여 쿼리 성능을 23배까지 향상시킨 사례가 있습니다.
  • 서버리스 옵션: Amazon Athena와 같은 서버리스 쿼리 서비스를 사용하면 데이터 스캔량에 따라 비용이 청구되며, S3 Express One Zone 스토리지 클래스를 활용하여 쿼리 성능을 최대 2.1배 향상시킬 수 있습니다.
이러한 요소들을 고려하여 총소유비용(TCO)을 산정하고, 애플리케이션의 요구사항에 맞는 최적의 데이터베이스 솔루션을 선택해야 합니다.
 
 

Spring Boot 환경에서 DynamoDB 를 사용할때 설정해야 하는 부분

Spring Boot 환경에서 DynamoDB를 사용할 때는 다음과 같은 주요 설정을 고려해야 합니다:
  • 의존성 추가: spring-boot-starter-data-dynamodb와 AWS SDK 의존성을 pom.xml에 추가합니다.
  • DynamoDB 클라이언트 구성: AmazonDynamoDB 빈을 생성하고, 리전, 엔드포인트, 인증 정보를 설정합니다.
  • 리포지토리 인터페이스 정의: @EnableDynamoDBRepositories 어노테이션을 사용하여 DynamoDB 리포지토리를 활성화하고, CrudRepository를 확장한 인터페이스를 생성합니다.
  • 엔티티 매핑: @DynamoDBTable, @DynamoDBHashKey, @DynamoDBRangeKey 등의 어노테이션을 사용하여 Java 객체를 DynamoDB 테이블에 매핑합니다.
  • 트랜잭션 관리: DynamoDB의 제한된 트랜잭션 지원을 고려하여, 필요한 경우 @Transactional 어노테이션을 사용하되 주의가 필요합니다.
이러한 설정을 통해 Spring Boot 애플리케이션에서 DynamoDB를 효과적으로 사용할 수 있으며, 개발 생산성을 높일 수 있습니다.
 
 

DynamoDB 사용과 Application Integration에서 고려사항

DynamoDB를 애플리케이션에 통합할 때 성능과 비용 최적화를 위해 고려해야 할 주요 사항들은 다음과 같습니다:
  • 지연 시간 관리: DynamoDB는 일반적으로 10-20ms의 낮은 지연 시간을 제공하지만, 반복적인 다중 항목 작업의 경우 일관된 평균 성공 요청 지연 시간을 보장합니다.
  • 데이터 모델링: 애플리케이션의 액세스 패턴에 맞춰 효율적인 파티션 키와 정렬 키를 설계하여 읽기/쓰기 성능을 최적화합니다.
  • 배치 작업 활용: 여러 개의 개별 요청 대신 BatchGetItem 또는 BatchWriteItem 작업을 사용하여 처리량을 향상시키고 비용을 절감합니다.
  • 글로벌 테이블 고려: 다중 지역 배포가 필요한 경우, 글로벌 테이블을 사용하여 지연 시간을 줄이고 데이터 일관성을 유지할 수 있습니다.
  • 캐싱 전략: Amazon DynamoDB Accelerator(DAX)를 활용하여 읽기 성능을 향상시키고 DynamoDB 요청 비용을 절감합니다.
  • 비용 모니터링: AWS Cost Explorer를 사용하여 DynamoDB 사용량을 지속적으로 모니터링하고 필요에 따라 용량을 조정합니다.

이러한 고려사항들을 적절히 적용하면 DynamoDB를 효율적으로 활용하여 애플리케이션의 성능을 최적화하고 운영 비용을 절감할 수 있습니다.


 

DynamoDB 비용 최적화 전략

DynamoDB 비용 최적화를 위해서는 다음과 같은 전략을 고려할 수 있습니다:
  • 적절한 용량 모드 선택: 온디맨드 용량 모드는 트래픽 예측이 어려운 경우에 유용하며, 프로비저닝된 용량 모드는 일정한 트래픽 패턴에 더 경제적입니다
  • 스토리지 클래스 최적화: 자주 액세스하지 않는 데이터의 경우 Standard-Infrequent Access(IA) 스토리지 클래스로 전환하여 스토리지 비용을 절감할 수 있습니다.
  • 효율적인 쿼리 설계: Scan 작업 대신 Query 작업을 사용하고, 적절한 인덱스를 설정하여 읽기 용량 단위(RCU) 사용을 최소화합니다.
  • 데이터 수명 주기 관리: TTL(Time to Live) 기능을 활용하여 불필요한 데이터를 자동으로 삭제하고 스토리지 비용을 절감합니다.
  • 모니터링 및 최적화: AWS Cost Explorer를 활용하여 비용 구조를 분석하고, 필요에 따라 용량을 조정합니다.

이러한 전략을 적용하면 DynamoDB 사용 비용을 크게 절감할 수 있으며, 특히 대규모 데이터를 다루는 경우 더욱 효과적입니다.


+ Recent posts