<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Backend Developer</title>
    <link>https://minsoolog.tistory.com/</link>
    <description>https://github.com/minsoozz</description>
    <language>ko</language>
    <pubDate>Sun, 23 Aug 2026 23:55:34 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>김민수</managingEditor>
    <item>
      <title>데이터 중심 애플리케이션 설계 9장</title>
      <link>https://minsoolog.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;리더 기반 복제 (Leader-Based Replication)&lt;br&gt;&lt;br&gt;리더(Primary)가 쓰기 작업을 처리하고, 팔로워(Replica)는 리더의 로그를 따라감&amp;nbsp;&amp;nbsp;&lt;br&gt;일관성을 비교적 쉽게 유지할 수 있는 구조&lt;br&gt;&lt;br&gt;장점&amp;nbsp;&amp;nbsp;&lt;br&gt;쓰기 순서를 리더가 결정하므로 순차성 보장&amp;nbsp;&amp;nbsp;&lt;br&gt;클라이언트는 리더로만 쓰기 요청 → 충돌 방지&lt;br&gt;&lt;br&gt;단점&amp;nbsp;&amp;nbsp;&lt;br&gt;리더 장애 시 리더 선출 필요 (합의 알고리즘 필요)&amp;nbsp;&amp;nbsp;&lt;br&gt;팔로워가 리더와 동기화되지 않으면 최신 데이터 보장 안 됨&lt;br&gt;&lt;br&gt;클라이언트 쓰기 옵션&amp;nbsp;&amp;nbsp;&lt;br&gt;리더에게만 쓰기&amp;nbsp;&amp;nbsp;&lt;br&gt;팔로워 읽기 허용 vs 제한 (Read Your Writes 등 보장 여부)&lt;br&gt;&lt;br&gt;일관성 모델 (Consistency Model)&lt;br&gt;&lt;br&gt;어떤 시점에 어떤 노드가 어떤 데이터를 읽을 수 있는가에 대한 규칙&lt;br&gt;&lt;br&gt;강한 일관성 (Strong Consistency)&amp;nbsp;&amp;nbsp;&lt;br&gt;모든 노드가 항상 같은 값을 읽음&amp;nbsp;&amp;nbsp;&lt;br&gt;장점: 단순함&amp;nbsp;&amp;nbsp;&lt;br&gt;단점: 성능 저하, 지연 증가&lt;br&gt;&lt;br&gt;약한 일관성 (Weak Consistency)&amp;nbsp;&amp;nbsp;&lt;br&gt;읽는 시점에 따라 다른 값을 볼 수 있음&amp;nbsp;&amp;nbsp;&lt;br&gt;장점: 빠름&amp;nbsp;&amp;nbsp;&lt;br&gt;단점: 복잡한 로직 필요&lt;br&gt;&lt;br&gt;최종 일관성 (Eventual Consistency)&amp;nbsp;&amp;nbsp;&lt;br&gt;시간이 지나면 결국 모든 노드가 같은 값을 가지게 됨&amp;nbsp;&amp;nbsp;&lt;br&gt;예: DNS, S3, Cassandra&lt;br&gt;&lt;br&gt;세부 모델&amp;nbsp;&amp;nbsp;&lt;br&gt;Read-Your-Writes&amp;nbsp;&amp;nbsp;&lt;br&gt;Monotonic Reads&amp;nbsp;&amp;nbsp;&lt;br&gt;Causal Consistency (인과 일관성)&amp;nbsp;&amp;nbsp;&lt;br&gt;→ 사용자 경험 개선에 유용&lt;br&gt;&lt;br&gt;다중 리더 복제 (Multi-Leader Replication)&lt;br&gt;&lt;br&gt;여러 노드가 동시에 쓰기를 받아들이는 구조&amp;nbsp;&amp;nbsp;&lt;br&gt;장소/네트워크 단절 환경에서 유용 (ex. 모바일, 오프라인 편집)&lt;br&gt;&lt;br&gt;장점&amp;nbsp;&amp;nbsp;&lt;br&gt;지역 간 쓰기 지연 감소&amp;nbsp;&amp;nbsp;&lt;br&gt;장애 대응력 향상&lt;br&gt;&lt;br&gt;단점&amp;nbsp;&amp;nbsp;&lt;br&gt;충돌 발생 가능성 증가&amp;nbsp;&amp;nbsp;&lt;br&gt;병합 로직이 복잡함&lt;br&gt;&lt;br&gt;적용 예시&amp;nbsp;&amp;nbsp;&lt;br&gt;카렌더 동기화, 모바일 노트 앱 등&lt;br&gt;&lt;br&gt;무리더 복제 (Leaderless Replication)&lt;br&gt;&lt;br&gt;리더 없이 모든 노드가 쓰기/읽기 가능&amp;nbsp;&amp;nbsp;&lt;br&gt;충돌 해결을 클라이언트 또는 애플리케이션이 수행해야 함&lt;br&gt;&lt;br&gt;리더 기반: 단순하지만 장애 처리 복잡&amp;nbsp;&amp;nbsp;&lt;br&gt;다중 리더: 네트워크 분리/병합 환경에 유용&amp;nbsp;&amp;nbsp;&lt;br&gt;무리더: 완전한 분산성, 그러나 충돌 해결 복잡&lt;br&gt;&lt;br&gt;2PC: 2-Phase Commit&lt;br&gt;&lt;br&gt;이해하기 쉬운 합의 알고리즘을 가져와봤다. 2단계 커밋이다. 여러 노드에 걸친 원자적 트랜잭션 커밋을 보장한다. 즉, 모든 노드가 커밋되거나 모든 노드가 어보트되도록 보장한다.&lt;br&gt;&lt;br&gt;2-phase인 이유는 이 알고리즘을 수행하는 주체가 2가지로 나뉘기 때문이다. 바로 코디네이터(혹은, 트랜잭션 관리자)와 참여자다. 코디네이터가 전체 흐름을 관장하고 참여자가 신호를 보내는 역할이다. 참여자의 판단 하에 수정 내용은 커밋되거나 어보트된다. 책에서는 이 방식에 대한 자세한 설명과 함께 장애 발생 가능성을 알려주고, 더 나아가 3단계 커밋이 등장하기도 한다.&lt;/p&gt;</description>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/67</guid>
      <comments>https://minsoolog.tistory.com/67#entry67comment</comments>
      <pubDate>Wed, 4 Jun 2025 18:26:54 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 설계 8장</title>
      <link>https://minsoolog.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: justify;&quot;&gt;분산 시스템에서 일관성을 유지하는 것은 매우 어려운 과제이다. 이 장에서는 분산 환경에서 흔히 발생하는 문제들과 그 원인을 다룬다.&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;1. 부분 장애 (Partial Failure)&lt;/h3&gt;&lt;ul&gt; 
 &lt;li&gt;단일 시스템에서는 전체가 성공하거나 실패하지만,&lt;br&gt;분산 시스템에서는 일부 노드, 일부 네트워크 링크 등만 실패하는 &lt;strong&gt;부분 장애&lt;/strong&gt;가 일반적이다.&lt;/li&gt; 
 &lt;li&gt;장애 감지는 어렵고, 실패인지 지연인지 구분하기 힘들다.&lt;/li&gt; 
 &lt;li&gt;복구 가능한 실패인지 여부도 알 수 없는 경우가 많다.&lt;/li&gt; 
&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;2. 신뢰할 수 없는 네트워크&lt;/h3&gt;&lt;ul&gt; 
 &lt;li&gt;분산 시스템은 비동기 네트워크 위에서 동작하며,&lt;br&gt;패킷 지연, 손실, 재정렬, 중복 전송 등의 문제가 발생할 수 있다.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;메시지가 수신되지 않았다고 해서, 전송되지 않은 것은 아니다.&lt;/strong&gt;&lt;/li&gt; 
 &lt;li&gt;타임아웃과 재시도를 통한 실패 감지는 부정확하다.&lt;/li&gt; 
&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;3. 신뢰할 수 없는 시계&lt;/h3&gt;&lt;ul&gt; 
 &lt;li&gt;각 노드의 시계는 서로 정확히 동기화되지 않으며, 클럭 드리프트가 존재한다.&lt;/li&gt; 
 &lt;li&gt;시간 기반 순서 판단은 종종 잘못된 결정을 내리게 한다.&lt;/li&gt; 
 &lt;li&gt;해결책: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;물리적 시계&lt;/strong&gt;: NTP 등은 오차가 존재함&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;논리적 시계&lt;/strong&gt;: Lamport Timestamp, Vector Clock 등으로 인과관계만 판단 가능&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;4. 지식, 진실, 그리고 거짓말&lt;/h3&gt;&lt;ul&gt; 
 &lt;li&gt;각 노드가 가지고 있는 상태는 다른 노드와 다를 수 있다.&lt;/li&gt; 
 &lt;li&gt;하나의 노드가 알고 있는 사실이 전체적으로 합의된 진실인지 보장되지 않는다.&lt;/li&gt; 
 &lt;li&gt;&lt;strong&gt;비잔틴 장애(Byzantine Fault)&lt;/strong&gt;: 
  &lt;ul&gt; 
   &lt;li&gt;노드가 악의적으로 거짓 정보를 보낼 수 있음&lt;/li&gt; 
   &lt;li&gt;단순 충돌보다 훨씬 다루기 어려운 문제&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;5. 시스템 모델과 현실의 차이&lt;/h3&gt;&lt;ul&gt; 
 &lt;li&gt;이상적인 시스템 모델: 
  &lt;ul&gt; 
   &lt;li&gt;동기 네트워크, 정확한 장애 감지, 동기화된 시계&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;현실: 
  &lt;ul&gt; 
   &lt;li&gt;네트워크 지연, 패킷 손실, 시계 불일치, 일시적 오류&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
 &lt;li&gt;안전성과 생존성의 균형: 
  &lt;ul&gt; 
   &lt;li&gt;&lt;strong&gt;안전성 (Safety)&lt;/strong&gt;: 잘못된 동작을 하지 않음&lt;/li&gt; 
   &lt;li&gt;&lt;strong&gt;생존성 (Liveness)&lt;/strong&gt;: 시스템이 계속 응답함&lt;/li&gt; 
  &lt;/ul&gt; &lt;/li&gt; 
&lt;/ul&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;h3 style=&quot;text-align: justify;&quot; data-ke-size=&quot;size23&quot;&gt;핵심&lt;/h3&gt;&lt;p&gt;분산 시스템은 본질적으로 실패와 불확실성에 노출되어 있다.&lt;br&gt;이러한 환경에서 일관성을 유지하려면, 시스템 설계자는 &lt;strong&gt;불확실성을 인정하고 설계에 반영&lt;/strong&gt;해야 한다.&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;&lt;li&gt;장애는 반드시 발생한다.&lt;/li&gt;&lt;li&gt;네트워크는 신뢰할 수 없다.&lt;/li&gt;&lt;li&gt;시계는 일치하지 않는다.&lt;/li&gt;&lt;li&gt;진실은 상대적일 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;따라서, 완벽한 일관성을 요구하기보다는 &lt;strong&gt;허용 가능한 수준의 일관성과 복구 전략을 세우는 것이 현실적인 접근&lt;/strong&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: justify;&quot;&gt;&lt;br&gt;회고 (부족한 내용 보충)&lt;br&gt;&lt;br&gt;1. 합의 (Consensus)&lt;br&gt;&lt;br&gt;분산 시스템에서 노드들이 같은 값을 결정하는 과정&amp;nbsp;&amp;nbsp;&lt;br&gt;장애 상황에서도 일관된 상태 유지가 핵심&lt;br&gt;&lt;br&gt;사용 예시&amp;nbsp;&amp;nbsp;&lt;br&gt;리더 선출 (Leader Election)&amp;nbsp;&amp;nbsp;&lt;br&gt;로그 복제 (Log Replication)&lt;br&gt;&lt;br&gt;대표 알고리즘&amp;nbsp;&amp;nbsp;&lt;br&gt;Paxos&amp;nbsp;&amp;nbsp;&lt;br&gt;Raft&amp;nbsp;&amp;nbsp;&lt;br&gt;Viewstamped Replication&lt;br&gt;&lt;br&gt;2. CAP 정리 (CAP Theorem)&lt;br&gt;&lt;br&gt;분산 시스템은 아래 세 가지 속성 중 동시에 두 가지만 보장할 수 있음&lt;br&gt;&lt;br&gt;Consistency (일관성): 모든 노드가 같은 데이터를 읽음&amp;nbsp;&amp;nbsp;&lt;br&gt;Availability (가용성): 모든 요청에 대해 유효한 응답을 제공&amp;nbsp;&amp;nbsp;&lt;br&gt;Partition Tolerance (분할 허용성): 네트워크 분할 상황에서도 시스템이 일부 동작을 계속 수행&lt;br&gt;&lt;br&gt;네트워크 분할(P)이 현실적으로 항상 존재한다고 가정하면&amp;nbsp;&amp;nbsp;&lt;br&gt;Consistency vs Availability 사이에서 선택해야 함&lt;br&gt;&lt;br&gt;3. 응답 불가능성 (Impossibility of Knowing)&lt;br&gt;&lt;br&gt;응답 없음 = 실패라고 단정할 수 없음&lt;br&gt;&lt;br&gt;원인&amp;nbsp;&amp;nbsp;&lt;br&gt;느린 네트워크&amp;nbsp;&amp;nbsp;&lt;br&gt;처리 지연&amp;nbsp;&amp;nbsp;&lt;br&gt;일시적인 노드 부하 등&lt;br&gt;&lt;br&gt;설계 전략&amp;nbsp;&amp;nbsp;&lt;br&gt;타임아웃과 재시도는 추정일 뿐이며, 정확한 실패 감지 불가&amp;nbsp;&amp;nbsp;&lt;br&gt;시스템은 항상 불확실성 속에 동작한다는 전제를 가져야 함&lt;br&gt;&lt;br&gt;4. 안전성과 생존성 (Safety vs Liveness)&lt;br&gt;&lt;br&gt;안전성 (Safety): 시스템이 잘못된 결과를 절대 내지 않음&amp;nbsp;&amp;nbsp;&lt;br&gt;생존성 (Liveness): 시스템이 언젠가는 반드시 응답함&lt;br&gt;&lt;br&gt;두 속성은 종종 트레이드오프 관계&amp;nbsp;&amp;nbsp;&lt;br&gt;예: 분할 발생 시, 일관성을 위해 응답을 일부 포기할 수도 있음&lt;br&gt;&lt;br&gt;설계 시 두 속성의 균형을 어떻게 잡을지가 핵심&lt;/p&gt;</description>
      <category>스터디</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/66</guid>
      <comments>https://minsoolog.tistory.com/66#entry66comment</comments>
      <pubDate>Tue, 27 May 2025 18:59:42 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 설계 7장</title>
      <link>https://minsoolog.tistory.com/65</link>
      <description>&lt;h2&gt;1. 트랜잭션이란?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;여러 데이터베이스 연산을 하나의 논리적 작업 단위로 묶는 개념&lt;/li&gt;
&lt;li&gt;중간 상태 없이 전부 성공하거나 전부 실패해야 함&lt;/li&gt;
&lt;li&gt;예: 은행 송금 시 출금과 입금은 함께 성공하거나 함께 롤백되어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. ACID 속성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Atomicity (원자성)&lt;/strong&gt;: 모든 연산이 전부 실행되거나 전부 실행되지 않아야 함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistency (일관성)&lt;/strong&gt;: 트랜잭션 전후의 데이터 상태가 일관성을 유지해야 함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Isolation (격리성)&lt;/strong&gt;: 동시 실행되는 트랜잭션들이 서로 간섭하지 않아야 함&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Durability (지속성)&lt;/strong&gt;: 트랜잭션 완료 후 변경 내용은 영구적으로 저장되어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. 격리 수준 (Isolation Level)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;격리 수준이 높을수록 일관성은 보장되지만 성능은 낮아짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Read Uncommitted&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;커밋되지 않은 데이터도 읽을 수 있음&lt;/li&gt;
&lt;li&gt;더티 읽기(Dirty Read) 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Read Committed&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;커밋된 데이터만 읽을 수 있음&lt;/li&gt;
&lt;li&gt;더티 읽기 방지, 비반복 읽기(Non-repeatable Read) 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Repeatable Read&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;같은 트랜잭션 내 같은 쿼리 결과가 항상 동일&lt;/li&gt;
&lt;li&gt;비반복 읽기 방지, 팬텀 리드(Phantom Read) 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Snapshot Isolation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트랜잭션 시작 시점의 스냅샷 기준으로 읽기&lt;/li&gt;
&lt;li&gt;대부분의 팬텀 리드, 쓰기 스큐(Write Skew) 방지&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Serializable&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트랜잭션을 직렬적으로 실행한 것과 같은 결과&lt;/li&gt;
&lt;li&gt;모든 문제 방지하지만 성능 오버헤드 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 동시성 제어 방법&lt;/h2&gt;
&lt;h3&gt;2단계 잠금 (2PL)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트랜잭션이 모든 잠금을 획득한 후 작업 수행&lt;/li&gt;
&lt;li&gt;교착 상태(Deadlock) 발생 가능성 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;낙관적 동시성 제어 (Optimistic Concurrency Control)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;충돌 감지 시 롤백 및 재시도&lt;/li&gt;
&lt;li&gt;대부분의 경우 성능 유리함&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. 트랜잭션의 실용적 고려사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;무조건 트랜잭션을 사용할 필요는 없음&lt;/li&gt;
&lt;li&gt;시스템 요구사항에 따라 격리 수준을 조절해야 함&lt;/li&gt;
&lt;li&gt;강한 일관성 vs 성능 트레이드오프 고려 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;회고&lt;/h1&gt;
&lt;h2&gt;트랜잭션이란?&lt;/h2&gt;
&lt;p&gt;트랜잭션은 데이터베이스에서 여러 연산을 하나의 논리적 단위로 묶어 처리하는 개념이다.&lt;br&gt;중간 상태 없이 &lt;strong&gt;전부 성공하거나 전부 실패&lt;/strong&gt;해야 하며, 데이터의 일관성을 보장하기 위한 핵심 메커니즘이다.&lt;/p&gt;
&lt;p&gt;예시: 은행 송금&lt;br&gt;출금이 성공했지만 입금이 실패하는 상황은 있을 수 없다. 둘은 반드시 함께 성공하거나 함께 실패해야 한다.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;ACID 속성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Atomicity (원자성)&lt;/strong&gt;: 트랜잭션 내 연산은 전부 실행되거나 전혀 실행되지 않아야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Consistency (일관성)&lt;/strong&gt;: 트랜잭션 전후의 데이터 상태는 항상 유효한 상태여야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Isolation (격리성)&lt;/strong&gt;: 동시 실행되는 트랜잭션들이 서로 간섭하지 않도록 해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Durability (지속성)&lt;/strong&gt;: 트랜잭션이 커밋되면 그 결과는 영구적으로 저장되어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;실무 관점: 모든 속성을 절대적으로 지키는 것보다, &lt;strong&gt;요구사항에 따라 균형 있게 적용&lt;/strong&gt;하는 것이 중요하다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr&gt;
&lt;h2&gt;격리 수준 (Isolation Level)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;격리 수준&lt;/th&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;th&gt;발생 가능한 문제&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Read Uncommitted&lt;/td&gt;
&lt;td&gt;커밋되지 않은 데이터도 읽을 수 있음&lt;/td&gt;
&lt;td&gt;Dirty Read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read Committed&lt;/td&gt;
&lt;td&gt;커밋된 데이터만 읽음&lt;/td&gt;
&lt;td&gt;Non-repeatable Read&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repeatable Read&lt;/td&gt;
&lt;td&gt;같은 트랜잭션 내 같은 쿼리 결과 유지&lt;/td&gt;
&lt;td&gt;Phantom Read (MySQL은 방지함)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot Isolation&lt;/td&gt;
&lt;td&gt;트랜잭션 시작 시점의 스냅샷 기준으로 읽기&lt;/td&gt;
&lt;td&gt;Write Skew 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serializable&lt;/td&gt;
&lt;td&gt;트랜잭션을 직렬화한 것처럼 동작&lt;/td&gt;
&lt;td&gt;성능 저하, 락 경합&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;격리 수준이 높을수록 일관성은 좋아지지만, 그만큼 &lt;strong&gt;성능과 동시성 제약이 커진다&lt;/strong&gt;.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr&gt;
&lt;h2&gt;동시성 제어 방식&lt;/h2&gt;
&lt;h3&gt;1. 2단계 잠금(2PL, Two-Phase Locking)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;모든 잠금을 획득한 후 작업 수행&lt;/li&gt;
&lt;li&gt;변경 완료 후 잠금 해제&lt;/li&gt;
&lt;li&gt;단점: 교착 상태(Deadlock) 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 낙관적 동시성 제어 (Optimistic Concurrency Control)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;트랜잭션 수행 중엔 잠금 없음&lt;/li&gt;
&lt;li&gt;커밋 시점에 충돌 여부 검사&lt;/li&gt;
&lt;li&gt;충돌 시 롤백 후 재시도&lt;/li&gt;
&lt;li&gt;장점: 충돌 가능성이 낮은 시스템에 적합, 락 경합 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;실무에서 많이 쓰는 방식. 특히 API 서버에서 병렬 요청이 많은 경우에 유리.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;hr&gt;
&lt;h2&gt;트랜잭션의 실용적 고려사항&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;모든 작업에 트랜잭션을 쓰는 것은 오히려 독이 될 수 있다.&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;불필요한 락과 성능 저하 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;시스템의 요구사항에 따라 적절한 격리 수준을 선택&lt;/strong&gt;해야 한다.&lt;ul&gt;
&lt;li&gt;대부분의 OLTP 시스템은 Read Committed나 Repeatable Read 정도에서 절충&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;강한 일관성과 성능 사이에서 적절한 트레이드오프&lt;/strong&gt;가 필요하다.&lt;ul&gt;
&lt;li&gt;특히 분산 시스템에서는 일관성 유지 비용이 크므로 더욱 중요하다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/65</guid>
      <comments>https://minsoolog.tistory.com/65#entry65comment</comments>
      <pubDate>Tue, 20 May 2025 18:53:10 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 설계 5장 회고</title>
      <link>https://minsoolog.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;복제 방식에는 크게 두 가지가 있음&lt;br&gt;1.	리더-팔로워 복제&lt;br&gt;리더가 모든 쓰기를 처리함.&lt;br&gt;팔로워는 리더의 데이터를 따라감.&lt;br&gt;대부분의 데이터베이스가 이 방식을 씀.&lt;br&gt;읽기를 팔로워로 분산하면 성능은 좋아짐.&lt;br&gt;근데 리더 장애 시 복구가 어려울 수 있음.&lt;br&gt;또 팔로워의 데이터가 최신이 아닐 수도 있었음.&lt;br&gt;&lt;br&gt;2.	멀티리더 복제&lt;br&gt;여러 노드가 동시에 쓰기 처리함.&lt;br&gt;충돌이 발생할 수 있음.&lt;br&gt;충돌 해결 정책이 필요했음.&lt;br&gt;지리적으로 분산된 시스템에서 유용함.&lt;br&gt;&lt;br&gt;3.	리더 없는 복제&lt;br&gt;모든 노드가 동등하게 읽기/쓰기 처리함.&lt;br&gt;높은 가용성을 가짐.&lt;br&gt;일관성 유지가 어려움.&lt;br&gt;애플리케이션이 충돌을 감수하거나 직접 해결해야 했음.&lt;br&gt;&lt;br&gt;복제를 하면 생기는 문제도 있었음.&lt;br&gt;	•	복제 지연 때문에 읽었을 때 최신 데이터가 아닐 수 있었음.&lt;br&gt;	•	팔로워가 리더보다 뒤처질 수 있었음.&lt;br&gt;	•	일관성과 가용성 사이에서 선택이 필요했음. (CAP 정리랑 연결됨)&lt;/p&gt;</description>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/64</guid>
      <comments>https://minsoolog.tistory.com/64#entry64comment</comments>
      <pubDate>Tue, 13 May 2025 18:55:42 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 설계 6장</title>
      <link>https://minsoolog.tistory.com/63</link>
      <description>&lt;h2&gt;1. 파티셔닝이란?&lt;/h2&gt;
&lt;p&gt;파티셔닝은 데이터를 여러 파티션 또는 샤드로으로 나누어 저장하는 방법입니다. 각 파티션은 독립적인 저장소이자 처리 단위가 되어, 분산 시스템에서 데이터 작업을 병렬로 수행할 수 있게 해준다.&lt;/p&gt;
&lt;p&gt;예:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;트위터는 유저 ID 기준으로 트윗을 파티셔닝하여 수억 명의 사용자 트윗을 분산 저장&lt;/li&gt;
&lt;li&gt;MySQL의 샤딩된 테이블은 서로 다른 서버에 분산되어 트래픽을 나눔&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. 파티셔닝 키 (Partitioning Key) 선택&lt;/h2&gt;
&lt;p&gt;파티셔닝에서 가장 중요한 결정은 어떤 필드를 기준으로 데이터를 나눌 것인지입니다. 이 필드를 샤딩 키라고 부른다.&lt;/p&gt;
&lt;p&gt;좋은 파티셔닝 키의 조건:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;균등 분산: 특정 키에 데이터가 몰리지 않아야 함&lt;/li&gt;
&lt;li&gt;쿼리 효율성: 자주 조회되는 쿼리가 해당 키로 빠르게 조회 가능해야 함&lt;/li&gt;
&lt;li&gt;불변성: 파티셔닝 키는 한 번 저장된 후 바뀌지 않는 것이 좋음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;나쁜 키 예시:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;가입일: 초기에 가입한 사용자에만 데이터가 몰릴 수 있음&lt;/li&gt;
&lt;li&gt;성별: 파티션이 두 개뿐이라면 분산이 제대로 되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;3. 주요 파티셔닝 전략&lt;/h2&gt;
&lt;h3&gt;1) 해시 파티셔닝 (Hash Partitioning)&lt;/h3&gt;
&lt;p&gt;파티셔닝 키에 해시 함수를 적용해 파티션을 결정.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;장점&lt;ul&gt;
&lt;li&gt;데이터가 고르게 분산됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점&lt;ul&gt;
&lt;li&gt;파티션 수가 바뀌면 대부분의 데이터가 이동해야 함&lt;/li&gt;
&lt;li&gt;범위 쿼리에 적합하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예시&lt;ul&gt;
&lt;li&gt;MongoDB의 기본 샤딩&lt;/li&gt;
&lt;li&gt;Cassandra의 consistent hashing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2) 범위 파티셔닝 (Range Partitioning)&lt;/h3&gt;
&lt;p&gt;파티셔닝 키의 값 범위로 파티션을 나눈다.&lt;br&gt;예: 1&lt;/p&gt;
&lt;p&gt;&lt;del&gt;1000, 1001&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;2000...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;장점&lt;ul&gt;
&lt;li&gt;범위 기반 쿼리에 유리 (예: 날짜 검색)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점&lt;ul&gt;
&lt;li&gt;특정 범위에 데이터가 몰릴 경우, 핫 파티션 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예시&lt;ul&gt;
&lt;li&gt;시계열 데이터 저장소 (예: Prometheus, InfluxDB)&lt;ul&gt;
&lt;li&gt;로그 수집 시스템&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3) 리스트 파티셔닝 (List Partitioning)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파티션 키의 특정 값 집합에 따라 파티션을 정의&lt;/li&gt;
&lt;li&gt;예: 국가 = KR → 파티션1, US → 파티션2&lt;/li&gt;
&lt;li&gt;장점&lt;ul&gt;
&lt;li&gt;카테고리 분류가 명확한 경우 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단점&lt;ul&gt;
&lt;li&gt;범주가 너무 많아지면 파티션 관리 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사용 예시&lt;ul&gt;
&lt;li&gt;멀티테넌시 SaaS 시스템 (테넌트 ID 기준)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;4. 파티셔닝 쿼리의 동작&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;단일 파티션 쿼리&lt;ul&gt;
&lt;li&gt;파티션 키를 명시한 조회&lt;/li&gt;
&lt;li&gt;효율적이며 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;다중 파티션 쿼리&lt;ul&gt;
&lt;li&gt;범위 또는 보조 인덱스를 사용하는 쿼리&lt;/li&gt;
&lt;li&gt;파티션 전체를 탐색하거나 병렬 조회 + 병합 필요 → 느림&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. 파티션 재조정 (Rebalancing)&lt;/h2&gt;
&lt;p&gt;운영 중인 시스템에서 파티션 수를 변경해야 할 때, 기존 데이터를 재배치하는 과정을 재조정이라고 한다.&lt;/p&gt;
&lt;h3&gt;어려운 점:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;대량의 데이터를 이동해야 하므로 비용이 큼&lt;/li&gt;
&lt;li&gt;시스템의 일관성과 가용성을 유지하면서 재조정해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;대표적인 해결책:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Consistent Hashing&lt;ul&gt;
&lt;li&gt;전체 데이터의 일부만 재배치되도록 설계&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;미들웨어 라우터 사용&lt;ul&gt;
&lt;li&gt;실제 파티션 수와 관계없이 라우팅 테이블에서 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;6. 파티셔닝과 트랜잭션&lt;/h2&gt;
&lt;h3&gt;단일 파티션 트랜잭션:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;한 파티션 내에서만 이루어짐&lt;/li&gt;
&lt;li&gt;간단하고 빠름&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;다중 파티션 트랜잭션:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2PC(2단계 커밋) 같은 분산 트랜잭션 필요&lt;/li&gt;
&lt;li&gt;실패 가능성, 성능 저하 등 위험 존재&lt;/li&gt;
&lt;li&gt;전략&lt;ul&gt;
&lt;li&gt;트랜잭션 범위가 파티션을 넘지 않도록 데이터 모델링&lt;/li&gt;
&lt;li&gt;카산드라, DynamoDB 등은 아예 다중 파티션 트랜잭션을 지원하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;7. 보조 인덱스와 파티셔닝&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;전역 보조 인덱스(Global Secondary Index)는 모든 파티션을 참조해야 하므로 비용이 큼&lt;/li&gt;
&lt;li&gt;로컬 인덱스(Local Index)는 파티션 안에서만 동작 → 빠르지만 제약 있음&lt;/li&gt;
&lt;li&gt;트레이드오프&lt;ul&gt;
&lt;li&gt;전역 인덱스: 검색은 빠르나 업데이트와 확장성이 떨어짐&lt;/li&gt;
&lt;li&gt;로컬 인덱스: 확장성은 좋지만 검색 제약&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;회고&lt;/h1&gt;
&lt;h2&gt;파티셔닝 학습 정리&lt;/h2&gt;
&lt;h3&gt;파티셔닝의 개념&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;데이터를 여러 파티션(또는 샤드)으로 나눠 분산 저장&lt;/li&gt;
&lt;li&gt;확장성과 처리 성능 확보에 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;좋은 파티셔닝 키의 조건&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;균등 분산&lt;/li&gt;
&lt;li&gt;자주 조회되는 쿼리에 적합&lt;/li&gt;
&lt;li&gt;변경되지 않는 값일 것&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;파티셔닝 전략&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;해시 파티셔닝: 균등 분산은 잘 되지만 범위 쿼리에 불리&lt;/li&gt;
&lt;li&gt;범위 파티셔닝: 범위 기반 쿼리에 유리하나 핫 파티션 우려&lt;/li&gt;
&lt;li&gt;리스트 파티셔닝: 명확한 범주가 있을 때 유용, 범주가 많아지면 관리 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;쿼리와 파티션&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;단일 파티션 쿼리는 빠름&lt;/li&gt;
&lt;li&gt;다중 파티션 쿼리는 느리고 비용이 큼&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;파티션 재조정&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;파티션 수 변경 시 데이터 이동 필요&lt;/li&gt;
&lt;li&gt;Consistent Hashing이나 라우팅 테이블로 일부만 이동하는 구조 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;트랜잭션 처리&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;단일 파티션 트랜잭션은 단순하고 빠름&lt;/li&gt;
&lt;li&gt;다중 파티션 트랜잭션은 복잡하고 실패 가능성 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;보조 인덱스&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;전역 인덱스: 쿼리는 빠르지만 확장성 떨어짐&lt;/li&gt;
&lt;li&gt;로컬 인덱스: 확장성 좋지만 쿼리에 제약 있음&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/63</guid>
      <comments>https://minsoolog.tistory.com/63#entry63comment</comments>
      <pubDate>Tue, 13 May 2025 18:45:55 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 설계 5장</title>
      <link>https://minsoolog.tistory.com/62</link>
      <description>&lt;h1&gt;5장. 복제 (Replication)&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 복제를 사용하는 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 복제는 하나의 데이터를 여러 서버에 저장하여 다음과 같은 목적을 달성하기 위해 사용된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;내결함성 향상&lt;/b&gt;: 하나의 서버가 장애를 일으켜도 다른 복제본을 통해 서비스 지속 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지연 시간 단축&lt;/b&gt;: 사용자와 가까운 지역의 서버에서 응답 제공 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;읽기 처리량 확장&lt;/b&gt;: 읽기 요청을 여러 서버에 분산&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 복제는 &lt;b&gt;동기화 지연, 일관성 문제, 충돌 처리&lt;/b&gt;와 같은 복잡한 문제도 함께 수반한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 리더-팔로워 복제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;구조&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;리더&lt;/b&gt; 서버에서만 쓰기 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;팔로워&lt;/b&gt; 서버는 리더의 데이터를 복제하여 읽기만 수행&lt;/li&gt;
&lt;li&gt;리더의 변경 사항은 로그를 통해 팔로워로 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;데이터 흐름&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트가 리더에게 쓰기 요청&lt;/li&gt;
&lt;li&gt;리더가 데이터를 변경하고 로그에 기록&lt;/li&gt;
&lt;li&gt;리더가 변경 로그를 팔로워에게 전송&lt;/li&gt;
&lt;li&gt;팔로워가 로그를 읽고 데이터 반영&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조가 단순하고 구현이 쉬움&lt;/li&gt;
&lt;li&gt;읽기 부하 분산 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리더 장애 시 리더 교체 과정 필요&lt;/li&gt;
&lt;li&gt;&lt;b&gt;복제 지연&lt;/b&gt;으로 인한 일관성 문제 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 리더 장애 상황 처리&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;리더 장애 시&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 리더를 선출해야 함&lt;/li&gt;
&lt;li&gt;리더가 전파하지 못한 변경 사항은 유실 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가장 최신 로그를 가진 팔로워&lt;/b&gt;가 리더로 선출되어야 안전&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클라이언트 관점 문제&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리더에 쓰기 요청을 보낸 직후 리더가 죽으면
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 내용이 복제되지 않았을 수 있음&lt;/li&gt;
&lt;li&gt;클라이언트는 성공 응답을 받았지만 데이터는 손실될 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 로그를 통한 복제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;트랜잭션 로그 기반&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리더 서버의 &lt;b&gt;트랜잭션 로그&lt;/b&gt;를 그대로 팔로워가 수신해 재실행&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;변경 내용 캡처(Change Data Capture, CDC)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리더의 변경 로그를 외부에서 캡처해 다른 시스템으로 전파&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 다중 리더 복제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 리더가 &lt;b&gt;동시에 쓰기 요청을 처리&lt;/b&gt;할 수 있음&lt;/li&gt;
&lt;li&gt;각 리더는 자신의 변경 내용을 다른 리더로 복제&lt;/li&gt;
&lt;li&gt;&lt;b&gt;지리적으로 분산된 환경&lt;/b&gt;에서 유리&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로컬 서버에서 빠르게 쓰기 가능&lt;/li&gt;
&lt;li&gt;네트워크 지연 시간 최소화&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;동일한 데이터에 대해 서로 다른 리더가 동시에 변경&lt;/b&gt;하면 충돌 발생&lt;/li&gt;
&lt;li&gt;충돌을 자동 혹은 수동으로 해결해야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;충돌 해결 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;최종 쓰기 우선 (Last Write Wins)&lt;/b&gt;: 가장 마지막 변경을 우선시&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버전 벡터&lt;/b&gt;를 통한 충돌 감지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;애플리케이션 수준 병합 로직&lt;/b&gt; 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 리더 없는 복제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개념&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;모든 노드가 동등한 역할을 수행&lt;/b&gt;하며, 특정 리더가 없음&lt;/li&gt;
&lt;li&gt;클라이언트는 여러 노드에 쓰기/읽기 요청을 보냄&lt;/li&gt;
&lt;li&gt;다수의 응답으로 정합성을 결정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;높은 내결함성&lt;/li&gt;
&lt;li&gt;네트워크 분할 상황에서도 일부 기능 유지 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;단점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;충돌 가능성 높음&lt;/li&gt;
&lt;li&gt;데이터 버전 관리가 복잡함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예시 시스템&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Amazon Dynamo, Apache Cassandra, Riak&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;7. 복제와 읽기 일관성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복제는 읽기 일관성에 영향을 준다. 다음은 주요 읽기 일관성 모델이다:&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 선형화 가능성&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 직관적인 일관성 모델&lt;/li&gt;
&lt;li&gt;어떤 사용자가 쓴 값을, 다른 사용자도 바로 읽을 수 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2) 자신의 쓰기 읽기 보장&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 자신이 작성한 데이터를 다시 읽을 때 반드시 반영되어 있어야 함&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3) 순차적 읽기 보장&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전에 읽은 값보다 오래된 값이 다시 반환되면 안 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4) 순차적 쓰기 보장&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자의 쓰기 작업 순서가 뒤바뀌지 않고 반영되어야 함&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>스터디</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/62</guid>
      <comments>https://minsoolog.tistory.com/62#entry62comment</comments>
      <pubDate>Thu, 8 May 2025 17:28:37 +0900</pubDate>
    </item>
    <item>
      <title>데이터 중심 애플리케이션 1,2장</title>
      <link>https://minsoolog.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot; style=&quot;text-align: left;&quot;&gt;1장. 신뢰할 수 있고, 확장 가능하며 유지 관리가 쉬운 애플리케이션 설계&lt;br&gt;&lt;br&gt;1. 애플리케이션의 역할 변화&lt;br&gt;예전에는 애플리케이션이 단순히 데이터를 입력받아 저장하고 조회하는 역할이었지만,&lt;br&gt;지금은 수많은 사용자, 데이터, 외부 서비스와 통신하는 복잡한 시스템이 됨.&lt;br&gt;이런 변화 속에서, 애플리케이션의 핵심 품질 속성 세 가지를 기준으로 설계해야 함.&lt;br&gt;&lt;br&gt;2. 신뢰성 (Reliability)&lt;br&gt;장애가 발생해도 시스템이 올바르게 동작하는 것.&lt;br&gt;장애의 예:&lt;br&gt;하드웨어 오류 (디스크 불량, 서버 다운 등)&lt;br&gt;소프트웨어 오류 (버그, 예외 처리 실패)&lt;br&gt;사람의 실수 (잘못된 설정, 운영 실수 등)&lt;br&gt;이를 대비하는 방법:&lt;br&gt;복제(replication): 데이터를 여러 곳에 복사해 장애 시에도 접근 가능&lt;br&gt;리트라이와 타임아웃: 일시적 오류에 대비&lt;br&gt;모니터링과 알림: 문제가 생겼을 때 빠르게 대응 가능&lt;br&gt;&lt;br&gt;3. 확장성 (Scalability)&lt;br&gt;시스템이 데이터양, 사용자 수, 요청 수 증가에 효율적으로 대응할 수 있어야 함.&lt;br&gt;확장성의 질문은 “더 큰 부하가 들어올 때 시스템은 어떻게 반응하는가?”&lt;br&gt;수직 확장: 더 강력한 하드웨어로 교체&lt;br&gt;수평 확장: 서버를 여러 대 추가해 분산 처리&lt;br&gt;지표에 따라 다르게 접근해야 함:&lt;br&gt;초당 요청 수 증가&lt;br&gt;데이터 쓰기/읽기량 증가&lt;br&gt;저장해야 하는 데이터 용량 증가 등&lt;br&gt;&lt;br&gt;4. 유지보수성 (Maintainability)&lt;br&gt;시스템이 시간이 지나고 팀원이 바뀌더라도 쉽게 이해하고 변경할 수 있어야 함.&lt;br&gt;&lt;br&gt;주요 요소:&lt;br&gt;모듈화: 시스템을 작게 나눠서 독립적으로 개발/배포 가능&lt;br&gt;관찰 가능성 (observability): 로그, 메트릭, 트레이싱 등으로 현재 상태 파악 가능&lt;br&gt;자동화된 테스트: 변경이 기존 기능을 망가뜨리지 않는지 검증&lt;br&gt;&lt;br&gt;2장. 데이터 모델과 질의 언어&lt;br&gt;&lt;br&gt;1. 데이터 모델이 중요한 이유&lt;br&gt;데이터 모델은 단순히 데이터를 저장하는 형식이 아니라, 애플리케이션이 데이터를 어떻게 다루는지를 결정함.&lt;br&gt;적절한 데이터 모델을 선택하면 개발과 운영이 쉬워지고, 그렇지 않으면 구조 변경이 고통스러움.&lt;br&gt;&lt;br&gt;2. 관계형 데이터베이스 (RDBMS)&lt;br&gt;테이블, 행(Row), 열(Column) 기반 모델.&lt;br&gt;SQL이라는 강력한 선언형 질의 언어를 사용.&lt;br&gt;&lt;br&gt;장점:&lt;br&gt;정형화된 구조, 명확한 스키마&lt;br&gt;JOIN을 통한 관계 표현&lt;br&gt;ACID 트랜잭션으로 데이터 정합성 보장&lt;br&gt;&lt;br&gt;단점:&lt;br&gt;스키마가 엄격해 구조 변경이 어렵고 유연성이 떨어짐&lt;br&gt;중첩된 구조(예: 주소 안에 좌표 정보가 있음 등)를 표현하기 어려움&lt;br&gt;&lt;br&gt;3. 문서 지향 데이터베이스 (Document DB)&lt;br&gt;JSON 같은 문서 형태로 데이터를 저장 (MongoDB, CouchDB 등)&lt;br&gt;계층적 구조를 자연스럽게 표현할 수 있음&lt;br&gt;&lt;br&gt;장점:&lt;br&gt;유연한 스키마: 서로 다른 필드를 가진 문서 저장 가능&lt;br&gt;객체지향 프로그래밍과 잘 어울림&lt;br&gt;중첩된 데이터를 단일 쿼리로 가져오기 쉬움&lt;br&gt;&lt;br&gt;단점:&lt;br&gt;중복 데이터 발생 가능성 (주소, 사용자 정보 등)&lt;br&gt;JOIN이 어려워 관계형 데이터엔 부적합할 수 있음&lt;br&gt;&lt;br&gt;4. 그래프 데이터베이스&lt;br&gt;노드(객체)와 엣지(관계)로 데이터를 표현 (Neo4j, Amazon Neptune 등)&lt;br&gt;친구의 친구, 추천 알고리즘, 트리 탐색 등 관계 중심 쿼리에 강함&lt;br&gt;쿼리 언어: Cypher 같은 그래프 쿼리 언어 사용&lt;br&gt;&lt;br&gt;5. 질의 언어&lt;br&gt;선언형 언어(SQL): &quot;무엇을 원하는가&quot;를 표현, 내부 실행 방식은 DB가 결정&lt;br&gt;명령형 API: 프로그래머가 쿼리 절차를 명시적으로 작성 (NoSQL에서 많이 사용)&lt;br&gt;&lt;br&gt;6. 데이터 모델 선택 기준&lt;br&gt;트레이드오프 존재:&lt;br&gt;관계형: 정합성과 일관성 중시, 유연성 부족&lt;br&gt;문서형: 유연성 좋고 읽기 빠름, 중복과 정합성 관리 필요&lt;br&gt;그래프형: 관계 중심 문제에 특화&lt;br&gt;데이터 모델이 애플리케이션 구조와 직접 연결되므로, 요구사항과 데이터 액세스 패턴에 따라 신중히 선택해야 함&lt;br&gt;&lt;br&gt;&lt;/p&gt;</description>
      <category>스터디</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/61</guid>
      <comments>https://minsoolog.tistory.com/61#entry61comment</comments>
      <pubDate>Tue, 22 Apr 2025 18:48:26 +0900</pubDate>
    </item>
    <item>
      <title>2023년 주니어 개발자 회고</title>
      <link>https://minsoolog.tistory.com/60</link>
      <description>&lt;h2&gt;회고를 시작하며&lt;/h2&gt;
&lt;p&gt;2023년은 나에게 많은 일이 있던 해였다. 이룬것도 많았고 놓친것도 많았다. 말고 많고 탈도 많았던 2023년을 되돌아보자.&lt;/p&gt;
&lt;h2&gt;팀 이동&lt;/h2&gt;
&lt;p&gt;줌인터넷 재직 당시 다른 팀에서 진행하는 스터디에 합류해서 같이 공부해 보자는 제안을 받았다. 평소 다른 팀들과 친해질 수 있는 계기가 없기 때문에 좋은 기회라고 생각되어 &lt;code&gt;가상 면접 사례로 배우는 대규모 시스템 설계 기초&lt;/code&gt; 라는 책을 같이 학습하였다. 단순히 책을 읽는 것으로 끝나지 않고, 각자 생각하는 설계를 화이트보드에 적어가면서 토론하는 방식으로 진행되었는데 새삼스레 다른 팀 문화를 느낄 수 있어 좋은 경험이었다.&lt;/p&gt;
&lt;p&gt;스터디를 진행하던 도중 파트장님이 같이 근무해 보자는 제안을 먼저 해주셨고, 몇 차례의 면담 끝에 핀테크개발팀 에 합류하게 되었다. 사내에서 주력으로 진행하는 프로젝트를 담당하는 팀에 합류한다는 사실이 행복했지만, 좋은 인상을 보여 합류한만큼 그에 보답해야겠다는 생각이 한편으론 많은 부담이 있었다.&lt;/p&gt;
&lt;p&gt;그때 큰 힘이 되어주었던 글이 있었는데 &lt;a href=&quot;https://jojoldu.tistory.com/675&quot;&gt;이동욱 님의 신뢰 자본&lt;/a&gt;이라는 글이다.&lt;br&gt;새로운 팀원들은 아직 나에 대해 잘 모르기 때문에 코드 리뷰, 설계 리뷰하는 과정에서 팀원들의 의견에 지지를 해주되 조심스럽게 내 의견을 제시하면서 신뢰를 쌓아갔다. 감사하게도 팀원들은 내 의견에 많은 힘을 실어주었고 덕분에 이른 시일 내에 적응해서 업무를 진행할 수 있었다.&lt;/p&gt;
&lt;h2&gt;기술 블로그 발행&lt;/h2&gt;
&lt;p&gt;미루고 미루던 버킷리스트 중 하나인 기술 블로그를 드디어 작성했다. 특정 기술에 대한 설명보다는 &lt;code&gt;업무를 진행하면서 어떤 어려움이 있었고,&lt;/code&gt; &lt;code&gt;어떻게 해결했는지&lt;/code&gt; 내가 고민했던 경험을 소개하고 싶었다. 줌인터넷에서는 많은 기술 과제가 있었는데 그중 하나를 혼자 담당하게 되어 해결하였고, 그 과정을 기술 블로그에 발행하게 되었다. 생각보다 많은 분들이 감사하게도 좋은 피드백을 해주셔서 작성한 보람을 많이 느낄 수 있었다.&lt;/p&gt;
&lt;p&gt;기술적으로 뛰어난 글은 아니지만, 업무를 진행하면서 생각했던 많은 고민이 담겨있는 글이다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zuminternet.github.io/spring-session/&quot;&gt;제목은 Spring Session 도입기로 하겠습니다. 근데 이제 Redis를 곁들인&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;우연히 찾아온 합격&lt;/h2&gt;
&lt;p&gt;처음부터 이직할 생각은 없었다. 새로운 팀에 합류한 지 얼마 안됐고, 도전하고 싶은 많은 기술 과제가 눈앞에 있었다.&lt;br&gt;당시 소위 말하는 네카라쿠배 중 한 곳이 대규모 공채를 진행 중이었는데 &lt;code&gt;이 정도면 서류 합격할 수 있을까?&lt;/code&gt; 라는 생각에 시작한 채용 프로세스가 최종 면접까지 가버렸다. 아쉽게도 최종 면접에서는 탈락했지만 계기로 삼아 &lt;code&gt;한번 도전해 볼까?&lt;/code&gt; 라는 생각에 이직 준비를 시작하게 되었다.&lt;/p&gt;
&lt;h2&gt;이직 준비&lt;/h2&gt;
&lt;p&gt;업무를 진행하면서 이직 준비는 생각보다 힘들다. 평일에 퇴근 후 공부를 한다는 게 나이 탓인지 체력적으로 많이 지쳤고, 집중도 잘 안됐다. 온전히 모든 시간 동안 학습한다는 건 현실적으로 불가능하다고 생각했고, &lt;code&gt;출퇴근 자투리 시간&lt;/code&gt; 과 &lt;code&gt;주말&lt;/code&gt; 을 적극적으로 활용하면서 준비했다. 한 가지 일에 몰두하게 되면 너무 집중한 나머지 다른 것들을 놓치는 경향이 있는데 이직은 성공했지만, 많은 것을 놓친 기간이기도 하다.&lt;/p&gt;
&lt;h2&gt;이직&lt;/h2&gt;
&lt;p&gt;운이 좋게도 동시에 최종 합격을 한 곳이 있었지만 고민 끝에 &lt;code&gt;카카오페이&lt;/code&gt; 에 합류했다. 단순히 지식의 차이를 다루는 면접이 아닌 같은 개발자로서 어떤 생각을 가졌는지, 서로의 경험을 토대로 소통하는 면접 경험이 정말 좋았다.&lt;/p&gt;
&lt;p&gt;개발자라는 직업을 처음 시작했을 때 주변 사람들에게 막무가내로 &lt;code&gt;국비지원교육&lt;/code&gt; 출신 개발자도 네카라쿠배 갈 수 있어! &lt;code&gt;내 계획은 5년짜리 계획이야&lt;/code&gt; 라는 말을 뱉고 다녔다. 이룰 수 없을 것 같은 목표로 시작했던 커리어 여정의 보답을 받은 것 같아 합격 메일을 받고 정말 기분이 좋았던 생각이 난다.&lt;/p&gt;
&lt;h2&gt;자기관리&lt;/h2&gt;
&lt;p&gt;어느 정도의 꾸밈은 하고 다녔지만, 신체적으로 자기관리는 개발자를 시작하고 한 번도 한 적이 없다.&lt;br&gt;보드를 타러 갔는데 몸이 무거워서 못 일어나는 내 모습을 보고 현실을 깨닫게 돼서 올해부터는 자기관리를 하고 있다.&lt;br&gt;헬스, 필라테스를 병행하면서 운동을 하고 있는데 &lt;code&gt;체지방률 15% 이하&lt;/code&gt; 를 목표로 꾸준히 하고 있다.&lt;br&gt;식습관도 많은 부분 개선하였다. 현실적으로 샐러드, 닭가슴살로 다이어트를 하게 되면 얼마 못 가 실패할 가능성이 높아 저탄수화물·고지방으로 식단을 개선하였고, 혈당 관리를 위해서 단 것은 최대한 자제하고 있다. 관리하면 빼 놓을 수 없는 피부 관리도 제모, 흉터 치료를 받으며 외모를 열심히 가꾸고 있다.&lt;/p&gt;
&lt;p&gt;30대부터는 자기관리의 유무로 인한 격차가 굉장히 심하다고 한다. &lt;code&gt;배 나온 아저씨&lt;/code&gt; 는 되기 싫다.&lt;/p&gt;
&lt;h2&gt;경험치&lt;/h2&gt;
&lt;p&gt;업무를 진행하면서, 이직을 준비하면서 주변 사람들의 도움을 정말 많이 받았다.&lt;br&gt;가끔 채용 혹한기에 어떻게 이직했냐는 질문을 받으면 &lt;code&gt;주변 사람들의 경험치를 먹고 성장했어요&lt;/code&gt; 라고 답변한다.&lt;/p&gt;
&lt;p&gt;개발자로 경력을 쌓으면서 결과물에 대한 자부심은 있지만 단 한 번도 자만했던 적이 없다.&lt;br&gt;늘 부족하다고 느꼈고, 피드백을 받으며 내가 생각지도 못한 걸 배우곤 한다.&lt;/p&gt;
&lt;p&gt;이제는 내가 그동안 쌓아 올린 경험치를 다른 사람들에게 나눠주고 싶다. 구체적인 방법은 더 모색해 봐야겠지만, 우선 내가 도움이 될 수 있는 주변 사람들에게 좋은 영향을 주기 위해 노력하고 있다.&lt;/p&gt;
&lt;h2&gt;회고를 마치며&lt;/h2&gt;
&lt;p&gt;회사에서 닉네임을 사용하다 보니 나만의 부캐릭터가 생긴 느낌이다. 회사에서도 맡은 업무를 열심히 진행하고 있지만&lt;br&gt;올해는 본캐릭터를 열심히 키울 예정이다. 운동과 재테크를 병행하면서 &lt;code&gt;멋진 30대를 위한 초석을 다지는 한 해가 되기를 바라며&lt;/code&gt;&lt;/p&gt;</description>
      <category>메모장</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/60</guid>
      <comments>https://minsoolog.tistory.com/60#entry60comment</comments>
      <pubDate>Fri, 9 Feb 2024 23:58:32 +0900</pubDate>
    </item>
    <item>
      <title>2022년 하반기 주니어 개발자 회고</title>
      <link>https://minsoolog.tistory.com/59</link>
      <description>&lt;h2&gt;회고를 시작하며&lt;/h2&gt;
&lt;p&gt;2022년 하반기는 개인의 성장보다는 회사 업무에 집중했던 시기였다. 이직 후 회사 업무 프로세스에 적응이 필요하기도 했고&lt;br&gt;보상 심리가 생겨 나름대로 휴식도 많이 취했다. 스스로 만족스럽지 못한 2022년 하반기 회고를 시작해보자&lt;/p&gt;
&lt;h2&gt;파일럿 프로젝트&lt;/h2&gt;
&lt;p&gt;사내 신규 입사자들은 입사 후 파일럿 프로젝트를 진행하는 문화가 있다. 입사 시기에 맞춰 파일럿 프로젝트 과제를 준비해주셨고 내가 진행했던 과제는 기존 회원 구조를 통합 회원으로 개선하는 것이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHAcpl/btrWTKUGfUP/r753reY2DmipyfgXO7TfpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHAcpl/btrWTKUGfUP/r753reY2DmipyfgXO7TfpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHAcpl/btrWTKUGfUP/r753reY2DmipyfgXO7TfpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHAcpl%2FbtrWTKUGfUP%2Fr753reY2DmipyfgXO7TfpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;518&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;통합 회원을 간단하게 설명하면 하나의 계정이 여러 개의 소셜 아이디와 연동하는 것을 의미한다.&lt;/p&gt;
&lt;p&gt;단기간에 기존 회원 구조를 파악하면서 개선하는 것은 생각보다 쉽지 않았다. 인수인계를 해주신 파트장님도 다른 파트에서 근무하고 계셨고, 회원 서비스 담당 기획자분도 입사하신 지 얼마 되지 않아 회원 정책을 같이 파악하면서 진행하였다. 기술적으로도 많은 배움이 있었다. &lt;code&gt;Spring Security&lt;/code&gt;, &lt;code&gt;OAuth2.0&lt;/code&gt;, &lt;code&gt;Cookie&lt;/code&gt;, &lt;code&gt;Session&lt;/code&gt; 등 기존에 알고 있던 지식을 한층 고도화시킨 것 같아 만족스러웠던 파일럿 프로젝트였다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sNBqs/btrWVLr5a7e/7ihula51TO4o8BbftrFsn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sNBqs/btrWVLr5a7e/7ihula51TO4o8BbftrFsn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sNBqs/btrWVLr5a7e/7ihula51TO4o8BbftrFsn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsNBqs%2FbtrWVLr5a7e%2F7ihula51TO4o8BbftrFsn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;368&quot; height=&quot;107&quot; data-origin-width=&quot;368&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;파일럿 프로젝트를 진행하면서 처음으로 코드 리뷰를 받아봤다. &lt;code&gt;칭찬은 고래도 춤추게 한다&lt;/code&gt; 라는 속담이 있듯이 파일럿 프로젝트를 진행하면서 코드 리뷰는 많은 가르침을 얻을 수 있는 시간과 큰 힘이 되었다. 지금은 파트에서 코드 리뷰를 진행하고 있지 않아 아쉽다. 내가 진행한 파일럿 프로젝트는 특이하게도(?) 바로 운영 중인 서비스에 배포될 예정이었기에 부담감도 있었지만 입사한 지 얼마 되지 않아 바로 회사 서비스에 기여를 했다는 점이 뿌듯하였다.&lt;/p&gt;
&lt;h2&gt;동료&lt;/h2&gt;
&lt;p&gt;회사 생활을 적응할 때 가장 큰 힘이 되어준 사람들이다. 같이 입사하여 큰 힘이 되었지만 지금은 아쉽게도 다른 회사에서 근무하는 동기, 다른 파트지만 매번 커피 한잔하자고 DM 주시는 분 등등&lt;/p&gt;
&lt;p&gt;프로젝트를 진행하면서 기술적인 어려움이 있거나, 개인적인 고민이 있을 때 늘 큰 힘이 되어주는 고마운 사람들이다. 열심히 노력하는 모습을 보면서 매번 자극받으며 그 모습을 본받고 있다. 사내에서 시작한 좋은 인연이 앞으로도 이어졌으면 좋겠다.&lt;/p&gt;
&lt;h2&gt;건강&lt;/h2&gt;
&lt;p&gt;나이 탓인지는 몰라도 급격하게 체력이 부족해지는 것을 느끼고 있다. 2023년 키워드는 건강으로 정했다. 개발 지식도 기초 체력이 필요하듯이 오랜 시간 동안 책상에 앉아있기 위해 체력 증진의 필요성을 느꼈다. 하루에 5-6시간 정도는 수면 시간으로 정하고 주 1-2회 정도는 운동을 시작할 예정이다. 개발도 결국 장거리 마라톤이라고 생각한다. 공부가 하고 싶어도 허리가 아파서, 몸이 힘들어서 못 하는 일이 없도록 건강 관리를 할 예정이다.&lt;/p&gt;
&lt;h2&gt;학습&lt;/h2&gt;
&lt;p&gt;2022년 12월을 기점으로 &lt;code&gt;만 3년 개발자&lt;/code&gt;가 되었다. 이제는 결코 낮은 연차가 아니기에 연차에 대한 부담감이 있는 것은 사실이다. 블로그 포스팅도 단순 내용 정리 글이 아닌 의미 있는 글을 작성하고 싶어 반년째 멈춘 상태고, 꾸준히 학습은 하고 있지만 갈피를 못 잡고 있는 것 같아 회의감이 와서 연말에 꽤 휴식을 했다. 회사 업무에 필요한 학습을 위주로 하면서 부족한 역량을 채우려고 한다. 학습에 대한 전략보다는 우선 절대적인 공부 시간을 늘리는 게 학습 목표다. 짧은 시간에 공부 효율이 나타나는 사람들도 있겠지만, 주위에 내가 존경하는 동료들을 보면 절대 짧은 시간을 투자하지 않는다.&lt;/p&gt;
&lt;h2&gt;2023년 목표&lt;/h2&gt;
&lt;p&gt;2023년 목표는 학습한 내용을 바탕으로 다양한 사람들과 대화를 나누어 보려고 한다. 내가 습득한 지식을 다른 사람들한테 공유하면서 피드백을 통해 놓친 부분을 바로 잡을 수 있고, 다른 사람들에게 좋은 영향력을 끼치고 싶다. 거창한 것부터 시작하기보다는 블로그 포스팅부터 시작하려고 한다. 기회가 된다면 사내 블로그 포스팅도 상반기에 작성하고 싶다.&lt;/p&gt;
&lt;h2&gt;회고를 마치며&lt;/h2&gt;
&lt;p&gt;뉴스를 보면 세계 경제가 몰락하고 있다고 한다. 코스피 주가는 코로나 이전으로 회귀하였고, 수도권 집값은 거품이 빠지고 있다. 이럴 때일수록 자테크를 해보는 건 어떨까? 자테크란 자기 자신이 종목이 되어 자기 계발에 투자하는 것을 가리켜 &lt;code&gt;자(自)테크&lt;/code&gt; 라고 부른다. 나는 주식투자에는 재능이 없다. 그래서 올해는 내가 종목이 되어 나 자신에게 투자하려고 한다.&lt;/p&gt;
&lt;p&gt;스스로 부끄러운 2022년 하반기였다. 회고를 통한 반성도 좋은 회고라고 생각한다.&lt;/p&gt;
&lt;p&gt;2023년에는 단순히 기능만을 구현하는 것에 그치는 개발자가 아닌 &lt;code&gt;소프트웨어 개발의 본질을 이해하는 개발자&lt;/code&gt;가 되고 싶다.&lt;/p&gt;</description>
      <category>메모장</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/59</guid>
      <comments>https://minsoolog.tistory.com/59#entry59comment</comments>
      <pubDate>Mon, 23 Jan 2023 21:44:32 +0900</pubDate>
    </item>
    <item>
      <title>2022년 상반기 주니어 개발자 회고</title>
      <link>https://minsoolog.tistory.com/58</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;회고를 시작하며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올해를 맞이하며 처음으로 정했던 첫 목표는 &lt;code&gt;회고 작성하기&lt;/code&gt; 였다. 자신을 아무리 잘 알고 있다고 해도 스스로 칭찬과 피드백을 글로 남긴다면 지속적인 성장에 도움을 줄 수 있으리라 생각했다.&lt;br /&gt;2022년 상반기는 &lt;code&gt;선택과 집중&lt;/code&gt; 이 필요한 시기였고 나에게 많은 변화가 있던 시간이었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시나브로&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;모르는 사이에 조금씩 조금씩&lt;/code&gt; 라는 의미를 가진 순우리말이다. 나는 올해의 키워드를 &lt;code&gt;시나브로&lt;/code&gt; 로 정했다.&lt;br /&gt;출퇴근 시간, 평일 저녁, 주말에 꾸준히 공부하는 습관을 길들였다. 이렇게 꾸준히 공부하는 습관은 시나브로 어느샌가 머릿속에 지식으로 축적되리라 생각했고 매일 공부하기 위해 노력하였다.&lt;br /&gt;&lt;code&gt;1일 1커밋&lt;/code&gt; 문화는 지속해서 공부하는 습관을 길들이기에 효과적이라고 생각한다. 시각적으로 재미도 있고, 공부한 내용을 &lt;code&gt;public&lt;/code&gt; 공간에 정리하면서 내가 어떤 공부를 하는지 다른 개발자들과 소통하게 되는 장점도 있다. 단점을 굳이 꼽자면 잔디를 채우기 위해 의미 없는 커밋을 채운 적도 있었다. 하지만 괜찮다고 생각한다. 어떤 커밋을 남기던 공부를 하기 위해 귀찮은 몸을 이끌고 코드를 작성했다는 의미니까.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1534&quot; data-origin-height=&quot;402&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zo6m2/btrGQotB9ZK/OuSkWBebbBgSHlMGOt1X5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zo6m2/btrGQotB9ZK/OuSkWBebbBgSHlMGOt1X5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zo6m2/btrGQotB9ZK/OuSkWBebbBgSHlMGOt1X5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZo6m2%2FbtrGQotB9ZK%2FOuSkWBebbBgSHlMGOt1X5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1534&quot; height=&quot;402&quot; data-origin-width=&quot;1534&quot; data-origin-height=&quot;402&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;홀로서기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 회사에서 팀장님의 갑작스러운 퇴사로 인해 약 6개월 동안 리더의 역할을 맡았다. 업무 분배와 팀 운영까지 혼자 담당했고, 신입 두 분을 이끌고 가는 일은 생각보다 쉽지 않았다. 퇴사로 인해 분위기가 팀이 흔들리지 않도록 &lt;code&gt;나도 팀장님만큼 할 수 있어&lt;/code&gt; 라는 모습을 팀원들에게 많이 보여주려고 노력하였다. 늦은 저녁까지 팀원들의 모든 커밋을 확인하고 코드 리뷰를 해드렸고, 팀원의 성장에 도움이 될 수 있는 업무를 할당해드렸다. 작은 회사이지만 나름 &lt;code&gt;자체 서비스&lt;/code&gt; 를 하는 기업이므로 구색을 갖추기 위해 많이 노력하였다. 모니터링 도구, CI/CD, 문서화 등 그동안 사내에서 부족했던 부분을 &lt;code&gt;회사의 성장이 곧 나의 성장&lt;/code&gt; 이라는 생각으로 기여하였다. 결과적으로 회사에서 성과를 인정해주었고, 파격적이진 않았지만 &lt;code&gt;사내 연봉 인상률 1등&lt;/code&gt; 이라는 쾌거를 이루었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;퇴사를 결심하다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하자면 올해 퇴사는 할 예정이었다. 회사에 대한 불만보다는 더 이상 성장 동력이 없었다. 주니어 시절에 더 많은 경험과 성장이 하고 싶었다.&lt;br /&gt;지속해서 다른 개발자들과 공부를 하면서 실력을 향상해왔지만 결국 실무에서의 경험과는 절대 비교할 수 없다고 생각했기에 단 한 번의 고민도 없이 이직 준비를 시작하였다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이직&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직 목표는 &lt;code&gt;무조건 서비스 기업&lt;/code&gt; 이었다. 내가 직접 만든 서비스를 누군가 사용한다는 건 늘 설렌다. 기업 규모보다는 좋은 개발 문화와 맥북을 지급하는 회사를 목표로 정했다. 큰 의미는 없지만, 맥북이 가지고 싶었고 개발자들에게 맥북을 지급하는 회사는 개발자를 대우해준다는 느낌이 들어 기준에 넣었다. 준비 기간은 5월까지 무조건 이직을 목표로 준비하였다. 시간이 지날수록 경력이 쌓이는 부담감에 &lt;code&gt;쓸데없는 경력&lt;/code&gt; 이 되지 않기 위해선 빠른 이직이 필요하다고 느꼈다. 5시에 퇴근해서 10시까지는 무조건 회사에 남아서 공부했다. &lt;code&gt;선택과 집중&lt;/code&gt; 이 필요한 시점에 코딩 테스트는 과감히 포기하였다. 하지만 코딩 테스트를 포기한 만큼 지원할 수 있는 회사의 폭은 절반 이상으로 줄어들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 회사가 있었지만 많은 고민 끝에 &lt;code&gt;줌인터넷&lt;/code&gt; 에 합류하게 되었다.&lt;br /&gt;우선 &lt;code&gt;기술 블로그&lt;/code&gt; 를 운영한다는 점에서 좋은 개발 문화를 가지고 있다고 생각했고,&lt;br /&gt;어느 정도 규모도 있기에 개발에 집중할 수 있다는 점도 매력적으로 다가왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직에 대한 자세한 이야기는 따로 작성하도록 하겠다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대외활동&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022년 상반기에는 미친 듯이 대외활동을 했다. 안목을 키우고 싶었고 우물 안 개구리가 되기 싫었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;디프만&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;디프만&lt;/code&gt; 이라는 동아리에 선발되어 4개월 동안 프로젝트에 참여하였다. 기획부터 운영까지 모든 단계에 참여하면서 폭발적인 성장을 할 수 있었다.&lt;br /&gt;업무 능력에 직접적으로 도움이 되는 &lt;code&gt;하드 스킬&lt;/code&gt; 에도 도움이 되었지만, 짧은 기간 동안 출시를 목표로 하는 만큼 &lt;code&gt;소프트 스킬&lt;/code&gt; 을 키우는 데 많은 도움이 되었다. &lt;code&gt;디프만&lt;/code&gt; 동아리에서 정말 많은 사람을 만났고 좋은 얘기를 많이 나누었다. 개발을 사랑하는 사람들이라면 지원하는 것을 강력히 추천한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;우아한 유스방 3기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오톡 오픈채팅 &lt;code&gt;유쾌한 스프링 방&lt;/code&gt; 에서 &lt;code&gt;제이슨&lt;/code&gt; 님이 진행하는 스터디이다. 운 좋게 선발되어 합류하게 되었다. 스터디 과정을 전부 공개하지는 못하지만, 이력서를 작성하는 방법부터 모의 면접까지 이직을 준비하는 과정에서 많은 도움을 받았다. 특히 매일 저녁 10시 &lt;code&gt;SLiPP&lt;/code&gt; 게더타운에서 데일리 스크럼을 하며 서로의 생각을 공유하는 문화는 &lt;code&gt;우아한 유스방 3기&lt;/code&gt; 가 끝나도 계속 하고 싶을 정도로 좋았다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;회고를 마치며&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음으로 작성하는 회고록이라 내 감정을 100% 글로 표현하지 못했지만, 상반기를 되돌아볼 수 있는 계기가 되어 좋다. 최근 김창준 님의 &lt;code&gt;함께 자라기&lt;/code&gt; 라는 책을 출퇴근 길에 읽고 있다. 학습 방법부터 성장 방향성까지 좋은 개발자로 성장하기 위한 내용들이 가득하다. 2022년 상반기에는 이직을 위한 학습을 했다면, 2022년 하반기에는 부족한 전공 지식이나, 박재성 님이 운영하시는 &lt;code&gt;NEXTSTEP&lt;/code&gt;, &lt;code&gt;코틀린&lt;/code&gt; 등 내가 하고 싶은 공부하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가가 나를 소개했을 때 &lt;code&gt;같은 팀에서 일하고 싶은 사람&lt;/code&gt; 이 되기 위해&lt;/p&gt;</description>
      <category>메모장</category>
      <author>김민수</author>
      <guid isPermaLink="true">https://minsoolog.tistory.com/58</guid>
      <comments>https://minsoolog.tistory.com/58#entry58comment</comments>
      <pubDate>Fri, 1 Jul 2022 23:10:42 +0900</pubDate>
    </item>
  </channel>
</rss>