<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_jaehye0n.log</title>
        <link>https://velog.io/</link>
        <description>BlockChain Engineer</description>
        <lastBuildDate>Sat, 12 Aug 2023 06:03:30 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. _jaehye0n.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_jaehye0n" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Raw SQL vs ORM]]></title>
            <link>https://velog.io/@_jaehye0n/Raw-SQL-vs-ORM</link>
            <guid>https://velog.io/@_jaehye0n/Raw-SQL-vs-ORM</guid>
            <pubDate>Sat, 12 Aug 2023 06:03:30 GMT</pubDate>
            <description><![CDATA[<h3 id="1-원시-sql-문">1. 원시 SQL 문:</h3>
<h4 id="장점">장점:</h4>
<ul>
<li>성능**: 일반적으로 더 직접적이고 ORM 번역의 오버헤드가 없으므로 일반적으로 더 빠르다.</li>
<li>유연성**: ORM으로 쉽게 표현할 수 없는 복잡한 쿼리를 작성할 수 있다.</li>
<li>제어**: 실행되는 정확한 SQL에 대한 더 많은 제어 기능을 제공하므로 필요에 따라 최적화할 수 있다.</li>
</ul>
<h4 id="단점">단점:</h4>
<ul>
<li>안전성**: 주의 깊게 다루지 않으면 SQL 인젝션이 발생하기 쉽다.</li>
<li>휴대성**: 다른 데이터베이스 엔진으로 전환할 경우 쿼리를 변경해야 할 수 있다.</li>
<li>유지보수성**: 유지 관리에 더 많은 노력이 필요할 수 있으며 복잡한 쿼리로 인해 관리가 어려워질 수 있다.</li>
</ul>
<h3 id="2-sqlalchemy-orm">2. SQLAlchemy ORM:</h3>
<h4 id="장점-1">장점:</h4>
<ul>
<li>추상화**: 더 직관적으로 작업할 수 있는 더 높은 수준의 Python 인터페이스를 제공한다.</li>
<li>안전**: 입력 이스케이프를 자동으로 처리하여 SQL 인젝션의 위험을 줄인다.</li>
<li>휴대성**: 쿼리가 연결된 데이터베이스 엔진의 SQL 언어로 번역되므로 서로 다른 데이터베이스 간 호환성이 향상된다.</li>
<li>유지보수성**: 데이터 조작을 객체로 구성하기 때문에 특히 복잡한 애플리케이션의 경우 유지 관리가 더 쉽다.</li>
</ul>
<h4 id="단점-1">단점:</h4>
<ul>
<li>성능**: 번역 및 추상화의 오버헤드로 인해 일반적으로 원시 SQL보다 느리며, 특히 복잡한 쿼리의 경우 더욱 그렇다.</li>
<li>복잡성**: 일부 복잡한 쿼리는 ORM을 통해 표현하기 어렵거나 심지어 불가능할 수도 있다.</li>
</ul>
<h3 id="결론">결론:</h3>
<p>특히 단순하고 직접적인 쿼리에서 성능이 중요한 문제라면 원시 SQL이 더 나은 선택일 수 있다. 반면에 유지보수성, 안전성, 추상화를 중시하고 성능을 어느 정도 희생할 의향이 있다면 SQLAlchemy ORM이 더 좋을 수 있다.</p>
<p>높은 정확도와 효율적인 DB 연결에 중점을 두는 상황에서는 성능이 중요한 부분에는 원시 SQL을 사용하고 유지보수성과 추상화가 더 중요한 상황에는 SQLAlchemy ORM을 사용할 수 있다. 테스트 및 프로파일링을 통해 특정 사용 사례에서 실제 성능에 미치는 영향에 대한 인사이트를 얻을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB Table의 Index 개념 정리]]></title>
            <link>https://velog.io/@_jaehye0n/DB-Table%EC%9D%98-Index-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@_jaehye0n/DB-Table%EC%9D%98-Index-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 11 Aug 2023 03:17:10 GMT</pubDate>
            <description><![CDATA[<h2 id="0-index">0. Index</h2>
<p>DataBase의 Index는 어떤 데이터가 어디에 있는지 정보를 제공하는 주소록과 유사하다. Index는 Table의 모든 행을 스캔하지 않고도 필요한 데이터를 빠르게 찾을 수 있도록 도와준다.</p>
<h2 id="1-database-관점에서-table의-index">1. DataBase 관점에서 Table의 Index</h2>
<h3 id="1-1-index의-작동-방식">1-1. Index의 작동 방식:</h3>
<ul>
<li>DataBase 버퍼 캐시: **DataBase는 하드 디스크의 데이터에 액세스하기 전에 메모리의 버퍼 캐시를 확인한다. 자주 사용하는 Table은 캐시에 저장되며, 해당 Table에서 데이터를 찾으면 빠르게 검색된다.</li>
<li>하드 디스크 검색:** 데이터가 캐시에 없는 경우 DataBase는 하드 디스크의 데이터 파일을 찾기 시작한다.</li>
<li>Index 사용:** Index를 사용하면 버퍼 캐시와 하드 디스크 검색을 건너뛰고 데이터가 있는 주소로 바로 이동하여 전국을 조사하지 않고 특정 주소로 택배를 배달하는 것과 같이 데이터가 있는 주소로 바로 이동한다(Full Scan).</li>
</ul>
<h3 id="1-2-index-생성-원리">1-2. Index 생성 원리</h3>
<p>Index를 생성할 때 중간에 데이터가 변경되면 문제가 발생할 수 있다. 따라서 데이터 변경을 방지하기 위해 예방 조치를 취하고 메모리에서 데이터를 정렬한다(PGA의 정렬 영역). 공간이 충분하지 않으면 임시 Table 공간이 사용된다. 전체 Table을 스캔한 후 메모리에서 정렬하고 블록을 쓰는 과정이 포함된다.</p>
<blockquote>
<p>PGA는 Program Global Area의 약자로, 단독 사용하는 공간이다. 따라서 Private Global Area라고 불리기도 한다. PGA는 프로세스에 대한 데이터와 제어정보가 포함된 비 공유 메모리 영역으로 서버 프로세스가 시작될 때 생성되며, DataBase에 접속하는 모든 사용자에게 할당된 각각의 서버 프로세스가 독자적으로 사용하는 오라클 DataBase의 메모리 공간이다.</p>
</blockquote>
<p>PGA는 서버 프로세스가 시작될 때 오라클 DataBase에 의해 생성되며 프로세스가 종료될 때 해제된다. PGA는 SQL의 작업공간이기 때문에 정렬 작업을 할 때 주로 사용된다. 따라서 SQL 정렬 작업을 위해 PGA 메모리 영역을 사용할 경우, PGA 크기 내에서 정렬이 일어나면 메모리 내에서 정렬되는 것이므로 수행속도가 빠르고 PGA 크기를 초과하면 디스크에서 정렬이 일어나므로 수행속도가 느려지게 된다.</p>
<h3 id="1-3-index-구조-및-작동-원리b-tree-index-기준">1-3. Index 구조 및 작동 원리(B-TREE Index 기준)</h3>
<p>Index는 Key(Indexing을 위해 지정된 컬럼)와 ROWID의 두 개의 컬럼으로 구성된다.</p>
<h4 id="예시">예시:</h4>
<p>EMP Table에서 EMPNO = 7902에 대한 쿼리를 고려하고, 데이터 파일에 100,000개의 블록이 있다고 가정한다:</p>
<ul>
<li>Index가 없는 경우:** 100,000개의 데이터 조각이 모두 DB 버퍼 캐시에 복사되고 전체 스캔을 통해 데이터가 검색된다.</li>
<li>Index가 있는 경우:** WHERE 절 열이 Index의 키로 생성되었는지 확인한 후, 서버가 먼저 Index로 이동하여 7902 정보가 있는 ROWID를 확인한다. 해당 ROWID에서 블록을 찾아 DB Buffer 캐시로 가져와서 정보를 표시한다.</li>
</ul>
<h3 id="1-4-index의-종류">1-4. Index의 종류</h3>
<ol>
<li><strong>B-TREE Index :</strong> 실시간 데이터 입력 및 수정이 필요한 OLTP(온라인 트랜잭션 처리) 환경에서 사용된다. <ul>
<li>구조:** 루트 블록(루트 블록에 대한 정보), 브랜치 블록(브랜치 블록에 대한 정보), 리프 블록(실제 데이터의 주소)을 포함한다.</li>
</ul>
</li>
<li><strong>비트맵 Index :</strong> 분석이나 통계 정보 출력을 위한 OLAP(온라인 분석 처리)에서 사용된다. 데이터 값의 종류가 적고 동일한 데이터가 많을 때 자주 사용된다.</li>
</ol>
<h3 id="1-5-index-주의-사항">1-5. Index 주의 사항</h3>
<ul>
<li>SELECT 작업 :** Index는 일반적으로 Indexing된 열이 쿼리 조건에서 사용되는 한 선택 쿼리 성능을 향상시킨다.</li>
<li>UPDATE 작업 :** 기존 데이터를 삭제하고 새로운 값을 삽입하는 이중 프로세스가 필요하여 부하가 증가한다.</li>
<li>INSERT 작업 :** Index가 많을수록 Index 분할을 유발하여 성능 문제를 일으킬 수 있다.</li>
<li>DELETE 작업 :** Index에서 삭제된 데이터는 제거되지 않고 미사용으로만 표시되어 성능 문제가 발생할 수 있다.</li>
</ul>
<h3 id="1-6-index-생성-시-고려-사항">1-6. Index 생성 시 고려 사항</h3>
<ul>
<li>데이터 검색을 위한 Index는 Table 전체 행 수의 15% 이하로 생성한다.</li>
<li>작은 Table이나 수정이 잦은 Table은 Indexing 하지 않는다.</li>
<li>고유성이 높은 열을 지정하고 NULL 값이 많은 열은 피한다.</li>
<li>열 순서와 SQL 쿼리 구조를 고려한다.</li>
<li>너무 많은 Index를 만들면 성능이 저하될 수 있으므로 주의한다.</li>
<li>Index 사용과 빠른 검색 및 수정, 삭제, 삽입과 같은 작업의 필요성 간에 균형을 맞추는 것이 좋다.
DataBase<blockquote>
<p>이러한 측면을 이해하면 블록체인 데이터 엔지니어로서의 요구사항에 맞춰 DataBase 성능을 최적화하여 대량의 데이터를 효율적으로 처리하고, 메트릭을 빠르게 계산하며, DataBase에 과부하를 주지 않으면서 쿼리 속도를 줄일 수 있다.</p>
</blockquote>
</li>
</ul>
<h2 id="2-hardware-관점에서-table의-index">2. Hardware 관점에서 Table의 Index</h2>
<h3 id="2-1-index-유형">2-1. Index 유형</h3>
<p>DataBase는 종종 B-트리, 해시 Index, 비트맵 Index와 같은 다양한 유형의 Index를 제공한다. 선택은 데이터의 특성과 실행하려는 쿼리 유형에 따라 달라진다. B-트리는 가장 일반적인 Index 구조 중 하나이다.</p>
<h3 id="2-2-index-구조-작업">2-2. Index 구조 작업</h3>
<h4 id="b-트리-index">B-트리 Index</h4>
<ul>
<li>트리 구조:** B-트리 Index는 검색, 삽입, 삭제가 효율적으로 수행될 수 있도록 정렬된 데이터를 유지하는 균형 잡힌 트리 구조이다.</li>
<li>노드:** B-트리의 각 노드에는 키와 포인터가 포함되어 있다. 키는 마커 역할을 하고 포인터는 검색을 올바른 데이터 하위 집합으로 안내한다.</li>
<li>리프:** 트리의 리프 노드는 DataBase의 실제 레코드에 대한 포인터(또는 때로는 레코드로 연결되는 클러스터링 키에 대한 포인터)를 보유한다.</li>
</ul>
<h4 id="해시-색인">해시 색인</h4>
<ul>
<li>해시 함수:** 해시 Index는 해시 함수를 사용하여 값을 배열의 특정 위치에 매핑한다. 동일한 값으로 해시된 모든 값은 해당 위치의 링크된 목록에 저장된다.</li>
<li>버킷:** 배열을 해시 Table이라고도 하고 각 배열 요소를 버킷이라고도 한다.</li>
</ul>
<h3 id="2-3-index로-쿼리">2-3. Index로 쿼리</h3>
<p>Indexing된 열을 사용할 수 있는 쿼리가 실행되는 경우이다:</p>
<ul>
<li>B-트리:** DataBase 엔진은 B-트리의 루트에서 시작하여 각 노드의 키를 사용하여 트리를 따라 내려가면서 따라야 할 올바른 경로를 결정한다. 리프 노드에 도달하면 올바른 데이터 하위 집합을 찾은 것이다.</li>
<li>해시 Index: 쿼리의 값이 해시되고 해시 Table의 해당 버킷에 직접 액세스한다. 이 방식은 조회 속도가 매우 빠르지만 B-트리에 비해 유연성이 떨어진다.</li>
</ul>
<h3 id="2-4-index-업데이트">2-4. Index 업데이트</h3>
<ul>
<li>삽입 및 삭제:** 데이터가 삽입되거나 삭제되면 그에 따라 Index를 업데이트해야 한다. B-트리에서는 트리의 균형을 유지하기 위해 노드를 분할하거나 병합해야 할 수 있다. 해시 Index에서는 해당 버킷의 링크된 목록을 업데이트해야 할 수 있다.</li>
<li>유지 관리: 시간이 지남에 따라, 특히 데이터 수정이 많은 경우 Index를 재구성하거나 재구축해야 할 수 있다. 이렇게 해야 Index가 계속 효율적으로 작동할 수 있다.</li>
</ul>
<h3 id="2-5-스토리지-고려-사항">2-5. 스토리지 고려 사항</h3>
<p>Index는 추가 디스크 공간을 소비하며, 그 양은 Index 유형과 Indexing된 열의 수와 크기에 따라 달라진다.</p>
<h2 id="3-table에서-index-추가">3. Table에서 Index 추가</h2>
<p>DataBase의 기존 데이터에 Index를 추가할 수 있으며, 이는 특정 열에 대한 쿼리 성능을 최적화하기 위해 종종 수행된다. Index를 만드는 정확한 방법은 사용 중인 DataBase 관리 시스템(DBMS)에 따라 다르다. 또한, DataBase에서 Index를 만드는 것은 특히 지금 작업 중인 것과 같은 대규모 데이터 집합을 다룰 때 쿼리의 효율성을 개선하는 강력한 도구가 될 수 있다. 아래에서는 기존 열에 Index를 생성하는 방법, Index인 새 열을 생성하는 방법, Indexing된 열이 있는 새 테이블을 생성하는 방법을 SQL과 Python에서 모두 SQLAlchemy 또는 Pandas와 같은 라이브러리를 사용하여 설명하겠다.</p>
<blockquote>
<p>*<em>열 식별하기: *</em>색인할 열을 결정한다. 일반적으로 쿼리 조건에서 자주 사용되는 열이어야 한다.</p>
</blockquote>
<blockquote>
<p><strong>Index 유형 선택하기:</strong> 사용 중인 DBMS에 따라 다양한 유형의 Index(예: B-tree, 해시 등)에 대한 옵션이 있을 수 있다. 쿼리 패턴과 데이터 구조에 가장 적합한 것을 선택한다.</p>
</blockquote>
<blockquote>
<p>**Index 생성: 대부분의 SQL 기반 DataBase에서는 다음과 같은 SQL 명령을 사용하여 Index를 생성할 수 있다:</p>
</blockquote>
<h3 id="3-1-기존-컬럼에-index-생성">3-1. 기존 컬럼에 Index 생성</h3>
<h4 id="sql">SQL:</h4>
<pre><code class="language-sql">CREATE INDEX index_name ON table_name (column_name);</code></pre>
<h4 id="파이썬sqlalchemy-사용">파이썬(SQLAlchemy 사용):</h4>
<pre><code class="language-python">from sqlalchemy import Index

index_name = Index(&#39;index_name&#39;, table_name.c.column_name)
index_name.create(bind=engine)</code></pre>
<h3 id="3-2-index인-새-컬럼-생성">3-2. Index인 새 컬럼 생성</h3>
<h4 id="sql-1">SQL:</h4>
<pre><code class="language-sql">ALTER TABLE table_name ADD column_name data_type;
CREATE INDEX index_name ON table_name (column_name);</code></pre>
<h4 id="파이썬-sqlalchemy-사용">파이썬 (SQLAlchemy 사용):</h4>
<pre><code class="language-python">from sqlalchemy import Column, Index

# 새 칼럼 추가
table_name.addColumn(Column(&#39;column_name&#39;, data_type))

# Index 생성
index_name = Index(&#39;index_name&#39;, table_name.c.column_name)
index_name.create(bind=engine)</code></pre>
<h3 id="3-3-indexing된-열이-있는-새-테이블-생성">3-3. Indexing된 열이 있는 새 테이블 생성</h3>
<h4 id="sql-2">SQL:</h4>
<pre><code class="language-sql">CREATE TABLE table_name (
  COLUMN_NAME1 DATA_TYPE1,
  COLUMN_NAME2 DATA_TYPE2,
  ...
  INDEX index_name (indexed_column_name)
);</code></pre>
<h4 id="파이썬sqlalchemy-사용-1">파이썬(SQLAlchemy 사용):</h4>
<pre><code class="language-python">from sqlalchemy import Table, Column, Index

table_name = Table(&#39;table_name&#39;, metadata,
    Column(&#39;column_name1&#39;, data_type1),
    Column(&#39;column_name2&#39;, data_type2),
    ...
    Index(&#39;index_name&#39;, &#39;indexed_column_name&#39;)
)

table_name.create(bind=engine)</code></pre>
<h3 id="3-4-열-indexing-조건">3-4. 열 Indexing 조건</h3>
<ol>
<li><strong>쿼리에서 자주 사용됨:</strong> 칼럼이 WHERE 절에 자주 나타나거나 쿼리에서 자주 비교되는 경우 Indexing에 적합한 후보이다.</li>
<li><strong>데이터 고유성:</strong> 고유성이 높고 값의 범위가 넓은 열은 일반적으로 Indexing에 적합하다. 반복되는 값이 많은 열을 Indexing하는 것은 큰 이점을 제공하지 못할 수 있다.</li>
<li><strong>데이터 유형:</strong> 일부 데이터 유형은 Indexing하는 것이 더 효율적일 수 있다. 숫자 또는 날짜/시간 유형은 텍스트 또는 BLOB 유형에 비해 더 나은 성능을 제공할 수 있다.</li>
<li><strong>읽기 작업과 쓰기 작업의 균형:</strong> 테이블을 자주 업데이트, 삭제 또는 삽입하는 경우 Indexing을 사용하면 이러한 작업 속도가 느려질 수 있다. 읽기 작업이 많은 테이블의 열에 대해서는 Indexing을 고려해야 한다.</li>
</ol>
<p>Indexing은 쿼리 속도를 크게 높일 수 있지만, 저장 공간을 추가로 소모하고 쓰기 작업의 속도를 저하시킬 수 있다는 점에 유의한다. 블록체인 데이터 엔지니어는 이러한 측면을 고려하면 데이터를 처리할 때 높은 정확도와 효율성이라는 목표를 달성하는 데 도움이 될 수 있다.</p>
<h3 id="4-결론">4. 결론</h3>
<p>Indexing은 복잡한 트리 또는 해시 구조의 균형을 맞춰 빠른 검색 기능을 구현하는 DataBase의 강력한 도구이다. 내부 작업에는 데이터에 대한 효율적인 액세스를 제공하는 동시에 데이터 변경 시 Index의 무결성을 유지하도록 설계된 데이터 구조와 알고리즘이 포함된다. 이는 물론 방대한 양의 데이터를 효율적으로 처리하고, 메트릭을 빠르게 계산하며, DataBase에 과부하를 주지 않으면서 쿼리 속도를 줄여야 하는 데이터 엔지니어의 요구사항과도 일치하는 부분이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Services 기본]]></title>
            <link>https://velog.io/@_jaehye0n/AWS</link>
            <guid>https://velog.io/@_jaehye0n/AWS</guid>
            <pubDate>Thu, 10 Aug 2023 18:10:46 GMT</pubDate>
            <description><![CDATA[<h2 id="aws">AWS</h2>
<h3 id="컴퓨팅">컴퓨팅</h3>
<p>Amazon EC2 (Elastic Compute Cloud)</p>
<ul>
<li>크기를 조정할 수 있는 컴퓨팅 용량을 제공하는 웹 서비스</li>
<li>컴퓨팅 용량이란 소프트웨어 시스템 구축 및 호스팅에서 사용하는 Amazon 데이터 센터의 서버를 의미</li>
</ul>
<p>Amazon ECS (Elastic Container Service)</p>
<ul>
<li>Docker 컨테이너를 손쉽게 실행, 중단 및 관리할 수 있게 해주는 고도로 확장 가능하고 빠른 컨테이너 관리 서비스</li>
</ul>
<p>Amazon EKS (Elastic Container Service for Kubernetes)</p>
<ul>
<li>자체 Kubernetes 클러스터를 설치 및 운영할 필요 없이 AWS에서 Kubernetes를 쉽게 실행할 수 있도록 해주는 관리형 서비스<h3 id="스토리지">스토리지</h3>
Amazon S3 (Simple Storage Service)</li>
<li>인터넷을 위한 오브젝트 스토리지</li>
<li>언제 어디서나 웹의 모든 데이터를 저장하고 검색할 수 있음</li>
</ul>
<p>Amazon EBS (Elastic Block Storage)</p>
<ul>
<li>EC2 인스턴스에서 파일시스템용으로 사용되는 블록 스토리지</li>
<li>데이터에 빠르게 액세스하고 장기적으로 지속해야 하는 경우 사용<h3 id="데이터베이스">데이터베이스</h3>
Amazon RDS (Relational Database Service)</li>
<li>클라우드에서 관계형 데이터베이스를 더욱 쉽게 설치, 운영 및 확장할 수 있는 웹 서비스</li>
<li>경제적이고 크기 조절이 가능한 용량을 제공</li>
<li>Amazon Aurora, PostgreSQL, MySQL, MariaDB, Oracle, MsSQL 관리 서비스 (RDBMS)<h3 id="분석">분석</h3>
Amazon MSK (Managed Streaming for Kafka)</li>
<li>Amazon Managed Streaming for Kafka(Amazon MSK)는 Apache Kafka를 사용하여 스트리밍 데이터를 처리하는 애플리케이션의 편리한 개발 및 실행을 위한 완전관리형 서비스</li>
<li>Apache Kafka API를 사용하여 데이터 레이크를 채우고, 데이터베이스와 변경 사항을 스트리밍 방식으로 주고 받으며, 기계 학습 및 분석 애플리케이션을 강화할 수 있음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Sync와 Async: 데이터 처리 모델에 대한 심층 분석]]></title>
            <link>https://velog.io/@_jaehye0n/%EB%8F%99%EA%B8%B0%EC%8B%9D-%EB%8C%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%8B%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC-%EB%AA%A8%EB%8D%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%AC%EC%B8%B5-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@_jaehye0n/%EB%8F%99%EA%B8%B0%EC%8B%9D-%EB%8C%80-%EB%B9%84%EB%8F%99%EA%B8%B0%EC%8B%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%B2%98%EB%A6%AC-%EB%AA%A8%EB%8D%B8%EC%97%90-%EB%8C%80%ED%95%9C-%EC%8B%AC%EC%B8%B5-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Wed, 09 Aug 2023 14:55:08 GMT</pubDate>
            <description><![CDATA[<h3 id="0-배경지식">0. 배경지식</h3>
<p>프론트엔드 개발에는 종종 데이터 처리 모델을 다루고 동기식과 비동기식의 차이점을 이해하는 작업이 포함된다. 이러한 지식은 특히 최신 웹 개발에서 백엔드 시스템을 설계하고 상호 작용하는 방식에 큰 영향을 미칠 수 있다. 또한, SQLAlchemy ORM의 &#39;asyncSession&#39;과 같은 최신 데이터베이스 작업은 더 나은 성능을 위해 비동기 작업의 힘을 활용한다. 이러한 개념에 대해 자세히 알아보겠다.</p>
<h3 id="1-동기-작업-이해">1. 동기 작업 이해</h3>
<p><strong>동기식</strong> 작업은 작업이 차례로 완료되는 시퀀스를 의미한다. 이전 작업이 완료될 때까지 한 작업이 시작되지 않는다.</p>
<h4 id="동기식-작업의-주요-특징">동기식 작업의 주요 특징:</h4>
<ul>
<li>직접 피드백**: 작업은 즉각적인 피드백을 제공한다. 데이터를 요청하고 데이터를 기다린다.</li>
<li>차단**: 피드백을 기다리는 동안 다른 작업을 수행할 수 없다. 이는 특히 피드백에 오랜 시간이 걸리는 경우 비효율성을 초래할 수 있다.</li>
<li>단순성**: 작업이 선형적으로 진행되기 때문에 더 간단하고 직관적으로 이해할 수 있다.</li>
</ul>
<h4 id="예시">예시:</h4>
<p>서버에 데이터를 요청하는 사용자를 생각보면, 사용자의 시스템은 서버가 이 요청에 응답할 때까지 기다리며 다른 작업을 수행하지 않는다.</p>
<h3 id="2-비동기-작업-이해">2. 비동기 작업 이해</h3>
<p><strong>비동기</strong> 작업을 사용하면 이전 작업이 완료될 때까지 기다리지 않고 작업을 실행할 수 있다. 직접 순서대로 실행되지 않으므로 리소스 활용도를 높일 수 있다.</p>
<h4 id="비동기-작업의-주요-특징">비동기 작업의 주요 특징:</h4>
<ul>
<li>지연된 피드백**: 데이터를 요청하고 데이터를 기다리지 않고 다른 작업으로 넘어갈 수 있다.</li>
<li>비차단**: 피드백을 기다리는 동안 다른 작업을 자유롭게 수행할 수 있다.</li>
<li>효율성**: 리소스 활용도가 높아져 잠재적인 성능 향상으로 이어진다.</li>
<li>복잡성**: 작업이 엄격한 순서를 따르지 않으므로 이해하고 설계하기가 더 복잡할 수 있다.</li>
</ul>
<h4 id="예시-1">예시:</h4>
<p>웹 개발에서 사용자가 서버에 요청을 보내면 서버의 응답을 기다리는 동안 다른 작업을 수행하거나 다른 요청을 보낼 수 있다.</p>
<h3 id="3-sqlalchemy-orm의-asyncsession">3. SQLAlchemy ORM의 <code>asyncSession</code></h3>
<p>널리 사용되는 SQL 툴킷이자 Python용 객체 관계형 매핑(ORM) 라이브러리인 SQLAlchemy는 데이터베이스 쿼리를 보다 효율적으로 만들기 위해 비동기 패러다임을 수용했다.</p>
<h4 id="주요-기능">주요 기능:</h4>
<ul>
<li>비동기 쿼리**: 데이터베이스 쿼리를 비동기적으로 수행할 수 있다. 쿼리가 처리되는 동안 애플리케이션은 다른 작업을 처리할 수 있으므로 전반적인 처리량이 향상된다.</li>
<li>비차단**: 데이터베이스 쿼리 시 애플리케이션 흐름을 차단하는 기존 SQLAlchemy Session과 달리, <code>asyncSession</code>은 애플리케이션이 응답성을 유지하도록 한다.</li>
<li>파이썬의 <code>asyncio</code>**를 활용한다: 내부적으로 <code>asyncSession</code>은 Python의 <code>asyncio</code> 라이브러리를 기반으로 구축되어 호환성과 성능을 보장한다.</li>
</ul>
<h4 id="사용-예시">사용 예시:</h4>
<p>SQLAlchemy에서 <code>asyncSession</code>을 사용하려면:</p>
<pre><code class="language-python">from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = &quot;postgresql+asyncpg://user:password@localhost/mydatabase&quot;

# Create an instance of the async engine
engine = create_async_engine(DATABASE_URL, echo=True)

# Create async session
AsyncSessionLocal = sessionmaker(
    bind=engine,
    class_=AsyncSession
)

# Asynchronous query
async with AsyncSessionLocal() as session:
    result = await session.execute(&quot;SELECT * FROM users&quot;)
    users = result.fetchall()</code></pre>
<h2 id="4-동기과-비동기의-활용">4. 동기과 비동기의 활용</h2>
<p>동기식 및 비동기식 작업의 개념을 아는 것도 중요하지만, 실제 시나리오에서 언제 어느 쪽을 사용해야 하는지를 이해하는 것이 더 중요하다.</p>
<h3 id="동기식-시나리오">동기식 시나리오:</h3>
<ul>
<li>중요 시퀀스**: 계정 액세스 권한을 제공하기 전에 먼저 사용자를 인증해야 하는 경우와 같이 특정 순서대로 작업을 수행해야 하는 경우.</li>
<li>단순성**: 성능과 확장성이 주요 관심사가 아닌 소규모 애플리케이션 또는 스크립트용.</li>
<li>즉각적인 피드백**: 오류 확인이나 데이터 유효성 검사와 같이 즉각적인 피드백이 중요한 작업의 경우.</li>
</ul>
<h3 id="비동기-시나리오">비동기 시나리오:</h3>
<ul>
<li>입출력 작업**: 데이터베이스, 파일 또는 네트워크 호출에 대한 읽기/쓰기를 포함하는 작업은 비동기화를 통해 상당한 이점을 얻을 수 있다. 이렇게 하면 메인 애플리케이션 스레드가 유휴 상태로 대기하지 않도록 할 수 있다.</li>
<li>UI/UX**: 최신 사용자 인터페이스는 일반적으로 비차단 방식으로 설계된다. 사용자가 버튼을 클릭할 때 기다리게 해서는 안 되며, UI는 계속 반응성을 유지해야 한다.</li>
<li>확장성**: 대규모 애플리케이션, 특히 웹 서버는 비동기 작업의 이점을 누릴 수 있다. 리소스를 동등하게 늘리지 않고도 많은 요청을 처리할 수 있다.</li>
</ul>
<h3 id="5-파이썬에서-비동기-프로그래밍의-진화">5. 파이썬에서 비동기 프로그래밍의 진화</h3>
<p>파이썬은 비동기 프로그래밍을 지원하는 데 있어 먼 길을 걸어왔다. 초기에는 파이썬이 주로 동기식 프로그래밍을 지원했지만, 파이썬 3.5에 <code>async/await</code> 구문이 도입되면서 네이티브 코루틴과 비동기 프로그래밍을 위한 전체 에코시스템이 도입되었다.</p>
<p><strong>라이브러리 및 도구</strong>:</p>
<ul>
<li>**`동기화``: 이 라이브러리는 파이썬 비동기 프레임워크의 핵심이다. 모든 비동기 애플리케이션의 핵심인 이벤트 루프를 제공한다.</li>
<li>asyncpg`**: PostgreSQL 및 SQLAlchemy를 위해 특별히 설계된 비동기 데이터베이스 인터페이스 라이브러리이다.</li>
<li>aiohttp`**: 비동기 HTTP 클라이언트/서버 프레임워크.</li>
</ul>
<h4 id="예시-2">예시:</h4>
<p><code>aiohttp</code>를 사용하여 비동기 웹 요청을 수행한다:</p>
<pre><code class="language-python">import aiohttp
import asyncio

async def fetch_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

loop = asyncio.get_event_loop()
html_content = loop.run_until_complete(fetch_url(&#39;https://example.com&#39;))</code></pre>
<h3 id="결론">결론</h3>
<p>프론트엔드 개발이든 백엔드 데이터베이스 운영이든, 동기식 작업과 비동기식 작업 사이의 선택은 프로젝트의 특정 요구 사항과 과제에 따라 결정된다. 직접성(동기식)과 잠재적인 성능 이점(비동기식) 사이의 장단점을 비교하며 차이점을 이해하는 것이 중요하다.비동기 패러다임을 수용하는 SQLAlchemy와 같은 라이브러리를 통해 비동기 접근 방식이 애플리케이션의 효율성, 응답성 및 확장성을 보장하는 데 점점 더 중요해지고 있음이 분명해졌다. 또한, 도구와 라이브러리가 비동기 작업을 점점 더 많이 지원함에 따라 최신 애플리케이션은 더욱 효율적이고 사용자 친화적으로 발전할 준비가 되어 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kubernetes(K8s)에 대한 이해와 주요 구성요소]]></title>
            <link>https://velog.io/@_jaehye0n/KubernetesK8s%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4%EC%99%80-%EC%A3%BC%EC%9A%94-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C</link>
            <guid>https://velog.io/@_jaehye0n/KubernetesK8s%EC%97%90-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4%EC%99%80-%EC%A3%BC%EC%9A%94-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C</guid>
            <pubDate>Tue, 08 Aug 2023 06:48:41 GMT</pubDate>
            <description><![CDATA[<h2 id="0-docker와-차이점">0. Docker와 차이점</h2>
<ul>
<li>Docker는 컨테이너화 플랫폼 및 런타임이며 Kubernetes는 여러 컨테이너 런타임에서 컨테이너를 실행하고 관리하기 위한 플랫폼이다. Kubernetes는 Docker를 포함한 수많은 컨테이너 런타임을 지원한다.</li>
</ul>
<h2 id="1-kubernetesk8s-소개">1. Kubernetes(K8s) 소개</h2>
<p>**흔히 K8s라고 줄여서 부르는 Kubernetes는 컨테이너화된 애플리케이션을 자동화, 확장, 관리하기 위해 설계된 컨테이너 오케스트레이션 플랫폼이다. 컨테이너는 애플리케이션을 위한 가볍고 일관된 환경을 제공하지만, 특히 대규모로 여러 개의 컨테이너를 관리하는 것은 어려울 수 있다. 이것이 바로 Kubernetes가 필요한 이유이다.</p>
<ul>
<li><p>로드 밸런싱 및 비밀 관리**: 컨테이너화된 애플리케이션의 균형 잡힌 분산을 지원한다. Kubernetes는 애플리케이션 인스턴스(또는 포드) 간의 트래픽 분산을 처리할 뿐만 아니라 데이터베이스 자격 증명이나 API 키와 같은 민감한 정보를 관리하여 애플리케이션 코드에서 안전하게 보호하는 메커니즘도 내장되어 있다.</p>
</li>
<li><p>로드에 따른 확장**: 부하가 증가할 때 특정 이미지를 사용하여 빠르게 여러 애플리케이션 인스턴스를 디플로이먼트할 수 있다. Kubernetes는 CPU 사용량 또는 네트워크 트래픽과 같은 메트릭을 사용하여 확장에 대한 정보에 기반한 결정을 내린다. 이를 통해 리소스를 효율적으로 사용하고 시스템이 증가하는 수요를 처리할 수 있다.</p>
</li>
<li><p>페일오버**: 인스턴스가 실패하면 다른 인스턴스를 자동으로 생성하므로 몇 초 안에 복구된다. Kubernetes는 애플리케이션의 상태를 지속적으로 확인한다. 애플리케이션 중 하나에서 장애가 감지되면 클러스터의 다른 부분에서 장애 인스턴스를 재시작하여 다운타임을 최소화한다.</p>
</li>
<li><p>유연한 디플로이먼트 전략**: 디플로이먼트가 잘못될 경우, 롤백과 같은 유연한 대처가 가능하다. Kubernetes는 여러 가지 디플로이먼트 전략을 지원한다. 애플리케이션의 새 버전에 문제가 있는 경우 안정적인 상태로 쉽게 롤백할 수 있다.</p>
</li>
</ul>
<p>로드밸런싱은 컴퓨터 네트워크 기술의 일종으로, 여러 서버나 자원에 작업을 분산시키는 것을 의미한다.</p>
<h2 id="2-kubernetes의-주요-구성-요소">2. Kubernetes의 주요 구성 요소</h2>
<h3 id="2-1-컨테이너">2-1. 컨테이너</h3>
<ul>
<li>컨테이너**: 애플리케이션의 실행 단위이다. 이는 완전한 애플리케이션 그 자체일 수도 있고, 부분 기능일 수도 있다.</li>
</ul>
<h3 id="2-2-클러스터">2-2. 클러스터</h3>
<ul>
<li><p>클러스터**: Kubernetes 내에서 가장 큰 단위로, 여러 가상 서버들이 결합된 구조를 의미한다. Kubernetes 클러스터는 단순한 단일 머신이 아니라 함께 작동하는 머신(노드)의 집합이다. 이러한 집합적 접근 방식을 통해 Kubernetes는 모든 리소스를 하나의 큰 리소스로 취급할 수 있다.</p>
</li>
<li><p>노드**: 클러스터 내의 가상 서버 혹은 컴퓨팅 엔진 단위이다. Kubernetes 클러스터의 각 머신을 노드라고 한다. 노드는 물리적 머신 또는 가상 머신일 수 있다.</p>
<ul>
<li>마스터 노드**: 전체 Kubernetes 시스템을 관리 및 통제하는 컨트롤 플레인을 담당한다. 조정 노드이다. 마스터 노드는 Kubernetes 컨트롤 플레인을 관리하여 시스템의 전반적인 상태를 보장한다.</li>
<li>워커 노드**: 디플로이먼트하려는 애플리케이션의 실제 실행을 담당한다. 워커 노드는 마스터 노드로부터 작업을 받아 컨테이너를 실행한다.</li>
</ul>
</li>
</ul>
<h3 id="2-3-파드">2-3. 파드</h3>
<ul>
<li>파드**: Kubernetes에서 생성하고 관리할 수 있는 디플로이먼트 가능한 가장 작은 컴퓨팅 단위이다. 여러 개의 컨테이너를 그룹화한 것이다. 파드를 하나의 디플로이먼트 단위이다. 컨테이너는 단일 애플리케이션을 실행하지만, 파드는 함께 동작해야 하는 여러 컨테이너를 실행할 수 있다. 파드의 모든 컨테이너는 동일한 네트워크 IP, 포트 공간 및 스토리지를 공유한다.</li>
</ul>
<h3 id="2-4-레플리카셋">2-4. 레플리카셋</h3>
<ul>
<li>레플리카셋**: 특정 파드의 수를 보장하기 위한 개념이다. 예를 들어, 레플리카 세트를 3으로 설정하면 파드의 수가 항상 3개를 유지하도록 보장된다. 지정된 수의 파드 레플리카가 유지되도록 한다. 파드가 충돌하면, 레플리카셋은 새 파드가 이를 대체하도록 한다.</li>
</ul>
<h3 id="2-5-디플로이먼트">2-5. 디플로이먼트</h3>
<ul>
<li>디플로이먼트**: 애플리케이션을 디플로이먼트하고 업데이트하는 리소스이다. 디플로이먼트는 레플리카셋을 제어하므로, 레플리카셋을 생성하는 역할도 한다. 디플로이먼트는 단순히 파드를 생성하는 것 외에도 다운타임 없이 파드를 업데이트하고 필요한 경우 이전 버전으로 롤백하는 데 도움을 준다. 이것은 레플리카셋을 제어하고 파드에 선언적 업데이트를 제공하는 상위 레벨 구조이다.</li>
</ul>
<p>Kubernetes는 컨테이너화된 애플리케이션의 디플로이먼트, 확장 및 관리를 도와주는 강력한 도구이다. 다양한 구성요소를 통해 애플리케이션의 안정성과 확장성을 보장하므로, 컨테이너 기반의 애플리케이션 서비스를 운영하려는 경우 적극적으로 고려해볼 만한 선택이다.</p>
<h2 id="3-kubernetes와-디플로이먼트-전략">3. Kubernetes와 디플로이먼트 전략</h2>
<h3 id="3-1-제로-다운타임무중단-디플로이먼트">3-1. 제로 다운타임(무중단) 디플로이먼트</h3>
<p>Kubernetes를 사용하면 현재 실행 중인 버전에 영향을 주지 않고 업데이트를 수행할 수 있다. 만약 업데이트된 버전에 문제가 발생한다면, 서비스는 이전 버전으로 복구하여 문제없이 계속 실행될 수 있다. 트래픽은 새 버전이 준비된 후에만 새 버전으로 전달되므로 사용자가 서비스 중단을 경험하지 않는다. 이러한 능력을 제대로 이해하려면 디플로이먼트의 디플로이먼트 방식을 알아야 한다.</p>
<h3 id="3-2-kubernetes-서비스-및-ip-할당">3-2. Kubernetes 서비스 및 IP 할당</h3>
<p>Kubernetes에서 파드는 각자 고유한 IP 주소를 갖게 된다. 간단히 말하면, 하나의 어플리케이션에 여러 파드가 있을 경우 각각의 파드는 다른 IP 주소를 가지고 있고 이러한 IP는 클러스터 외부에 노출되지 않는다. 하지만, 사용자는 여러 파드에 대한 단일 IP로의 접근을 원하게 된다.</p>
<h3 id="3-3-서비스의-이해">3-3. 서비스의 이해</h3>
<p>서비스는 파드 집합에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 리소스다. 서비스는 파드 앞에 위치하는 안정적인 엔드포인트이다. 로드 밸런싱과 일관된 IP 주소를 제공하여 사용자 트래픽이 여러 파드 인스턴스 간에 효율적으로 분산되도록 한다. 따라서 서비스를 사용하면, 여러 파드에 대한 단일 IP 접속이 가능하다. </p>
<h3 id="3-4-레이블을-통한-파드-관리">3-4. 레이블을 통한 파드 관리</h3>
<p>라벨을 사용하여 특정 애플리케이션 집단의 파드들만을 선택하고 하나의 IP로 연결하는 것이 가능하다. 이를 통해 특정 서비스 오브젝트와 연관된 파드를 정확하게 지정하고 관리할 수 있다. 레이블은 파드와 연관된 키-값 쌍으로 구성되어 있다. 레이블은 버전이나 환경과 같은 특성에 따라 파드를 분류하고 구성할 수 있게 해준다. 서비스는 이러한 레이블에 기반한 셀렉터를 사용하여 트래픽을 전송할 파드를 결정한다.</p>
<h3 id="3-5-디플로이먼트와-및-롤링-업데이트">3-5. 디플로이먼트와 및 롤링 업데이트</h3>
<p>디플로이먼트는 애플리케이션 디플로이먼트와 업데이트를 수행하는 Kubernetes의 핵심 리소스다. 이를 통해 애플리케이션을 안전하게 업데이트하면서 동시에 서비스 중단 없이 지속적인 서비스를 제공할 수 있다. </p>
<p>롤링 업데이트를 사용하면 새 파드 버전이 점진적으로 디플로이먼트되고 이전 버전은 단계적으로 제거된다. 이 방식의 가장 큰 장점은 서비스 다운타임 없이 애플리케이션을 업데이트할 수 있다는 것이고, 이 과정에서 문제가 발생하면 Kubernetes는 이전 상태로 쉽게 롤백할 수 있다.</p>
<h2 id="4-kubernetes-아키텍처-심층-분석">4. Kubernetes 아키텍처 심층 분석</h2>
<h3 id="4-1-컨트롤-플레인">4-1. 컨트롤 플레인</h3>
<p>컨트롤 플레인의 구성 요소는 클러스터에 대한 전역 결정(예: 스케줄링)을 내리고 클러스터 이벤트(예: 새 파드 시작)를 감지하고 응답한다.</p>
<ul>
<li>API 서버**: 명령과 쿼리를 위한 진입점 역할을 하며 사용자와 클러스터 간의 통신을 보장한다.</li>
<li>에트시디**: Kubernetes가 모든 클러스터 데이터에 사용하는 일관되고 가용성이 높은 키-값 저장소이다.</li>
<li>컨트롤러 매니저**: 백그라운드 작업을 처리하는 컨트롤러를 조절한다.</li>
<li>스케줄러**: 워커 노드에 파드와 같은 작업을 할당한다.</li>
</ul>
<h3 id="4-2-kubernetes의-스토리지">4-2. Kubernetes의 스토리지</h3>
<p>스토리지는 스테이트풀 애플리케이션을 다룰 때 중요한 역할을 한다.</p>
<ul>
<li>볼륨**: 물리 스토리지에서 추상화된 스토리지 계층을 제공한다.</li>
<li>퍼시스턴트 볼륨(PV) 및 퍼시스턴트 볼륨 클레임(PVC)**: 이는 스토리지 오케스트레이션을 용이하게 하여 파드가 종료된 후에도 데이터가 남아 있는지 확인한다.</li>
<li>스토리지 클래스**: 스토리지 볼륨 세트가 동적으로 프로비저닝되는 방법을 설명한다.</li>
</ul>
<h3 id="4-3-kubernetes의-네트워킹">4-3. Kubernetes의 네트워킹</h3>
<p>Kubernetes의 뛰어난 기능 중 하나는 파드, 노드 및 외부 세계 간의 통신을 용이하게 하도록 설계된 네트워킹 기능이다.</p>
<ul>
<li>서비스**: Kubernetes 서비스는 파드 집합과 파드에 액세스하기 위한 정책에 대한 논리적 추상화이다. 서비스 유형에는 클러스터IP, 노드포트, 로드밸런서, 외부 이름이 포함된다.</li>
<li>접근**: 클러스터의 서비스에 대한 외부 액세스를 관리하는 API 오브젝트(일반적으로 HTTP)이다.</li>
<li>네트워크 정책**: 파드가 서로 및 다른 네트워크 엔드포인트와 통신하는 방법에 대한 규칙을 정의한다.</li>
</ul>
<h3 id="4-4-구성-및-시크릿">4-4. 구성 및 시크릿</h3>
<ul>
<li>컨피그맵**: 애플리케이션의 외부 구성을 허용하여 구성을 이미지 콘텐츠와 분리한다.</li>
<li>비밀**: 비밀번호, OAuth 토큰, SSH 키와 같은 민감한 데이터를 저장하는 데 사용한다. 컨피그맵과 달리 시크릿 데이터는 암호화된다.</li>
</ul>
<h2 id="5-어드밴스-디플로이먼트-패턴">5. 어드밴스 디플로이먼트 패턴</h2>
<h3 id="5-1-카나리아-디플로이먼트">5-1. 카나리아 디플로이먼트</h3>
<p>Kubernetes는 애플리케이션의 최신 버전을 안정 버전과 함께 릴리스하여 트래픽의 일부를 새 버전으로 보내는 카나리아 디플로이먼트를 허용한다. 이는 파드 레이블을 조작하고 여러 디플로이먼트 구성을 사용하여 제어할 수 있다.</p>
<h3 id="5-2-블루-그린-디플로이먼트">5-2. 블루-그린 디플로이먼트</h3>
<p>블루-그린 디플로이먼트 전략에서는 두 개의 환경(현재 환경은 블루, 새 환경은 그린)이 유지된다. 새 버전을 디플로이할 준비가 되면 트래픽을 파란색 환경에서 녹색 환경으로 전환한다. Kubernetes는 두 개의 별도 파드 세트(블루-그린)를 유지하고 서비스 또는 인그레스 컨트롤러가 원하는 세트를 가리키도록 전환함으로써 이를 지원할 수 있다.</p>
<h3 id="5-3-수평-파드-자동-스케일링">5-3. 수평 파드 자동 스케일링</h3>
<p>Kubernetes는 특정 메트릭(예: CPU 사용률)에 따라 디플로이먼트 또는 레플리카 세트의 파드 수를 자동으로 확장 및 축소할 수 있다.</p>
<h2 id="6-모니터링-및-로깅">6. 모니터링 및 로깅</h2>
<h3 id="6-1-프로메테우스를-사용한-모니터링">6-1. 프로메테우스를 사용한 모니터링</h3>
<p><strong>프로메테우스</strong>는 Kubernetes 에코시스템에서 널리 사용되는 모니터링 도구이다. 지정된 간격으로 구성된 타깃에서 메트릭을 수집하고, 규칙 표현식을 평가하고, 결과를 표시할 수 있다.</p>
<h3 id="6-2-elk-스택-또는-로키-스택으로-로깅">6-2. ELK 스택 또는 로키 스택으로 로깅</h3>
<p>로깅의 경우, <strong>ELK</strong>(Elasticsearch, Logstash, Kibana)가 널리 사용된다. 또는 Kubernetes에 맞게 조정된 <strong>Loki-Stack</strong>이 로깅을 위한 일련의 솔루션을 제공한다.</p>
<h2 id="7-kubernetes-예시">7. Kubernetes 예시</h2>
<ul>
<li>보안**: 항상 역할 기반 액세스 제어(RBAC)를 사용하여 액세스를 제한한다. 네트워크 정책을 사용하여 파드 통신을 제한한다.</li>
<li>리소스 관리**: 항상 CPU와 메모리에 대한 리소스 요청과 제한을 정의하여 파드가 필요한 리소스를 얻을 수 있도록 한다.</li>
<li>상태 확인**: 애플리케이션이 원활하게 실행되고 있고 건강한지 확인하기 위해 활성 및 준비 상태 프로브를 구현한다.</li>
<li>백업 및 재해 복구**: 정기적으로 etcd 데이터 저장소를 백업한다. 재해 복구 계획이 마련되어 있는지 확인한다.</li>
</ul>
<h2 id="8-kubernetes-에코시스템-및-도구">8. Kubernetes 에코시스템 및 도구</h2>
<p>패키지 관리를 위한 <strong>Helm</strong>, 서비스 메시를 위한 <strong>Istio</strong>, 지속적인 개발을 위한 <strong>Skaffold</strong>와 같이 Kubernetes 경험을 향상시키기 위해 설계된 수많은 도구가 있다.</p>
<p>결론적으로, Kubernetes는 컨테이너 오케스트레이션에 관한 것이 아니다. 애플리케이션을 디플로이먼트, 확장, 모니터링, 관리하기 위한 전체적인 에코시스템을 제공하여 가동 시간, 확장성, 복원력을 극대화한다. 방대한 에코시스템과 유연성 덕분에 컨테이너화된 애플리케이션과 마이크로서비스를 도입하려는 조직에게 최고의 선택이 될 수 있다.</p>
<h2 id="9-마치며">9. 마치며</h2>
<p>Kubernetes는 마이크로 서비스 아키텍처의 트렌드와 함께 무중단 디플로이먼트의 중요성이 커지는 현대의 애플리케이션 환경에 아주 적합한 도구다. 이를 통해 안정적이고 지속 가능한 서비스 제공이 가능하다.</p>
<p><strong>reference</strong> : <a href="https://kubernetes.io/ko/docs/concepts/">https://kubernetes.io/ko/docs/concepts/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스 연결(DB Connection)]]></title>
            <link>https://velog.io/@_jaehye0n/dbconnection</link>
            <guid>https://velog.io/@_jaehye0n/dbconnection</guid>
            <pubDate>Tue, 18 Jul 2023 13:09:48 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스(DB) 연결은 애플리케이션과 DB 간의 통신을 가능하게 하는 수단이다. 이를 위해 데이터베이스 드라이버와 데이터베이스 연결 정보를 포함하는 URL이 필요하다. 자바의 DB 연결에는 주로 JDBC(Java Database Connectivity)가 사용되며, 이는 URL 형식을 사용한다.</p>
<h3 id="데이터베이스-연결-구조">데이터베이스 연결 구조</h3>
<p>데이터베이스 연결 구조에는 2Tier와 3Tier 두 가지가 있다.</p>
<ul>
<li><strong>2Tier</strong>: 자바 프로그램(예: JSP)이 클라이언트로서 직접 데이터베이스 서버에 접근하여 데이터를 액세스하는 구조이다.</li>
<li><strong>3Tier</strong>: 자바 프로그램과 데이터베이스 서버 사이에 미들웨어 계층이 존재하는 구조이다. 미들웨어 계층은 비즈니스 로직 구현, 트랜잭션 처리, 리소스 관리 등을 담당한다.</li>
</ul>
<h3 id="jdbc">JDBC</h3>
<p>JDBC는 Java Database Connectivity의 약어로, 다양한 종류의 관계형 데이터베이스에 접속하고 SQL 문을 수행할 때 사용되는 표준 SQL 인터페이스 API이다. 각 DBMS에 맞는 JDBC 드라이버를 이용하면 다양한 DBMS(MySQL, MsSQL, Oracle, PostgreSQL 등)와 쉽게 연동할 수 있다.</p>
<p>자바 애플리케이션에서 데이터베이스에 접근하기 위해서는 다음과 같은 구조로 동작한다: <code>Java (Web) Application -&gt; JDBC API -&gt; JDBC Driver -&gt; DB</code></p>
<h3 id="jdbc-드라이버">JDBC 드라이버</h3>
<p>JDBC 드라이버는 자바 프로그램의 요청을 DBMS가 이해할 수 있는 프로토콜로 변환해 주는 클라이언트 측 어댑터이다. 각 DBMS 제공자는 자신에게 알맞은 JDBC 드라이버를 제공한다.</p>
<h3 id="jdbc-실행과정">JDBC 실행과정</h3>
<p>JDBC를 이용한 데이터베이스 연결 및 쿼리 수행의 기본적인 순서는 다음과 같다:</p>
<ol>
<li>DB 벤더에 맞는 드라이버 로드</li>
<li>DB 서버의 IP, ID, PW 등을 <code>DriverManager</code> 클래스의 <code>getConnection()</code> 메소드를 사용하여 Connection 객체 생성</li>
<li>Connection에서 <code>PreparedStatement</code> 객체를 생성</li>
<li><code>executeQuery</code>를 수행하고 <code>ResultSet</code> 객체를 받아 데이터를 처리</li>
<li>사용했던 <code>ResultSet</code>, <code>PreparedStatement</code>, <code>Connection</code>을 <code>close</code> 하여 자원을 반납</li>
</ol>
<h3 id="connection-pooldbcp">Connection Pool(DBCP)</h3>
<p>매번 사용자가 요청할 때마다 JDBC 드라이버를 로드하고 연결 객체를 생성하는 것은 비효율적이다. 이를 해결하기 위해 커넥션 풀(Connection Pool)을 사용한다.</p>
<p>connection pool은 웹 컨테이너(WAS)가 실행될 때 일정량의 Connection 객체를 미리 만들어서 pool에 저장한다. 클라이언트 요청이 오면 Connection 객체를 빌려주고, 임무가 완료되면 다시 Connection 객체를 pool에 반환한다.</p>
<h3 id="connection-pool-풀의-장점">Connection pool 풀의 장점</h3>
<ul>
<li>DB 접속 설정 객체를 미리 만들어 연결하여 메모리 상에 등록해 놓기 때문에 불필요한 작업(connection 생성, 삭제)이 사라지므로 클라이언트가 빠르게 DB에 접속이 가능하다.</li>
<li>DB Connection 수를 제한할 수 있어서 과도한 접속으로 인한 서버 자원 고갈 방지가 가능하다.</li>
<li>DB 접속 모듈을 공통화하여 DB 서버의 환경이 바뀔 경우 쉬운 유지 보수가 가능하다.</li>
<li>연결이 끝난 Connection을 재사용함으로써 새로 객체를 만드는 비용을 줄일 수 있다.</li>
</ul>
<h3 id="connection-pool의-주의사항">Connection pool의 주의사항</h3>
<p>동시 접속자가 많을 경우나 너무 많은 DB 접근이 발생할 경우, connection은 한정되어 있기 때문에 쓸 수 있는 connection이 발납될 때까지 기다려야 한다. 이때, 너무 많은 connection을 생성하면 메모리 소모가 크고 프로그램의 성능을 떨어뜨릴 수 있다. 따라서 사용량에 따라 적정량의 connection 객체를 생성해 두어야 한다.</p>
<h3 id="connection-pool의-크기와-성능-관계">Connection Pool의 크기와 성능 관계</h3>
<p>Connection Pool의 크기를 무한정 늘리면 성능이 좋아질까? 그렇지 않다. Connection의 주체는 Thread이므로 Thread와 함께 고려해야 한다. </p>
<p>Thread Pool 크기가 Connection Pool 크기보다 작으면 남는 Connection은 메모리 공간만 차지하게 됩니다. 반면에 Thread Pool 크기와 Connection Pool 크기가 동시에 증가하면 더 많은 Context Switching이 발생하여 성능에 부정적인 영향을 미칠 수 있다. </p>
<h3 id="적절한-connection-pool-크기-설정">적절한 Connection Pool 크기 설정</h3>
<p>Connection Pool의 크기를 어떻게 설정해야 적절한가에 대해 Hikari CP의 공식 문서에서는 아래의 공식을 제시하고 있다.</p>
<p>1 connections = ((core_count) * 2) + effective_spindle_count</p>
<p>여기서 core_count는 현재 서버에서 사용하는 CPU 개수를 나타내고, effective_spindle_count는 DB 서버가 처리할 수 있는 동시 I/O 요청 수를 나타냅니다. 이 공식에 따르면, CPU 속도가 Disk I/O 보다 월등히 빠르므로, Thread가 Disk 작업에서 블로킹되는 시간에 다른 Thread의 작업을 처리할 수 있는 여유가 생긴다는 점을 반영하고 있다.</p>
<h3 id="connection-pool의-종류">Connection pool의 종류</h3>
<ol>
<li>commons-dbcp: 아파치에서 제공하는 대표적인 connection pool 라이브러리이다. </li>
<li>tomcat-jdbc-pool: Tomcat에 내장되어 있으며, Apache Commons DBCP 라이브러리를 기반으로 만들어졌다.</li>
<li>HikariCP: 스프링 부트 2.0부터 default JDBC connection pool로 사용되며, zero-overhead의 특징을 가지고 있다.</li>
</ol>
<h3 id="결론">결론</h3>
<p>JDBC는 자바 애플리케이션이 데이터베이스에 접근할 수 있도록 만든 JAVA에서 제공하는 API이며, connection pool은 JDBC 실행 과정 중에서 생성되어야 할 Connection 객체를 미리 만들어 저장해두는 기법이다. 이로 인해 불필요한 과정(Connection 객체 생성,삭제)을 줄여 성능을 향상시킬 수 있다. </p>
<p>그러나 Connection Pool의 크기를 크게 설정하면 메모리 소모가 크며, 많은 사용자가 대기 시간이 줄어들지만, 반대로 작게 설정하면 대기 시간이 길어집니다. 따라서 사용량에 따라 적정량의 Connection 객체를 생성해 두어야 한다.</p>
]]></description>
        </item>
    </channel>
</rss>