<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>기억 저장소</title>
    <link>https://kingds.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 20 Aug 2026 11:47:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>어제</managingEditor>
    <item>
      <title>golang의 call by value</title>
      <link>https://kingds.tistory.com/151</link>
      <description>&lt;h1&gt;Call by value와 Call by reference&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Call by value&lt;/h2&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;type a struct {
	value int
}

func run(aa,bb a) {
	aa.value = 111
	bb = aa
	fmt.Println(aa, bb)
}

func main()  {
	a1 := a{value: 1}
	a2 := a{value: 2}

	run(a1,a2)
	fmt.Println(a1, a2)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;{111} {111}
{1} {2}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;run 함수 내부에서는 변경이 되지만 외부까지 변경이 전파가 되진 않는다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그 이유는 run 함수 내부의 파라미터가 실제 객체를 복사한 값을 사용하기 때문&lt;/li&gt;
&lt;li&gt;이 방식이 &lt;b&gt;Call by Value&lt;/b&gt; 다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Call by reference&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하지만 Go 에서는 Call By Value 대신 Call By Referece도 사용할 수 있는데&lt;/li&gt;
&lt;li&gt;그 방법은 바로 &lt;b&gt;Pointer&lt;/b&gt;를 사용하는 방법이다&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;go&quot;&gt;&lt;code&gt;type a struct {
	value int
}

func run(aa,bb *a) {
	aa.value = 111
	bb = aa
	fmt.Println(aa, bb)
}

func main()  {
	a1 := a{value: 1}
	a2 := a{value: 2}

	run(&amp;amp;a1,&amp;amp;a2)
	fmt.Println(a1, a2)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;&amp;amp;{111} &amp;amp;{111}
{111} {2}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;run 함수 내부의 변경이 외부까지 전파가 되었다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하지만 bb 파라미터의 변경은 외부에 전파가 되지 않았다. 그 이유는 뭘까 ?
&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;실제 객체를 변경하는 것이 아닌 파라미터에 할당한 값이 bb의 주소에서 aa의 주소로 변경 된것일 뿐이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자바와 다른점&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;java는 Call by value 지만 객체를 넘겼을 경우 객체 내부의 변경이 외부에 전파가 된다.&lt;/li&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;파라미터에 Pointer를 사용하는 경우&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;보통 Pointer를 사용시 내부에서의 변경이 외부까지 전파가 되므로 최대한 사용을 자제하는 방향이다.&lt;/li&gt;
&lt;li&gt;하지만 객체가 생성비용이 비싼 경우 Call by value로 복사를 하므로 생성비용이 과하게 나오는 경우가 생긴다.&lt;/li&gt;
&lt;li&gt;이런 경우 Pointer를 사용하여 객체 생성비용을 절약할 수 있다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Go</category>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/151</guid>
      <comments>https://kingds.tistory.com/151#entry151comment</comments>
      <pubDate>Sat, 23 Jul 2022 20:53:14 +0900</pubDate>
    </item>
    <item>
      <title>BIG-O 표기법</title>
      <link>https://kingds.tistory.com/150</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(1)
&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;/li&gt;
&lt;li&gt;O(n)
&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;for문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(n^2)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(n) 안에서 또 루프를 돌려서 O(n)으로 돌아가는 알고리즘
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2중 for문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(n^m)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(n) 안에서 m개만큼 다중 O(n)이 돌아가는 알고리즘
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;m중 for문&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(2^n)
&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ex) 1일때는 1칸이 늘어나고 이렇게 늘어나서 사각형중 면적이 가장큰 3으로 늘어나고 점점 늘어난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(m^n)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2개가 아닌 m개씩 추가로 호출&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(log n)
&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;li&gt;조회할때마다 조회해야할 데이터의 양이 절반씩 떨어지는 알고리즘&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;O(sqrt(N))
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n개의 아이템을 정사각형에 채우고 가장 윗줄이 sqrt(N)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;9일경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1,2,3&lt;/li&gt;
&lt;li&gt;4,5,6&lt;/li&gt;
&lt;li&gt;7,8,9&lt;/li&gt;
&lt;li&gt;이므로 9의 sqrt(N)은 3이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Big O에서 상수는 과감하게 버린다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;O(2n) &amp;rArr; O(n) 으로 표기한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;https://www.youtube.com/watchv=6Iq5iMCVsXA&amp;amp;ab_channel=%EC%97%94%EC%A7%80%EB%8B%88%EC%96%B4%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD&lt;/p&gt;</description>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/150</guid>
      <comments>https://kingds.tistory.com/150#entry150comment</comments>
      <pubDate>Fri, 3 Dec 2021 02:12:39 +0900</pubDate>
    </item>
    <item>
      <title>쿠버네티스 노드가 죽고나서 그 이후</title>
      <link>https://kingds.tistory.com/147</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;가끔가다 노드 서버가 죽는 경우가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우 죽은 노드에 배포된 deplyoment는 제대로 failover를 수행하여 다른 노드로 재배포 되지만 statefulset은 failover를 수행하지 못한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 이런걸까 ?&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Pod Eviction Timeout 이란&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ready 컨디션의 상태가 pod-eviction-timeout (kube-controller-manager에 전달된 인수) 보다 더 길게 Unknown 또는 False로 유지되는 경우, 노드 상에 모든 파드는 노드 컨트롤러에 의해 삭제되도록 스케줄 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;562&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHWm26/btrg7G6lQnp/iV0oURDSrpl1FkYj2E0AOk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHWm26/btrg7G6lQnp/iV0oURDSrpl1FkYj2E0AOk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHWm26/btrg7G6lQnp/iV0oURDSrpl1FkYj2E0AOk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHWm26%2Fbtrg7G6lQnp%2FiV0oURDSrpl1FkYj2E0AOk%2Fimg.jpg&quot; data-origin-width=&quot;661&quot; data-origin-height=&quot;562&quot; data-ke-mobilestyle=&quot;widthOrigin&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://medium.com/tailwinds-navigator/kubernetes-tip-how-statefulsets-behave-differently-than-deployments-when-node-fails-d29e36bca7d5&quot;&gt;https://medium.com/tailwinds-navigator/kubernetes-tip-how-statefulsets-behave-differently-than-deployments-when-node-fails-d29e36bca7d5&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 노드가 죽은 경우 (Not Ready 상태) Pod는 계속 실행되지만 pod를 종료상태로 설정하기 전에 pod eviction timeout에 설정된 시간만큼 기다린다 ( default는 5분 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 후 위의 flow대로 흘러 pod가 다시 새로운 노드에 재배포된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sts는 cluster application 내에서 master, slave 구조를 가진다.&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;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;pod Spec에서 terminationGracePeriodSeconds를 0으로 설정하기.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이렇게 하면 노드가 클러스터에 다시 합류할때 sts pod이 강제로 삭제된다.&lt;/li&gt;
&lt;li&gt;그럼 마스터는 새 복제본을 생성&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;노드가 정확하게 죽은거를 감지할 방법을 확인할수 있는 경우 노드를 강제로 삭제한다.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그럼 다른 노드에 sts가 재배포된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;그냥 디플로이먼트 사용&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;레퍼런스&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://medium.com/tailwinds-navigator/kubernetes-tip-how-statefulsets-behave-differently-than-deployments-when-node-fails-d29e36bca7d5&quot;&gt;https://medium.com/tailwinds-navigator/kubernetes-tip-how-statefulsets-behave-differently-than-deployments-when-node-fails-d29e36bca7d5&lt;/a&gt;&lt;/p&gt;</description>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/147</guid>
      <comments>https://kingds.tistory.com/147#entry147comment</comments>
      <pubDate>Thu, 7 Oct 2021 22:28:09 +0900</pubDate>
    </item>
    <item>
      <title>10월 5일 메트릭 기반 모니터링 환경 구축</title>
      <link>https://kingds.tistory.com/145</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://if.kakao.com/session/79&quot;&gt;https://if.kakao.com/session/79&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;메트릭 기반 모니터링 환경 구축(feat. Prometheus)&lt;/b&gt;&lt;/h1&gt;
&lt;h1&gt;카카오 페이 모니터링&lt;/h1&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;elk 스택 사용&lt;/li&gt;
&lt;li&gt;수집은 file beats, log stash&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;메트릭 &amp;amp; Tracing
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자체 제작 Neo 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;문제점&lt;/h2&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;서블릿 기반만 지원하는 APM
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모니터링이 안됨 (Webflux, Netty, Akka)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;메트릭 기반 모니터링 목표&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MTTD (평균 탐지시간) 5분 이내
&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;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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;메트릭 기반 모니터링&lt;/h1&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;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;/li&gt;
&lt;/ul&gt;
&lt;/li&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;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;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;메트릭에 대한 이야기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메트릭은 Label이 강력하다.
&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;200만개의 레이블 추가후 프로메테우스의 scrape timeout이 발생&lt;/li&gt;
&lt;li&gt;전체 모니터링에 장애가 남&lt;/li&gt;
&lt;li&gt;이런 문제를 Cardinality 문제라고 함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떤 메트릭을 수집해야 하는가 ?&lt;/h2&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;system 입장&lt;/li&gt;
&lt;li&gt;고객 입장
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;netflix의 예
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스트리밍의 정상작동 확인을 위해 playback 요청을 메트릭으로 활용&lt;/li&gt;
&lt;li&gt;사람들이 영상이 안나오면 playback 버튼을 누르기 때문에&lt;/li&gt;
&lt;li&gt;이를 통해 서비스가 정상인지 비정상인지를 파악&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RED 방법론
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Rate: 서비스에서 제공하고 있는 시간당 요청 수&lt;/li&gt;
&lt;li&gt;Errors: 시간당 에러 숫자&lt;/li&gt;
&lt;li&gt;Duration: 각 요청에 걸리는 시간 분포&lt;/li&gt;
&lt;li&gt;컨트롤러 단이 아닌 도메인단에 메트릭을 추가&lt;/li&gt;
&lt;li&gt;RED 방법론은 효과적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떻게 보여줄 것인가 ?&lt;/h2&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;li&gt;분석을 위한 대시보드와 운영을 위한 대시보드는 따로 만드는것이 효과적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Alert은 어떻게 하는게 좋을까 ?&lt;/h1&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;exception으로 인해 발생한 증상을 alert으로 전달&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;li&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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;장애 알림 프로세스는 어떻게 할까&lt;/h2&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;h1&gt;확장 가능한 메트릭 저장소&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;메트릭 저장소 확장하기&lt;/h2&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;push 방식의 메트릭 저장소는 사용자의 증가를 감당하기 위해 중앙 수집 서비스가 스케일 아웃 하는 과정에서 운영비용의 증가가 너무 심함&lt;/li&gt;
&lt;li&gt;확장에 용이한 pull 방식인 프로메테우스 채택&lt;/li&gt;
&lt;li&gt;target의 증가에 따라 수집에 걸리는 시간이 늘어남
&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;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;계층을 두고 tree 형태로 구성하는 방식
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 ZONE마다 수집하는 프로메테우스를 두고 중앙 프로메테우스가 pull해가는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동일한 레벨의 프로메테우스 서버 사이에 페더레이션을 구성하는 크로스 서비스 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;계층 방식을 채택하여 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ha 구성에 문제가 생기면 오탐으로 인해 어려움이 생길수 있다.
&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;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;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&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;li&gt;타노스는 데이터의 저장을 s3와 같은 오브젝트 스토리지를 사용
&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;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;타노스를 선택한 이유
&lt;ol 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;HA를 위한 특별한 고민을 하지 않아도 됨&lt;/li&gt;
&lt;li&gt;프로메테우스는 로컬 디스크를 사용하기 떄문에 언젠가 삭제됨
&lt;ol 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;/ol&gt;
&lt;/li&gt;
&lt;li&gt;사용자 측면 , 그라파나 또는 애플리케이션 개발자 측면에서는 달라지는 것이 없다.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단지 그라파나 주소만 바뀌기만 하면 된다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;타노스는 외부 스토리지로 aws s3 혹은 클라우드 서비스를 사용하게 함.
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카카오는 IDC를 사용하기 떄문에 외부 서비스를 사용하는게 적합하지 않다고 생각&lt;/li&gt;
&lt;li&gt;현재 minio와 openstack swift를 실험중&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;정리&lt;/h1&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;h1&gt;후기&lt;/h1&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;/li&gt;
&lt;/ul&gt;</description>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/145</guid>
      <comments>https://kingds.tistory.com/145#entry145comment</comments>
      <pubDate>Wed, 6 Oct 2021 00:59:12 +0900</pubDate>
    </item>
    <item>
      <title>헬름차트 1강</title>
      <link>https://kingds.tistory.com/130</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;헬름은 늘어나는 yaml들을 편하게 관리하기 위한 패키지 매니저&lt;/li&gt;
&lt;li&gt;헬름1은 tiller를 사용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그래서 사용자가 client를 사용하여 grpc 통신을 하여 tiller에게 전달하면 tiller가 k8s apiserver와 통신하는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;헬름3는 tiller를 사용안하고 바로 cilent를 사용하여 k8s apiserver와 통신&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;헬름 범위&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;introduction
&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;/li&gt;
&lt;li&gt;Topics
&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;/li&gt;
&lt;li&gt;chart Template Guide
&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;/li&gt;
&lt;li&gt;helm commands
&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;/li&gt;
&lt;li&gt;Best Practices / How To&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;장점&lt;/h3&gt;
&lt;ol 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;/ol&gt;</description>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/130</guid>
      <comments>https://kingds.tistory.com/130#entry130comment</comments>
      <pubDate>Sat, 4 Sep 2021 20:02:40 +0900</pubDate>
    </item>
    <item>
      <title>k8s CertificateSigningRequest v1beta1에서 v1으로 업그레이드</title>
      <link>https://kingds.tistory.com/127</link>
      <description>&lt;h1&gt;CertificateSigningRequest&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Certificates API는 Kubernetes API의 클라이언트가 X.509를 요청하고 획득 할 수 있도록 프로그래밍 방식의 인터페이스를 제공하여 X.509 자격 증명 프로비저닝을 자동화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/&quot;&gt;https://kubernetes.io/docs/reference/access-authn-authz/certificate-signing-requests/&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;k8s api server와 통신하기 위해서 3가지 방법을 주로 사용해왔었다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;kubernetes 의 ca파일을 사용&lt;/li&gt;
&lt;li&gt;certmanager 사용&lt;/li&gt;
&lt;li&gt;csr 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기존에 csr의 v1beta1버전을 사용하다 deprecated 된다는 메세지를 보고 v1으로 업그레이드 하기로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CSR v1 업그레이드 시 생기는 문제&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존의 v1beta1는 signer가 &lt;a href=&quot;http://kubernetes.io/legacy-unknown&quot;&gt;kubernetes.io/legacy-unknown&lt;/a&gt; 여서 따로 뭔가를 지정할 필요가 없었지만 v1에서는 signerName이 spec에 생겼고 &lt;a href=&quot;http://kubernetes.io/legacy-unknown&quot;&gt;kubernetes.io/legacy-unknown&lt;/a&gt;는 사용금지당했다. (v1버전부터 금지)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;나는 [&quot;key encipherment&quot;, &quot;digital signature&quot;, &quot;server auth&quot;] 를 사용해야 했으므로 signerName을 &lt;a href=&quot;http://kubernetes.io/kubelet-serving&quot;&gt;kubernetes.io/kubelet-serving&lt;/a&gt;로 사용해야 했다.&lt;/li&gt;
&lt;li&gt;하지만 &lt;a href=&quot;http://kubernetes.io/kubelet-serving&quot;&gt;kubernetes.io/kubelet-serving&lt;/a&gt;의 organizations은 system:nodes&lt;/li&gt;
&lt;li&gt;기존의 v1beta1에서 따로 organizations을 지정하지 않았기 때문에 organizations 에러가 뜨는 상황&lt;/li&gt;
&lt;li&gt;CN에서 organizations을 system:nodes를 주고 해결했다.&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/127</guid>
      <comments>https://kingds.tistory.com/127#entry127comment</comments>
      <pubDate>Fri, 3 Sep 2021 20:05:47 +0900</pubDate>
    </item>
    <item>
      <title>4장 처리율 제한 장치의 설계</title>
      <link>https://kingds.tistory.com/123</link>
      <description>&lt;article id=&quot;0feca405-c3fb-4044-ac7d-80cb4f85958b&quot; class=&quot;page sans Notion_P&quot;&gt;&lt;div class=&quot;page-body&quot;&gt;&lt;p id=&quot;33660e75-d33d-4ad8-b086-9fa6694e48b0&quot; class=&quot;&quot;&gt;네트워크 시스템에서 처리율 제한 장치는 클라이언트 또는 서비스가 보내는 트래픽의 처리율을 제어하기 위한 장치다&lt;/p&gt;&lt;p id=&quot;caa933f7-eb7e-4362-82f1-fa60b0f17e30&quot; class=&quot;&quot;&gt;HTTP로 예를 들면 이 장치는 특정 기간 내에 전송되는 클라이언트의 요청 횟수를 제한한다.&lt;/p&gt;&lt;p id=&quot;e7392c3d-ed54-4a3c-b916-68ff05d371db&quot; class=&quot;&quot;&gt;API의 요청 횟수가 제한 장치에 정의된 임계치를 넘어서면 추가로 도달한 모든 호출은 처리가 중단된다.&lt;/p&gt;&lt;p id=&quot;93449d1d-4a56-4809-b850-4af76de1e860&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;fb58f3f4-f7bf-41be-8c83-baa34899b160&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;사용자는 초당 2회 이상 새글을 올릴 수 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;49957cad-839c-4cab-8760-0534a78165c6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;같은 IP 주소로는 하루에 10개이상의 계정을 생성할 수 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;fd00dcf3-f78a-4fd3-9432-5e4c1145220f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;같은 디바이스로는 주당 5회이상 리워드를 요청할 수 없다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;445fbe93-54fe-4afb-970f-8c714afe4a53&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;c4bf679e-93cb-4c5c-88e2-9d0186121c4d&quot; class=&quot;&quot;&gt;API 처리율 제한 장치의 장점&lt;/h2&gt;&lt;ol type=&quot;1&quot; id=&quot;7c87d798-52df-4901-84cc-20a5479c25ae&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;Dos 공격에 의한 자원 고갈을 방지 할 수 있다.&lt;ul id=&quot;d9928400-94d1-42c9-ba3c-1d6fae9b2f3d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;대형 IT 기업들이 공개한 거의 대부분의 API는 어떤 형태로든 처리율 제한 장치를 갖고 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;cbed4ea1-b473-4930-a131-69f748cda452&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;비용을 절감 한다.&lt;ul id=&quot;febd320f-73a8-4940-a2d7-48b9abee39cb&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;추가 요청에 대한 처리를 제한하면 서버를 많이 두지 않아도 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;27fc8134-dd6a-4ad2-a974-800f43104b9f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한은 서드파티 API에 사용료를 지불하고 있는 회사들에게 아주 중요하다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6125049a-e797-4c11-be99-64bd0efe777b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;호출하는 API에 대한 과금이 횟수에 따라 이루어지는 경우 횟수를 제한하고 비용을 절감할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;32f80009-4a21-428a-87d0-f292d549cb5a&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;서버 과부하를 막는다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;4ceb315a-fd28-49e6-814e-da36e95d928c&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;f72a3883-fd74-4c75-b6b2-c11ce0300d27&quot; class=&quot;&quot;&gt;1단계 문제 이해 및 설계 범위 확정&lt;/h1&gt;&lt;h2 id=&quot;3cff1975-c601-4f34-a86e-5a777649479a&quot; class=&quot;&quot;&gt;요구사항&lt;/h2&gt;&lt;ul id=&quot;5bfc4d9c-ed77-4e16-be9f-c81f2412917f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;설정된 처리율을 초과하는 요청은 정확하게 제한한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;30e15feb-c591-4c26-90ff-205044ae0377&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;낮은 응답시간: 이 처리율 제한 장치는 HTTP 응답시간에 나쁜 영향을 주어서는 곤란하다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1353bd94-eef7-4ece-a33f-aa7ec639c4fa&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가능한 한 적은 메모리를 써야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1d7560ed-864d-4eaf-8c0c-072dcec5af3b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;분산형 처리율 제한: 하나의 처리율 제한 장치를 여러 서버나 프로세스에 공유할 수 있어야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;93206f44-dd70-415e-85e3-1414f5f1a370&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예외 처리: 요청이 제한되었을 떄는 그 사실을 사용자에게 분명하게 보여주어야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0956a714-efcf-4d5d-ad12-c3ff4408f294&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;높은 결함 감내성: 제한 장치에 장애가 생기더라도 전체 시스템에 영향을 주어서는 안된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;2484145c-1910-4777-8210-23aaf3ded148&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;fdf21659-97a4-4b34-8764-6df470a6ad3b&quot; class=&quot;&quot;&gt;2단계 개략적 설계안 제시 및 동의 구하기&lt;/h1&gt;&lt;h2 id=&quot;08c335e9-9d67-4c93-88e4-4317cabc2a03&quot; class=&quot;&quot;&gt;처리율 제한 장치는 어디에 둘것인가 ?&lt;/h2&gt;&lt;ol type=&quot;1&quot; id=&quot;42a1cd7e-995b-4582-a1d0-8b86d0f6a6f4&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;클라이언트에 두기&lt;ul id=&quot;a15f68a0-7e00-45ed-ae49-a644dd2a84c6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일반적으로 클라이언트는 안정적으로 걸수있는 장소가 못된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;66c0b8ff-4de3-4d6f-ac80-4c625a9aec85&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;클라이언트 요청은 위변조가 쉽게 가능하기 때문이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;7582bae5-ec22-4ea1-9f48-1e607f96a5de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;모든 클라이언트의 구현을 통제하는 것도 어려울 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;b8fefd9e-5057-4d4f-91c2-72f7941726f7&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;서버에 두기&lt;ol type=&quot;a&quot; id=&quot;ae70cb0f-4bf5-4d1a-864b-2a27d108c867&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;API 서버에 두는 방법&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;9cbf2028-3bac-44bb-ae09-ccfe8e7c5255&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;API 서버에 안두고 처리율 제한 미들웨어를 만들어 해당 미들웨어로 하여금 API 서버로 가는 요청을 통제하는 것이다&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;5ef154d6-86fb-415f-bde6-927a189034cb&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;클라우드 마이크로 서비스의 경우 처리율 제한 장치는 보통 API 게이트웨이라 불리는 컴포넌트에 구현된다.&lt;ul id=&quot;01a4293a-a045-4667-8fa8-6831dcef83a1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;API 게이트웨이는 처리율 제한, SSL 종단, 사용자 인증, IP 허용 목록 관리 등을 지원하는 완전 위탁관리형 서비스 즉 클라우드 업체가 유지보수를 담당하는 서비스다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5d063e0e-ff7a-4b10-ba3f-91f924f9462f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일단은 API 게이트 웨이가 처리율 제한을 지원하는 미들웨어 라는 점만 기억하도록 하자.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;8bff5102-d4da-4beb-8b0b-63386954860b&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;1bc0f6b5-2f90-47c8-b429-05432203f035&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한 장치를 어디에 둔다는 것에 대한 정답은 없다. 하지만 일반적인 지침은 있다.&lt;ol type=&quot;1&quot; id=&quot;4e5f033d-4192-4aed-b464-1f6a426aa082&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;프로그래밍 언어, 캐시 서비스 등 현재 사용하고 있는 기술 스택을 점검하고 현재 사용하는 프로그래밍 언어가 서버측 구현을 지원하기 충분할 정도로 효율이 높은지 확인하라.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;4c3c79d4-a359-4f2b-9986-6c90de4f0c7d&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;여러분의 사업 필요에 맞는 처리율 제한 알고리즘을 찾아라. 서버측에서 구현하기로 했다면 알고리즘 선택은 자유롭지만 서드파티의 게이트웨이를 사용한다면 폭은 제한된다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;d0f5a70a-8c00-4767-b6f1-4667b1b973ad&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;설계가 마이크로서비스에 기반하고 있고 사용자 인증이나 IP 허용목록 관리등을 처리하기 위해 API 게이트웨이를 이미 설계에 포함시켰다면 처리율 제한 기능 또한 게이트웨이에 포함시켜야 할 수도 있다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;c273a4fb-0b44-40b7-9d6d-1315d53f60d5&quot; class=&quot;numbered-list&quot; start=&quot;4&quot;&gt;&lt;li&gt;처리율 제한 서비스를 직접 만드는 데는 시간이 든다. 처리율 제한 장치를 구현하기에 인력이 없다면 상용 API 게이트웨이를 쓰는것이 바람직한 방법일 것이다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;ae8afe80-f797-471a-ad86-85731adc6aaf&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;a7f8edb1-8356-403b-be8d-3e0c43d3f6e3&quot; class=&quot;&quot;&gt;처리율 제한 알고리즘&lt;/h3&gt;&lt;ul id=&quot;77966abb-e25c-43e8-a00d-3fd8767f5a1e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;토큰 버킷 알고리즘&lt;ul id=&quot;7ffe2274-2233-49fe-9e96-b66215a139de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;보편적으로 사용되는 알고리즘으로 아마존과 스트라이프가 API 요청을 통제하기 위해 사용한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f44fcedd-01b0-4762-b3b4-257f5b616731&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;통상적으로 API 엔드포인트 마다 별도의 버킷을 둔다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;3c88468a-97c4-4c00-a919-8424e0a3fc72&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예를 들어 사용자마다 하루에 한번만 포스팅할수 있고 친구는 150명까지 추가할수 있고 좋아요 버튼은 다섯번 까지만 누를수 있다면 사용자마다 3개의 버킷을 두어야 할것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d9424d2c-0ed4-4e17-b990-d359b78d5879&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;IP주소별로 처리율 제한을 적용하면 IP 주소마다 버킷을 하나씩 할당&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2d58edcb-2d84-4914-bec4-ffb006ba4a94&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템의 처리율을 초당 만개요청으로 제한하고 싶다면 모든 요청이 하나의 버킷을 공유하도록 해야 할것&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;71726eda-27ff-4fad-804b-e2698063a815&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;d7e7c04d-3f0d-4b8d-8c55-8764b85fb9ee&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;장점&lt;ul id=&quot;88f4cd37-4ca0-4079-936a-e01dcce876bc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;구현이 쉽다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;496ebd21-60f2-4de4-a148-6b90cb8699de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메모리 사용 측면에서도 효율적이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;847c8307-108f-4ca0-8caa-0eb2dd6d523f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;짧은 시간에 집중되는 트래픽도 처리 가능하다 버킷에 남은 토큰이 있기만 하면 요청은 시스템에 전달될 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b23851f9-e81a-470d-bb45-243f2a6ba891&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;단점&lt;ul id=&quot;eca821b8-ecc3-477f-89f8-8cd849f7b79c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이 알고리즘은 버킷 크기와 토큰 공급률이라는 두개의 인자를 갖고 있는데 이 값을 적절하게 튜닝하는것은 까다로운 일이 될 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;c368ea4f-d5b4-49cc-b889-e5bf929bcd9c&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1afab85a-52ed-4089-b2b3-57a2b94f99ab&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;누출 버킷&lt;ul id=&quot;dce43ba9-880a-4a79-81ad-5266b1acd14b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;FIFO 큐로 구현한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2020f351-6681-403a-ad95-88bbe9b28a92&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;요청이 도착하면 큐가 가득차 있는지 본다.빈자리가 있는 경우에는 큐에 요청을 추가 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;659d57da-a026-4077-ac33-6c9bed46f7e6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;큐가 가득차 있는 경우에는 새 요청은 버린다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f7edfe6a-35e1-456e-9ec2-85ed9a50e41d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;지정된 시간마다 큐에서 요청을 꺼내어 처리한다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;87c85d7f-d918-45ec-b36a-a461a3f4455e&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;6565c706-aa66-4327-8a51-b4478b56d640&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;장점&lt;ul id=&quot;c4c2e915-d6a2-4bc2-a984-59f3a8fec992&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;큐의 크기가 제한되어 있어 메모리 사용량 측면에서 효율적이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;7f6f0068-7a71-4685-9319-051875671f3a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;고정된 처리율을 갖고 있기 때문에 안정된 출력이 필요한 경우에 적합하다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;90b1143d-73c2-4de4-9b2e-ce7d348aced7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;단점&lt;ul id=&quot;b1d21cb4-5a42-42bd-98c5-aacf4b3b0a25&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;단시간에 많은 트래픽이 몰리는 경우 큐에는 오래된 요청들이 쌓이게 되고 그 요청들을 제때 처리하지 못하면 최신 요청은 버려진다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;61021cc8-0b64-4c2e-a533-d4420271b5e3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;두개의 인자를 갖고 있는데 튜닝하기가 힘들다&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;a3fc5197-9ac6-40f6-a6ee-73ccc390e4f0&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e6359b3f-7fd2-4d52-8b52-a6eb78d24512&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;고정 윈도우 카운터&lt;ul id=&quot;8b5fdc27-fbdf-47e2-b649-f15c96153030&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;책 참고&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a20b7f99-86e4-4ac0-b4ed-3caa42da5ac1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이동 윈도우 로그&lt;ul id=&quot;568f94db-eb72-42b5-917b-ddb4884b08d4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;책 참고&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;cf991cb8-5906-483b-9f96-0ac237d921f4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이동 윈도우 카운터&lt;ul id=&quot;e4e242f1-b9de-4e89-90b0-d0dce2939f23&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;책 참고&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;d3b87dfc-6fe7-4c9f-9825-d8682abcdca6&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;a85602fb-9e86-4f41-811f-612e4ebde131&quot; class=&quot;&quot;&gt;개략적인 아키텍처&lt;/h3&gt;&lt;ul id=&quot;1a3c88c7-7c11-4de0-beb6-0b9497de38f2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;얼마나 많은 요청이 접수 되었는지를 추적할 수 있는 카운터를 추적 대상 별 ( 사용자 별로 할것인가 IP별로 할것인가 아니면 API 엔드포인트나 서비스 단위로 ? )로 이 카운터의 값이 어떤 한도를 넘어서면 한도를 넘어 도착한 요청은 거부하는 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;375fbbe3-b0ce-48cb-b321-ba40adf33463&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그렇다면 이 카운터는 어디에 보관할 것인가 ?&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4bd035e2-7482-446e-bd91-e04684858fd4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터베이스는 디스크 접근때문에 느리니까 사용하면 안될것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;3349e85d-ebd3-48da-af3a-a1d632d2b40d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메모리상에 동작하는 캐시가 바람직한데 빠른데다 시간에 기반한 만료 정책을 지원하기 때문이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5532d390-7882-4595-b5d4-7285d67cbb1a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일례로 레디스는 처리율 제한 장치를 구현할 때 자주 사용되는 메모리 기반 저장장치로서 INCR과 EXPIRE의 두가지 명령어를 지원한다.&lt;ul id=&quot;8030bec2-8590-4db0-9226-38bf69b7867e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;INCR: 메모리에 저장된 카운터의 값을 1만큼 증가시킨다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;29774872-dd8b-4e6e-8d10-141d1b46c3d4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;EXPIRE: 카운터에 타임아웃 값을 설정한다. 설정된 시간이 지나면 카운터는 자동으로 삭제된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;857a5677-6de0-464b-9afe-59561b3b9606&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;7e379a28-7b2f-40ec-b0e9-bbaed9e2f6e3&quot; class=&quot;&quot;&gt;3단계 상세 설계&lt;/h1&gt;&lt;ul id=&quot;622a0a6c-3305-40af-88c4-382c5706cd54&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한 규칙은 어떻게 만들어지고 어디에 저장되는가 ?&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;526a8d62-0bbf-4373-8e80-c146b00b66ee&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리가 제한된 요청들은 어떻게 처리되는가 ?&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;f9a2a2e8-2314-4a50-b1ec-65aac23d4785&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;b1b8ff3a-6dbc-452e-ad69-857d08d3bd14&quot; class=&quot;&quot;&gt;처리율 제한 규칙&lt;/h2&gt;&lt;ul id=&quot;958459c3-2494-49eb-a017-c2efc2d1a00e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;규칙이 설정 파일인 경우는 디스크에 저장된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;fbdae6ef-8b64-4675-9a4d-c6fb39fe07a0&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;82675be9-02c9-459f-bd6a-ac8199afb8a6&quot; class=&quot;&quot;&gt;처리율 한도 초과 트래픽의 처리&lt;/h2&gt;&lt;ul id=&quot;ffa76d54-706e-4708-8131-d74871a81df5&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;경우에 따라서 제한에 초과된 트래픽을 버리는것만이 아닌 따로 모아놓고 나중에 처리할 수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;dc119b11-be42-4757-b771-5ec7d48dac98&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;9dd6e4de-951a-4e40-9ca9-6e2d11863f85&quot; class=&quot;&quot;&gt;처리율 제한 장치가 사용하는 HTTP 헤더&lt;/h3&gt;&lt;ul id=&quot;c6171026-347a-4375-9d8e-f156f19a872c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;HTTP 처리율 장치는 HTTP 응답 헤더를 통해 요청이 처리율 제한에 걸리기까지 얼마나 많은 요청을 보낼수 있는지, 자기 요청이 처리율 제한에 걸리고 있는지를 어떻게 감지하는지 를 알 수 있다.&lt;ul id=&quot;fb909935-6d22-44eb-87d8-351e7c1f6d7b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;X-Ratelimit-Remaining: 윈도 내에 남은 처리 가능 요청의 수&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;43de36d0-91b3-47a5-bbd5-08afda570e44&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;X-Ratelimit-Limit: 매 윈도마다 클라이언트가 전송할 수 있는 요청의 수&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1249d105-d0c7-4e26-aca1-7520edc2d937&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;X-Ratelimit-Retry-After: 한도 제한에 걸리지 않으려면 몇초 뒤에 요청을 다시보내야 하는지 알림&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;c2d1187e-4c07-48b6-bb1e-59263a3f214c&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;7a0fe0d3-d365-4475-936f-6d81571b25ef&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;사용자가 너무 많은 요청을 보내면 429 too many requests 오류를 X-Ratelimit-Retry-After 헤더와 함꼐 반환하도록 한다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;eceb74dd-df2d-41f4-83b0-800e56c93d4e&quot; class=&quot;&quot;&gt;상세 설계&lt;/h2&gt;&lt;ul id=&quot;c8fa92ca-86c3-49b8-94df-0e0648065422&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한 규칙은 디스크에 보관한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a23a6afd-92bf-4682-92b1-09b9e01d02d8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;작업 프로세스는 수시로 규칙을 디스크에서 읽어 캐시에 저장한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;3eebb710-c209-4870-83f6-43c1721bad37&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;클라이언트가 요청을 서버에 보내면 요청은 먼저 처리율 제한 미들웨어에 도달한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;70a0e137-9fee-4dfa-811c-2623c2f2e5ea&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한 미들웨어는 제한 규칙을 캐시에서 가져온다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e3f86d4a-0479-4668-b6c7-911c6d99781e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아울러 카운터 및 마지막 요청의 타임스탬프를 레디스 캐시에서 가져온다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;80da0ac6-ce1b-4f1f-904c-bdaa191a389d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가져온 값들에 근거하여 미들웨어는 요청을 처리한다.&lt;ul id=&quot;724d29b3-249c-424a-b8c6-f2ad262a610d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;제한에 안걸리면 API 서버로 보낸다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e33600c7-3b0a-48d5-b1e2-20f567701116&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;제한에 걸리면 429 에러를 클라이언트에 보내고 요청을 버릴수도 있고&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;985bc8cc-36a0-4dfd-9bd0-fb84ebd3ae49&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;요청을 큐에 넣어 보관할수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;463bbb21-0e8c-4417-8201-185810199d93&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;b32c419e-2ab0-459e-8215-069a29dab4c5&quot; class=&quot;&quot;&gt;분산 환경에서의 처리율 제한 장치의 구현&lt;/h2&gt;&lt;ul id=&quot;facdf3a1-5f41-410c-b868-b3ad620ba697&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;여러대의 서버와 병렬 스레드를 지원하도록 시스템을 확장하는 것은 &lt;strong&gt;경쟁조건&lt;/strong&gt;과 &lt;strong&gt;동기화&lt;/strong&gt;의 문제를 풀어내야 한다&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;251a937a-4cd8-4c02-8526-72223ce00363&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;0eae3668-95c3-4669-b2ec-977a8a567bc2&quot; class=&quot;&quot;&gt;경쟁조건&lt;/h3&gt;&lt;ul id=&quot;e8987098-1ea9-44bb-aa2d-32317e6d7574&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;레디스에서 카운터의 값을 읽는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8a53d6ad-3e7e-46d2-a872-c30df1603e3f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;count+1의 값이 임계치를 넘는지 본다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f0dbf274-8040-4d86-a5e5-3035f07dda45&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;넘지 않는다면 레디스에서 보관된 카운터 값을 1만큼 증가시킨다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d40b8ac1-50a1-40d3-b254-1de8e531029d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;병행성이 심한 환경에서는 각각 병렬로 count의 값을 읽어 다른 요청의 처리 상태는 상관하지 않고 count에 1을 더한 값을 레디스에 저장할 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ff84758c-9a89-4544-85ad-59b8e1992cb3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이런 경우 lock을 이용해서 처리하는것이 널리 알려진 해결책이지만 lock은 시스템의 성능을 떨어뜨린다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;c1933ce9-9214-4412-9468-3fce4544c289&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;락 대신 쓸수 있는 해결책 두가지가 있다.&lt;ol type=&quot;1&quot; id=&quot;0956bb5b-1868-4c91-80b2-1eb6712088e3&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;lua 스크립트&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;3ff11ba0-5ea0-42b1-8d7a-bc7486feaef4&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;정렬 집합&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;3c930bcf-54aa-4860-95df-23442abcd71c&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;a864a118-0a04-4afb-9c0d-12330255d7e0&quot; class=&quot;&quot;&gt;동기화 이슈&lt;/h3&gt;&lt;ul id=&quot;41864c53-85a1-4980-a22c-448cbfa274d6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;동기화는 분산환경에서 고려해야 할 또다른 중요한 요소다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d7eef6af-5120-491b-bf25-ff795569c5be&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;대규모 환경에서는 한대의 처리율 제한 장치로는 서버가 충분하지 않을수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;79aed9d7-1e07-444d-8e45-b88300f77ed9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한 장치 서버를 여러대 두게되면 동기화가 필요해 진다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;c2bef466-055d-433b-96b1-0505b9579682&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이에 대한 해결책중 하나는 스티키 세션을 활용하여 같은 클라이언트로의 요청은 항상 같은 처리율 제한장치로 보낼수 있도록 하는것이다.&lt;ul id=&quot;1e576844-75c3-46c1-961f-76f4c74d4318&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이 방법은 비추천&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d4f0fdfc-e411-4747-96a4-812910af54d9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;규모면에서 확장 가능하지도 않고 유연하지도 않다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9e835b2b-79dc-415d-8655-35357b5da6f9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;더 나은 방법은 레디스와 같은 중앙 집중형 데이터 저장소를 사용하는 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;b8f7727e-41f2-4997-8fb8-39616ecd8ba5&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;72c9ea9c-7cb5-4e91-9c02-da88c5fd427b&quot; class=&quot;&quot;&gt;성능 최적화&lt;/h3&gt;&lt;ol type=&quot;1&quot; id=&quot;f771e656-2d2a-428f-9193-f08f7df0a13e&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;데이터센터에서 멀리 떨어진 사용자를 지원하려다 보면 레이턴시가 증가할 수 밖에 없다.&lt;ul id=&quot;c15a1bde-f9eb-497f-bd26-c81b2e248b64&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;사용자의 트래픽을 가까운 에지서버로 전달하여 레이턴시를 줄인다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;65b65513-fcba-492c-a51b-81db88b66f7f&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ol type=&quot;1&quot; id=&quot;7fca25c8-79b3-484d-8980-10ca1cc6edeb&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;제한장치간의 데이터를 동기화할 때 최종 일관성 모델을 사용하는 것이다.&lt;ul id=&quot;9c7c1b90-2a5b-49fb-9f9c-201aa4e25ffc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;6장을 참고&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;d84d2dc8-084c-4bfc-af5b-a19af64114a3&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;6c2b7e13-2280-4e0f-a917-42e70693f813&quot; class=&quot;&quot;&gt;모니터링&lt;/h3&gt;&lt;p id=&quot;fe293a43-c6b5-42ff-99c7-e6e3a77c7d10&quot; class=&quot;&quot;&gt;처리율 제한 장치를 설치 한 후에 모니터링을 통해 효과적으로 작동하는지 데이터를 모을 필요가 있다.&lt;/p&gt;&lt;p id=&quot;3aa87f5c-b4ec-4419-a0ec-49d3f7724e3b&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ol type=&quot;1&quot; id=&quot;808f31c2-b3f0-402f-9b90-82c681517f54&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;채택된 처리율 제한 알고리즘이 효과적이다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;c2bef525-a7e1-4573-8113-7b4edce68283&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;정의한 처리율 제한 규칙이 효과적이다.&lt;/li&gt;&lt;/ol&gt;&lt;ul id=&quot;a7617aaf-3a7f-42ec-bd64-27102838b3d2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;위의 두가지를 모니터링을 통해 확인하자.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;991caa97-22c8-4eb5-875c-ab688e36ff65&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;78f73d87-f6fb-4a4b-b2e0-10320d2d49ef&quot; class=&quot;&quot;&gt;4단계 마무리&lt;/h1&gt;&lt;ul id=&quot;409da71e-1f69-4a76-b511-adb128402399&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;hard 또는 soft 처리율 제한&lt;ul id=&quot;a603ab48-457c-4555-9ab0-7c39eec68c0b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;hard 제한: 요청의 개수는 임계치를 절대 넘어설수 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0b982c18-24c3-4f72-9967-52d1d59ecb67&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;soft 제한: 요청 개수는 잠시 동안은 임계치를 넘을수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b1067710-5818-499d-ac0c-ac53783fdb7d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다양한 계층에서의 처리율 제한&lt;ul id=&quot;e5b8aac0-0cbf-49d6-abbd-81fd0a6f7f67&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이번장은 애플리케이션 계층에서의 처리율만 확인했지만 iptables를 사용하면 네트워크 계층에서도 처리할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2a7cc294-a6d7-4ec7-8aae-cfe25eb2e8ce&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한을 회피하는 방법&lt;ul id=&quot;975e3b92-0435-4731-a4d5-62e03b373efd&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;클라이언트 측 캐시를 사용하여 API 호출을 줄인다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6b0bb18b-4ca7-43c0-8255-8b9c400a99d0&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;처리율 제한의 임계치를 이해하고 짧은 시간 동안 너무 많은 메시지를 보내지 않도록 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;eb4bef5c-f8fd-4c07-ac2b-d9e77309c397&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예외나 에러를 처리하는 코드를 도입하여 클라이언트가 예외적 상황으로부터 우아하게 복구될 수 있도록 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d5d56045-7e49-4d1b-8e0d-e92a7f780f1f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;재시도 로직을 구현할 때는 충분한 백오프 시간을 둔다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;00391cfa-ae29-4464-9a52-afbe1dced5ef&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;dfad1d61-2c68-4551-8c6d-2709c91c0364&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;div class=&quot;n2t_comment&quot;&gt;&lt;p&gt;
&lt;/p&gt;&lt;p class=&quot;block-color-gray&quot;&gt;&lt;a href=&quot;https://boltlessengineer.github.io/Notion2Tistory&quot;&gt;Uploaded by Notion2Tistory v1.1.0&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;</description>
      <category>book/대규모 시스템 설계 기초</category>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/123</guid>
      <comments>https://kingds.tistory.com/123#entry123comment</comments>
      <pubDate>Tue, 31 Aug 2021 21:12:18 +0900</pubDate>
    </item>
    <item>
      <title>3장 시스템 설계 면접 공략법</title>
      <link>https://kingds.tistory.com/122</link>
      <description>&lt;article id=&quot;31df0d72-72ed-4001-9a04-7914ee023d02&quot; class=&quot;page sans Notion_P&quot;&gt;&lt;div class=&quot;page-body&quot;&gt;&lt;h1 id=&quot;49bd00ce-6dcf-40aa-942f-c15e1df7c9ef&quot; class=&quot;&quot;&gt;효과적 면접을 위한 4단계 접근 법&lt;/h1&gt;&lt;p id=&quot;a393475d-cda5-41f5-864c-18f9e5612e41&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;5a9baaf5-2bf4-41bf-a331-0a63b7a0e28d&quot; class=&quot;&quot;&gt;1단계 문제 이해 및 설계 범위 확정&lt;/h2&gt;&lt;ul id=&quot;31846a0c-27d3-4e7e-9dac-ec0c3a64bee3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템 설계 면접시 바로 답을 내지 말자&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;16eb3d25-6726-4dcc-a515-411b68c01bbb&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;요구사항을 완전히 이해하지 않고 답을 내놓는 행위는 아주 엄청난 부정적인 신호다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;386cb352-26ee-42c9-983c-930749b19093&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;답부터 들이밀지말고 속도를 늦춰라 깊이 생각하고 질문하여 요구사항과 가정들을 분명히 하라&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;75721021-3d23-47f7-af7e-20798e5c4d05&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;올바른 질문, 올바른 가정을 하는것 그리고 시스템 구축에 필요한 정보를 모으는것이 중요하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;e6d54945-6964-4c50-9963-a3edc6d1bad5&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;e177ad4b-1054-4cdf-ac64-8db73e092f16&quot; class=&quot;&quot;&gt;2단계 개략적인 설계안 제시 및 동의 구하기&lt;/h2&gt;&lt;ul id=&quot;c74f17e9-c7a9-4052-abe9-e86ef568e267&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;설계안에 대한 최초 청사진을 제시하고 의견을 구하라&lt;ul id=&quot;55d4fd74-eba4-4f1e-a078-b3fdb3c78cc9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;면접관을 마치 팀원인것처럼 대하라&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;dbd7ad5c-8cc8-40ea-a54b-28bc4e8c5873&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;8da67516-3357-4856-a667-1448cae538f2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;화이트보드나 종이에 핵심 컴포넌트를 포함하는 다이어그램을 그려라&lt;ul id=&quot;c671c827-5613-40a3-b38a-df00b9d6cbe6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;클라이언트, API, 웹 서버, 데이터 저장소, 캐시 CDN, 메시지 큐 같은것들이 포함된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;71f4279e-c211-4bff-92ef-49f8e89dd138&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;b6289ffb-fd06-43e9-9d88-414b502ac5ae&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이 최초 설계안이 시스템 규모에 관계된 제약사항들을 만족하는지를 개략적으로 계산해보라.&lt;ul id=&quot;6ed888bd-afbd-4978-9e88-331d0aa7c3ba&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이런 추정이 필요한지는 미리 면접관에게 물어보도록 하자.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;257c6fbb-0e48-41f4-9298-a86e2cf0f578&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;ed071f39-96dd-4788-9be8-e96e65a213eb&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;520e5792-1798-42a1-baec-9c6a8adfd89b&quot; class=&quot;&quot;&gt;3단계 상세 설계&lt;/h2&gt;&lt;ul id=&quot;d7a817d4-5237-4058-b354-9a2de9bf5c28&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템에서 전반적으로 달성해야 할 목표와 기능 범위 확인&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6b78b9f6-fa77-4ec7-9800-aaff4d349126&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;전체 설계의 개략적 청사진 마련&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0efd661a-67f7-48da-9c50-a5ed2b7d7551&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;해당 청사진에 대한 면접관의 의견 청취&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;37311df5-6f37-46e6-8e24-30eba1d58f3d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;상세 설계에서 집중해야 할 영역들 확인&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;422226dc-a785-4908-b1be-820f8caf83d7&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;fdfa3d74-a23a-4019-bc2e-a5131f0e44c0&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템의 성능 특성에 대한 질문을 던질것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a4b48f85-86d5-4c78-abe5-0c3f5da3c0cb&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그 경우 질문 내용은 시스템의 병목 구간이나 자원 요구량 추정치에 초점이 맞춰져 있을 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e0fd3fc3-7460-4af4-9fdf-59be3404c53b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;대부분의 경우 면접관은 우리가 특정 시스템 컴포넌트들의 세부사항을 깊이 있게 설명하는 것을 보길 원한다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;9260896a-185a-4981-bcfa-2fc75285033a&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;p id=&quot;5873ee74-5c8a-4188-822c-7ba20026d6d2&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;4d8c8b54-7176-49ca-80dd-bca73de3df25&quot; class=&quot;&quot;&gt;4단계 마무리&lt;/h2&gt;&lt;ul id=&quot;124cf6b6-803e-4ad9-b79f-7c59da3e82a7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;면접관이 더 개선 가능한 지점을 찾아달라고 할 가능성이 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;c961ccc3-ccac-4ed3-a545-3acdbef89103&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이럴때 완벽하다느니 찾을곳이 없다느니 이런말은 하지 말자&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;7fb0177a-1dc8-4da3-8445-62e661968c86&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;6faaae54-ba48-4d5f-99fd-653333d8804e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;우리가 만든 설계를 다시 요약해주는 것도 도움이 될 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;884e1a2a-2c6b-479c-81c0-86597dfd96d7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;우리가 해결책을 제시했을 경우 특히 중요하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;4b3158b5-7283-4826-b7c1-e8acec798637&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;ba8234fe-f1fd-4600-b5d7-9d5f234b3a43&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;오류가 발생하면 무슨일이 생기는지 ( 서버오류, 네트워크 장애 등 ) 따져보면 흥미로울 것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;63297003-76de-4ce8-999a-b87e047b0818&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;운영 이슈도 논의할 가치가 충분하다.&lt;ul id=&quot;6ff30d41-4733-41d3-ac4a-088bc3fac33c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메트릭은 어떻게 수집하고 모니터링 할것인가 ?&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;81529c73-f6e2-47c6-b953-19fd12c2e5f5&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로그는 ?&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4b4c6c3f-f92c-4984-915c-981cf6ecdce4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템은 어떻게 배포해 나갈것인가 ?&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;015cfcec-02af-4b0d-897c-7da90929ef81&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;미래에 닥칠 규모 확장 요구에 어떻게 대처할 것인지도 흥미로운 주제다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;6615c0a3-1be8-4b9a-93b3-b76f9b152a1e&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;div class=&quot;n2t_comment&quot;&gt;&lt;p&gt;
&lt;/p&gt;&lt;p class=&quot;block-color-gray&quot;&gt;&lt;a href=&quot;https://boltlessengineer.github.io/Notion2Tistory&quot;&gt;Uploaded by Notion2Tistory v1.1.0&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;</description>
      <category>book/대규모 시스템 설계 기초</category>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/122</guid>
      <comments>https://kingds.tistory.com/122#entry122comment</comments>
      <pubDate>Tue, 31 Aug 2021 21:11:50 +0900</pubDate>
    </item>
    <item>
      <title>2장 개략적인 규모 추정</title>
      <link>https://kingds.tistory.com/121</link>
      <description>&lt;article id=&quot;b7c3da27-212f-4a1b-8cd8-b1a48c8f142f&quot; class=&quot;page sans Notion_P&quot;&gt;&lt;div class=&quot;page-body&quot;&gt;&lt;p id=&quot;e1ad6bad-1307-4954-a1b5-3be1b0ea7927&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;2f70aefa-42ac-48ba-bced-9c049d4ce027&quot; class=&quot;&quot;&gt;2의 제곱수&lt;/h1&gt;&lt;ul id=&quot;c5469095-ade4-46f3-a6df-21eca0922ad7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;분산 시스템에서 다루는 데이터 양은 엄청나게 커질 수 있으나 그 계산법은 기본을 크게 벗어나지 않는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;3dc40d4d-106d-4c76-b1bc-d82b6596d724&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터 볼륨의 단위를 2의 제곱수로 표현하면 어떻게 되는지를 알아야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;707b3575-d668-4350-bcaa-1551e07b849a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;최소 단위는 1바이트고 8비트로 구성된다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5b42781c-a6cd-4398-84dd-42be1bbf7876&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아스키 문자 하나가 차지하는 메모리 크기는 1바이트다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;96092eaa-923f-4c04-9823-22a1bcec491f&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;37920197-70a2-4d34-84af-51bdbc8f0306&quot; class=&quot;&quot;&gt;모든 프로그래머가 알아야 하는 응답지연 값&lt;/h1&gt;&lt;p id=&quot;e97a6818-caf3-4fea-a522-fb7bbc8080eb&quot; class=&quot;&quot;&gt;(수치 이미지 추후 추가)&lt;/p&gt;&lt;ul id=&quot;54e26f3d-4ad1-4056-9052-cb018e86fa25&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;제시된 수치들을 분석하면 다음과 같은 결론이 나온다.&lt;/li&gt;&lt;/ul&gt;&lt;ol type=&quot;1&quot; id=&quot;3b955e28-d395-4057-917a-6f8f19930f4c&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;메모리는 빠르지만 디스크는 아직도 느리다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;28db1b4e-55f4-4ef3-8b74-a01e5bb16a99&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;디스크 탐색(seek)은 가능한 한 피하라&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;0f4ca68d-8b2b-4747-915c-505a33194117&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;단순한 압축 알고리즘은 빠르다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;58213f8b-6874-4e01-a269-603fa05b43d0&quot; class=&quot;numbered-list&quot; start=&quot;4&quot;&gt;&lt;li&gt;데이터를 인터넷으로 전송하기 전에 가능하면 압축하라.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;cb1c9e9d-e9c5-4e78-a6b0-4ae2e0933a97&quot; class=&quot;numbered-list&quot; start=&quot;5&quot;&gt;&lt;li&gt;데이터 센터는 보통 여러 지역에 분산되어 있고 센터들 간에 데이터를 주고받는 데는 시간이 걸린다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;31b97e31-545e-4475-9ec8-dd0420e04e45&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;1c4f8dd6-9f73-413b-88e7-a4dd931b25e6&quot; class=&quot;&quot;&gt;가용성에 관련된 수치들&lt;/h1&gt;&lt;ul id=&quot;0577de6b-eebf-4cf2-8f5b-a4b40485d885&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;고가용성은 시스템이 오랜 시간 동안 지속적으로 중단 없이 운영될 수 있는 능력을 지칭하는 용어다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8f44d6c5-a17b-48c3-ae4c-102738a54403&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;고가용성을 표현하는 값은 퍼센트로 표현한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2c8769f8-0404-4348-aa26-f09e8c0e6c2b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;100%는 시스템이 단 한번도 중단된 적이 없었음을 의미한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1ee51f5f-f6b3-435e-b2e0-7cd31bf8a096&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;SLA는 서비스 사업자가 보편적으로 사용하는 용어로 서비스 사업자와 고객 사이에 맺어진 합의를 의미한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;572321f6-535c-452b-b726-7911fa031618&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이 합의에는 서비스 사업자가 제공하는 서비스의 가용시간 ( uptime ) 이 공식적으로 기술되어 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;38454dd3-2d30-43ca-8d3c-b425bfb99bdc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아마존, 구글, 마이크로소프트 같은 사업자는 99% 이상의 SLA를 제공한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ea302ace-d4f2-44a1-b795-7a0ff0f38030&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가용시간은 관습적으로 숫자 9를 사용해 표시한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8ee477a9-7b0d-4b89-ba81-21ebac30d005&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;9가 많을수록 좋다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;226296f7-d3c8-4387-9e34-eae9c3f1301d&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;p id=&quot;2e958876-9991-46eb-9c64-099a7d447201&quot; class=&quot;&quot;&gt;(표 나중에 추가 )&lt;/p&gt;&lt;p id=&quot;56656a8e-2637-4fa9-b152-0ff639372e58&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;b03193ae-57e3-48a8-a076-63d95e1a3a10&quot; class=&quot;&quot;&gt;예제: 트위터 QPS와 저장소 요구량 추정&lt;/h1&gt;&lt;ul id=&quot;82e2a1d9-6c31-43de-975b-173350ed13bd&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가정&lt;ul id=&quot;edda1323-3bc7-4c3e-8b9f-2257014ca8c9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;월간 능동 사용자는 3억명이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;adebb697-a5a7-41ce-b503-54e064687b02&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;50%의 사용자가 트위터를 매일 사용한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;35020559-01c7-47a6-8443-8ef00e280bdc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;평균적으로 각 사용자는 매일 2건의 트윗을 올린다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6e00ff08-a2c1-47d7-afe9-fe534a6a879c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;미디어를 포함하는 트윗은 10% 정도다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d2ade78a-fb10-4094-987c-537a2d4531cc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터는 5년간 보간된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;43a3e78c-b86a-4039-9a19-b716d078ee42&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;4aebd651-c23a-4779-982c-428c4de68a2d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;추정&lt;ul id=&quot;8f3d6e1e-5519-45f8-9ae6-64e340844a36&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;QPS (query per second) 추정치&lt;ul id=&quot;8bfe41e5-1722-49e2-b451-00ebe9550e49&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일간 능동 사용자 = 3억 * 50% = 1.5억&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;dfaebaba-9b13-4cb0-9e7b-8429960bea6f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;QPS = 1.5억 * 2트윗 / 24시간 / 3600초 = 약 3500&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;af90f14a-32a6-4cd3-aad8-b6e29b3196dd&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;최대 QPS = 2 * QPS = 7000&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;b40258a1-bcf6-4127-9dd0-8d8d78941ca5&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;bdc2e4b7-bc66-4e56-bfec-c89e12091026&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;미디어 저장을 위한 저장소 요구량&lt;ul id=&quot;fc434066-2c3e-4368-aae8-e5dbe24b7c98&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;평균 트윗 크기&lt;ul id=&quot;2787f262-6f87-48ff-a9eb-78fb71dfae0f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;tweet_id에 64바이트&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;339503e4-9a61-41c8-835a-1e0992f73a4a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;텍스트에 140바이트&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8826d258-1251-45cb-979f-16f9020f3317&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;미디어에 1MB&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0af781e1-1e5a-42d1-abb9-b1fed3c4e01a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;미디어 저장소 요구량 = 1.5억 * 2 * 10% * 1M =  30TB / 일&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;270eca39-dfb9-4a2a-b566-637a823b8b83&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;5년간 미디어를 보관하기 위한 저장소 요구량 = 30TB * 365 * 5 = 55PB&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;8c6cc800-9b49-4648-9e4f-8623db48e1a3&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;52df5574-7bd5-4f41-b3fc-e5bde92f5346&quot; class=&quot;&quot;&gt;팁&lt;/h1&gt;&lt;p id=&quot;f110eac8-cd82-4133-a02c-5f21c3d9a156&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;94a10241-bc3c-4c5f-aeee-ef27fb4c719c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;면접시에 완벽하게 계산하려고 하지말고 근사치를 활용하여 시간을 절약하자&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2608179e-aac3-4082-8028-1b12edc43104&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가정들은 적어두라 나중에 살펴볼수 있게&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4b5ade75-fac0-42d5-aab3-e03ff7f66dc1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;단위를 붙여라 5라고만 적으면 5mb인지 tkb인지 알수가 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8e46abd3-9e4f-44cf-9a04-755c399c3673&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;많이 출제되는 문제는 QPS, 최대 QPS, 저장소 요구량, 캐시 요구량, 서버 수 등을 추정하는 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;459949c6-226c-4f64-853d-af6c9faf17a6&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;div class=&quot;n2t_comment&quot;&gt;&lt;p&gt;
&lt;/p&gt;&lt;p class=&quot;block-color-gray&quot;&gt;&lt;a href=&quot;https://boltlessengineer.github.io/Notion2Tistory&quot;&gt;Uploaded by Notion2Tistory v1.1.0&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;</description>
      <category>book/대규모 시스템 설계 기초</category>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/121</guid>
      <comments>https://kingds.tistory.com/121#entry121comment</comments>
      <pubDate>Tue, 31 Aug 2021 21:11:26 +0900</pubDate>
    </item>
    <item>
      <title>1장 사용자 수에 따른 규모 확장성</title>
      <link>https://kingds.tistory.com/120</link>
      <description>&lt;article id=&quot;074b99b7-5968-4070-810b-148af9e6d575&quot; class=&quot;page sans Notion_P&quot;&gt;&lt;div class=&quot;page-body&quot;&gt;&lt;p id=&quot;8447b781-f515-44c8-a2f1-449613b7b56d&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;351149b1-2bb1-47fd-a470-6fb17549d13d&quot; class=&quot;&quot;&gt;단일 서버&lt;/h1&gt;&lt;ul id=&quot;8df7ea8f-ace5-4422-9196-256a6591cdfd&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;모든 컴포넌트가 단 한대의 서버에서 실행되는 간단한 시스템&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1bab4485-9532-48e7-860f-0be04cb5ccf6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;DB, 웹, 캐시 등이 전부 서버 한대에서 실행된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;a1c6a4a3-cbed-431c-bcc5-fcd82b0fc1c6&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;aa128f3a-818d-40d1-99b4-b54fa2547f1f&quot; class=&quot;&quot;&gt;요청처리흐름&lt;/h2&gt;&lt;ul id=&quot;926dc2c7-74c8-42f1-a3e3-bee90627c94e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;사용자가 웹브라우저에 주소를 입력하면 브라우저에 캐시에 있는 도메인과 연결된 서버의 주소를 찾는다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9729b1ba-ae90-43f1-b383-1c0af71eacb4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;없으면 DNS로 요청을 해서 서버의 주소를 가져온다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0a872688-1be2-4451-accc-91fc8fecab34&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;서버의 주소로 요청을 보낸 후 응답을 받는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9e93d3d4-9883-43b2-9590-1ea33c4bdb2e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;응답을 토대로 브라우저가 화면을 렌더링 해준다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;672ee1ea-485f-4767-a25b-3ded4ed6e2fc&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;de1aca4b-64c9-4312-bcee-7aa20f8a81f3&quot; class=&quot;&quot;&gt;데이터 베이스&lt;/h1&gt;&lt;ul id=&quot;b41ec04c-0ce2-4604-972c-a06278dada04&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;위의 흐름에서 데이터베이스는 웹 서버와 통신을 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1aec245d-4a42-4f50-abf3-aede90663a43&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;비관계형 데이터베이스는 4가지로 분류된다.&lt;ul id=&quot;09ebb553-f3f4-44cc-b6c2-4ca35ce06157&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;키-밸류 저장소 ( etcd )&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;636f9b46-d606-414f-83ac-b7e1952b2342&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그래프 저장소&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1657ef30-d62a-439f-b97b-1e5d86763e59&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;칼럼 저장소&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;3c4825fe-c7be-4a89-bf0f-3717d7493d06&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;문서 저장소 ( 몽고 )&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;015e863d-4bbe-42db-9a58-bfa0ed65c432&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;비관계형 데이터베이스는 조인 을 지원하지 않는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;83d034a6-0945-4957-8529-86da716892fc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;비관계형 데이터베이스가 바람직한 경우&lt;ul id=&quot;dc953d4c-7743-4d14-8155-204fcdec212d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아주 낮은 응답 지연시간이 요구되는 경우&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;15c41b23-4ad2-4007-af69-320205690256&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다루는 데이터가 비정형 이라 관계형 데이터가 아님&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;eb84b9de-ddcc-4b00-8bce-7008348f1613&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터 (JSON, YAML, XML 등) 를 직렬화 하거나 역직렬화 할수 있기만 하면 됨&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;21b6dcd2-2e44-4b59-b150-6825070378df&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아주 많은 양의 데이터를 저장할 필요가 있음&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;fef8dfc8-8a1a-40dc-8c3d-7c7221fbcd97&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;0e75ab17-1bf8-4013-a531-7d717f1ec8b9&quot; class=&quot;&quot;&gt;수직적 규모 확장 vs 수평적 규모 확장&lt;/h1&gt;&lt;ul id=&quot;9c85588b-a8c9-4b7a-97f2-ea10475506e1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스케일 업과 스케일 아웃&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;69b46fdc-cdce-48c4-b01e-3d01ff896cc7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스케일 업&lt;ul id=&quot;f3730c1f-2e8b-4e4c-af47-7ea0d1fb8105&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;한대의 서버에 CPU나 메모리를 증설하는 방식&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ade31a84-4c4c-4cdc-b34b-57597c937eba&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스케일 아웃&lt;ul id=&quot;65871929-4a03-47b1-b778-74fa717139ff&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;서버를 여러대 추가하여 로드밸런스로 연결시키는 방식&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;e0b5b24b-3afd-448b-b2b9-64c92eef8963&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;2cdadbc7-7b1c-4fe2-a07d-8d70a0dadfd7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스케일업의 단점&lt;ul id=&quot;af81aa3c-a0e0-4450-84a8-0605558b56e6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;무한대로 CPU와 메모리를 증설할 수 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b42ac1ac-aa3b-447f-84bf-acfbf032e92d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;자동복구 ( failover ) 방안이나 다중화 방안을 제시하지 않는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e900ef53-7544-4697-b373-ee60accfc985&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;서버에 장애가 발생하면 웹이나 앱이 완전히 죽는다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;e9536218-0159-4df8-903c-da938eb48aa0&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;b80438df-1aca-4c89-a0f5-6474771fd47f&quot; class=&quot;&quot;&gt;로드밸런서&lt;/h2&gt;&lt;ul id=&quot;bd0a7f5e-9ebc-448e-89c9-cb2481710d3d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;부하분산집합에 속한 웹 서버들에게 트래픽 부하를 고르게 분산하는 역할&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;442dd1e7-d19c-4423-b6a9-c64a2202512e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로드밸런서는 처음 흐름과 다르게 도메인 주소와 연결된게 웹서버의 IP가 아닌 로드밸런서의 공개 IP 주소와 연결된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b696832a-9556-4621-a91c-eed6bf980a7c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;더 나은 보안을 위해 서버간 통신( 로드밸런서와 서버)에는 사설 IP주소가 이용된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;0a37f7a3-c10c-4e84-af99-6fa5bed2b098&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;71efac54-52e8-4542-b5d5-289cbc2de0bb&quot; class=&quot;&quot;&gt;데이터베이스 다중화&lt;/h2&gt;&lt;ul id=&quot;f618aad5-1e9b-4216-be99-2a67eedb2f21&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;보통 서버사이에 master서버와 slave서버 관계를 설정하고 데이터 원본은 master에 저장하고 사본은 slave에 저장하는 방식이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6a6934a9-6524-48b6-9772-4c87a296e55c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;write operation ( 쓰기 연산) 은 마스터에만 지원한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;74e1ea43-13c0-4d7a-99c0-65f09132e7c6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;슬레이브는 마스터로부터 사본을 전달받으며 &lt;strong&gt;읽기 연산&lt;/strong&gt;만 지원한다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d63ca0f7-409d-4a3f-b31d-44aeacc6f8f0&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터베이스를 변경하는 명령어들 가령 insert, delete, update 등은 주 데이터베이스로만 전달되어야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;867b6526-c22c-4a6c-a097-ad8fb0e48353&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;대부분의 애플리케이션은 읽기 연산의 비중이 매우 높다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4c7a5fab-2613-4a82-989a-4a579a8c1a36&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그래서 슬레이브 서버를 많이두고 마스터서버를 적게 둔다.&lt;h3 id=&quot;6d6f69c3-8a79-4e5e-ab51-34d0189316e1&quot; class=&quot;&quot;&gt;장점&lt;/h3&gt;&lt;ul id=&quot;ea382fcb-b8d0-4bc2-8390-b348f453a64a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;더 나은 성능&lt;ul id=&quot;ecbcbae1-6d61-4794-9f48-7514086e624a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;master-slave 다중화 모델에서 모든 데이터 변경 연산은 주 데이터베이스 서버로만 전달되는 반면 읽기 연산은 부 데이터베이스 서버들로 분산된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;39856d27-b00c-4016-8b62-71005321bc5f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;병렬로 처리될수 있는 쿼리의 수가 늘어나므로 성능이 좋아진다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f2680af7-9038-43a1-a0c7-2ec2b211b595&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;안전성&lt;ul id=&quot;c0288789-0bac-4446-b5b8-f4fc573de3df&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;디비 서버 중 몇개가 파괴되어도 데이터는 보존된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;82637c83-94e2-4f51-a059-4253a3e51172&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가용성&lt;ul id=&quot;c1c372a6-5040-4970-afde-902da825d8c0&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;디비의 데이터를 여러지역에 복제해둠으로써 하나의 디비서버에서 장애가 일어나도 다른 서버에 있는 데이터를 가져와 계속 서비스할 수 있게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;c477c578-de1a-46f7-9c78-b71c01ea5733&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h3 id=&quot;09bb321a-bcee-443d-80ff-670da4b00e03&quot; class=&quot;&quot;&gt;시나리오&lt;/h3&gt;&lt;ul id=&quot;2308f05b-9bc5-44d8-843e-de5d79f0c33f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;부 서버가 한대뿐인데 다운됐을 경우&lt;ul id=&quot;ceed78e4-e13a-4535-845f-0db541caf789&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;읽기 연산이 모두 마스터 디비로 전달&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;06738e8a-871c-44b3-95d3-6d8f8e8b844d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;즉시 새로운 슬레이브 디비 서버가 장애난 슬레이브 서버 디비를 대체&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;56ecb546-bda8-4d5d-a0ea-96ea3176938b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;부 서버가 여러대인데 그중 한대가 다운됐을 경우&lt;ul id=&quot;9db6bd51-372a-4e1f-9064-6cd3305d2bbc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;읽기 연산이 나머지 슬레이브 디비로 분산되며&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d56cd2ae-34d8-4036-943d-dc7919b8dff4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;새로운 슬레이브 디비 서버가 장애난 슬레이브 디비서버를 대체&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6dcc0a1f-bf23-4602-852e-5ba5b6f3c3e8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;주 디비서버가 다운되면&lt;ul id=&quot;ec7f9448-5849-4f1f-9705-4f2bbba695a8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;부 디비서버가 한개일 경우&lt;ul id=&quot;3e25a724-6d12-4ca0-a44b-d9d0722b8ad9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;슬레이브 서버중 한대가 새로운 마스터 서버가 될것이며 모든 디비 연산은 일시적으로 새로운 마스터 서버에서 수행된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5d51bf16-bdba-4846-a85b-20406f688aa3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그리고 새로운 슬레이브 서버가 추가된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8c41ace8-d6b4-4311-b63b-6cf85db3092e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;하지만 이런 경우 부 서버에 보관된 데이터가 최신 상태가 아닐 수 있기 때문에 복구 스크립트를 돌려서 추가 해야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1bf47c45-0bda-4ede-a435-e49cd6246468&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다중 마스터나 원형 다중화 방식을 도입하면 이런 상황에 대처하는데 도움이 될수도 있지만&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1ad48093-7aaf-4058-83d2-1185b26e3b2a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;해당 구성은 훨씬 복잡하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;7b356008-9a51-4371-82f1-5daad825f5ca&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;41066a96-5af6-4c02-b2d6-2d84392996cd&quot; class=&quot;&quot;&gt;캐시&lt;/h1&gt;&lt;ul id=&quot;9dee8083-20cf-4745-b5ce-5a181ffc3e84&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시는 값비싼 연산 결과 또는 자주 참조되는 데이터를 메모리 안에 두고 뒤이은 요청이 보다 빨리 처리될 수 있도록 하는 저장소다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2fdd0ced-05a8-448d-acfe-84e4d484b745&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;애플리케이션의 성능은 데이터 베이스를 얼마나 자주 호출하느냐에 크게 좌우되는데 캐시는 그런 문제를 완화할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;43325728-fbb5-4fa1-854f-275492893ebd&quot; class=&quot;&quot;&gt;캐시계층&lt;/h2&gt;&lt;ul id=&quot;953d11c2-afc5-4f43-a8dc-4de35aeb0e32&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터가 잠시 보관되는 곳으로 데이터베이스보다 훨씬 빠르다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;22185f69-a4f3-4978-b7d3-c46f441dd99a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;별도의 캐시 계층을 두면 성능이 개선될 뿐 아니라 데이터베이스의 부하를 줄일수 있고&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;292246d2-037d-4a2c-992f-7b042aa077f5&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;별도의 캐시 계층을 두면 성능이 개선될 뿐 아니라 데이터베이스의 부하를 줄일 수 있고 캐시 계층의 규모를 독립적으로 확장시키는것도 가능해 진다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;5ff3fc4d-18fa-4a9a-825e-655335d58aec&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;ad45ae86-8496-4204-ac55-5cc98a9f3ffb&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;요청받은 웹 서버는 캐시에 응답이 저장되어 있는지를 본다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9c5a4acf-cf5c-48c2-80dc-1d9521bb058b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;만일 저장되어 있다면 해당 데이터를 클라이언트에 반환한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ca7bc472-6c65-4189-b742-5d36c79e9247&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;없는 경우 데이터베이스에 쿼리를 날린 후 데이터를 찾아 캐시에 저장한 뒤 클라이언트에 반환한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5965fe2a-67e9-46f8-8fee-b34b72e6a81e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이러한 캐시 전략을 읽기 주도형 캐시 전략 이라고 부른다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;24a0e4a0-5937-491c-9b88-0410a2f3d5de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다양한 캐시전략이 있는데 캐시할 데이터 종류, 크기, 액세스 패턴에 맞는 캐시전략을 선택하면 된다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;7a0f6786-5cca-4c88-aad4-296845e6b14e&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;c662a744-3a76-49df-bf61-d391f32d7adc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시 서버를 이용하는 방법은 간단한데 대부분의 캐시 서버들이 일반적으로 널리 쓰이는 프로그래밍 언어로 API를 제공하기 때문이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;18b2d07c-c6b8-47f7-ab64-6d772061a606&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;a49820ea-ea72-48c5-b88c-5024848b015c&quot; class=&quot;&quot;&gt;캐시 사용시 유의할 점&lt;/h2&gt;&lt;ul id=&quot;28c66392-a5c8-4c06-a614-3a68ccd1c0b2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시는 어떤 상황에서 바람직 한가 ?&lt;ul id=&quot;b529984b-b8d0-4d5e-a711-0e1670a0aac2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터 갱신은 자주 일어나지 않지만 참조는 빈번하게 일어난다면 바람직하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;c9d0ad7b-d294-4d8a-a928-d5ff29f08a8b&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;7d9a89e4-ecec-4d56-be60-fd8abcd1df21&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;어떤 데이터를 캐시에 두어야 하는가?&lt;ul id=&quot;05f85263-51db-43b9-917b-cad44354dccf&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시는 데이터를 휘발성 메모리에 두므로 영속적으로 보관할 데이터를 캐시에 두는 것은 바람직 하지 않ㄴ다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d000eab0-a97a-4428-a970-48b8d63a40c7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예를 들어 캐시 서버가 재 시작되면 캐시 내의 모든 데이터는 사라진다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6d2387f5-0641-4bab-8cf1-f8f4a8e9b1bf&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;중요한 데이터는 여전히 지속적 저장소(persistent data store)에 두어야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;2bd06ebc-f495-4bbc-b658-932ac8b5aabd&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;bdfc7436-c601-4358-a2b1-c726573b143d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시에 보관된 데이터는 어떻게 만료 되는가 ?&lt;ul id=&quot;726954d6-b44f-48e6-8389-e4e1fd47ee18&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이에 대한 정책을 마련해 두는것은 좋은 습관이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b1aea0a9-a7b9-4db5-a3cf-50feed4a714d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;만료된 데이터는 캐시에서 삭제되어야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8773cafb-fa6f-4997-870a-debaf5b725de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;만료 정책이 없으면 데이터는 캐시에 계속 남게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e148029e-d9e4-441e-89b7-51289ca7f399&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;만료 기한은 너무 짧으면 곤란한데 데이터베이스를 너무 자주 읽게 될것이기 떄문이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;2752c7f9-2bf3-43fc-8e06-0890ba65cd17&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;너무 길어도 곤란한데 원본과 차이날 가능성이 높아지기 때문이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;1cd46003-33f9-4a97-a55d-2db567be930d&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;c9a2849b-5d32-47ab-a28c-d7a1bb8cbd2b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일관성은 어떻게 유지되는가 ?&lt;ul id=&quot;172efde2-6922-4cfd-9beb-ab516ef9ebf6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;일관성은 데이터 저장소의 원본과 캐시 내의 사본이 같은지 여부다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;fb29ce5b-04ca-40c3-afb1-17c093a7546b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;저장소의 원본을 갱신하는 연산과 캐시를 갱신하는 연산이 단일 트랜잭션으로 처리되지 않는 경우 이 일관성은 깨질수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b41e1053-987a-46cb-90ca-caedad544994&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;여러 지역에 걸쳐 시스템을 확장해 나가는 경우 캐시와 저장소 사이에 일관성을 유지하는것은 어려운 문제다&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;ee9c5cdf-9b51-4fdd-bf22-8c403f475670&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4abd318e-ac1d-4c7f-b9f8-08ff3fb82c14&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;장애에는 어떻게 대처할 것인가 ?&lt;ul id=&quot;01c7b441-6f40-4e91-9b20-c773cf341ca1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시 서버를 한대만 두는 경우 해당 서버는 단일 장애 지점이 되어버릴 가능성이 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9ffce039-cbb0-46db-b414-f3011c82df01&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;&lt;strong&gt;단일 장애 지점 이란?&lt;/strong&gt;&lt;ul id=&quot;e954764c-73e1-4ef9-b217-58340aceb73f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;어떤 특정 지점에서의 장애가 전체 시스템의 동작을 중단시켜버릴 수 있는 경우 우리는 해당 지점을 단일 장애 지점이라고 부른다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;059daae3-6590-4d25-9201-3e311e1d3c28&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;단일 장애 지점을 피하려면 여러지역에 캐시 서버를 분산시켜야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;ef2d7967-492c-4b91-8fc7-7173715973ce&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;10b3cff1-1b2b-4f99-88fb-9c6a2c8b3237&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시 메모리는 얼마나 크게 잡을 것인가 ?&lt;ul id=&quot;896505f1-1b2b-46c5-bf44-3e9ee2b761e2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시 메모리가 너무 작으면 액세스 패턴에 따라서는 데이터가 너무 자주 캐시에서 밀려나버려 ( eviction ) 캐시의 성능이 떨어지게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;e4fa9437-0956-40c5-9c12-569f63d9be6a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이를 막을 한가지 방법은 캐시 메모리를 과할당 하는것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a1cae4d7-fc16-4251-b748-7cd995eac6b8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이렇게 하면 캐시에 보관될 데이터가 갑자기 늘어났을 때 생길 문제도 방지할 수 있게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;dd29b687-90b5-43db-ac6b-90120db3fd66&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;36dee7e0-e4c7-4748-9630-bf3ccabbc59c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터 방출 ( eviction ) 정책은 무엇인가 ?&lt;ul id=&quot;8d25c026-c029-4324-9db2-9fd4c8ffc634&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시가 꽉 차버리면 추가로 캐시에 데이터를 넣어야 할 경우 기존 데이터를 내보내야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5f2d2d9f-54cf-4110-8e61-552eebbc9f38&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이것을 캐시 데이터 방출 정책이라 하는데 가장 널리 쓰이는 것은 &lt;strong&gt;마지막으로 사용된 시점이 가장 오래된 데이터를 내보내는 정책&lt;/strong&gt;이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f6e6be9f-6029-492a-b36f-be6f0e6876b6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다른 정책으로는 사용빈도가 가장 낮은 데이터를 내보내는 정책이다&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a44b7aeb-22e9-4f48-a8ec-1b2cfa171277&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;FIFO 같은 것도 있으며 경우에 맞게 적용 가능하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;3c855802-95dd-46f0-bb06-661496005703&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;b21d9338-7b49-4791-aa1d-3b294535bf43&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;6233e039-bf67-4a42-9e32-910c7e455cac&quot; class=&quot;&quot;&gt;CDN&lt;/h1&gt;&lt;ul id=&quot;0a3077ab-7041-4668-8d1d-8917e4850f65&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;정적 콘텐츠를 전송하는 데 쓰이는 지리적으로 분산된 서버의 네트워크이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ee6e7ef2-1dad-4605-90e9-e2de7744b2c5&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이미지, 비디오, CSS, javascript 파일 등을 캐시할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;4780cbec-be3b-4c6e-a471-bebd426a4a33&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;885d776b-3d66-4076-bf6a-43412ae9ae28&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;어떤 사용자가 웹사이트를 방문하면 그 사용자에게 가장 가까운 CDN서버가 정적 콘텐츠를 전달하게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;820abeaa-39e2-46f6-818b-9838ff0caac4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;직관적으로도 당연하겠지만 사용자가 CDN 서버로부터 멀면 멀수록 웹사이트는 천천히 로드될 것이다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;f7a5c80f-817e-46eb-b5b1-95717f1968d6&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;a1b7cfda-7595-4ad9-9743-94f6cfa010eb&quot; class=&quot;&quot;&gt;동작&lt;/h2&gt;&lt;ol type=&quot;1&quot; id=&quot;2464a113-fe47-48ac-b195-c5d0a319f63d&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;사용자 A가 이미지 URL을 이용해 image.png에 접근한다.&lt;ul id=&quot;84f391b6-b683-4bfc-a280-75187ab17c23&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;URL의 도메인은 CDN 사업자가 제공한 것&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;9abd0ee8-5f7a-4892-9b4f-c155972bba6c&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;CDN 서버의 캐시에 해당하는 이미지가 없는경우, 서버는 원본 서버에 요청하여 파일을 가져온다. 원본서버는 웹서버일수도 있고 아마존 S3와 같은 온라인 저장소 일수도 있다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;c7904687-6cd5-48bc-8d75-e25ec07f5582&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;원본 서버가 파일을 CDN서버에 반환한다. 응답의 HTTP 헤더에는 해당 파일이 얼마나 오래 캐시될 수 있는지를 설명하는 TTL 값이 들어 있다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;72691a7f-ba42-478d-917b-8071949d1d86&quot; class=&quot;numbered-list&quot; start=&quot;4&quot;&gt;&lt;li&gt;CDN 서버는 파일을 캐시하고 사용자 A에게 반환한다. 이미지는 TTL에 명시된 시간이 끝날때 까지 캐시된다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;dbe57ab6-5f39-4727-bf28-f8083c5c3099&quot; class=&quot;numbered-list&quot; start=&quot;5&quot;&gt;&lt;li&gt;사용자 B가 같은 이미지에 대한 요청을 CDN 서버에 전송한다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;a8df08e9-195d-4367-9c70-ce0f74ca2fe4&quot; class=&quot;numbered-list&quot; start=&quot;6&quot;&gt;&lt;li&gt;만료되지 않은 이미지에 대한 요청은 캐시를 통해 처리된다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;2b1a57ef-df66-4ff4-8fff-58fa72d6c83c&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;56469a66-c544-4737-9907-910bc8cca828&quot; class=&quot;&quot;&gt;CDN 사용시 고려해야할 사항&lt;/h2&gt;&lt;ul id=&quot;9aa23c32-2536-4fd6-8714-f4eb1b3f8876&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;비용&lt;ul id=&quot;5a4a755b-160d-423a-a664-cf58aa1ae236&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;CDN은 보통 서드파티에 의해 운영되며 CDN 이용자는 CDN으로 들어가고 나가는 데이터 전송 양에 따라 요금을 내게 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b954912b-5d58-45ad-baea-ee8ae21738ee&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;자주 사용되지 않는다면 CDN에서 제외하도록 하자.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;507ae386-75dc-422c-a9d7-4863fcf2cf18&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;6b4c9d62-62c4-4a88-84ac-ac468a1fae77&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;적절한 만료 시한 설정&lt;ul id=&quot;74d53d6c-dd6d-40f7-99fc-fe70e9149499&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시의성이 중요한 컨텐츠의 경우 만료 시점을 잘 정해야한다. 너무 길지도 짧지도 않아야 하는데&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;1f0a1a19-99ee-4868-adcd-0ec0d51d8ed2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;너무 길면 컨텐츠의 신선도가 떨어지고 너무 짧으면 원본 서버에 번번히 접속하게 되어서 좋지 않다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;4ce1290c-1d52-4ed8-af67-3f29620e6dcf&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;dc37abc8-730a-411d-a275-adc65339245f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;CDN 장애에 대한 대처 방안&lt;ul id=&quot;8ebdc64a-7522-4775-be54-fd26857b876f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;CDN 자체가 죽었을 경우 웹사이트/애플리케이션이 어떻게 동작해야 하는지 고려한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;639c9c0f-6089-454e-8dc3-ae252c3ed66e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가령 일시적으로 CDN이 응답하지 않더라도 해당 문제를 감지하여 원본 서버로부터 직접 컨텐츠를 가져오도록 클라이언트를 구성하는 것이 필요할 수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;e3fc2226-6c81-447d-915d-bf637ab7b5bd&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;3ba1a186-44b3-4060-9135-0c574c4bff66&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;컨텐츠 무효화&lt;ul id=&quot;18968863-e516-4f61-b8e4-8940ccd27d0d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;아직 만료되지 않은 컨텐츠라 하더라도 아래 방법 가운데 하나를 쓰면 CDN에서 제거할 수 있다.&lt;ul id=&quot;953f745c-c77c-4295-9a08-40304de665ab&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;CDN서비스 사업자가 제공하는 API를 이용하여 컨텐츠 무효화&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;45fbad05-2f11-4b91-98e6-2c5123d15f4f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;컨텐츠의 다른 버전을 서비스 하도록 오브젝트 버저닝 이용&lt;ul id=&quot;f13c6490-c9e5-4db4-9627-11ea7ca300f6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;컨텐츠의 새로운 버전을 지정하기 위해서는 URL 마지막에 버전 번호를 인자로 주면 된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5c913412-876c-477d-acf5-37e512d0cee2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예를 들어 image.png?v=2와 같은 방식이다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;1917488d-e431-43ab-837b-a24889c76560&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;p id=&quot;e453a773-d4eb-4908-bfd3-364747f4412a&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;a1853e6b-5163-4b56-bb5b-7d070ea815bb&quot; class=&quot;&quot;&gt;CDN 사용시 변화된 부분&lt;/h2&gt;&lt;ul id=&quot;0c31b228-26c1-48cd-8d8a-5e4dde507f07&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;더이상 정적 컨텐츠를 웹서버를 통해 서비스 하지 않는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;25dd1d3a-bb72-4d90-a46e-a5d978396e50&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;캐시가 DB부하를 줄여준다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;34092150-22c2-4c1c-9ee8-d00195e029bd&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;1473294d-f5ec-4193-9475-4f7356ee2e3f&quot; class=&quot;&quot;&gt;무상태 웹 계층&lt;/h1&gt;&lt;ul id=&quot;002420d8-6065-4deb-90be-9170523e3a21&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;웹 계층을 수평적으로 확장하기 위해서는 상태정보 ( 사용자 세션 데이터와 같은)를 웹 계층에서 제거하여야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;de753082-e24c-4d2f-afcb-7a750e3160da&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;바람직한 전략은 상태 정보를 RDB나 noSql같은 지속성 저장소에 보관하고 필요할 때 가져오도록 하는것이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6c8cfb0a-1dde-4589-8ef8-692cc54f8ce2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이렇게 구성된 웹 계층을 무상태 웹 계층이라 부른다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;03a275e9-61bf-4e39-b6ba-ebe309651d2a&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;5e70590c-c6f0-4386-9929-5f7370559fd7&quot; class=&quot;&quot;&gt;상태 정보 의존적인 아키텍처&lt;/h2&gt;&lt;ul id=&quot;b075b240-a205-45d1-bf28-e76ff0bc318c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;상태 정보를 보관하는 서버는 클라이언트 정보 즉 상태를 유지하여 요청들 사이에 공유되도록 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0d3f145c-1b1d-49bc-a260-b3caf3384db1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;무상태 서버와는 반대&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;b3709c51-bd87-42e5-9f1a-09e52d3bd611&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로드밸런서 사용시 사용자 정보를 가지고 있는 서버에 접속해야 상태정보가 유지된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;31ac5163-7863-4cbd-81ed-1cc02f5b554d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로드밸런서가 이를 지원하기 위해 고정 세션(stickey session)이라는 기능을 제공하는데&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;c74da3d1-d202-44c3-a137-cb67b86231d8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이는 로드밸런서에 부담을 준다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;48283926-c965-4228-9a75-1768809633f7&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;게다가 로드밸런서 뒷단에 서버를 추가하거나 제거하기도 까다로워진다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;cef22a41-6943-4e09-988d-81e583eaf05c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이들 서버의 장애를 처리하기도 복잡하다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;6d421953-4f73-45ba-87a8-d23441f20959&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;9c036680-1cc4-45a7-b403-50760a0043e9&quot; class=&quot;&quot;&gt;무상태 아키텍처&lt;/h2&gt;&lt;ul id=&quot;9a4af07c-6b43-474e-b718-da82594fad79&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;무상태 아키텍처는 사용자로부터의 HTTP 요청은 어떤 웹서버로도 전달될 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;61608034-53c1-4d9f-b717-11b5495fabd8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;웹서버에서 상태정보가 필요할 경우 공유 저장소에서 데이터를 가져온다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;74c3a023-36a9-4c89-a29c-506416efdf4f&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;상태정보가 분리되어 있기때문에 구조가 단순하고 안정적이며 규모 확장이 쉽다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;32f424cb-6f8d-496e-b000-c3d240620d43&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이 공유 저장소는 rdb일수도 있고 멤캐시드나 레디스같은 캐시 시스템일수도 있고 nosql일수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;8dcc333f-adfa-46b3-a93b-f7e2b24e7956&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;f114be6f-7dc5-44ed-9cb0-e7827223fb42&quot; class=&quot;&quot;&gt;데이터 센터&lt;/h1&gt;&lt;ul id=&quot;6183fed7-e649-4338-8a9c-45ba3e3912cc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;장애가 없는 상황에서 사용자는 가장 가까운 데이터 센터로 안내되는데 통상 이 절차를 지리적 라우팅이라 부른다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;d096dcbc-5471-4195-8a01-bd675f544576&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;지리적 라우팅에서 geoDNS는 사용자의 위치에 따라 도메인 이름을 어떤 IP주소로 변환할지 결정할수 있도록 해주는 DNS 서비스다&lt;ul id=&quot;c7dd8ac4-cbd6-4eda-879b-7e40191a47ec&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로드밸런서에 의해 지리적 라우팅이 작동할수도 있고&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;5efca00a-9ef9-4383-a0e3-baf80b315029&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다른 시스템에 의해 라우팅이 작동할수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;00f276c1-e949-4b83-ae50-52e00e9ef4d0&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;135e8032-7f23-4bf2-baec-a4281a5ac9dd&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;다중 데이터센터 아키텍처를 만드려면 몇가지 기술적 난제를 해결해야 한다.&lt;ol type=&quot;1&quot; id=&quot;d08de1c2-dbb1-4263-91c0-b34a06d31ffb&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;트래픽 우회&lt;ol type=&quot;a&quot; id=&quot;13484e7b-dad6-4fea-8921-62fc4e2271db&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;올바른 데이터 센터로 트래픽을 보내는 효과적인 방법을 찾아야 한다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;dd903095-6d9b-4316-971a-ae26e4ecf028&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;GeoDNS는 사용자에게서 가장 가까운 데이터 센터로 트래픽을 보낼수 있도록 해준다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;5445d3b2-d338-472c-97e2-b8197e9229db&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;데이터 동기화&lt;ol type=&quot;a&quot; id=&quot;98c326ed-52b8-41d3-a901-a1c548bdceff&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;데이터 센터마다 별도의 데이터베이스를 사용하기 때문에 장애가 자동으로 복구되어 트래픽이 다른 데이터베이스로 우회된다 해도 해당 데이터센터에는 찾는 데이터가 없을 수 있다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;d2314b57-1cf0-4d14-9e78-474b82d915d5&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;이런 상황에서는 데이터를 여러 데이터센터에 걸쳐 다중화 하는것이다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;37c8ed72-0261-4a65-8965-c027ade75dad&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;테스트와 배포&lt;ol type=&quot;a&quot; id=&quot;a569be3b-3c54-4aa6-987b-f5748f6be004&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;여러 데이터센터를 사용하도록 시스템이 구성된 상황이라면 웹 사이트 또는 애플리케이션을 여러 위치에서 테스트해보는것이 중요하다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;a48572d3-7822-4e8e-b348-d27dbaac3e91&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;한편 자동화된 배포 도구는 모든 데이터센터에 동일한 서비스가 설치되도록 하는데 중요한 역할을 한다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;721050ec-ec5e-4721-80cf-67c9c7a1ea2e&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;b33b9ec5-848a-4a1b-828a-6fe67a562681&quot; class=&quot;&quot;&gt;메시지 큐&lt;/h1&gt;&lt;ul id=&quot;fcf52aa7-5719-45f3-8820-12d60ff52950&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메시지의 무손실을 보장하는 비동기 통신을 지원하는 컴포넌트&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;f989eae8-ed8f-4acb-a8b7-743b72802dcc&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메시지의 버퍼 역할을 하며 비동기적으로 전송한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a3a27007-8ed1-454e-bc9a-f26b853bd612&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메시지 큐의 기본 아키텍처는 생산자 또는 발행자 ( 프로듀서/퍼블리셔 ) 라고 불리는 입력 서비스가 메시지를 만들어 메시지 큐에 발행한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;29a71e14-8391-4cc6-b943-5b47cc5c8d0e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;큐에는 소비자 혹은 구독자 ( 컨슈머 / 섭스크라이버 ) 라고 불리는 서비스 혹은 서버가 연결되어 있는데 메시지를 받아 그에 맞는 동작을 수행하는 역할을 한다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;6ed98e61-6fce-41f5-b0ed-da4bcb78980b&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;1278333e-5e0a-4a79-b279-92447fe1fa7a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메시지 큐를 이용하면 서비스 또는 서버간 결합이 느슨해져서 규모 확장성이 보장되어야 하는 안정적 애플리케이션을 구성하기 좋다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;ad3d0941-5e0e-41f8-847a-877c98ad81de&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;생산자는 소비자 프로세스가 다운되어 있어도 메시지를 발행할 수 있고, 소비자는 생산자 서비스가 가용한 상태가 아니더라도 메시지를 수신할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;a121f38f-ec5e-4dba-ac8a-5512b8d4898f&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;p id=&quot;d02b0219-f1d4-4a25-8dd6-eff2713b15a6&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;14bfccd1-eccf-4264-b6cb-5d7012b1fe65&quot; class=&quot;&quot;&gt;로그 메트릭 그리고 자동화&lt;/h1&gt;&lt;ul id=&quot;58fe569c-202c-41c8-a963-0b6347e1f9a4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;로그&lt;ul id=&quot;45a4caf1-02c6-47d5-8f01-9c85d556c0ca&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;에러 로그를 모니터링 하는것은 중요하다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;422bb16b-669d-4ba1-a927-3685822a45d1&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템의 오류와 문제를 쉽게 찾을 수 있기 때문&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;62b60b28-918d-4f5a-ada1-64a7c33457c9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;에러 로그를 서버단위로 모니터링 할 수도 있지만 로그를 단일 서비스로 모아주는 도구를 활용하면 더 편리하게 검색하고 조회할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;044b775b-fd25-44f2-8956-75c83176a30a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메트릭&lt;ul id=&quot;e6bef4fd-65a5-4404-862f-193db7b6f91a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메트릭을 잘 수집하면 사업현황에 관한 유용한 정보도 얻고 시스템의 현재 상태를 손쉽게 파악할 수도 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;51fb7ed0-7f1e-4695-81a5-df230e8fa268&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;메트릭 가운데 유용한 메트릭 몇가지&lt;ol type=&quot;1&quot; id=&quot;e0013539-2001-4e6e-935c-cfdba2490f1c&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;호스트 단위 메트릭&lt;ol type=&quot;a&quot; id=&quot;c693ce9a-0117-4a2c-9b08-45feaacda678&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;CPU, 메모리, 디스크 I/O에 관한 메트릭이 여기 해당한다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;e1728cc4-c1e2-4379-a2a5-1d6600c12269&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;종합 메트릭&lt;ol type=&quot;a&quot; id=&quot;1561d1a9-cad5-4578-8e72-168b39d8c823&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;데이터베이스 계층의 성능, 캐시 계층의 성능 같은 것이 여기 해당한다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;a95fb485-b20d-4943-95c1-68c21b239b7d&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;핵심 비지니스 메트릭&lt;ol type=&quot;a&quot; id=&quot;86e31562-095e-4176-814d-31a75491ee6d&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;일별 능동 사용자 ( daily active user ), 수익, 재방문 같은것이 여기 해당한다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;ea386905-240c-42a4-9d91-22a6f9e27fea&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;dcd85201-06dc-4026-900c-7a4703394bee&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;자동화&lt;ul id=&quot;af661011-539a-4334-9827-8560f811077a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템이 크고 복잡해지면 생산성을 높이기 위해 자동화 도구를 활용해야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;00ed9f1b-13c5-4487-9bab-d307dc3675e4&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가령 지속적 통합을 도와주는 도구를 활용하면 개발자가 만드는 코드가 어떤 검증 절차를 자동으로 거치도록 할 수 있어서 문제를 쉽게 감지할 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;724a6499-4ef5-4eb4-8270-6c41671722fe&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;이외에도 빌드, 테스트, 배포 등의 절차를 자동화 할 수 있어서 개발 생산성을 크게 향상시킬수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;c9434f0c-9527-4297-b75e-ca62b4fa36d1&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;p id=&quot;836cabef-71f5-4caf-a882-1f86ac62a390&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h1 id=&quot;a42fcf40-5a88-436f-bcd1-89b06cea0e38&quot; class=&quot;&quot;&gt;데이터 베이스의 규모 확장&lt;/h1&gt;&lt;ul id=&quot;66d66239-fad5-4b30-ac91-d68396b33aa2&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;저장할 데이터가 많아지면 DB에 대한 부하도 증가한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;255b35d8-10c8-4a7f-ba45-eff3c518f184&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그때가 오면 DB를 증설할 방법을 찾아야 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;7bd2b75d-6bc0-4026-8e82-9e2dabfdda8c&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;규모확장에는 두가지가 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;aeb5f737-b0f6-4245-afe7-394753fe3d91&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;수평적 확장, 수직적 확장&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;bbfd60c2-99c4-439c-aaa6-c7ba58036099&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h2 id=&quot;39df7e4f-3221-43ac-8777-2101b675f639&quot; class=&quot;&quot;&gt;수직적 확장&lt;/h2&gt;&lt;ul id=&quot;f2ed2e27-de54-4e11-a610-6b6cb5948046&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스케일 업이라고 불리우며 서버의 사양을 고성능으로 증설하는 방법이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;35bd6064-e95e-46f0-a6d8-5e25cd79a5bf&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;스택오버플로는 2013년 한해 동안 방문한 천만명의 사용자 전부 단 한대의 마스터 데이터베이스로 처리하였다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;68468c1a-2d68-4afb-9a64-28942b017142&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;하지만 수직적 접근법에는 약점이 있다.&lt;ol type=&quot;1&quot; id=&quot;007a21b3-9e75-40ee-bd31-9a2da0546c63&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;무한히 서버의 사양을 증설할 수 없다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;15aa67cb-e19d-49e9-a2c4-28492502dcd9&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;SPOF&lt;ol type=&quot;a&quot; id=&quot;ecef8493-ce6f-4ffb-be06-3760a34616fc&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;단일 실패지점이 될 확률이 크다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;e09242cb-37fe-4ced-85b9-e99d6b92b325&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;단일실패지점: 실패했을경우 서버가 전부 멈춰버리는 지점&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;095f72ca-b1f4-4dd4-9bad-9bc2c364450f&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;비용이 많이 든다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;62e8df00-b375-4faf-b54c-8555fcad5fb9&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;29239644-51b3-4c06-a934-900624883db7&quot; class=&quot;&quot;&gt;수평적 확장&lt;/h2&gt;&lt;ul id=&quot;20ea0058-f85f-4629-9cd8-6703d6a4d34e&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터베이스의 수평적 확장은 샤딩이라고 불리운다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;781a667c-bb8f-4dff-961d-845dfe851da9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;많은 서버를 추가함으로써 성능을 향상시킬수 있도록 한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;13fb76fa-bba5-4adc-b88c-774d3e57c734&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;샤딩은 대규모 데이터베이스를 샤드라고 부르는 작은 단위로 분할하는 기술을 일컫는다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;4ab240c9-d389-4c76-aa6a-3368a1284c36&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;모든 샤드는 같은 스키마를 쓰지만 샤드에 보관되는 데이터사이에는 중복이 없다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;0bd021d2-bd0e-485c-94af-e7a997598496&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;사용자 데이터를 어느 샤드에 넣을지는 사용자 ID에 따라 정한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;27f43656-7669-4af8-ab74-e1af50f0771a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;예제는 사용자 아이디를 4로 나눈것을 해시함수로 사용하여 데이터가 보관되는 샤드를 정한다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;fa65cec4-cdde-49b8-b8f4-d93a47c270c3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;결과가 0이면 0번 샤드, 1이면 1번 샤드&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;dc6d7e43-024f-49e8-a7b2-0d3283830e1f&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;ul id=&quot;fcaafd03-6eef-47e7-86ef-846b0f421be8&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;&lt;strong&gt;샤딩 전략을 구현할 떄 고려해야 할 가장 중요한 것은 샤딩 키를 어떻게 정하느냐 하는것이다.&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;6e93c61b-f56e-4d35-9f50-0c9df957e6b6&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;샤딩키는 파티션 키라고도 부르는데 데이터가 어떻게 분산될지 정하는 하나 이상의 칼럼으로 구성된다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;81712fce-bbc6-4743-81d3-d8eea379be42&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;그럼 위의 예제 같은 경우 샤딩키는 사용자 ID 이다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;08c60bed-0ef0-4925-8571-34981b6210ea&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;샤딩키를 통해 올바른 데이터베이스에 쿼리를 보내어 데이터 조회나 변경을 처리하므로 효율을 높일 수 있다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;323dc119-bdf2-4177-a60e-a23d6f81e0aa&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;샤딩은 디비 규모 확장을 실현하는 훌륭한 기술이지만 완벽하진 않다.&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;919c0f1d-9699-4afc-8f57-eb4dc38be8ec&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;샤딩을 도입하면 시스템이 복잡해지고 풀어야할 문제도 늘어난다.&lt;ol type=&quot;1&quot; id=&quot;028325da-3b7d-4c5e-bb3a-b333c87fbfbf&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;데이터의 재 샤딩&lt;ol type=&quot;a&quot; id=&quot;1846bf69-ae9b-472e-a49d-99b6ba7917ce&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;데이터가 너무 많아져서 하나의 샤드로는 더이상 감당하기 어려울 때&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;ad4a33ad-a12f-4ec5-bc14-7e10b35bb20e&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;샤드간 데이터 분포가 균등하지 못하여 어떤 샤드에 할당된 공간 소모가 다른 샤드에 비해 빨리 진행될 때 ( 샤드 소진이라고 부른다 ) 이런 현상이 발생하면 샤드 키를 계산하는 함수를 변경하고 데이터를 재 배치 해야 한다. 안정 해시 기법을 활용하면 이 문제를 해결 할 수 있다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;4e148395-767e-40fc-965c-3dc6ec54bea6&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;셀레브리티 문제&lt;ol type=&quot;a&quot; id=&quot;5b0d0a6e-99f0-48cc-96ba-a9785847f8d3&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;핫스팟 키 문제라고도 부르는데 특정 샤드에 쿼리가 집중되어 서버에 과부하가 걸리는 문제다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;108bc553-0744-4f95-8481-098e6ab6398e&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;가령 자주 조회되는 데이터가 한 샤드에 몰려있다고 생각해보면 된다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;436a0868-60a3-488a-af08-fd1842d9514a&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;이럴 경우 샤드에는 읽기 연산 때문에 과부하가 걸리게 될것이다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;bf716509-4e24-4521-b6de-20ac06477a3f&quot; class=&quot;numbered-list&quot; start=&quot;4&quot;&gt;&lt;li&gt;자주 접속되는 데이터를 균등하게 분배해야 할수도 있다. 아니면 각 샤드당 하나씩 분배해야 할수도 있다.&lt;/li&gt;&lt;/ol&gt;&lt;p id=&quot;c1a71f82-10c3-45fc-be4a-a28453466927&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;1&quot; id=&quot;a4aab925-b033-4caa-9dc6-86f08deaf330&quot; class=&quot;numbered-list&quot; start=&quot;3&quot;&gt;&lt;li&gt;조인과 비정규화&lt;ol type=&quot;a&quot; id=&quot;c1404a9a-3756-4110-8fd4-ef509cdc8f67&quot; class=&quot;numbered-list&quot; start=&quot;1&quot;&gt;&lt;li&gt;하나의 디비를 여러 샤드 서버로 쪼개고 나면 여러 샤드에 걸친 데이터를 조인하기가 힘들어진다.&lt;/li&gt;&lt;/ol&gt;&lt;ol type=&quot;a&quot; id=&quot;50d7efbb-2f2e-4c84-9adf-d66e1975743c&quot; class=&quot;numbered-list&quot; start=&quot;2&quot;&gt;&lt;li&gt;이를 해결하는 한 가지 방법은 디비를 비정규화하여 하나의 테이블에서 질의가 수행될수 있도록 하는 것이다.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p id=&quot;5b8d9792-a1fe-4398-b4aa-6b8d823c7432&quot; class=&quot;&quot;&gt;
&lt;/p&gt;&lt;h1 id=&quot;3c710d57-c012-4804-9c44-e068e17cc5b4&quot; class=&quot;&quot;&gt;백만 사용자, 그리고 그 이상&lt;/h1&gt;&lt;ul id=&quot;8820ed8d-ee4f-4f4a-99fd-0dff74310afb&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;웹 계층은 무상태 계층으로&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;48f382f0-5539-49bc-ba1a-f337999f098b&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;모든 계층에 다중화 도입&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;9122304a-cd0d-4bdb-8089-f109b2e02fe9&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;가능한한 많은 데이터를 캐시 할것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;02c98c92-bac2-485e-9926-c7c29a506fa3&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;여러 데이터 센터를 지원할 것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;26588ec5-ceb6-4446-842d-958be1ac4a5d&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;정적 콘텐츠는 CDN을 통해 서비스 할것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;aeba4340-72ca-4dab-90b9-d4fea180d897&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;데이터 계층은 샤딩을 통해 그 규모를 확장할 것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;8bf59431-e7dc-4f2e-8316-fb83efc53010&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;각 계층은 독립적 서비스로 분할할 것&lt;/li&gt;&lt;/ul&gt;&lt;ul id=&quot;a4e821dd-09b1-4520-918c-5f201ed3060a&quot; class=&quot;bulleted-list&quot;&gt;&lt;li&gt;시스템을 지속적으로 모니터링하고 자동화 도구들을 활용 할 것&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;n2t_comment&quot;&gt;&lt;p&gt;
&lt;/p&gt;&lt;p class=&quot;block-color-gray&quot;&gt;&lt;a href=&quot;https://boltlessengineer.github.io/Notion2Tistory&quot;&gt;Uploaded by Notion2Tistory v1.1.0&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/article&gt;</description>
      <category>book/대규모 시스템 설계 기초</category>
      <author>어제</author>
      <guid isPermaLink="true">https://kingds.tistory.com/120</guid>
      <comments>https://kingds.tistory.com/120#entry120comment</comments>
      <pubDate>Sun, 29 Aug 2021 08:28:13 +0900</pubDate>
    </item>
  </channel>
</rss>