<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>allen_dy.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 26 Sep 2021 04:45:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>allen_dy.log</title>
            <url>https://images.velog.io/images/allen_dy/profile/4af215a4-7ee2-45f6-9b46-a2a10a189023/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. allen_dy.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/allen_dy" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[가상 면접 사례로 배우는 대규모 시스템 설계 기초 - Chapter2]]></title>
            <link>https://velog.io/@allen_dy/%EA%B0%80%EC%83%81-%EB%A9%B4%EC%A0%91-%EC%82%AC%EB%A1%80%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EB%8C%80%EA%B7%9C%EB%AA%A8-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A4%EA%B3%84-%EA%B8%B0%EC%B4%88-Chapter2</link>
            <guid>https://velog.io/@allen_dy/%EA%B0%80%EC%83%81-%EB%A9%B4%EC%A0%91-%EC%82%AC%EB%A1%80%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EB%8C%80%EA%B7%9C%EB%AA%A8-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%84%A4%EA%B3%84-%EA%B8%B0%EC%B4%88-Chapter2</guid>
            <pubDate>Sun, 26 Sep 2021 04:45:45 GMT</pubDate>
            <description><![CDATA[<h2 id="개략적인-규모-추정">개략적인 규모 추정</h2>
<p>시스템 설계 면접에서 시스템 용량이나 성능 요구사항을 개략적인 수치로 나타낼 수 있어야한다.</p>
<p>구글의 시니어 제프 딘은 다음과 같이 말했다.</p>
<blockquote>
<p>개략적인 규모 추정은 보편적으로 통용되는 성능 수치상에서 사고실험을 행하여 추정치를 계산하는 행위로서, 어떤 설계가 요구사항에 부합할 것인지 보기 위한 것이다.</p>
</blockquote>
<p>즉 개략적인 수치 계산을 통해 어떤 설계가 어울릴지 찾아내는 것이다. 수치 계산을 위해 규모 확장성을 표현하는 기본기에 대해 알려주는게 이번 챕터2다.</p>
<ul>
<li>2의 제곱수</li>
<li>응답지연 값</li>
<li>가용성에 관계된 수치들</li>
</ul>
<h3 id="2의-제곱수">2의 제곱수</h3>
<ul>
<li>1천바이트 ≒ 1KB</li>
<li>1백만(million) 바이트 ≒ 1MB</li>
<li>10억(billion) 바이트 ≒ 1GB</li>
<li>1조(trillion) 바이트 ≒ 1TB</li>
<li>1000조(quadrillion) 바이트 ≒ 1PTB</li>
</ul>
<h3 id="모든-프로그래머가-알아야-하는-응답-지연-값">모든 프로그래머가 알아야 하는 응답 지연 값</h3>
<ul>
<li>L1 캐시 참조 : 0.5ns</li>
<li>분기 예측 오류(branch mipredict) : 5ns</li>
<li>L2 캐시 참조 : 7ns</li>
<li>뮤텍스(mutex) 락/언락 : 100ns</li>
<li>주 메모리 참조 : 100ns</li>
<li>Zippy로 1KB 압축 : 10,000ns : 10μS</li>
<li>1 Gbps 네트워크로 2kb 전송 : 20,000ns = 20μS</li>
<li>메모리에서 1MB 순차적으로 read : 250,000ns = 250μS</li>
<li>같은 데이터 센터 내에서의 메시지 왕복 지연시간: 500,000ns = 500μS</li>
<li>디스크 탐색(seek) : 10,000,000ns = 10ms</li>
<li>네트워크에서 1MB 순차적으로 read : 10,000,000ns = 10ms</li>
<li>디스크에서 1MB 순차적으로 read : 30,000,000ns = 30ms</li>
<li>한 패킷의 CA(캘리포니아)로부터 네덜란드까지의 왕복 지연시간 : 150,000,000ns = 150ms</li>
</ul>
<blockquote>
<p>메모리는 빠르지만 디스크는 아직도 느리다.</p>
</blockquote>
<blockquote>
<p>디스크 탐색(seek)은 가능한 피하라.</p>
</blockquote>
<blockquote>
<p>단순한 압축 알고리즘은 빠르다.</p>
</blockquote>
<blockquote>
<p>데이터를 인터넷으로 전송하기 전에 가능하면 압축하라.</p>
</blockquote>
<blockquote>
<p>데이터 센터는 보통 여러 지역에 분산되어 있고, 센터들 간의 데이터를 주고받는 데는 시간이 걸린다.</p>
</blockquote>
<h3 id="가용성에-관한-수치들">가용성에 관한 수치들</h3>
<p>고가용성(high availability) </p>
<ul>
<li>시스템이 오랜 시간동안 중단 없이 운영이 지속되는것.</li>
<li>퍼센트로 표기. 대부분의 서비스는 99% ~ 100%사이의 값을 가진다.</li>
<li><table>
<thead>
<tr>
<th>가용률</th>
<th>하루당 장애시간</th>
<th>주당 장애시간</th>
<th>개월당 장애시간</th>
<th>연간 장애시간</th>
</tr>
</thead>
<tbody><tr>
<td>99%</td>
<td>14.40분</td>
<td>1.68시간</td>
<td>7.31시간</td>
<td>3.65일</td>
</tr>
<tr>
<td>99.9%</td>
<td>1.44분</td>
<td>10.08분</td>
<td>43.83분</td>
<td>8.77</td>
</tr>
<tr>
<td>99.99%</td>
<td>8.64초</td>
<td>1.01분</td>
<td>4.38분</td>
<td>52.60분</td>
</tr>
<tr>
<td>99.999%</td>
<td>864.000밀리초</td>
<td>6.05초</td>
<td>26.30초</td>
<td>5.26분</td>
</tr>
<tr>
<td>99.9999%</td>
<td>86.40밀리초</td>
<td>604.80밀리초</td>
<td>2.63초</td>
<td>31.56초</td>
</tr>
</tbody></table>
</li>
</ul>
<h3 id="예제-트위터-qps와-저장소-요구량-추정">예제: 트위터 QPS와 저장소 요구량 추정</h3>
<h4 id="가정">가정</h4>
<ul>
<li>MAU : 3억(300million)명이다.</li>
<li>50%의 사용자가 트위터를 매일 사용한다.</li>
<li>평균적으로 각 사용자는 매일 2건의 트윗을 올린다.</li>
<li>미디어를 포함하는 트윗을 10%정도다.</li>
<li>데이터는 5년간 보관된다.</li>
</ul>
<blockquote>
<p>QPS(Query per Second) 추정치는?
DAU = 3억 * 50% = 1.5억명
1.5억 * 2 / 86400 = 3472.2 == 3500
최대 qps는 2*QPS = 7000</p>
</blockquote>
<blockquote>
<p>미디어 저장을 위한 저장소 요구량은?
평균 트윗 크기</p>
</blockquote>
<ul>
<li>id : 64바이트</li>
<li>text : 140바이트</li>
<li>미디어어: 1MB
3억건 * 0.9<em>200바이트 + 3억건</em>0.1*1mb(30TB/일)
5년간 미디어를 보관하기 위한 저장소 요구량 = 30TB * 365 * 5 = 약 55PB</li>
</ul>
<h3 id="팁">팁</h3>
<ul>
<li>근사치를 활용해라</li>
<li>단위를 붙여라</li>
<li>QPS, 최대 QPS, 저장소 요구량, 캐시 요구량, 서버 수등을 추정</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Chapter 1. 사용자 수에 따른 규모 확장성]]></title>
            <link>https://velog.io/@allen_dy/system-designchapter1</link>
            <guid>https://velog.io/@allen_dy/system-designchapter1</guid>
            <pubDate>Tue, 21 Sep 2021 13:00:24 GMT</pubDate>
            <description><![CDATA[<p>대규모 시스템 설계는 처음부터 몇백만 유저를 고려하여 설계하기보다 단일 시스템에서 발전시켜 나가는 방향으로 해야 한다. 첫 번째 장은 <strong>규모 확장성</strong>과 관계된 설계 문제를 푸는데 유용한 지식들에 대해 알아볼 것이다.</p>
<h4>단일 서버 </h4>
모든 컴포넌트, 캐시, 데이터베이스, was등이 전부 서버 한대에서 실행된다.

<blockquote>
<p>모바일 앱에서 api.mysite.com에 접속했을때 일어어나는 flow는?</p>
</blockquote>
<ol>
<li>DNS에 요청 api.mysite.com의 IP주소를 얻어온다.</li>
<li>해당 IP주소로 HTTP 요청을 전달</li>
<li>요청을 받은 웹서버는 응답값을 HTML페이지나 JSON으로 응답</li>
<li>응답값을 받은 클라이언트는 화면을 렌더링</li>
</ol>
<h4>데이터베이스 </h4>
사용자가 늘면 서버 한대로는 부족하므로 서버를 늘린다. 트래픽 처리 용도의 웹서버와 데이터 처리 쪽 용도의 데이터 서버로 분리해 독립적으로 확장해 나갈 수 있도록 한다.

<ul>
<li>Realational database(SQL)<ul>
<li>MySQL, Oracle, PostgreSQL</li>
<li>데이터를 열과 컬럼으로 표시, 조인으로 여러 데이터를 합칠 수 있다.</li>
</ul>
</li>
<li>Non realational database(NoSQL)<ul>
<li>CouchDB, Cassandra, HBase, Amazon DynamoDB, MongoDB</li>
<li>4가지 종류로 나뉜다. Key-value store, graph store, column store, document store</li>
</ul>
</li>
</ul>
<blockquote>
<p>어떤 데이터베이스를 사용할 것인가?</p>
</blockquote>
<p>특별한 요구사항이 없다면, RDB로. 이미 40년 이상 시장에서 검증 받아온 시스템. 하지만 다음과 같은 경우라면 비관계형 데이터베이스를 선택해야 한다.</p>
<ul>
<li>아주 낮은 응답 지연시간이 요구됨</li>
<li>다루는 데이터가 형식이 정해져있지 않음.</li>
<li>데이터(JSON, XML, YAML 등)을 직렬화 하거나 역직렬화 할 수 있기만 하면 됨.</li>
<li>아주 많은 양의 데이터를 저장할 필요가 있음.</li>
</ul>
<h4>Scale up vs Scale out </h4>

<ul>
<li>Scale up<ul>
<li>서버로 유입되는 트래픽이 적을때</li>
<li>단순함 but 자동복구(Failover), 다중화(Redundancy)에 대한 해결책이 없다.</li>
</ul>
</li>
</ul>
<p>대규모 트래픽을 지원하는 애플리케이션에서는 Scale out이 적절한 방법이다. Scale out을 해가는 방법에 대해 살펴보겠다.</p>
<ol>
<li><p>로드밸런서
로드밸런싱 셋에 속한 서버들에게 트래픽 부하를 고르게 분산시켜주는 역할을 한다. 클라이언트는 서버에 직접 접속하는 게 아닌, 로드밸런서와 연결한다.</p>
<ul>
<li>웹서버 장애로 인한 fail over문제는 해결</li>
<li>웹 계층의 가용성은 향상</li>
</ul>
</li>
<li><p>데이터베이스 다중화</p>
<ul>
<li>마스터, 슬레이브(Read only) 모델을 사용</li>
<li>안정성(Realiabiliy), 가용성(Availabiliy) 향상</li>
</ul>
</li>
<li><p>캐시</p>
<ul>
<li>데이터베이스 부하를 줄인다.
캐시 사용시 유의해야할점<blockquote>
<p>캐시는 어떤 상황에 바람직한가?
갱신보다 참조가 빈번하게 일어날때
ㅡㅡㅡ
어떤 데이터를 캐시에 두어야 하는가?
영구저장할 필요가 없는 데이터
ㅡㅡㅡ
expire 정책은?
너무 짧으면 db access가 늘어나므로 좋지 않다.
ㅡㅡㅡ
일관성 있는 데이터 유지법
페이스북의 논문  Scaling Memcache at Facebook참고
ㅡㅡㅡ
캐시서버 장애시 대처방법은? SOF를 피해야한다.
ㅡㅡㅡ
캐시 메모리는 얼마나 크게 잡을 것인가?
적게 잡는것보다 과할당을 하는것이 더 낫다.
ㅡㅡㅡ
데이터 방출 정책은?
가장 많이 쓰이는 방식은 LRU(Least Recently Used)</p>
</blockquote>
</li>
</ul>
<ol start="4">
<li>CDN 
정적 콘텐츠를 전송하는데 쓰이는, 지리적으로 분산된 서버의 네트워크<ul>
<li>요청경로, 질의 문자열, 쿠키, 헤더값 정보에 기반하여 HTML페이지 캐싱</li>
</ul>
</li>
</ol>
<p>CDN의 동작 순서</p>
<ol>
<li>사용자 A가 CDN 서버로 image.png 요청 </li>
<li>CDN서버에 image.png가 없다면 원본 서버로 요청</li>
<li>원본서버는 http response에 TTL(얼마나 오래 캐시될수 있는지)값을 포함해서 반환</li>
<li>CDN서버는 imgae.png를 캐시하고 사용자에게 반환</li>
<li>사용자 B가 CDN 서버로 image.png 요청</li>
<li>CDN서버가 image.png 반환</li>
</ol>
</li>
</ol>
<blockquote>
<p>CDN 사용시 고려해야할 점은?</p>
</blockquote>
<pre><code> - 적절한 만료 시한 설정
     - 너무 길면 콘텐츠의 신선도는 떨어지고, 짧으면 원본 서버에 빈번하게 접속
 - 비용
      - CDN은 요금을 내고 제공하는 서비스를 이용하는 식. 전송 양에 따라 요금을 내게 되므로, 필요한 콘텐츠만 캐싱
 - 장애에 대한 대처 방안
      - CDN이 죽었을때 원본서버로 직접 요청할 수 있도록 고려
 - 콘텐츠 무효화 방법
   - CDN에서 제공해주는 API 사용
   - 오브젝트 버저닝 이용. ex) image.png</code></pre><ol start="5">
<li><p>Stateless 웹 계층 이용</p>
<ul>
<li>사용자의 상태정보를 저장하는 서버는 따로 분리</li>
</ul>
</li>
<li><p>여러 지역의 데이터 센터 운영
기술적 난제 존재</p>
<ol>
<li><p>트래픽 우회: 올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야한다.</p>
</li>
<li><p>데이터 동기화: 장애가 났을시 특정 데이터 센터에는 찾는 데이터가 없을 수 있다.</p>
<ul>
<li>여러 데이터 센터에 걸쳐 다중화 하는것이 보편적인 전략</li>
</ul>
</li>
<li><p>테스트와 배포</p>
</li>
<li><p>메시지 큐</p>
</li>
</ol>
</li>
</ol>
<ul>
<li><p>비동기 통신을 지원하는 컴포넌트</p>
</li>
<li><p>시스템의 컴포넌트를 분리하여, 독립적으로 확장할 수 있도록 하기 위해 사용되는 핵심적 전략중 하나</p>
</li>
<li><p>서비스, 컴포터넌트간 결합이 느슨해져 <strong>규모 확장성</strong>을 보장되어야 하는 안정적 애플리케이션을 구성하기 좋다.</p>
<ol start="8">
<li><p>로그, 메트릭 그리고 자동화
로그: 여러 서버의 로그를 모아 모니터링은 필수
메트릭: 시스템 현재 상태 파악및 사업 현황에 관한 유용한 정보를 얻을 수 있다.
자동화: 생산성을 높이기 위해 자동화 도구는 필수</p>
</li>
<li><p>데이터베이스의 규모 확장
샤딩을 통한 scale out 활용</p>
</li>
</ol>
<ul>
<li>샤딩은 대규모 데이터 베이스를 샤드라고 부르는 작은 단위로 분할하는 기술</li>
<li>모든 샤드는 같은 스키마를 사용하지만, 데이터는 중복되지 않는다.</li>
<li>가장 중요한건 샤딩 전략 즉 샤딩 키를 어떻게 설정할것인가이다.</li>
</ul>
<blockquote>
<p>샤딩을 도입하면 생기는 복잡한 문제는?</p>
</blockquote>
<ul>
<li>데이터의 재샤딩<ul>
<li>데이터가 너무 많아져서 하나의 샤드로 더이상 감당이 어려울때 </li>
<li>샤드간 데이터 분포가 균등하지 못할때 (샤드 소진 발생)</li>
<li>샤드키를 계산하는 함수 변경 및 데이터 재배치 필요, 안정해시 기법 활용</li>
</ul>
</li>
<li>유명 인사 문제(hotspot key)<ul>
<li>특정 샤드에 질의가 집중되어 서버가 과부하가 걸리는 문제</li>
</ul>
</li>
<li>조인과 비정규화<ul>
<li>여러 샤드로 쪼개면 조인하기가 힘들어진다.</li>
<li>데이터베이스를 비정규화 하는게 필요하다.</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[페이스북 타임라인: 비정규화의 힘]]></title>
            <link>https://velog.io/@allen_dy/facebook-timeline</link>
            <guid>https://velog.io/@allen_dy/facebook-timeline</guid>
            <pubDate>Mon, 20 Sep 2021 09:45:49 GMT</pubDate>
            <description><![CDATA[<p> 페이스북 타임라인은 규모가 아주 크다. 사진, 위치, 상태 업데이트, 비디오와 같은 당신이 하는 모든것을 통해 당신의 인생을 한 화면에 담고자 한다. 즉 그건 언제든지 신속하고 빠르게 접근할 수 있는 수 십년의 데이터를 의미한다. 빅데이터 전문가들이 있는 페이스북에서도 이건 큰 기술적인 도전이었지만, 6개월만에 완성시켰다.</p>
<p> 페이스북의 Ryan Mack이 타임라인 구현 스토리대해 말한 기고문이 있다. 해당 기고문에서 크게 5가지만 뽑자면 다음과 같다.</p>
<p> <strong>1. 새로운 것을 구축하는 대신 기존 인프라를 활용해라</strong>
 당신은 페이스북이 타임라인을 위해 새로운 구조를 구축했을거라고 생각할 수 있지만, 그들은 이미 구축 되 있는 인프라를 사용했다.</p>
<ul>
<li>MySQL</li>
<li>Multifeed(가까운 친구들의 업데이트 상황을 받아 볼 수 있는 시스템)</li>
<li>Thrift</li>
<li>Memcached</li>
<li>Operations</li>
</ul>
<p>기존 인프라위에서 그들은 오직 비즈니스 로직만 집중했고, 결국 6개월만에 완성 될 수 있었던 것이다.</p>
<p><strong>2. 비정규화. 필요한 형태로 데이터를 포맷팅 해라</strong></p>
<ul>
<li><p>비정규화, 즉 필요해 맞는 테이블 생성(중복이 될지라도)으로 조인 쿼리의 감소와 데이터베이스 I/O를 최소화 시킬 수 있다. 비정규화 대신 캐싱을 사용할 수 도 있지만, 타임라인의 데이터는 방대하고 해당 데이터의 라이프 사이클을 측정할 수 없는 상황에서는 바람직하지 않다.</p>
</li>
<li><p>타임라인은 데이터를 메타데이터 토대로 랭킹을 매겨 순서에 따라 보여줘야 한다. 비정규화 프로세스는 모든 메타 데이터를 하나의 형태로 모아, 적은 I/O로 랭킹을 계산하고 PK range 쿼리로 데이터를 효율적으로 스트리밍 할 수 있다.</p>
</li>
<li><p>타임라인은 데이터웨어 하우스에 데이터마트와 같다. 수십 개의 서로 다른 시스템에서 데이터를 슬러핑 하여 정리하고 합쳐 새로운 표준 형식으로 다시 포맷해야 한다. 페이스북은 페이스북 방식으로 이것을 해냈다.
사용자 정의 데이터 변환 언어를 만들고, 기존 시스템에서 빠르게 데이터를 가져오기 위해 수백 대의 MySQL 서버를 배치하고 조인 속도를 높이기 위해 플래시 스토리지를 배치하고, 쿼리 프록시를 병렬화 시키고 향후 유연성을 위해 표준 Multifeed 데이터 포맷을 만들었다.  </p>
</li>
</ul>
<p><strong>3. 다른 종류의 캐시를 이용해라</strong></p>
<ul>
<li><p>Short term cache. 타임라인의 최근 활동은 계속해서 바뀐다. 이 캐시는 플래시 캐시 커널 드라이버를 사용하여 OS캐시를 플래시 장치로 확장하는 InnoDB내의 RAM row 캐시이다.</p>
</li>
<li><p>Long term cache. 쿼리 캐시는 맴캐시에 저장된다. 2010년 활동의 랭킹을 보여달라는 빅 쿼리 같은 케이스는 결과가 거의 바뀔리가 없기 때문에 캐싱하면 효율적이다.</p>
</li>
</ul>
<p><strong>4. 지역적으로 운영해라</strong>
타임라인 집계기는 각각의 데이터베이스에서 돌아가기 때문에 디스크를 최대화 할 수 있다. 표시할 데이터만 네트워크를 통해 전송해라</p>
<p><strong>5. 병렬적으로 개발해라</strong>
개발팀은 디자인, 프론트 앤드, 인프라, 데이터 마이그레이션으로 나누어 작업을 진행했다. 이와 동시에 테스트 백엔드의 UI 프로토타입, 시뮬레이션 백엔드의 프로덕션 UI, 확장 가능한 백엔드, 탈규격화 프레임워크, 데이터 웨어하우스 및 시뮬레이션 로드 테스트와 같이 구축되었다.</p>
<p>원문: <a href="http://highscalability.com/blog/2012/1/23/facebook-timeline-brought-to-you-by-the-power-of-denormaliza.html">링크
</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Test]]></title>
            <link>https://velog.io/@allen_dy/Test</link>
            <guid>https://velog.io/@allen_dy/Test</guid>
            <pubDate>Mon, 20 Sep 2021 08:10:08 GMT</pubDate>
            <description><![CDATA[<p>test</p>
]]></description>
        </item>
    </channel>
</rss>