<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>PyPyStory</title>
    <link>https://pypystory.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 18 Apr 2026 08:25:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>파이랜스</managingEditor>
    <image>
      <title>PyPyStory</title>
      <url>https://tistory1.daumcdn.net/tistory/4767732/attach/e2e517d1dab74095b74f37f8361ab709</url>
      <link>https://pypystory.tistory.com</link>
    </image>
    <item>
      <title>[컨퍼런스] 2025 당근 플랫폼 밋업 참여 후기 (2025.11.07.)</title>
      <link>https://pypystory.tistory.com/130</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6ac612f3-c438-49c5-bdcf-c3531e6b1d66.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1067&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOvoOE/dJMcabvMobT/IDh7cRUYB4oVOGM4d8JGtK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOvoOE/dJMcabvMobT/IDh7cRUYB4oVOGM4d8JGtK/img.jpg&quot; data-alt=&quot;https://www.ticketa.co/events/32&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOvoOE/dJMcabvMobT/IDh7cRUYB4oVOGM4d8JGtK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOvoOE%2FdJMcabvMobT%2FIDh7cRUYB4oVOGM4d8JGtK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;560&quot; data-filename=&quot;6ac612f3-c438-49c5-bdcf-c3531e6b1d66.jpg&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;1067&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.ticketa.co/events/32&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최근에 AWSKRUG AI enginnering 소모임, AWS Community Day 등 크고작은 컨퍼런스들에 참여해서 인사이트를 얻어왔는데, 최근 다녀온 당근 Platform Meetup에서도 인상 깊은 발표가 많았어서 해당 내용을 정리해보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UlA2k/dJMcabbtBde/wILFylIj4FkGlKP0aFSnhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UlA2k/dJMcabbtBde/wILFylIj4FkGlKP0aFSnhk/img.png&quot; width=&quot;428&quot; height=&quot;261&quot; data-origin-width=&quot;1192&quot; data-origin-height=&quot;726&quot; data-is-animation=&quot;false&quot; style=&quot;width: 64.5639%; margin-right: 10px;&quot; data-widthpercent=&quot;65.32&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UlA2k/dJMcabbtBde/wILFylIj4FkGlKP0aFSnhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUlA2k%2FdJMcabbtBde%2FwILFylIj4FkGlKP0aFSnhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1192&quot; height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUA7w2/dJMcahvZMRQ/LgTOPaokyvOcEVfepZmYNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUA7w2/dJMcahvZMRQ/LgTOPaokyvOcEVfepZmYNK/img.png&quot; width=&quot;367&quot; height=&quot;421&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;950&quot; data-is-animation=&quot;false&quot; style=&quot;width: 34.2734%;&quot; data-widthpercent=&quot;34.68&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUA7w2/dJMcahvZMRQ/LgTOPaokyvOcEVfepZmYNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUA7w2%2FdJMcahvZMRQ%2FLgTOPaokyvOcEVfepZmYNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;828&quot; height=&quot;950&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;수빈님께 무한한 감사를 / KRUG 소모임 갔을 때&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AUSG 슬랙방에 수빈님께서 관련 링크를 올려주셔서 미리 알고 광클해서 예매할 수 있었다. 예매하고 다시 들어가보니 2분만에 매진되어있었는데 느긋하게 예매했으면 못 갈뻔했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;총 7개의 발표와 네트워킹 시간으로 구성되어 있었는데 그 중 몇가지를 정리해보겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;1362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ybRKT/dJMcagw5Bhi/kCi4k3kQKIH7MPqKzYX1XK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ybRKT/dJMcagw5Bhi/kCi4k3kQKIH7MPqKzYX1XK/img.png&quot; data-alt=&quot;발표장이 넓고 좋았다. 마치 연극이나 영화관 처럼 생긴 공간이었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ybRKT/dJMcagw5Bhi/kCi4k3kQKIH7MPqKzYX1XK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FybRKT%2FdJMcagw5Bhi%2FkCi4k3kQKIH7MPqKzYX1XK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2080&quot; height=&quot;1362&quot; data-origin-width=&quot;2080&quot; data-origin-height=&quot;1362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;발표장이 넓고 좋았다. 마치 연극이나 영화관 처럼 생긴 공간이었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발표1 - 달리는 자동차의 잠금장치 교체하기: 인증 시스템의 중앙화&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;오현준님께서 발표해주셨다. 주된 내용은 MSA의 인증 시스템을 중앙화 시키기 위해 로직을 교체하는 과정에서 중단 없이 교체한 내용이었다. 수십만 트래픽을 받는, 심지어 앱 서비스라 버전에 따른 처리도 해줘야하는 상황에서 프로덕션 환경의 인증 서비스를 교체한 부분이었다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;제일 인상 깊었던 부분은&lt;span&gt; 기존 API도 살리면서, 새로운 인증도 병행해서 동작할 수 있게 한다음 기존 인증을 제거하는 방식이었다. &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;MSA에서 이런식으로 설계하면 확실히 역할과 책임의 분리가 되겠다는 생각이 들었다.&lt;/b&gt;&lt;/p&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;amp; 무중단 마이그레이션&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그아웃 전까지 토큰이 유지되는 등 보안 문제&lt;/li&gt;
&lt;li&gt;트래픽 증가로 인한 DB 부하&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인증 중앙화&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;JWT + 토큰 페어
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;성능 문제 &amp;amp; 보안 문제 해결 &amp;rarr; JWT는 스스로 정보를 담을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;마이크로 서비스가 많았기에 매번 미들웨어에서 인증하는데, 인증 갈아끼면 모든 MSA에서 미들웨어 교체해야함&lt;/li&gt;
&lt;li&gt;당근의 MSA 인프라 쿠버네티스와 Istio (서비스 mesh?)&lt;/li&gt;
&lt;li&gt;쿠버위에 Istiod 설치하면 각 pod에 istio-proxy를 주입함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Istio의 AutorizationPolicy 를 만들어두고, istio-proxy가 rule base로 api 인증 가능&lt;/li&gt;
&lt;li&gt;커스텀도 가능해서 gRPC 요청을 auto-rule-server로 넘겨줌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;인증 로직 gRPC로 중앙화&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;처음에 신규 클라에서는 구/신 토큰을 모두 쓸 수 있도록 하고 배포&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 클라 요청을 istio-proxy에서 받으면, envoyauth에 오도록하여 기존 토큰 인증 API 호출 &amp;rarr; 커스텀 헤더(user_id)를 반환&lt;/li&gt;
&lt;li&gt;신규 클라 요청은 istio-proxy에서 받으면, envoyauth가 신규 API를 호출하도록 함 &amp;rarr; 커스텀 헤더(user_id)를 반환&lt;/li&gt;
&lt;li&gt;MSA에 있는 서비스 로직을 바꿈 &amp;rarr; 인증 미들웨어 를 걷어내기 위해서 , 마이그레이션 미들웨어로 바꿔줌 커스텀 헤더가 있는지 여부로 판단.&lt;/li&gt;
&lt;li&gt;신규 api만 있는 클라 만들어서 배포&lt;/li&gt;
&lt;li&gt;이후 사용자 점유율에 따라서 앞에서부터, 닫아버림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결 사례&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인증 서비스 하나만 수정하면 되도록 바뀜&lt;/li&gt;
&lt;li&gt;메타정보 취합이 어려운점 해결&lt;/li&gt;
&lt;li&gt;인증에 대한 가시성 확보(얼마나 성공하는지)&lt;/li&gt;
&lt;li&gt;istio-proxy로 복잡한 라우팅 설정이 가능한데, namespace를 잘 명시해줘야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발표2 - 어느 날, 이미지 CDN이 터졌습니다: 킬 스위치&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;김수빈님께서 발표해주신 내용이다. 그동안 당근에서 어떤걸 개발 하시는지 정확히 알지는 못했었는데, 이번 기회에 알게되었다. 제목 그대로 클라우드 제공사의 CDN이 동작하지 않아서 이미지가 노출되지 않는 상황을 겪고, 새로운 아키텍처를 설계하신 이야기를 해주셨다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;특히 이 발표는 더욱더 인상 깊게 봤던게, 이때와 동일한 이슈인지는 모르겠지만 당근마켓에 이미지가 되지 않을 때 내가 유저로서 당근을 썼던 것이다. 발표를 보다가 생각나서 채팅을 찾아보니, 올해 6월에 한창 야구에 미쳐서 카드 모을 때 있었던 일이었다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;1619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lwbZr/dJMcadf3LG3/vkUChD7MtwqCV4bq3NVbQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lwbZr/dJMcadf3LG3/vkUChD7MtwqCV4bq3NVbQ1/img.png&quot; data-alt=&quot;아ㅋㅋ&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lwbZr/dJMcadf3LG3/vkUChD7MtwqCV4bq3NVbQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlwbZr%2FdJMcadf3LG3%2FvkUChD7MtwqCV4bq3NVbQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;304&quot; height=&quot;417&quot; data-origin-width=&quot;1179&quot; data-origin-height=&quot;1619&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아ㅋㅋ&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;더욱 집중해서 들을 수 있었고, 최근에 있었던 AWS DDB DNS 이슈와도 맞물려서 인상 깊은 발표였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Edge Node(PoP) 배치하고, 콘텐츠 제공 &amp;rarr; 장애 발생시 해당 PoP만 비활성화하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 터졌는가&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Signed URL을 Cloud Run에서 검증 &amp;larr; 민감한 이미지 signed를 위해서&lt;/li&gt;
&lt;li&gt;GCP에서 갑자기 cloud run에 넘어갈 때 header가 없어짐
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;x-client-request-url&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;킬 스위치 아키텍처를 도입함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 요인으로 부터의 장애 발생 대응&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DNS &amp;rarr; LB &amp;rarr; CDN &amp;rarr; Serverless &amp;rarr; Origin&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;dual write는 어려운 상황 &amp;rarr; presigned url 이용하기 때문&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;비용과 작업 공수 많이듬, 이미 겹치는 object-key 변경도 어려움&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;버킷에 없는 object라면 반대편 클라우드 Bucket도 조회 시도
&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;특정 도메인으로 요청시 고정적으로 반대편 클라우드의 Bucket 사용&lt;/li&gt;
&lt;li&gt;도메인을 합치고 DNS 스위칭
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ID 대신 이미지 URL을 저장하여 사용하거나 캐시하여 사용하는 경우&lt;/li&gt;
&lt;li&gt;스토리지 이중화 등 선행작업 필요&lt;/li&gt;
&lt;li&gt;TTL도 300초 필요&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;킬스위치 아키텍처&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CDN이랑 lambda@edge를 GCS를 바라보도록 유지&lt;/li&gt;
&lt;li&gt;CDN이랑 cloud run을 S3를 바라보도록 유지&lt;/li&gt;
&lt;li&gt;어떤 CDN을 볼지 어떻게 결정?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장애가 발생시 Feature Flag만 변경하여, 클라가 사용할 이미지 url의 호스트만 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파편화된 장애 모니터링 대시보드 합치기 &amp;larr; datadog, grafana, cw 등등&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다양한 리전, 환경에서 검증&lt;/li&gt;
&lt;li&gt;전면 장애 방지&lt;/li&gt;
&lt;li&gt;장애 중 flag 활성시 지연이 늘어나는 한계점&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발표3 - 10x 빠르게 10x 싸게: Quickwit 기반 신규 로그 파이프라인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이승훈님께서 발표해주셨다. Quickwit 이라는 오픈소스를 이용해서 로그 파이프라인을 구축하신 이야기를 발표해주셨다. 대규모 시스템에서 어떤식으로 로깅이 돌아가는지 이해할 수 있었다. 재미있었던 건 예전에 소마에서 서비스 개발할 때 로깅을 Opensearch에 다 넣었다가, 프리티어 끝나자마자 요금이 어마무시하게 나가서 바로 때버렸던 기억이 났는데, 당근 같은 큰 규모 서비스에서도 로깅 비용까지 고려해서 설계를 하는 부분이 인상깊었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;로그시스템&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 시스템
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Loki
&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;Loki는 label만 인덱싱 &amp;larr; 인덱싱이 빠르고, 용량 감소 가능&lt;/li&gt;
&lt;li&gt;같은 label 묶음끼리 stream이 되고, chunk로 나눠서 저장됨&lt;/li&gt;
&lt;li&gt;label이 늘어날 수록 기하급수적으로 stream 늘어남&lt;/li&gt;
&lt;li&gt;Shared Disk Arch. &amp;rarr; 스토리지 컴퓨팅 분리(S3 싸다!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OpenSearch - Access Log 수집, 빠름 &amp;larr; 비용 4~5배 비쌈 == 짧은 보관 기간, 일부 서비스만
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;역인덱스 사용 - 문장을 단어 단위로 저장해서 단어 단위로 인덱스 &amp;larr; 필요한 문서 위치를 인덱스로 만들어 둠&lt;/li&gt;
&lt;li&gt;Shared Nothing 아키텍처 - 각 노드마다 독립적으로 CPU Memory 유지&lt;/li&gt;
&lt;li&gt;노드 실패시 유실을 막기 위해 복제본 유지 x3배 비용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Quickwit
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;loki보다 빠르고, opensearch보다 싸다&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;/li&gt;
&lt;li&gt;낮은 성숙도 - 2021년산&lt;/li&gt;
&lt;li&gt;실시간성 부족 (1분 이상 걸림)&lt;/li&gt;
&lt;li&gt;레이턴시에 민감한 서비스 트래픽에는 적합하지 않음&lt;/li&gt;
&lt;li&gt;인덱스의 여러개 split으로 구성 &amp;larr; 퀵윗 최소단위
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수백 MB~수GB&lt;/li&gt;
&lt;li&gt;불변 구조&lt;/li&gt;
&lt;li&gt;객체 저장소 하나의 파일&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Log &amp;rarr; Indexer - S3, MetaStore(Postgres) - Searcher
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Upload Split&lt;/li&gt;
&lt;li&gt;Insert Split metadata&lt;/li&gt;
&lt;li&gt;Searcher는 root - leaf로 구성, 요청 받은놈이 Root가 됨
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Root &amp;rarr; Metadata 검색, Leaf한테 검색 요청&lt;/li&gt;
&lt;li&gt;Leaf &amp;rarr; HotCache 메모리에 올림, 빠르게 DocList읽기 &amp;rarr; DocStore에서 최종 결과 얻기&lt;/li&gt;
&lt;/ul&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;도입전 PoC 진행 &amp;larr; 로그가 가장 많은 팀을 대상으로 사용성 평가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 파이프라인으로 듀얼 write를 통해 사용성 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Datadog의 Quickwit 인수&lt;/li&gt;
&lt;li&gt;로그 콘솔로 찍으면, Pod Log &amp;rarr; Collector(백터?)가 카프카(다른 컨슈머 붙일 수 있도록)로 던짐 &amp;rarr; 카프카에서 Quickwith Index Cluster로 넘김&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;성과 &amp;rarr; 로그비용 감소, 저장기간 증가
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MCP 붙여서 Quickwit 조회도 가능&lt;/li&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발표4 - &lt;span data-token-index=&quot;0&quot;&gt;로컬 스크립트에서 하루에 한 번 돌아가는 파이프라인이 되기까지: 당근지도의 여정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;박소희님께서 발표해주셨다. 당근지도를 만드는 과정에 대해서 발표해주셨는데, 그간 지도는 여러 서비스에서 SDK로 받아와서 사용해본적은 있지만, 한번도 이 지도가 어떻게 만들어질까에 대해서 생각해본적 없었던 것 같다. 이 발표로 지도 생성 시스템이 어떻게 돌아가는지 엿볼 수 있었고, 그간 내가 알지 못했던 새로운 분야에 대한 고민이어서 신선하게 들을 수 있었다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지도 만드는 과정&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WMTS: 웹 환경에서 지구 전체를 표현하기 위한 표준 프로토콜
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Map tile이라는 최종 단위로 나뉨 (z,x,y) &amp;rarr; zoom-index, x,y 로 정의할 수 있음
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;z+1마다 2^n으로 tile 수 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;미리 만들어놓은 조각을 불러오기만하면됨 &amp;rarr; 조각 합쳐서 랜더링해주면됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;한국 기준 8M 조각필요&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;제작, 서빙 프로세스 PoC
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RabbitMQ 써서 메시징 파이프라인 사용&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;하이브서빙으로 z-level &amp;lt; 15까지는 cloudfront에 박고, 나머지는 동적으로 가져오기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;근데 NW/CPU 부하 증가, DB 부하 증가&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;시스템 구축 및 운영 전환 - 확장성, 신뢰성, 운영성&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RabbitMQ &amp;rarr; Kafka
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;topic 단위 파티션으로 병렬 처리 가능&lt;/li&gt;
&lt;li&gt;재처리 보장 가능, 메시지 offset 기반&lt;/li&gt;
&lt;li&gt;gRPC 요청 받기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;공간복잡도로 인해 DB 부하
&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;vertex 많은 부분 더 작게 쪼개기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 시스템 가시화 모니터링&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하루에 한번, 작업을해서 안정적인 배포&lt;/li&gt;
&lt;li&gt;실패시 그 작업만 재시도 가능하도록&lt;/li&gt;
&lt;li&gt;DB기반 작업 큐 관리&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;후기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;블로그에 담지못한 나머지 발표들도 재미있는 포인트들이 있고, 인상깊었는데 발표해주신 분들 모두 개발 난이도나 성과를 떠나서, 발표력에 감탄했다. 30분 동안 한 주제로 이야기를 풀어가기가 쉽지 않은데 한 분도 절지않고 발표하시는 걸 보고 발표 스킬에 대해서도 많이 배우고 생각해볼 수 있던 하루였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;네트워킹 시간에도 발표자분들께 자유롭게 질의응답을 할 수 있었는데, 발표에 대한 질문도 할 수 있었고, 당근 내에 개발 문화에 대해서도 궁금했던 부분들 많이 여쭤보고 좋은 말씀 많이 들을 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 나눠주신 굿즈?도 마음에 들었는데, 특히 AWS 로고가 같이 들어간 파우치와 안경닦기가 아주 마음에 들었다. 책도 한권 같이 들어있었는데, 최근에 트랜드가 AI를 이용한 개발이 핫한데, 당근에서 어떻게 사용하는지를 다루고 있는 책인듯하다. 최근에 Q 해커톤 다녀온 이후로 신경을 많이 쓰고 있는 분야인데, 틈틈이 읽어봐야겠다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oXudC/dJMcafEWQ0f/MGzl7qGaZV25MsP5ikgHKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oXudC/dJMcafEWQ0f/MGzl7qGaZV25MsP5ikgHKK/img.png&quot; data-origin-width=&quot;1154&quot; data-origin-height=&quot;1318&quot; data-is-animation=&quot;false&quot; style=&quot;width: 39.0144%; margin-right: 10px;&quot; data-widthpercent=&quot;39.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oXudC/dJMcafEWQ0f/MGzl7qGaZV25MsP5ikgHKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoXudC%2FdJMcafEWQ0f%2FMGzl7qGaZV25MsP5ikgHKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1154&quot; height=&quot;1318&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GJbKv/dJMcaiaBp4j/OJW4cAtjjt95vCkBeEXbG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GJbKv/dJMcaiaBp4j/OJW4cAtjjt95vCkBeEXbG0/img.png&quot; data-origin-width=&quot;2038&quot; data-origin-height=&quot;1518&quot; data-is-animation=&quot;false&quot; style=&quot;width: 59.8228%;&quot; data-widthpercent=&quot;60.53&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GJbKv/dJMcaiaBp4j/OJW4cAtjjt95vCkBeEXbG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGJbKv%2FdJMcaiaBp4j%2FOJW4cAtjjt95vCkBeEXbG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2038&quot; height=&quot;1518&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.ticketa.co/events/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.ticketa.co/events/32&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1763021424430&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2025 당근 플랫폼 밋업 | 티켓타코&quot; data-og-description=&quot;당근 플랫폼 밋업 2025 주관: 당근 일자: 2025년 11월 07일 (금요일) 13시 30분 ~ 19시 00분 장소: 서울특별시 서초구 강남대로 465 교보타워 A동 23층 드림홀 행사 소개 플랫폼 밋업이란? 플랫폼 밋업은 당&quot; data-og-host=&quot;www.ticketa.co&quot; data-og-source-url=&quot;https://www.ticketa.co/events/32&quot; data-og-url=&quot;https://www.ticketa.co/events/32&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cmSXah/hyZNCxjuHV/0TRdKNBpMLoKgNqJzaE8H0/img.jpg?width=600&amp;amp;height=800&amp;amp;face=0_0_600_800,https://scrap.kakaocdn.net/dn/c4Tp2v/hyZNyaBz0t/GnAxdgu4ALDg1nmaEHyshk/img.jpg?width=600&amp;amp;height=800&amp;amp;face=0_0_600_800,https://scrap.kakaocdn.net/dn/ydfcb/hyZNyuTtP2/eIo0tK9fT079gwrd9sr4tK/img.jpg?width=800&amp;amp;height=1067&amp;amp;face=0_0_800_1067&quot;&gt;&lt;a href=&quot;https://www.ticketa.co/events/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.ticketa.co/events/32&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cmSXah/hyZNCxjuHV/0TRdKNBpMLoKgNqJzaE8H0/img.jpg?width=600&amp;amp;height=800&amp;amp;face=0_0_600_800,https://scrap.kakaocdn.net/dn/c4Tp2v/hyZNyaBz0t/GnAxdgu4ALDg1nmaEHyshk/img.jpg?width=600&amp;amp;height=800&amp;amp;face=0_0_600_800,https://scrap.kakaocdn.net/dn/ydfcb/hyZNyuTtP2/eIo0tK9fT079gwrd9sr4tK/img.jpg?width=800&amp;amp;height=1067&amp;amp;face=0_0_800_1067');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2025 당근 플랫폼 밋업 | 티켓타코&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;당근 플랫폼 밋업 2025 주관: 당근 일자: 2025년 11월 07일 (금요일) 13시 30분 ~ 19시 00분 장소: 서울특별시 서초구 강남대로 465 교보타워 A동 23층 드림홀 행사 소개 플랫폼 밋업이란? 플랫폼 밋업은 당&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.ticketa.co&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/컨퍼런스</category>
      <category>당근 MEETUP</category>
      <category>컨퍼런스</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/130</guid>
      <comments>https://pypystory.tistory.com/130#entry130comment</comments>
      <pubDate>Thu, 13 Nov 2025 17:12:18 +0900</pubDate>
    </item>
    <item>
      <title>[짧글] AWS에 소소한 Bug-report 보내기</title>
      <link>https://pypystory.tistory.com/129</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;캡스톤 프젝을 하다가, STT 기능을 AWS Transcribe를 써서 구현할 일이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때, web console을 이용해서, Vocabulary Filter를 추가할 일이 생겼는데 눈에 밟히는게 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래가 바로 문제의 창이었는데 뭐가 문제인지 보이시나요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUEv3f/dJMcagRm5Xi/teSm8DqgxLXpK4KdCDxbVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUEv3f/dJMcagRm5Xi/teSm8DqgxLXpK4KdCDxbVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUEv3f/dJMcagRm5Xi/teSm8DqgxLXpK4KdCDxbVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUEv3f%2FdJMcagRm5Xi%2FteSm8DqgxLXpK4KdCDxbVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;504&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;바로바로...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제일 아래 파일 선택 부분에 &lt;b&gt;지원하는 파일 확장자에 csv가 scv로 적혀있었다&lt;/b&gt;. 사소한 typo 문제이긴 하지만 AWS 같은 큰 기업에서, 실제 사용자와 맞대는 부분에 이런 실수도 나오는구나 싶었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnWGzd/dJMcaaXVj4P/eKpPHZYHF38oIB4aARjToK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnWGzd/dJMcaaXVj4P/eKpPHZYHF38oIB4aARjToK/img.png&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;478&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; width=&quot;473&quot; height=&quot;269&quot; data-widthpercent=&quot;58.89&quot; style=&quot;width: 58.2082%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnWGzd/dJMcaaXVj4P/eKpPHZYHF38oIB4aARjToK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnWGzd%2FdJMcaaXVj4P%2FeKpPHZYHF38oIB4aARjToK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO7kpo/dJMcacVJUZu/Ln21cuhFnB87S4e9CdibSK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO7kpo/dJMcacVJUZu/Ln21cuhFnB87S4e9CdibSK/img.jpg&quot; data-origin-width=&quot;249&quot; data-origin-height=&quot;203&quot; data-is-animation=&quot;false&quot; style=&quot;width: 40.629%;&quot; data-widthpercent=&quot;41.11&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO7kpo/dJMcacVJUZu/Ln21cuhFnB87S4e9CdibSK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO7kpo%2FdJMcacVJUZu%2FLn21cuhFnB87S4e9CdibSK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;249&quot; height=&quot;203&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;형이 왜 여기서 나와&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;혹시 영문도 문제가 있나 확인해보았지만, 아무래도 번역할 때 문제가 있었는듯하다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUm0qf/dJMcadG68LQ/zL5L6qTO3goVkK06lICjek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUm0qf/dJMcadG68LQ/zL5L6qTO3goVkK06lICjek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUm0qf/dJMcadG68LQ/zL5L6qTO3goVkK06lICjek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUm0qf%2FdJMcadG68LQ%2FzL5L6qTO3goVkK06lICjek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;355&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 소소하지만 AWS를 좋아하는 사람으로서 나름의 contribute를 하고자, bug-report를 보내보기로 했다. 찾아보니 AWS에서는 re:Post 라는 공식 게시판 / 커뮤니티 같은 사이트를 운영하고 있었고, 여기에 글을 써보기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://repost.aws/en/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://repost.aws/en/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1762778519321&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Minor Bug Report: AWS Web Console &amp;ndash; Amazon Transcribe&quot; data-og-description=&quot;Hello, I&amp;rsquo;m currently using the AWS Web Console with the language set to Korean. While using Amazon Transcribe, I found a minor typo on the &amp;ldquo;Create and Import Custom Vocabulary&amp;rdquo; screen. It seems t...&quot; data-og-host=&quot;repost.aws&quot; data-og-source-url=&quot;https://repost.aws/en/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&quot; data-og-url=&quot;https://repost.aws/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfl9aA/hyZNGTMDCi/aZW6k3sPJKQwz15ONXRvLk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://repost.aws/en/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://repost.aws/en/questions/QUyOHTI9rWRzuTo7xU-PO95Q/minor-bug-report-aws-web-console-amazon-transcribe&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfl9aA/hyZNGTMDCi/aZW6k3sPJKQwz15ONXRvLk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Minor Bug Report: AWS Web Console &amp;ndash; Amazon Transcribe&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hello, I&amp;rsquo;m currently using the AWS Web Console with the language set to Korean. While using Amazon Transcribe, I found a minor typo on the &amp;ldquo;Create and Import Custom Vocabulary&amp;rdquo; screen. It seems t...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;repost.aws&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;s&gt;버그 리포트라고 하기엔 너무 거창한거 같아서, 'Minor'를 붙여줬다.&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그랬더니 1분도 지나지않아 답변이 달리길래 CS팀 속도에 감탄하려던 찰나, AI가 답변을 남겨줬다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;1070&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pMVw4/dJMcaaKoehV/7EKpkEAyRDB60gLIpfLPBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pMVw4/dJMcaaKoehV/7EKpkEAyRDB60gLIpfLPBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pMVw4/dJMcaaKoehV/7EKpkEAyRDB60gLIpfLPBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpMVw4%2FdJMcaaKoehV%2F7EKpkEAyRDB60gLIpfLPBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;506&quot; data-origin-width=&quot;1404&quot; data-origin-height=&quot;1070&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오ㅋㅋ 바로 인정하고, 관련 팀에 전달하겠으며 고맙다는 내용이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;분명 LLM을 쓰긴했을텐데, 굉장히 매끄럽고 상황 분석도 정확했다. 1분도 걸리지 않은걸로 봐서 gpt-5-thinking 같은 무거운 모델은 아닌 것 같고, 내부 모델에 docs를 검색하도록 RAG 같은걸 붙여쓸까? 아마 Sources가 같이 나온걸보니 RAG를 썼지 않을까 생각해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수정이 될지, 얼마만에 수정이 될지 궁금하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;틈틈이 들어가서 확인해봐야겠다.&lt;/p&gt;</description>
      <category>짧은 글</category>
      <category>AWS</category>
      <category>bug-report</category>
      <category>re:Post</category>
      <category>transcribe</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/129</guid>
      <comments>https://pypystory.tistory.com/129#entry129comment</comments>
      <pubDate>Mon, 10 Nov 2025 21:55:06 +0900</pubDate>
    </item>
    <item>
      <title>[해커톤] Amazon Q Developer Hackathon 2025 참가 및 대상 수상 후기 (2025.09.05.~2025.09.06.)</title>
      <link>https://pypystory.tistory.com/128</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1072&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I0aLk/btsQrnJRIok/70TIIA7LZPmdk0fOvBZKkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I0aLk/btsQrnJRIok/70TIIA7LZPmdk0fOvBZKkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I0aLk/btsQrnJRIok/70TIIA7LZPmdk0fOvBZKkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI0aLk%2FbtsQrnJRIok%2F70TIIA7LZPmdk0fOvBZKkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1916&quot; height=&quot;1072&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;1072&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;군대를 전역하고, 한동안 블로그에 손을 대지 못하다가 정말 오랜만에 글을 써본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전역하자마자 복학을 하여 1학기는 정신없이 보낸 것 같고, 여름방학부터 AUSG을 포함해서 대외활동을 조금씩 시도해보고 있던 와중, 좋은 기회가 닿아 Amazon Q라는 해커톤에 참가할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이틀동안 진행된 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;기간은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;짧은 대회였지만, 대상을 수상한 것과 별개로 개인적으로 배우고 느낀점이 많았던 대회였던지라, 중간고사가 끝난 지금 시간을 내어 두 달만에 회고글을 작성해보려한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;1082&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3bObt/btsQofz0L3b/eREKES5ISMVASAnMRT1z8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3bObt/btsQofz0L3b/eREKES5ISMVASAnMRT1z8K/img.png&quot; data-alt=&quot;역전의 용사들 팀원들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3bObt/btsQofz0L3b/eREKES5ISMVASAnMRT1z8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3bObt%2FbtsQofz0L3b%2FeREKES5ISMVASAnMRT1z8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;490&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;1082&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;역전의 용사들 팀원들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최종 결과물: &lt;a href=&quot;https://github.com/americano212/amazon-q-hackathon&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/americano212/amazon-q-hackathon&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;pre-해커톤&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AUSG(&lt;span style=&quot;background-color: #ffffff; color: #1f2937; text-align: start;&quot;&gt;AWSKRUG University Student Group)&lt;/span&gt; 슬랙에 해커톤 공고를 올려주셨는데, 1등 상품이 무려 맥북프로..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;나갈까 말까 다이어리를 보며 고민하던 찰나에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;현숙님께서&lt;span&gt; 먼저 DM을 주셔서 팀을 모으게 되었다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sVDx6/btsQoDm8JQi/6CFGSwPRK7jDqsxYm52VW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sVDx6/btsQoDm8JQi/6CFGSwPRK7jDqsxYm52VW0/img.png&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;634&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.8842%; margin-right: 10px;&quot; data-widthpercent=&quot;50.47&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sVDx6/btsQoDm8JQi/6CFGSwPRK7jDqsxYm52VW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsVDx6%2FbtsQoDm8JQi%2F6CFGSwPRK7jDqsxYm52VW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1240&quot; height=&quot;634&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbfcbr/btsQoPugP9X/qawjjAKAArNTDGPezHg4v0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbfcbr/btsQoPugP9X/qawjjAKAArNTDGPezHg4v0/img.png&quot; data-origin-width=&quot;2046&quot; data-origin-height=&quot;1066&quot; data-is-animation=&quot;false&quot; style=&quot;width: 48.953%;&quot; data-widthpercent=&quot;49.53&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbfcbr/btsQoPugP9X/qawjjAKAArNTDGPezHg4v0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbfcbr%2FbtsQoPugP9X%2FqawjjAKAArNTDGPezHg4v0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2046&quot; height=&quot;1066&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사실 해커톤 참가 확정이 늦어져서(해커톤 시작 이틀 전에 참가 확정이 되었다), 주제나 진행 방향에 대한 이야기를 미리 하진 못했다. 참가 확정이 되자마자 허겁지겁 해커톤을 진행할 장소를 물색하고, 각자 주제를 고민해보고 당일날 모여 이야기 해보기로 짧게 온라인 회의를 마쳤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해커톤-ing&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;주제 선정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;첫날 10시에 만나서 점심 먹기 전까지 주제를 정하고 구체화 시키는데 많은 시간을 썼던 거 같다. Amazon Q라는 생성형 AI를 잘 사용하면서도, 짧은 시간에 개발과 배포를 할 수 있고, 심사위원들의 흥미도 끌 주제를 골라야했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3osY7/btsQCtDhr08/TgKS6QN0vrVMZQeOUatn21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3osY7/btsQCtDhr08/TgKS6QN0vrVMZQeOUatn21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3osY7/btsQCtDhr08/TgKS6QN0vrVMZQeOUatn21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3osY7%2FbtsQCtDhr08%2FTgKS6QN0vrVMZQeOUatn21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;183&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각자 주제를 고민해왔고, 의견 교환을 한 끝에 '영어 학습을 위한 게이미피케이션 서비스'로 의견을 좁힐 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;영어 학습을 위해서 토익 스피킹처럼, 이미지를 보고 음성으로 이미지에 대해 설명하면, 사용자의 설명을 바탕으로 이미지를 생성해서 두 이미지 간의 유사도로 얼마나 영어로 설명을 잘했는지 판단을 하는 서비스였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;팀원 중 은지님께서 Amazon Nova Family(Sonic, Pro, Canvas)이라는 따끈따근한 모델군에 대해서, 최근에 Amazon에서 밀어주고 있기도 하고 사용해본 경험이 있다고 하셔서 해당 모델을 적극 사용해보기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개발 준비&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해커톤 특성 상 Amazon Q 해커톤이기에 Amazon Q라는 코드 생성 툴을 얼마나 잘 쓰는지도 채점 요소에 포함되어 있었다. MCP, Agent 등 다양한 기능을 최대한 살려보자는 의견으로 모아질 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리가 시도해본 것은&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. &lt;b&gt;Notion MCP&lt;/b&gt;를 통해서 notion에서 협업을 해서 Ideation을 하고, 개발에 대한 명세를 한 다음, notion MCP를 이용해 local에 markdown으로 명세를 불러오는 것이다. 불러온 명세를 Q Developer CLI에서 context로 먹여서 참고하도록 하니 품질이 더 높아졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사실 이게 Notion MCP를 써야지! 하고 나온게 아니라, 노션으로 작업하다보니 이걸 끌고 오면 편할거 같아서 낸 의견이었는데, 획기적이었다. notion에서는 여러명이 동시 읽기/수정이 부드럽기에 notion에서 함께 명세를 하고 개발할 때는 다들 MCP로 불러와서 먹이는 방식이었는데, 꽤나 좋은 방법인 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1626&quot; data-origin-height=&quot;1086&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I6FIY/dJMcagRlpxQ/unROJnDGbH74Dqh5a1zk8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I6FIY/dJMcagRlpxQ/unROJnDGbH74Dqh5a1zk8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I6FIY/dJMcagRlpxQ/unROJnDGbH74Dqh5a1zk8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI6FIY%2FdJMcagRlpxQ%2FunROJnDGbH74Dqh5a1zk8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;490&quot; height=&quot;327&quot; data-origin-width=&quot;1626&quot; data-origin-height=&quot;1086&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. &lt;b&gt;Draw.io MCP&lt;/b&gt;를 이용해서 아키텍처(CloudFormation으로 작성된)를 발표자료에 쓰기 위해서 쉽게 export 할 수 있었는데, 생각보다 괜찮게 뽑혀서 놀랐다. 원래라면 cloudcraft나 draw.io 등 드로잉 툴을 이용해서 하나하나 그려줬어야할텐데, '이거 AI로 그린거임!'하면 모두 납득할 정도의 퀄리티로 손쉽게 export 할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2398&quot; data-origin-height=&quot;1662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UPBQf/dJMcagcJWaz/nRCAi0k9vK8AoBaxV9HfwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UPBQf/dJMcagcJWaz/nRCAi0k9vK8AoBaxV9HfwK/img.png&quot; data-alt=&quot;최종 아키텍처이자. AI가 생성해준 draw.io&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UPBQf/dJMcagcJWaz/nRCAi0k9vK8AoBaxV9HfwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUPBQf%2FdJMcagcJWaz%2FnRCAi0k9vK8AoBaxV9HfwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;719&quot; height=&quot;498&quot; data-origin-width=&quot;2398&quot; data-origin-height=&quot;1662&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 아키텍처이자. AI가 생성해준 draw.io&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. &lt;b&gt;Custom Agent&lt;/b&gt; 도 사용해보았는데, 솔직히 이건 우리가 전문성 있게 역할 부여를 못해서 그런것도 있겠지만, 그냥 .md 파일로 pre-context(copilot-instructions.md 같은거) 먹이는 것과 성능면에서 큰 차이는 모르겠다. 근데, 기능 상으로 기업 레벨에서 쓸 때, AI가 접근할 수 있는 파일이나 툴 통제하고, 역할 부여하고 output_size, ttl 제어하고 그런면에서 일관성 유지하기에는 좋아보였다. 프로젝트가 커질 수록 빛을 볼 기능 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개발 진행&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;은지님께서 무료로 사용할 수 있는 장소를 대관해주셔서 첫날부터 모여서 작업할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주제 선정 이후에 각자 R&amp;amp;R을 나누고, 기술스택을 선정했다. Amazon Nova Sonic을 잘 써먹는게 우리 서비스 구현의 핵심이었는데, AWS에서 sample code로 WebSocket 통신을 이용하는 express 코드가 있었고, 마침 express를 사용 배포해본 경험이 있었기에 learning curve없이 사용할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G2BJ7/dJMcadmMz9F/xPwYdEvkvtK7Lcj65wAwI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G2BJ7/dJMcadmMz9F/xPwYdEvkvtK7Lcj65wAwI0/img.png&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;1320&quot; data-is-animation=&quot;false&quot; width=&quot;484&quot; height=&quot;563&quot; style=&quot;width: 51.1614%; margin-right: 10px;&quot; data-widthpercent=&quot;51.76&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G2BJ7/dJMcadmMz9F/xPwYdEvkvtK7Lcj65wAwI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG2BJ7%2FdJMcadmMz9F%2FxPwYdEvkvtK7Lcj65wAwI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1134&quot; height=&quot;1320&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BaIXK/dJMcabJgLAY/5Y49YCaKN7K7FEGklxDThK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BaIXK/dJMcabJgLAY/5Y49YCaKN7K7FEGklxDThK/img.png&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;1424&quot; data-is-animation=&quot;false&quot; style=&quot;width: 47.6758%;&quot; data-widthpercent=&quot;48.24&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BaIXK/dJMcabJgLAY/5Y49YCaKN7K7FEGklxDThK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBaIXK%2FdJMcabJgLAY%2F5Y49YCaKN7K7FEGklxDThK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1140&quot; height=&quot;1424&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;좌: 첫째날, 우: 둘째날&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본인은 원래는 백엔드와 인프라를 맡으려고 했으나, 생각보다 sample-code에서 많은 부분을 구현해놓았었고, Amazon API와의 연결은 은지님께서 해보신 경험이 있으셔서 내가 express를 크게 만질일은 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 인프라 설계와 배포에 집중했고, 관련된 내용에 대해서는 다음 단락에서 issue들과 함께 정리해보겠다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon Nova Family&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번에 해커톤하면서 알게된 것 중 하나인데, 바로 Nova model이다. 크게 3가지로 나눠져있었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;음성 Speach-to-Speach를 지원하는 Amazon Nova Sonic (그냥 STT/TTS가 아니라 LLM이 합쳐져서, 답변을 생성하여 대화할 수 있는 모델이다.),&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일반적인 LLM인 Amazon Nova Pro,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이미지를 생성하는 Amazon Nova Canvas이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Amazon에서 AI 모델이 많이 발달했다는 생각이 들었고, 특히 최근에 STT/TTS 프로젝트를 하고 있는데, Amazon Nova Sonic은 굉장히 자연스럽게 동작하도록 잘만들어졌었구나 하는 생각이 들었다. 별다른 튜닝 없이 Nova Sonic 그 자체만으로 대화형 챗봇을 구축할 수 있다는 점이 매력적이었다. (다만, 당연하게도 비용과의 trade-off는 있을 것이다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우리 서비스에서 Nova Sonic은 대화형 플랫폼에, Nova Pro는 이미지 결과 비교와 보고서 생성에, Nova Canvas는 사용자 설명으로 부터 이미지를 생성하는데 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;PartyRock&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이것도 이번에 해커톤하면서 처음본건데, 생성형 AI를 chaining?하여 테스트해볼 수 있는 플랫폼이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Amazon에서 공식적으로 지원하고 무료로 사용할 수 있다고 하는데, 퀄이 좋아보였다. 데이터와 AI 모델을 파이프라인으로 연결해서 테스트해볼 수 있었고, MVP 검증에 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;늘 서비스를 직접 올려서, 테스트 해봐야했는데 이런 서비스도 있다니... 편리하고 좋은 것 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2706&quot; data-origin-height=&quot;1752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zGOjB/dJMcabbqNSe/GOhycNspYowhLvpv7towLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zGOjB/dJMcabbqNSe/GOhycNspYowhLvpv7towLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zGOjB/dJMcabbqNSe/GOhycNspYowhLvpv7towLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzGOjB%2FdJMcabbqNSe%2FGOhycNspYowhLvpv7towLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;371&quot; data-origin-width=&quot;2706&quot; data-origin-height=&quot;1752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개발 중 이슈 - 트러블슈팅&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발하면서 내가 겪었던, 몇가지 기술적 이슈가 있었는데, 이슈와 해결 방법을 정리 해보려한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. IAM Role 부여 이슈&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본 해커톤을 진행하는 동안, Amazon에서 팀마다 IAM 계정을 부여해줬다. 그래서 모든 서비스를 비용 걱정없이 마음껏 써볼 수 있었는데, 이게 화근이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제는 Amazon Nova Family를 배포하는 과정에서 발생했는데, Nova Family는 Amazon Bedrock 플랫폼 위에서 돌아가고 있었고, 우리 서비스의 백엔드는 Docker로 말아서 ECS Fargate에 배포되었다. 이 배포 과정 자체는 Amazon Q CLI를 이용해서 CloudFormation을 생성하고 실행해서 인프라를 생성하고, image를 ECR에 올리고 ECS에서 해당 이미지로 run하는 방식을 자동화 시켰고 정상적으로 배포되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그런데 문제는 ECR Fargate에서 Bedrock에 요청을 보낼 때 권한을 제어할 방법이 없던 것이다. 대회용 계정이라 IAM 역할 권한이 막혀있어서 IAM Role을 부여할 수 없었던 문제가 있었다. 원래라면 ECR Fargate 자체에 IAM Role에 추가로 Bedrock 접근 권한을 열어줬으면 될 것 같은데, 이게 안열려서 한참동안 고생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과적으로 직접 IAM User를 만들고, Bedrock 권한을 넣어서 백엔드에서 직접적으로 .env에 API_KEY와 SECRET을 들고 있으면서, sdk로 호출하는 방식으로 해결하긴했는데, 보안 측면에서 좋은 방법은 아니다. (다만, 상황이 상황이니만큼 해커톤적 허용을 하는걸로...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Amazon Q의 할루시네이션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;두번째는 Amazon Q의 할루시네이션 때문에 (1)의 문제가 더 커진 것인데, 우리를 도와주시는 SA님께 (1) 문제에 대해서 말씀드리고, IAM Role 권한을 풀어달라고 요청드렸더니, Bedrock의 API Key를 이용해보라고 조언해주셨다. 결과적으로 이게 정답이었다. Bedrock에서는 접근 권한을 API Key를 부여 받아서, 서비스에서 호출할 수 있었는데, Daily Key로 해커톤이 진행되는 동안만 사용하고 폐기하면 될 일이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 이 내용을&amp;nbsp; Amazon Q에 질의해보았더니, Amazon nova sonic에서 API Key를 지원안해서 그렇게 할 수 없다는 답변을 받았다. 추정하기로는 Amazon Q가 학습될 때, Nova Sonic이 없었거나 API Key 지원을 안했을 수도 있을 것 같고, 공식 docs에서 명시적으로 해당 부분을 언급하지 않고 있어서 Amazon Q 학습에 해당 내용이 포함되지 않았나?라는 추측도 해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아무튼 이 답변 때문에 시간을 더 허비하게 되었고, 상기한 방식대로 IAM User의 ACCESS_KEY와 SECRET을 그대로 서버에 넣어버리는... 좋지 못한 패턴을 갖게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;LLM에서 생성된 답변을 맹목적으로 믿으면 안된다는 점을 다시 한번 상기시킬 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Amazon Nova Sonic에서 https만 지원&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;제 컴퓨터에서는 잘 돌아갔는데...를 느끼는 순간이었다. Nova Sonic은 localhost에서는 잘 동작하지만, production으로 배포하는 순간 https로 SSL/TLS를 지원하지 않으면, 음성 데이터를 보내서 그런지 전송 자체를 막았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2가지 해결 방법이 있었는데, 앞단에 https를 지원하도록 cloudfront 같은 CDN을 붙이거나, 도메인에 인증서를 발급 받고, CNAME으로 DNS에서 직접 ELB(ALB)를 바라보도록 할 수도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해커톤을 위해 도메인을 세팅할 필요까지는 없어서, 시연 정도를 할 수 있도록 cloudfront를 ELB 앞에 붙였고, cloudfront에서는 기본적으로 https가 적용된 endpoint를 제공하기에 이제 다 되었구나 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. CloudFront에서 websocket 사용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;잘 배포가 되었다 생각했는데, 이제 Nova Sonic까지 잘 붙었는데, 녹음된 데이터가 뒷단으로 넘어가지 않는 문제가 발생했다... 확인해보니 CloudFront에서는 websocket을 사용할 때 별도의 설정을 줘야한다더라...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Amazon Q를 이용해서 CloudFormation에 추가적인 속성을 넣었고, Cloudfront에서도 websocket을 지원하도록 수정할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정말 1박 2일 동안 해커톤인데, 실전 압축으로 많은 지식을 배울 수 있었다. 위의 모든 과정을 github actions으로 자동 trigger해서 배포되게 하는 것까지가 나의 임무였다. 그렇게 해커톤을 마무리할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHYfir/dJMcagqheBA/b9iY5f6juDYlTwk4fRMeTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHYfir/dJMcagqheBA/b9iY5f6juDYlTwk4fRMeTk/img.png&quot; data-alt=&quot;서비스 주요 이미지. 왼쪽을 바탕으로 영어로 설명을 하면 오른쪽 이미지를 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHYfir/dJMcagqheBA/b9iY5f6juDYlTwk4fRMeTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHYfir%2FdJMcagqheBA%2Fb9iY5f6juDYlTwk4fRMeTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1601&quot; height=&quot;1018&quot; data-origin-width=&quot;1601&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서비스 주요 이미지. 왼쪽을 바탕으로 영어로 설명을 하면 오른쪽 이미지를 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해커톤 결과&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;둘째날은 강남역 인근 스터디룸을 대관해서 새벽에 개발을 하다가, 역삼 센터필드의 AWS 회의실?, 컨퍼런스 룸?으로 이동해서 진행했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sQuTK/dJMcafSrh8W/IrJu6RV6RbUmblEGaygqE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sQuTK/dJMcafSrh8W/IrJu6RV6RbUmblEGaygqE0/img.png&quot; data-origin-width=&quot;1241&quot; data-origin-height=&quot;832&quot; data-is-animation=&quot;false&quot; width=&quot;476&quot; height=&quot;319&quot; data-widthpercent=&quot;65.79&quot; style=&quot;width: 65.024%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sQuTK/dJMcafSrh8W/IrJu6RV6RbUmblEGaygqE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsQuTK%2FdJMcafSrh8W%2FIrJu6RV6RbUmblEGaygqE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1241&quot; height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rt2FI/dJMcafkBjOC/IKTyu1krDmxkKTIyGsg2aK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rt2FI/dJMcafkBjOC/IKTyu1krDmxkKTIyGsg2aK/img.png&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;624&quot; data-is-animation=&quot;false&quot; style=&quot;width: 33.8132%;&quot; data-widthpercent=&quot;34.21&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rt2FI/dJMcafkBjOC/IKTyu1krDmxkKTIyGsg2aK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frt2FI%2FdJMcafkBjOC%2FIKTyu1krDmxkKTIyGsg2aK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;484&quot; height=&quot;624&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;최종 발표장&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발 종료 후 발표는 팀장이신 현숙님께서 맡아주셨다. 1차적으로 AWS 측 심사위원(아마 SA분이시지 않을까) 두 분께 10분 발표를 진행하고, 최종 4팀을 선정해서 2차 발표를 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과물이 잘 뽑혀서 내심 기대는 했지만, 다른 팀들도 직장인 단위로도 많이 참가하시기도해서 기대 반, 걱정 반인 상태로 발표를 지켜봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1차 발표 후 심사위원 분들께서 좋은 피드백을 많이 해주셨는데, 그 중 제일 기억에 남는 말은 '이거 다른 공모전에 낸적 없는거 맞냐?'라는 말을 들었을 때, 수상 가능성이 있겠다는 확신이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇게 2차 발표 대상으로 선정되어 발표까지 마무리를 하고, 상호평가 +&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;모든 심사위원 분들의 평가를 받았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최종적으로 대상 수상을 할 수 있었고, 맥북프로/5 를 부상으로 받았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC2tVr/dJMcabbqV5D/kmZ8wZ5y2O9elKap3p81K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC2tVr/dJMcabbqV5D/kmZ8wZ5y2O9elKap3p81K1/img.png&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;858&quot; data-is-animation=&quot;false&quot; style=&quot;width: 58.798%; margin-right: 10px;&quot; data-widthpercent=&quot;59.49&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC2tVr/dJMcabbqV5D/kmZ8wZ5y2O9elKap3p81K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC2tVr%2FdJMcabbqV5D%2FkmZ8wZ5y2O9elKap3p81K1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1254&quot; height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s1wi2/dJMcaezeeFg/MTZ3mbLMZ4tKcRKM45BrJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s1wi2/dJMcaezeeFg/MTZ3mbLMZ4tKcRKM45BrJ0/img.png&quot; data-origin-width=&quot;629&quot; data-origin-height=&quot;632&quot; data-is-animation=&quot;false&quot; style=&quot;width: 40.0392%;&quot; data-widthpercent=&quot;40.51&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s1wi2/dJMcaezeeFg/MTZ3mbLMZ4tKcRKM45BrJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs1wi2%2FdJMcaezeeFg%2FMTZ3mbLMZ4tKcRKM45BrJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;좋은 팀원들과 함께했기에 결과물도 잘 뽑히고, 대회 성적도 좋을 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;느낀점&amp;amp;배운점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대부분의 코드를 생성형 AI만 써서, 개발해본 건 처음이었는데, 확실히 아직 바이브 코딩만으로 모든 개발을 대체하기엔 어려운 부분도 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하지만, 결국 AI를 이용한 코딩을 했을 때 생산성이 기하급수적으로 상승하는 것은 자명한 사실이자 시대의 흐름이고, 이 또한 하나의 도구로서 어떻게 하면 잘 쓸 수 있을지 공부해야하는 시대가 왔다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가령 Amazon Q CLI를 잘 쓰는 방법을 공부하는 것이, 새로운 언어나 프레임워크를 배우는 것과 비슷하다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 발표자 분들을 보면서도 느꼈지만, 우리보다 생성형 AI를 훨씬 잘 쓰시는 분들도 많았고, 서비스 fit하게 이용하시는 모습을 보면서 감탄했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AI 모델에 대해서도 많이 무지했던 것 같아서, 전체적으로 기초가 되는 지식들을 공부해야겠다는 동기부여가 되었고, 그동안 써보지 못한 다양한 서비스를 사용해볼 수 있어서 좋은 공부였던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;a href=&quot;https://github.com/americano212/amazon-q-hackathon&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/americano212/amazon-q-hackathon&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;a href=&quot;https://github.com/aws-samples/amazon-nova-samples/tree/main/speech-to-speech/sample-codes&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/aws-samples/amazon-nova-samples/tree/main/speech-to-speech/sample-codes&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>대회</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/128</guid>
      <comments>https://pypystory.tistory.com/128#entry128comment</comments>
      <pubDate>Wed, 5 Nov 2025 01:04:39 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - 데이터베이스 엔진, 커서 (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBklCK/btsL4Nz0fBj/9N3TDPM6nJDMtQ2paEUP10/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBklCK/btsL4Nz0fBj/9N3TDPM6nJDMtQ2paEUP10/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBklCK/btsL4Nz0fBj/9N3TDPM6nJDMtQ2paEUP10/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBklCK%2FbtsL4Nz0fBj%2F9N3TDPM6nJDMtQ2paEUP10%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2htS1/btsL4M2gmOX/8iI2pudIKJKHETbLJk8fx0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2htS1/btsL4M2gmOX/8iI2pudIKJKHETbLJk8fx0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2htS1/btsL4M2gmOX/8iI2pudIKJKHETbLJk8fx0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2htS1%2FbtsL4M2gmOX%2F8iI2pudIKJKHETbLJk8fx0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;309&quot; height=&quot;309&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터베이스 엔진&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터베이스 엔진이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실제 디스크에 CRUD 작업을 처리하는 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 크게 2가지로 나눌 수 있음. 디스크에 데이터를 저장하는 것과 실제로 작업을 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단순히 key-value를 저장하는데 그칠 수도 있고, 완전한 ACID 트랜잭션을 지원하기 위해서 복잡할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터베이스&amp;nbsp; 엔진은 단순히 데이터를 저장하는 것뿐 아니라, Master-Slave 구조를 이루게 하거나 프로시저를 저장하는 등 엔터프라이즈 레벨에서 사용되는 다양한 기능을 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DBMS는 데이터베이스 엔진을 사용하여 그 위에 기능을 구축할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- use case에 따라 엔진을 고르기만 하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL &amp;amp; MariaDB와 같은 몇몇의 DBMS는 DB엔진을 변경할 수 있는 유연함을 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Postgres를 포함한 대부분은 내장 엔진이라 교체할 수 없음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터베이스 엔진 별 특징&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MyISAM&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Indexed sequential access method(인덱스 순차 접근 방법)의 줄임말&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-tree 인덱스들이 행을 직접 가리킴, 기본 키가 없음. (모든 게 인덱스여서 필요가 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션 지원 없음 (ACID x)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 삽입이 빠르고, 업데이트와 삭제는 문제가 있음(조각을 만들어냄)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 삽입은 파일 끝만 알면 되기 때문에 매우 빠르지만, 수정/삭제는 전체 파일의 구조를 변경하는 것이기에 느림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB가 충돌 나면 테이블이 손상됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블 수준 잠금 지원, 행 수준 잠금 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL 5.5까지는 MyISAM이 기본 엔진이었으나, 행 수준 잠금, 트랜잭션 지원을 위해 넘어감&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;InnoDB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B+tree로 항상 기본 키가 있어, index는 기본키를 가리킴(직접 행을 가리키지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL과 MariaDB의 default&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ACID 준수, 외래키 지원, 트랜잭션 지원, 테이블 스페이스 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 행 레벨 잠금 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 오라클의 소유&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;XtraDB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- InnoDB의 fork&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MariaDB 10.1까지 사용하다가 XtraDB는 InnoDB의 최신상태를 따라가지 못해, 10.2부터는 InnoDB로 default가 바뀜&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SQLite&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 매우 인기 있는 임베디드 로컬 데이터베이스 (운영체제, Web 등등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-Tree 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Postgres와 유사함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전한 ACID 지원, 테이블 수준 락 (행 잠금 X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동시에 읽고 쓸 수 있음&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aria&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MyISAM과 유사함 (오라클에서 벗어남)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MyISAM보다 충돌에 안전하도록 고침&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특히 MariaDB를 위해 설계됨&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Berkeley DB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 현재 오라클이 소유 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Key-value 내장형 데이터베이스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ACID, 트랜잭션, 락, 복제 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 때 bit coin core로 사용됨(현재는 LevelDB로 변경)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MemcacheDB에 사용되고 있음&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;LevelDB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Google에서 만듦, &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;빠른 삽입이 가능한 DB를 원함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- LSM tree 이용, SSD에 좋음(SSD는 업데이트에 대해 수명에 영향을 받음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일마다 레벨이 있음 (Memtable(메모리 테이블에 쓸 때, WAL(디스크에 커밋 로그 기록)을 통해 데이터 안정성 확보), 속도에 따라 Level 0~6&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일이 커지면, 더 큰 레벨은 병합되어 디스크로 보내짐&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Bit coin core, AutoCAD, Minecraft에서 사용&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RocksDB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Facebook에서 만듦, LevelDB를 fork&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- LSM사용, 트랜잭션 지원, ACID 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 높은 퍼포먼스, 멀티스레드 압축 지원 (LevelDB는 단일 스레드)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터베이스 커서&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;커서란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커서는 쿼리를 실행시키지 않고, 실행 계획만 짜서 declare 할 수 있음. 필요할 때 fetch 하면 N개의 행씩 가져올 수 있음. (한 번에 다 가져와서 처리하는 게 아닌, 조금씩 처리하는 것)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커서를 쓰면 DB에 연결된 백엔드 응용프로그램에서 클라이언트 측 메모리를 절약할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커서를 쓰면 스트리밍을 할 수 있음. 계속해서 행을 다른 웹 소켓 연결로 스트리밍 가능. (gRPC 등)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커서는 상태를 유지함. 데이터베이스에 할당된 메모리와 해당 커서를 가리키는 트랜잭션이 존재하게 됨. 이는 다른 서버나 프로세스에서 요청을 보내면 그 프로세스는 커서에 대해 알지 못하기에 기본적으로 커서를 공유할 수 없음. (이런 상황에서는 페이징이 더 좋을 수도 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장기간 실행되는 프로덕션에 커서를 사용하면, 트랜잭션이 장기간 실행되어 인덱싱이나 DDL을 정상 수행 못하는 등 DB에 좋지 못함.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서버 측 vs 클라이언트 측 커서&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트(예를 들면 python) 측 커서: 데이터베이스와 연결할 때 클라이언트에서 커서를 생성한 후, DB에서 쓰기/읽기 작업을 수행함. 쿼리의 모든 결과는 실행되고 네트워크를 통해 클라이언트에 전달됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버(DB) 측 커서: 데이터베이스에서 커서가 생성되고, 절대적으로 필요할 때만 그 결과를 가져오게 됨. 결과는 실제로 서버에서 실행되고 저장되며, 클라이언트는 점진적으로 가져오게 됨&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;클라이언트 측 커서&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점: 서버 측 오버헤드를 최소화, 데이터를 클라이언츠 측에서 메모리에 할당하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단점: 네트워크 대역폭에 문제 발생. 클라이언트 측 메모리가 부족할 경우 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;서버 측 커서&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점: 많은 행을 처리할 때 나눠서 처리할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단점: 많은 커서들이 누적되면, 메모리 leak 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;상황에 따라 올바른 방법 사용 필요&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>db cursor</category>
      <category>db 엔진</category>
      <category>db 커서</category>
      <category>InnoDB</category>
      <category>leveldb</category>
      <category>MyISAM</category>
      <category>rocksdb</category>
      <category>sqlite</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/125</guid>
      <comments>https://pypystory.tistory.com/125#entry125comment</comments>
      <pubDate>Sun, 2 Feb 2025 23:25:23 +0900</pubDate>
    </item>
    <item>
      <title>[해커톤] 2025 Blaybus 실전 앱 개발 경진대회 참가 및 수상 후기 (2025.01.05.~2025.01.17.)</title>
      <link>https://pypystory.tistory.com/124</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3709&quot; data-origin-height=&quot;2087&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zijCy/btsL5s20IAy/sLKoHgmvGkhIuc4ryNczyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zijCy/btsL5s20IAy/sLKoHgmvGkhIuc4ryNczyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zijCy/btsL5s20IAy/sLKoHgmvGkhIuc4ryNczyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzijCy%2FbtsL5s20IAy%2FsLKoHgmvGkhIuc4ryNczyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;739&quot; height=&quot;416&quot; data-origin-width=&quot;3709&quot; data-origin-height=&quot;2087&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;팀원 모집&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;한동안 개인 프로젝트만 하면서 복학 준비를 하던 중, 과 동기가 같이 대회를 나가보자는 제안을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공고를 보니 일반적인 해커톤과 다르게 '모바일 앱'을 타겟으로 진행한다는 점과, 사측에서 직접 사용할 서비스를 만든다는 점이 재미있어 보였고, 진행기간도 10일 정도로 적당해서 참가를 결정하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;무엇보다 개발자들만 모아서하는게 아닌 PM과 디자이너를 따로 모집해서 협업할 수 있다는 점도 좋은 경험이 될 것 같았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckxl3H/btsL4cmCQXV/CvD0vyH9UtaJYKtCkLe8qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckxl3H/btsL4cmCQXV/CvD0vyH9UtaJYKtCkLe8qk/img.png&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1977&quot; data-is-animation=&quot;false&quot; width=&quot;320&quot; height=&quot;586&quot; data-widthpercent=&quot;26.88&quot; style=&quot;width: 26.5682%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckxl3H/btsL4cmCQXV/CvD0vyH9UtaJYKtCkLe8qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fckxl3H%2FbtsL4cmCQXV%2FCvD0vyH9UtaJYKtCkLe8qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1080&quot; height=&quot;1977&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNXDL9/btsL2PFMTr1/k5mGS7lym7RtLCcg4c35M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNXDL9/btsL2PFMTr1/k5mGS7lym7RtLCcg4c35M1/img.png&quot; data-origin-width=&quot;1376&quot; data-origin-height=&quot;926&quot; data-is-animation=&quot;false&quot; width=&quot;771&quot; height=&quot;519&quot; data-widthpercent=&quot;73.12&quot; style=&quot;width: 72.269%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNXDL9/btsL2PFMTr1/k5mGS7lym7RtLCcg4c35M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNXDL9%2FbtsL2PFMTr1%2Fk5mGS7lym7RtLCcg4c35M1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1376&quot; height=&quot;926&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;구인구직&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대회 진행은 개인 혹은 팀으로 신청해서 참가자로 선정되면, 디스코드로 본인 어필을 통해 팀원을 추가 모집할 수 있는 방식이었다. 같이 신청한 팀원도 백엔드 경험을 쌓기를 희망했기에 디스코드에서 열심히 프론트 개발자, 기획자, 디자이너를 찾아다녔고, 디자이너, 기획자까지는 적극적으로 컨텍하고 다녔더니 어렵지 않게 구할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그런데...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;팀 매칭 마지막 날까지 프론트엔드 개발자를 구하지 못하는 이슈가 생겼다. 아무래도 앱 개발 해커톤이라 진입장벽이 있었던 것 같다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇게 프론트 전문 개발자 없이, 어째 저째 플러터 with GPT라도 써서 갈아 넣어야 하나 고민하던 찰나...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;205&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4pTvO/btsL4XWyHFE/ZlRdRtuWWUv1PqrYib6VOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4pTvO/btsL4XWyHFE/ZlRdRtuWWUv1PqrYib6VOK/img.png&quot; data-alt=&quot;PM1명 프론트1명이 추가된다고 했는데, 프론트만 한 분 더 오셨다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4pTvO/btsL4XWyHFE/ZlRdRtuWWUv1PqrYib6VOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4pTvO%2FbtsL4XWyHFE%2FZlRdRtuWWUv1PqrYib6VOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;431&quot; height=&quot;138&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;205&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PM1명 프론트1명이 추가된다고 했는데, 프론트만 한 분 더 오셨다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주최 측에서 마지막까지 남은 인원에 대해 랜덤 팀매칭을 해주셔서, 극적으로 프론트 개발자분이 한 분 더 합류하게 되었다! (끝나고 생각해 보니 만약 안 구해졌더라면.. 아찔했다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;총 5명(PM1, DE1, FE1, BE2)에서 10일 동안 개발을 진행하게 되었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주제 및 대회 진행&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;대회는 두핸즈라는 스타트업에서 의뢰(?)한 내용을 수행하는 것인데, &lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;주제는&lt;span&gt; &lt;/span&gt;&lt;/span&gt;'두핸즈 구성원의 성과관리를 위한 사내 게이미피케이션 앱 개발'이다. 기존에 사측에서 사용하는 인사 정보 체계(Google Spread Sheet)를 기반으로 구성원 개인이 본인의 성과를 실시간으로 확인하여 동기부여를 얻게 하는 것이 목표였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;처음에는 주제의 자유도가 떨어진다고, 생각했는데 고민할 수록 주어진 데이터로 풀어낼 수 있는 방법이 다양하게 나와서 이런 방식의 해커톤도 신선했다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주최 측 이벤트로 중간 인증샷을 찍어 올리는 팀 미션이 있었는데, 우리 팀은 온라인으로 진행하면서 매일 정기적으로 회의만 진행했는데, 몇몇 팀은 오프라인으로 모여서 진행하는 팀도 있었다. &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;902&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxh8N7/btsL4ahZ59W/dsGTNKzZ9HvHcwDjrhmMwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxh8N7/btsL4ahZ59W/dsGTNKzZ9HvHcwDjrhmMwk/img.png&quot; data-alt=&quot;Blaybus 협업 툴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxh8N7/btsL4ahZ59W/dsGTNKzZ9HvHcwDjrhmMwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxh8N7%2FbtsL4ahZ59W%2FdsGTNKzZ9HvHcwDjrhmMwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;769&quot; height=&quot;475&quot; data-origin-width=&quot;1459&quot; data-origin-height=&quot;902&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Blaybus 협업 툴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #1f2328;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;주최 측에서 제공되는 협업 툴을 사용해야 하는 규정이 있었는데, Jira/Asana 같은 느낌으로 에자일 하게 협업할 수 있는 툴이었다. 다른 툴과 달리 내가 실제로 일한 시간을 기록하고 팀원들과 비교해 볼 수 있는 게 특징이었는데, 서로 진행 상황을 보면서 더 자극을 받아서 개발할 수 있었다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;백엔드 설계&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대회가 시작하자마자 빠르게 기획 회의에서 나온 아이디어를 바탕으로 ERD부터 정리하고 깃헙, AWS, CI/CD부터 세팅했다. 그동안 개인 프젝들을 해오면서 짜놨던 boilerplate와 terraform이 빛을 보는 순간이었다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ma3EH/btsL5lQrqoQ/fA2rU8tzZ0tqJKIdKfu451/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ma3EH/btsL5lQrqoQ/fA2rU8tzZ0tqJKIdKfu451/img.png&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;748&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; width=&quot;681&quot; height=&quot;499&quot; style=&quot;width: 45.5867%; margin-right: 10px;&quot; data-widthpercent=&quot;46.12&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ma3EH/btsL5lQrqoQ/fA2rU8tzZ0tqJKIdKfu451/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMa3EH%2FbtsL5lQrqoQ%2FfA2rU8tzZ0tqJKIdKfu451%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1021&quot; height=&quot;748&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwrGx/btsL4wd6UEJ/auHhWHmoQPtTb6z9fNFtr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwrGx/btsL4wd6UEJ/auHhWHmoQPtTb6z9fNFtr1/img.png&quot; data-origin-width=&quot;1148&quot; data-origin-height=&quot;720&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;53.88&quot; data-filename=&quot;blob&quot; style=&quot;width: 53.2505%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwrGx/btsL4wd6UEJ/auHhWHmoQPtTb6z9fNFtr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmwrGx%2FbtsL4wd6UEJ%2FauHhWHmoQPtTb6z9fNFtr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1148&quot; height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;ERD와 인프라 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프론트엔드 개발자분과 회의를 통해 swagger로 API 문서화를 해드리기로 했고, 비대면으로 진행하는 만큼 API 문서를 작성할 때, 상세하게 명세하려 노력했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;고민한 부분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주최 측의 요구사항으로 웹/앱으로 된 관리자 페이지 대신, 기존에 사용하던 인사관리 시스템인 Google Spread Sheet(이하 구글 시트)와 연동되어야 했는데, 별도의 DB를 유지하면서 구글 시트와 동기화 유지를 위해서, 데이터 일관성에 대한 고민을 많이 하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;구글 시트는 한명의 사용자가 쓰는 것도 아니고, 여러 명이 동시에 수정을 할 수 있는 특징이 있으며, format을 제한하지 않기에 사용자 실수에 의해 invalid 한 데이터가 입력될 수도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또한, 구글 시트에 입력된 데이터가 DB에 2번 write되거나, write 되지 않는 상태가 되면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음에는 구글 시트에서 Apps Script를 이용해서 구글 시트에서 Data Change를 트리거로, 백엔드 API를 호출해서 DB에 데이터를 write(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;update&lt;/span&gt;)하는 것을 고려해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 이 경우에 만약 2명의 관리자 A, B가 동일 칸에 다른 데이터를 동시에 업데이트하였을 때, 구글 시트 상에는 나중에 입력된 B의 데이터가 기록되었지만, 네트워크 지연이나 DB lock 등의 이유로 인해 DB에는 A가 입력한 데이터가 기록되는 상태가 될 수 있다. 각 상황별로 rollback 하는 전략을 app script로 구현할 수 있을지는 모르겠지만 비효율적이라 판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 생각해 낸 방법이 백엔드에서 Task Scheduling으로 batch작업을 하고, 이걸 한 트랜잭션으로 묶는 방법을 이용했다. 구글 시트에서 Data Change가 될 때마다 기록하는 방식보다는 실시간성이 떨어지겠지만, 서비스 특성을 고려했을 때 30초/1분의 공백이 생기더라도 UX 측면에서 불편함이 없을 것이라 판단했고, 데이터 양을 고려했을 때 트래픽 문제도 없을 것이라 생각했다. 무엇보다 데이터의 무결성이 더 중요하다고 판단했다.&amp;nbsp;NestJS에서는 '@nestjs/schedule'을 기본적으로 지원하고 있었고, 동기화를 구현할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;최종 결과물 및 파이널데이&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최종적으로 10일 만에 주최 측의 모든 요구사항을 충족하는 앱을 출시할 수 있었고, 파이널 데이에 참석했다. 마침 팀원분들도 파이널데이가 금요일 낮 시간대임에도, 5명 모두 오실 수 있다고 해서 무리 없이 시연과 발표 질의응답을 준비할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1804&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPrBm4/btsL3ycAXZ4/mPBaSUF9TYtWtLOymwOdQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPrBm4/btsL3ycAXZ4/mPBaSUF9TYtWtLOymwOdQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPrBm4/btsL3ycAXZ4/mPBaSUF9TYtWtLOymwOdQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPrBm4%2FbtsL3ycAXZ4%2FmPBaSUF9TYtWtLOymwOdQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;748&quot; height=&quot;561&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;1804&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서울숲 쪽에 위치한 공유오피스에서 진행되었고, 예상외로 많은 분들께서 참여하셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특히 심사위원으로 사측 CEO, CTO, 인사담당자분들께서 오셨는데, 직접 사용하실 분들께서 평가를 해주시는 것도 인상 깊었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;발표뿐만 아니라 시연부스도 운영을 했는데, 디자이너분과 기획자분께서 정말 준비를 많이 해오셔서, 많은 타 팀 참가자 분들께서도 구경을 하고 가셨다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1031&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HPH70/btsL3p7We10/RKqcSUg4GCoh3ZIo0bWCik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HPH70/btsL3p7We10/RKqcSUg4GCoh3ZIo0bWCik/img.png&quot; data-alt=&quot;시연부스 (feat. 디자이너가 필요한 이유)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HPH70/btsL3p7We10/RKqcSUg4GCoh3ZIo0bWCik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHPH70%2FbtsL3p7We10%2FRKqcSUg4GCoh3ZIo0bWCik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;615&quot; height=&quot;587&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;1031&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;시연부스 (feat. 디자이너가 필요한 이유)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;총 18팀의 발표가 끝나고, 심사위원분들께서 시연까지 보시고, 최종 결과 발표 시간...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZhgOl/btsL4abnby5/Npr2tSbyYmnQKs5yKka1P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZhgOl/btsL4abnby5/Npr2tSbyYmnQKs5yKka1P1/img.png&quot; data-origin-width=&quot;2755&quot; data-origin-height=&quot;1837&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 65.2643%; margin-right: 10px;&quot; data-widthpercent=&quot;66.03&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZhgOl/btsL4abnby5/Npr2tSbyYmnQKs5yKka1P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZhgOl%2FbtsL4abnby5%2FNpr2tSbyYmnQKs5yKka1P1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2755&quot; height=&quot;1837&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgnTef/btsL3qTlPZJ/S1EAv065bIRTz1OzKKckd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgnTef/btsL3qTlPZJ/S1EAv065bIRTz1OzKKckd1/img.png&quot; data-origin-width=&quot;844&quot; data-origin-height=&quot;1094&quot; data-is-animation=&quot;false&quot; width=&quot;540&quot; height=&quot;700&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;33.97&quot; style=&quot;width: 33.5729%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgnTef/btsL3qTlPZJ/S1EAv065bIRTz1OzKKckd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgnTef%2FbtsL3qTlPZJ%2FS1EAv065bIRTz1OzKKckd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;844&quot; height=&quot;1094&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최종적으로 '우수상'이랑 '베스트 팀워크상'을 수상했다. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;물론 상을 받아서 좋았지만,&lt;/span&gt; 한편으로는 '충분히 1등 할 만했던 것 같은데'하는 아쉬움도 남는 대회였다. (&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;최우수/우수상 1팀 씩)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;1178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kKX0t/btsL4y35xvN/SXRE2NFhkIriNVv614lhyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kKX0t/btsL4y35xvN/SXRE2NFhkIriNVv614lhyk/img.png&quot; data-alt=&quot;흑돼지 엔딩&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kKX0t/btsL4y35xvN/SXRE2NFhkIriNVv614lhyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkKX0t%2FbtsL4y35xvN%2FSXRE2NFhkIriNVv614lhyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;387&quot; height=&quot;562&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;1178&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;흑돼지 엔딩&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;느낀 점 &amp;amp; 배운 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그동안 개발자들끼리 협업하면서 기획이나 디자인을 겸업하면서 프로젝트는 해보았지만, 이번처럼 기획/디자인/개발 각각 나눠서 각자가 전문성 있는 분야에서 협업해 본 경험은 처음이었다. 특히 프론트엔드와 디자이너분은 현직 경험도 있으신 분들이라 협업/소통 프로세스에 대해서도 겪어볼 수 있는 기회였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그동안 혼자서 백엔드 코드를 짜면서는 고민해보지 않았던 경험들도 있었는데, API를 어떻게 프론트 친화적이게 제공할 것인가에 대해서 고민하고 개발하는 과정에서 response format이나 error handling 등을 꼼꼼하게 해야 된다는 걸 다시 한번 느끼게 되었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;아쉬운 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개발 측면에서는 요구사항에 비해서 시간이 타이트했기에 따로 테스트코드를 짤 시간이 없었는데, 제출 마감 하루 이틀 전쯤 되어서 다양한 상황에서 에러가 튀어나왔다. 디버깅도 어려웠고, 급하게 코드를 고치다 보니 더 스파게티 한 코드가 만들어져 버렸다. 시간이 없어도 코어가 되는 서비스 로직에라도 테스트를 짜면서 할 껄 후회했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대회 측면에서는 기술적인 부분을 많이 어필하지 못한 게 아쉬웠다. 나중에 사측에 양도할 것까지 고려해서 로깅이나 자동화, 에러 핸들링, 데이터 무결성 보장 등 디테일에도 신경을 많이 썼는데, QnA 시간이나 부스에서도 기술적인 질문의 비중이 낮아서 아쉬웠다.&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;발전시켜본 점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대회가 끝나고 이대로 두기엔 찝찝해서 마지막에 급하게 개발한 스파게티 코드들을 정리하고, 테스트코드도 붙여봤다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기존에는 FCM으로 app push를 날리는 과정도 각각을 single message로 서버단에서 반복문으로 해결했었는데, 찾아보니 multicast 기능이 있어서, 보다 효율적이게 리펙토링도 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 기존에 코드를 그대로 AWS Elastic Beanstalk로 배포해 뒀었는데, Docker로 감싸서 홈 서버로 마이그레이션까지 시켜볼 수 있었다. (&lt;a href=&quot;https://blog.dongjun.me/122&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;참고&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://github.com/americano212/dohands-hackathon-backend&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/americano212/dohands-hackathon-backend&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과에는 아쉬움이 남지만, 좋은 팀원분들과 재미있게 2주가량 개발할 수 있었던 좋은 기회로 기억에 남을 것 같다. 스스로도 많은 공부도 되었고 발전한 것 같아 만족스러운 대회였다.&lt;/p&gt;</description>
      <category>대회</category>
      <category>2025 blaybus 실전 앱 개발 경진대회</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/124</guid>
      <comments>https://pypystory.tistory.com/124#entry124comment</comments>
      <pubDate>Sun, 2 Feb 2025 00:11:11 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - 동시성 제어, Lock, DB 복제 (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/123</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/szg96/btsL39PU4cv/1TZE2NLQoOUCDkVvu9EE00/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/szg96/btsL39PU4cv/1TZE2NLQoOUCDkVvu9EE00/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/szg96/btsL39PU4cv/1TZE2NLQoOUCDkVvu9EE00/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fszg96%2FbtsL39PU4cv%2F1TZE2NLQoOUCDkVvu9EE00%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dL9cFl/btsLDTNshN8/pVN2Bn7HGEAgQKua1rr2b1/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dL9cFl/btsLDTNshN8/pVN2Bn7HGEAgQKua1rr2b1/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dL9cFl/btsLDTNshN8/pVN2Bn7HGEAgQKua1rr2b1/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdL9cFl%2FbtsLDTNshN8%2FpVN2Bn7HGEAgQKua1rr2b1%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;292&quot; height=&quot;292&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;동시성 제어&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공유 락 vs 배타 락&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;배타 락(Exclusive Lock)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 데이터 조각을 읽거나 업데이트하려 할 때, 보안 및 일관성을 위해 이 값을 읽으려는 사람에게 오류가 발생하도록 하려고 할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 연결된 유일한 사용자가 되는 것... 나만이 업데이트 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시스템의 일관성을 보장하기 위해 도입&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 공유 락(Shared Lock)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내가 데이터를 읽을 때, 아무도 수정하지 못하게 하고 싶을 때 사용... 이 값을 편집하려는 사람에게 오류가 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 많은 사용자(각각의 연결)들이 각각의 다른 공유 락을 획득할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배타 락을 획득하려면 해당 값에 공유 락이 획득되어 있어서는 안 됨(반대도 마찬가지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 락은 cost가 많이 들지만, 여러 상황을 제어해줄 수 있음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데드 락&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 두 프로세스나 두 클라이언트가 하나 이상의 리소스를 경쟁하는 경우에 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각각의 다른 프로세스가 특정 리소스의 잠금을 해제하기를 기다리는 상황&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB 단에서 체크하고 트랜잭션을 실패시킴(데드 락에 먼저 진입한 트랜잭션이 실패)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2단계 잠금&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB 잠금을 획득하고 단계별로 해제하는 개념&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 번 해제하면 다시 획득할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이중 예약 문제 해결 가능&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* 이중 예약 문제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 영화표 등을 예약할 때, 두 사용자가 정확히 동일한 좌석을 정확히 동일한 ms에 예약하려고 하는 상황&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 2단계 잠금을 처리하지 않으면 생기는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배타 락이 걸려있어도, 먼저 배타 락을 획득한 사람이 update 한 이후에 lock이 풀리기에 마지막으로 update 한 사람 것으로 갱신되는 문제 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;방법 1&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1735803398658&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM seats where id = 1 FOR UPDATE;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 'FOR&amp;nbsp;UPDATE' 를 이용하면 select와 동시에 튜플에 대해 배타 락을 획득할 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 먼저 배타 락을 획득한 사람의 트랜잭션이 commit 된 이후에 배타 락이 풀린 튜플에 대해 동일 쿼리를 요청하더라도, select 단계에서 업데이트된 데이터를 획득&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;방법 2&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1735806338255&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;UPDATE seats set isbooked = 1, name = 'testuser' WHERE id = 1 and isbooked=0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SELECT 후 UPDATE가 아니라, UPDATE 문 자체에서 이런식으로 해결을 시도할 수도 있지만, DB엔진의 종류와 설정에 영향을 받음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- id와 isBooked가 둘 다 인덱스에 포함되어 있는지, 고립 수준이 어떻게 되어있는지... 에 따라서 이중 예약 문제를 해결 못할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- '방법 1' 이 더 명시적인 방법&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SQL offset을 피해야 하는 이유&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- offset 100 limit 10 일 경우, DB는 110개를 가져와서 100개를 논리적으로 drop 하는 방식으로 동작함... offset 값이 커지면 가져와야 하는 양이 많아져 느려질 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- offset을 순차적으로 실행하는 도중에 새로운 행이 insert되면 원치 않은 결과를 얻을 수 있음... 이전 페이지에서 보여줬던 데이터를 한 번 더 보여준다거나...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;대안&lt;/b&gt;: 마지막에 읽어왔던 id를 저장하고&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;where 절을 이용해 가져오는 방법 where ${&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;last_id&lt;/span&gt;}&amp;lt; id limit 10;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;ㄴ 이렇게 하면 IO를 줄여 cost를 줄일 수 있음&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DB 연결 풀링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- TCP 커넥션을 이용하여 사용 가능한 연결 풀을 생성하고, 여러 client가 이 연결 풀을 공유할 수 있는 패턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 GET 요청마다 커넥션을 새로 연결하는게 아닌, 이미 연결 풀을 만들어 놓고, 요청이 오면 연결 풀에서 랜덤으로 가져다 쓰는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- connection을 열고 받는 오버헤드가 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DB 복제&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;복제를 하는 이유?: 데이터 베이스의 신뢰성, 오류 허용성 및 접근성 향상 목적&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마스터/스탠바이 복제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 Leader DB가 테이블을 만들거나 DB를 변경하는 등의 DDL 작업을 수락하고 기록함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 쓰기 DML도 Leader DB에서 일어나고 수락함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나 이상의 백업/스탠바이 노드 들은 마스터로부터 쓰기 작업을 받음(직접 하지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동시에 노드들이 쓰기 작업을 하지 않으니 conflict 날 일이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 마스터와 레플리카 사이에는 완전한 양방향 TCP 연결이 되어있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기를 레플리카에 하더라도 최종적 일관성을 가짐 (단, 업데이트에 시간이 걸릴 수 있어서 감수할 수 있어야 함)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;다중 마스터 복제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쓰기 작업을 확장하려는 목적&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 본질적으로 여러 개의 Master/Leader 노드가 쓰기 작업을 수락하지만, conflict를 막기 위한 많은 작업이 필요&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;동기 vs 비동기 복제&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;동기식 복제&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 마스터에 쓰기를 요청할 때, 트랜잭션이 마스터에 기록될 때까지 기다린 후, 클라이언트가 unblock 되기 전까지 Backup/Standby 노드에 커밋하도록 강제해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Postgres에서는&lt;span&gt; &lt;/span&gt;&lt;/span&gt;N개의 standby가 있을 때, 몇 개까지 기다리고 unblock을 할지 옵션을 제공함&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;비동기식 복제&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 마스터에 작성하면 즉시 client와 연결 해제 후, 백그라운드에서 주기적으로 대기 복제본에 쓰는 프로세스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쓰기 속도는 빨라지는 장점이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백그라운드에서 동기화되는 동안 CPU 소모는 많고, 속도가 느려질 수 있음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;복제의 장단점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수평적 확장성을 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지역 기반 쿼리 가능 - DB per region&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최종적 일관성(용인 가능한 상황이면 괜찮음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 느린 쓰기 (동기식일 때, 트랜잭션을 기다려야 하기에 클라이언트 입장에서 느림)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구현이 복잡함&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>db 공유 락</category>
      <category>db 데드 락</category>
      <category>db 동기 비동기 복제</category>
      <category>db 동시성 제어</category>
      <category>db 배타 락</category>
      <category>db 복제</category>
      <category>offset 단점</category>
      <category>이중 예약 방지</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/123</guid>
      <comments>https://pypystory.tistory.com/123#entry123comment</comments>
      <pubDate>Thu, 30 Jan 2025 15:11:28 +0900</pubDate>
    </item>
    <item>
      <title>[홈 서버] 라즈베리파이에 Docker로 Nginx, MySQL, NestJS 구성, Github Actions로 환경 구성 자동화</title>
      <link>https://pypystory.tistory.com/122</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkWcJf/btsL1Xi1Gti/hLZA5V8JIj8Cgnb1a0k6o1/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkWcJf/btsL1Xi1Gti/hLZA5V8JIj8Cgnb1a0k6o1/tfile.dat&quot; width=&quot;325&quot; height=&quot;325&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1830&quot; data-filename=&quot;blob&quot; data-is-animation=&quot;false&quot; style=&quot;width: 45.5692%; margin-right: 10px;&quot; data-widthpercent=&quot;46.11&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkWcJf/btsL1Xi1Gti/hLZA5V8JIj8Cgnb1a0k6o1/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkWcJf%2FbtsL1Xi1Gti%2FhLZA5V8JIj8Cgnb1a0k6o1%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1830&quot; height=&quot;1830&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clQicq/btsL1DkOICU/OrqW0EJcJKrTr9bkNmoso0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clQicq/btsL1DkOICU/OrqW0EJcJKrTr9bkNmoso0/img.png&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;438&quot; data-is-animation=&quot;false&quot; style=&quot;width: 53.2681%;&quot; data-widthpercent=&quot;53.89&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clQicq/btsL1DkOICU/OrqW0EJcJKrTr9bkNmoso0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclQicq%2FbtsL1DkOICU%2FOrqW0EJcJKrTr9bkNmoso0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지난 1편에서 라즈베리파이 서버를 설치하고 네트워크 구성했고, 이어서 Nginx, MySQL, WAS(NestJS)를 Docker를 이용하여 구성하고 전 과정을 코드로 관리하여, Github Actions로 자동화까지 해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC7HID/btsL2QXpClR/18BgB6Ev4bJXOLhb9zUT60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC7HID/btsL2QXpClR/18BgB6Ev4bJXOLhb9zUT60/img.png&quot; data-alt=&quot;홈서버 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC7HID/btsL2QXpClR/18BgB6Ev4bJXOLhb9zUT60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC7HID%2FbtsL2QXpClR%2F18BgB6Ev4bJXOLhb9zUT60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;720&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;홈서버 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Docker &amp;amp; docker-compose 설치&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nNRAm/btsL0xcWe59/FLKXep4zSLfi8oCG9Gmkm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nNRAm/btsL0xcWe59/FLKXep4zSLfi8oCG9Gmkm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nNRAm/btsL0xcWe59/FLKXep4zSLfi8oCG9Gmkm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnNRAm%2FbtsL0xcWe59%2FFLKXep4zSLfi8oCG9Gmkm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1114&quot; height=&quot;254&quot; data-origin-width=&quot;1114&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 docker와 docker-compose를 설치해 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737979357964&quot; class=&quot;dsconfig&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Docker 디렉토리 생성 후 docker install
mkdir Docker
cd Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Docker 그룹에 사용자 추가
sudo usermod -aG docker ${USER}
groups ${USER}
sudo reboot
docker version

# Docker 를 시작 프로그램에 추가
sudo systemctl enable docker

# docker-compose 설치
sudo curl -L &quot;https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)&quot; -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각각의 서비스를 서로 다른 docker-compose.yml 파일에 정의하고, 서로 통신이 되어야 하기에 공통으로 사용할 docker network를 정의해 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737979357965&quot; class=&quot;routeros&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;docker network create docker-network
docker network inspect docker-network&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;MySQL 세팅&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1737982086329&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker-compose.yml
services:
  database:
    image: mysql/mysql-server:latest
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_HOST=%
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
    volumes:
      - ./data:/var/lib/mysql
    container_name: mysql
    networks:
      - docker-network

networks:
  docker-network:
    external: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 docker-compose 파일을 작성해 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737982192626&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;docker-compose --env-file &amp;lt;.env 경로&amp;gt; up -d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행할 때는 환경변수를 사용할 수 있도록 경로를 지정해 준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NestJS CI/CD세팅&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;필자는 이미 개발된 NestJS 프로젝트가 있어서 NestJS를 사용했을 뿐, 어떤 프레임워크로 개발하던 동일하게 적용할 수 있다.(그것이 API 서버가 아닌 Front 일지라도)&lt;/p&gt;
&lt;pre id=&quot;code_1737982379755&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Dockerfile
FROM node:20
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 8081
CMD [&quot;node&quot;, &quot;dist/src/main&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;docker image를 만들기 위해 Dockerfile을 작성해 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1737982566816&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker buildx create --use
docker buildx build --load --platform linux/arm64 -t &amp;lt;이미지 이름 지정&amp;gt; .
docker images&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기가 중요한데, 이미지를 빌드할 때 꼭 platform을 arm64로 지정해줘야 한다. 기본으로 설정하면 윈도우 PC나 github actions에서 빌드될 때, x86 아키텍처 기준으로 빌드되어 다른 CPU 아키텍처에서 호환이 안된다.&lt;/p&gt;
&lt;pre id=&quot;code_1737983893394&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker-compose.yml
services:
  nestjs-app:
    image: &amp;lt;이미지 이름 지정&amp;gt;:latest
    container_name: &amp;lt;컨테이너 이름 지정&amp;gt;
    ports:
      - &quot;8081:8081&quot;
    env_file:
      - .env
    networks:
      - docker-network

networks:
  docker-network:
    external: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 docker-compose를 작성할 수 있다. 이때 WAS에서 사용하는 환경변수가 있다면 경로를 명시하고, 사용하는 포트로 설정해 주도록 하자. 본인은 8081 포트를 사용하는데, 이거는 docker 내부에서 사용하는 포트라서 어떤 것으로 설정하던지 상관없다.(다른 이미지와 겹치지 않는 선에서) 후술 할 Nginx 리버스 프록시 설정할 때 80, 443으로 요청받을 수 있도록 설정해 줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Nginx 세팅 (+ssl 설정)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ssl 설정에 관해서는 아래의 포스팅을 참고했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737984181184&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Nginx and Let&amp;rsquo;s Encrypt with Docker in Less Than 5 Minutes&quot; data-og-description=&quot;Getting Nginx to run with Let&amp;rsquo;s Encrypt in a docker-compose environment is more tricky than you&amp;rsquo;d think&amp;nbsp;&amp;hellip;&quot; data-og-host=&quot;pentacent.medium.com&quot; data-og-source-url=&quot;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&quot; data-og-url=&quot;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UYZNb/hyX4tqdOuL/xxQ1BkdVTNxi3rOUpkpsjK/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/Ebeun/hyX7Wdfu2R/6ub5QBUZ7UVNJW9ra6xmKk/img.jpg?width=1358&amp;amp;height=764&amp;amp;face=0_0_1358_764&quot;&gt;&lt;a href=&quot;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pentacent.medium.com/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UYZNb/hyX4tqdOuL/xxQ1BkdVTNxi3rOUpkpsjK/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675,https://scrap.kakaocdn.net/dn/Ebeun/hyX7Wdfu2R/6ub5QBUZ7UVNJW9ra6xmKk/img.jpg?width=1358&amp;amp;height=764&amp;amp;face=0_0_1358_764');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Nginx and Let&amp;rsquo;s Encrypt with Docker in Less Than 5 Minutes&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Getting Nginx to run with Let&amp;rsquo;s Encrypt in a docker-compose environment is more tricky than you&amp;rsquo;d think&amp;nbsp;&amp;hellip;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pentacent.medium.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1737984211004&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker-compose.yml
services:
  nginx:
    image: nginx:latest
    volumes:
      - ./conf/nginx.conf:/etc/nginx/nginx.conf
      - ./data/certbot/conf:/etc/letsencrypt 
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    command: &quot;/bin/sh -c 'while :; do sleep 6h &amp;amp; wait $${!}; nginx -s reload; done &amp;amp; nginx -g \&quot;daemon off;\&quot;'&quot;
    networks:
      - docker-network

  certbot:
    image: certbot/certbot
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt 
      - ./data/certbot/www:/var/www/certbot
    entrypoint: &quot;/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h &amp;amp; wait $${!}; done;'&quot;
    networks:
      - docker-network

networks:
  docker-network:
    external: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;차근차근 따라 하면 여기까지는 쉽게 올 수 있다. 조심할 것은 인증서 발급과정에서 &lt;b&gt;도메인 연결&lt;/b&gt;이 되어있어야 하고, &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;80 포트를 확인하기 때문에&lt;span&gt; 포트포워딩으로 외부에서 라즈베리파이 80 포트에 접근할 수 있도록 뚫어놔야 한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;본인은 도메인 레코드를 AWS Route53을 이용해서 관리하고 있다. (호스팅영역 당 월 0.5$ 비용 발생) 도메인은 가비아 등 여러 DNS 제공 업체에서 구매할 수 있으니 비교해 보고 원하는 도메인을 고르면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;포트포워딩은 공유기 제조사마다 다르니 구글링 해보면 어렵지 않게 설정할 수 있을 것이다. 단, 집에서 통신사 모뎀을 쓰고 있다면 통신사 모뎀에서도 포트포워딩을 해줘야 하니 참고하자.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737984745161&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /conf/nginx.conf
events {
    worker_connections  1024;
}

http{
    server {
        listen 80;
        server_name &amp;lt;사용하는 도메인 주소&amp;gt;;
        server_tokens off;

        location /.well-known/acme-challenge/ {
            root /var/www/certbot;
        }

        location / {
            return 301 https://$host$request_uri;
        }   
    }
    server {
        listen 443 ssl;
        server_name &amp;lt;사용하는 도메인 주소&amp;gt;;
        server_tokens off;

        ssl_certificate /etc/letsencrypt/live/&amp;lt;사용하는 도메인 주소&amp;gt;/fullchain.pem; 
        ssl_certificate_key /etc/letsencrypt/live/&amp;lt;사용하는 도메인 주소&amp;gt;/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        resolver 127.0.0.11; # Docker의 내부 DNS 추가

        location / {
            proxy_pass  http://&amp;lt;WAS Docker 컨테이너 명&amp;gt;:8081;
            proxy_set_header    Host                $http_host;
            proxy_set_header    X-Real-IP           $remote_addr;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;nginx.conf가 중요한데, 80 포트로 들어오면 https로 리다이렉트 시키고, 443으로 들어오면 ssl 인증서를 이용해서 WAS 서버로 요청을 전송하는 리버스 프록시를 구성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본인은 request를 서브도메인으로 구분하여, 각기 다른 WAS에 요청을 전송하도록 구성하였다. 이때 ssl 인증서는 각 완전한 도메인 별로 발급받아야 한다. (와일드카드를 이용하면 더 쉽게 될 것 같기도 하다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주의할 점이라면&amp;nbsp; Docker 내부 DNS 주소인 127.0.0.11을 명시해야 컨테이너명으로 WAS 서버와 연결을 해준다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인프라 배포를 위한 Github Actions 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 Github에 인프라 설정 코드를 push 하면 자동으로 라즈베리파이에 적용되도록 github actions를 설정해 보았다.&lt;/p&gt;
&lt;pre id=&quot;code_1737985021300&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;git config --global credential.helper store
git pull origin main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 라즈베리파이 서버에 위와 같이 github 인증키를 저장해 준다. 실제 사용할 환경에 적용할 때는 ssh 키 적용하는 것이 보안 측면에서 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://docs.github.com/en/authentication/connecting-to-github-with-ssh&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.github.com/en/authentication/connecting-to-github-with-ssh&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1737984942043&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# .github/workflows/deploy.yml
name: Deploy to Raspberry Pi
...
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
     	...
      - name: Deploy MySQL with SSH
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ secrets.RASPBERRY_HOST }}
          username: ${{ secrets.RASPBERRY_USERNAME }}
          password: ${{ secrets.RASPBERRY_PASSWORD }}
          port: ${{ secrets.RASPBERRY_PORT }}
          script: |
            cd Docker/personal-server-setup
            git pull origin main
            cd home/raspberry-pi/mysql
            docker-compose down || true
            sh init.sh

      - name: Deploy Nginx with SSH
        uses: appleboy/ssh-action@v1.2.0
        with:
          host: ${{ secrets.RASPBERRY_HOST }}
          username: ${{ secrets.RASPBERRY_USERNAME }}
          password: ${{ secrets.RASPBERRY_PASSWORD }}
          port: ${{ secrets.RASPBERRY_PORT }}
          script: |
            cd Docker/personal-server-setup
            git pull origin main
            cd home/raspberry-pi/nginx
            docker-compose down || true
            sh init.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://github.com/appleboy/ssh-action&quot;&gt;https://github.com/appleboy/ssh-action&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1737985254902&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - appleboy/ssh-action: GitHub Actions for executing remote ssh commands.&quot; data-og-description=&quot;GitHub Actions for executing remote ssh commands. Contribute to appleboy/ssh-action development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/appleboy/ssh-action&quot; data-og-url=&quot;https://github.com/appleboy/ssh-action&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ooRdx/hyX7QxkREB/U0clm2lG7nKqBlbnSuc3ZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=1010_125_1056_175,https://scrap.kakaocdn.net/dn/745PR/hyX7PSIX9L/OXaAZtSSrN8uX1WAlRWkh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1010_125_1056_175&quot;&gt;&lt;a href=&quot;https://github.com/appleboy/ssh-action&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/appleboy/ssh-action&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ooRdx/hyX7QxkREB/U0clm2lG7nKqBlbnSuc3ZK/img.png?width=1200&amp;amp;height=600&amp;amp;face=1010_125_1056_175,https://scrap.kakaocdn.net/dn/745PR/hyX7PSIX9L/OXaAZtSSrN8uX1WAlRWkh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=1010_125_1056_175');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - appleboy/ssh-action: GitHub Actions for executing remote ssh commands.&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions for executing remote ssh commands. Contribute to appleboy/ssh-action development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ssh를 이용해서 github actions가 라즈베리파이에 접속하고, 코드를 pull 한 뒤에 docker-compose를 down/up 해주는 과정이다. 동일한 이유로 password를 직접 사용하는 것보다, ssh 키를 발급받아서 사용하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WAS 배포를 위한 Github Actions 설정&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1737985395410&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;- name: Build Docker Image
    run: |
      docker buildx create --use
      docker buildx build --load --platform linux/arm64 -t &amp;lt;이미지 명&amp;gt; .
      docker images
      docker save &amp;lt;이미지 명&amp;gt;:latest -o &amp;lt;이미지 명&amp;gt;.tar
      chmod 664 &amp;lt;이미지 명&amp;gt;.tar
      ls -al

  - name: Copy file to Raspberry Pi
    uses: appleboy/scp-action@v0.1.7
    with:
      host: ${{ secrets.RASPBERRY_HOST }}
      username: ${{ secrets.RASPBERRY_USERNAME }}
      password: ${{ secrets.RASPBERRY_PASSWORD }}
      port: ${{ secrets.RASPBERRY_PORT }}
      source: '&amp;lt;이미지 명&amp;gt;.tar,Dockerfile,docker-compose.yml,.env'
      target: '&amp;lt;라즈베리파이 상 WAS 경로&amp;gt;'

  - name: Deploy Docker Image on Remote Server
    uses: appleboy/ssh-action@v1.2.0
    with:
      host: ${{ secrets.RASPBERRY_HOST }}
      username: ${{ secrets.RASPBERRY_USERNAME }}
      password: ${{ secrets.RASPBERRY_PASSWORD }}
      port: ${{ secrets.RASPBERRY_PORT }}
      script: |
        cd &amp;lt;라즈베리파이 상 WAS 경로&amp;gt;
        ls -al
        docker load &amp;lt; &amp;lt;이미지 명&amp;gt;.tar
        rm &amp;lt;이미지 명&amp;gt;.tar
        docker-compose down || true
        docker-compose up -d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;백엔드 소스를 Checkout 해서 github actions VM 위에서 Docker Image로 빌드하고, 이미지를 tar 압축을 한 뒤 scp로 라즈베리파이로 옮겨준다. 이후 라즈베리파이에서 이미지를 load 한 뒤, docker-compse up/down을 해주는 로직이다. scp를 안 쓰고, DockerHub를 경유해 push 하는 방법도 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1503&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m0Cqv/btsL3xXtD2I/JrWehm3eur3zlATaJo6QC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m0Cqv/btsL3xXtD2I/JrWehm3eur3zlATaJo6QC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m0Cqv/btsL3xXtD2I/JrWehm3eur3zlATaJo6QC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm0Cqv%2FbtsL3xXtD2I%2FJrWehm3eur3zlATaJo6QC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1503&quot; height=&quot;94&quot; data-origin-width=&quot;1503&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최종적으로 docker ps를 했을 때 위와 같이 나오면 성공이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;성능 측정 및 분석&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Google PageSpeed Insights &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;swagger page를 불러오는 속도를 비교해 보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuKyf2/btsL24apnRs/z4kvflUjPkioeFVHbBs3V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuKyf2/btsL24apnRs/z4kvflUjPkioeFVHbBs3V0/img.png&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;238&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.5947%; margin-right: 10px;&quot; data-widthpercent=&quot;50.18&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuKyf2/btsL24apnRs/z4kvflUjPkioeFVHbBs3V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuKyf2%2FbtsL24apnRs%2Fz4kvflUjPkioeFVHbBs3V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;939&quot; height=&quot;238&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caZXwZ/btsL1B7YU18/hTVR55m5BbN7PByKXLVlPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caZXwZ/btsL1B7YU18/hTVR55m5BbN7PByKXLVlPk/img.png&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;242&quot; data-is-animation=&quot;false&quot; style=&quot;width: 49.2425%;&quot; data-widthpercent=&quot;49.82&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caZXwZ/btsL1B7YU18/hTVR55m5BbN7PByKXLVlPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaZXwZ%2FbtsL1B7YU18%2FhTVR55m5BbN7PByKXLVlPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;948&quot; height=&quot;242&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;좌: AWS 서울리전 / 우: 라즈베리파이 홈서버 &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어느 포인트에서 접속해서 측정하는지는 확실하지 않으나, &lt;b&gt;홈 서버가 클라우드에 비해서 접속 시간은 2,3배 느렸다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;tools.pingdom.com&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Health check를 해보았을 때, &lt;b&gt;홈 서버는 182ms, 클라우드는 123ms&lt;/b&gt;로 측정되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;blazemeter.com&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;20명 user로 10분 동안 Apache &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;JMeter로 &lt;/span&gt;API 테스트를 진행해 본 결과 아래와 같다. (DB에서 게시물 하나를 조회하는 API, Asia Japan 리전에서 접속)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;345&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDHrkX/btsL1Gu2bDG/5VOKy8xMdEufm8MPvvbaXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDHrkX/btsL1Gu2bDG/5VOKy8xMdEufm8MPvvbaXK/img.png&quot; data-alt=&quot;라즈베리파이 홈서버 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDHrkX/btsL1Gu2bDG/5VOKy8xMdEufm8MPvvbaXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDHrkX%2FbtsL1Gu2bDG%2F5VOKy8xMdEufm8MPvvbaXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1863&quot; height=&quot;345&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;345&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;라즈베리파이 홈서버 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r5xg0/btsL11L9lRo/9J7kYWJCPSVfk5faKNQIVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r5xg0/btsL11L9lRo/9J7kYWJCPSVfk5faKNQIVK/img.png&quot; data-alt=&quot;AWS 클라우드 서버 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r5xg0/btsL11L9lRo/9J7kYWJCPSVfk5faKNQIVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr5xg0%2FbtsL11L9lRo%2F9J7kYWJCPSVfk5faKNQIVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1853&quot; height=&quot;346&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS 클라우드 서버 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;90% Response Time을 보면 홈서버가 1383ms, AWS 서버가 906ms로 응답시간 측면에서 AWS에 비해 1.52배 정도 더 걸린다는 것을 확인할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;분석&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;추가로 API 테스트 도중에 각각의 CPU/MEM 사용량을 확인해 본 결과 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnoDPn/btsL23o10eW/bsZPtxuyykc9eVedLx4HSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnoDPn/btsL23o10eW/bsZPtxuyykc9eVedLx4HSK/img.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;363&quot; data-is-animation=&quot;false&quot; style=&quot;width: 31.4876%; margin-right: 10px;&quot; data-widthpercent=&quot;32.24&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnoDPn/btsL23o10eW/bsZPtxuyykc9eVedLx4HSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnoDPn%2FbtsL23o10eW%2FbsZPtxuyykc9eVedLx4HSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;695&quot; height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bs44Zd/btsL1A2lNOD/icZk91j2n9pH9KULTi3Rt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bs44Zd/btsL1A2lNOD/icZk91j2n9pH9KULTi3Rt1/img.png&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;202&quot; data-is-animation=&quot;false&quot; style=&quot;width: 31.2638%;&quot; data-widthpercent=&quot;32.01&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bs44Zd/btsL1A2lNOD/icZk91j2n9pH9KULTi3Rt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbs44Zd%2FbtsL1A2lNOD%2FicZk91j2n9pH9KULTi3Rt1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;좌: 라즈베리파이 홈서버 top -H / 우: AWS CloudWatch 모니터링&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;홈 서버에서 top 명령어로 확인해 본 결과에서 us, sy 합인 CPU 사용률이 35~45% 정도 왔다 갔다 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CloudWatch로 확인한 AWS EC2의 CPU 사용률이 40% 정도에 수렴하는 걸 감안했을 때, CPU 성능은 WAS와 함께 DB, WS까지 돌리고 있는 라즈베리파이가 더 우수한 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RAM도 용량 측면에서 라즈베리파이가 2GB, AWS t3.micro는 1GB로 라즈베리파이가 더 우수하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(다만, top 결과를 보면 RAM은 거의 꽉꽉 채워 쓰고도 부족해서 스왑 메모리까지 돌아가고 있는 걸 볼 수 있는데, SSD가 아니었으면 상당히 느렸을 것 같다. 이렇게 여러 개 docker로 띄워서 쓰려면 램 빵빵한 모델로 사는 게 장기적으로 좋을 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 위의 API 테스트 결과를 분석해 봤을 때 CPU/RAM 성능의 차이보다는 네트워크 성능에서 차이가 나는 것으로 추정해 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아무래도 클라우드 환경에서 t3.micro 기준 Burst시 5 Gbps를 지원하는데 비해, 라즈베리파이는 1 Gbps (125MB/s)를 지원하는 점과 가정 내에 공유기와 모뎀이 라즈베리파이만을 위한 독립된 환경이 아니라는 점에서 이러한 현상이 생기는 것으로 추정이 된다.&lt;/p&gt;</description>
      <category>홈 네트워크 &amp;amp; 서버</category>
      <category>docker github actions</category>
      <category>docker network</category>
      <category>mysql docker</category>
      <category>nestjs docker</category>
      <category>nginx docker</category>
      <category>nginx 서브도메인</category>
      <category>nginx 홈서버</category>
      <category>클라우드 vs 홈서버</category>
      <category>홈서버 docker</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/122</guid>
      <comments>https://pypystory.tistory.com/122#entry122comment</comments>
      <pubDate>Tue, 28 Jan 2025 00:48:27 +0900</pubDate>
    </item>
    <item>
      <title>[홈 서버] 라즈베리파이로 홈 서버 구성하기, SSD 부팅, 네트워크 구성, 총비용</title>
      <link>https://pypystory.tistory.com/121</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cS2900/btsLx4Xsbar/JEKYpOODhc5yBuYCEf6ed1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cS2900/btsLx4Xsbar/JEKYpOODhc5yBuYCEf6ed1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cS2900/btsLx4Xsbar/JEKYpOODhc5yBuYCEf6ed1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcS2900%2FbtsLx4Xsbar%2FJEKYpOODhc5yBuYCEf6ed1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;291&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1830&quot; data-origin-height=&quot;1830&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그동안 개인 프로젝트나 해커톤에 참여하게 되면, AWS를 이용해서 배포를 해왔다. 특히 Elastic Beanstalk, lambda 등 관리형 서비스를 쓰면 서버 관리나 배포를 신경 쓰지 않아도 되고, 최초 세팅만 해주면 손쉽게 구성을 할 수 있어서 애용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그런데 이게 서비스가 하나 일 때는 Freetier 지원도 받고, AWS 크레딧 받은 거를 쓰면 크게 문제 될 게 없었는데, 이것저것 개발하다 보니 살려놔야 할 서비스들도 늘어나고, 프리티어 기간이 끝날 때마다 계정을 갈아타는 것도 여간 귀찮은 일이 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사실 유저가 항상 있는 서비스도 아니고, 당장 운영 안정성이 필요한 서비스들도 아니었기에 클라우드 환경은 낭비되는 비용이 많다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Akzh/btsL10Gnl6i/PnAFK4pzI8ovdxAGHkXkYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Akzh/btsL10Gnl6i/PnAFK4pzI8ovdxAGHkXkYk/img.png&quot; data-alt=&quot;슬슬...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Akzh/btsL10Gnl6i/PnAFK4pzI8ovdxAGHkXkYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Akzh%2FbtsL10Gnl6i%2FPnAFK4pzI8ovdxAGHkXkYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;575&quot; height=&quot;186&quot; data-origin-width=&quot;575&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;슬슬...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음에는 terraform 등 IaC로 환경 구성을 여러 프리티어 계정에 나눠볼까도 생각했는데, 계정 관리도 어렵고 AWS라는 환경에 종속된다는 점도 불편하게 느껴졌다. 특히 작년에 AWS가 IPv4 주소에 대해 가격을 부과하도록 정책을 변경한 것과 같은 가격 정책 변동에 노출되어 있기에 그럴 때마다 구성을 바꾸는 등 끌려다녀야 하는 점도 홈 서버 구축을 결심하게 된 주요 요인이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;최종 구성 목표 아키텍처&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 서비스를 다 홈 서버로 마이그레이션 시킬 필요는 없을 것 같고, Route53이나 S3 등은 AWS 서비스를 일부 이용하면서, 서비스 수에 비례해서 가격이 나가는 EC2, RDS를 홈 서버로 마이그레이션해서 운영하려고 한다. 장기적으로 홈서버는 라즈베리파이 여러 대를 클러스터로 묶어서 쿠버로 관리하는 걸 목표로 하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvteXf/btsL3zuawWq/v3bp2kKu2jM1cm9u4KYrvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvteXf/btsL3zuawWq/v3bp2kKu2jM1cm9u4KYrvK/img.png&quot; data-alt=&quot;이번에 구성해볼 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvteXf/btsL3zuawWq/v3bp2kKu2jM1cm9u4KYrvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvteXf%2FbtsL3zuawWq%2Fv3bp2kKu2jM1cm9u4KYrvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;378&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이번에 구성해볼 아키텍처&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;라즈베리파이 설치&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;라즈베리파이 본체&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용할 라즈베리파이는 Raspbrry Pi 4b 2GB 모델이다. 예전에 학습용으로 5만원 정도에 새 상품으로 구매했다. 소비전력은 15W로 전기 요금이 걱정될 정도는 아니었다. CPU는 쿼드코어이며 &lt;b&gt;arm64 임에 유의해야 한다.(amd&lt;/b&gt; 계열에서 동작하는 프로그램/코드와 호환이 안될 수 있다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2307&quot; data-origin-height=&quot;2000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2ILq1/btsL2aPUcJB/5puBpbkz3Nw4LOC8rIeBO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2ILq1/btsL2aPUcJB/5puBpbkz3Nw4LOC8rIeBO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2ILq1/btsL2aPUcJB/5puBpbkz3Nw4LOC8rIeBO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2ILq1%2FbtsL2aPUcJB%2F5puBpbkz3Nw4LOC8rIeBO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;322&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2307&quot; data-origin-height=&quot;2000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;방열 케이스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;24시간 동작해야하기에 발열을 잡고, 이물질 방지를 위해 케이스도 준비했다. 나중에 여러대를 클러스터로 묶어 확장할 것까지 고려해서, 적층가능한 케이스를 선택했다. 쿠팡에서 15,000원 정도에 구매할 수 있었다. 전용 무소음 팬도 들어있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2oK5t/btsL1FJC8fY/WRgvnXcc2ZyFiKBWq87wvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2oK5t/btsL1FJC8fY/WRgvnXcc2ZyFiKBWq87wvK/img.png&quot; data-origin-width=&quot;2234&quot; data-origin-height=&quot;1759&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; width=&quot;467&quot; data-widthpercent=&quot;44.96&quot; style=&quot;width: 44.4404%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2oK5t/btsL1FJC8fY/WRgvnXcc2ZyFiKBWq87wvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2oK5t%2FbtsL1FJC8fY%2FWRgvnXcc2ZyFiKBWq87wvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2234&quot; height=&quot;1759&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0VFwn/btsL2fJ8bO6/iRy7MSSCPPfi5JLurKWUSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0VFwn/btsL2fJ8bO6/iRy7MSSCPPfi5JLurKWUSK/img.png&quot; data-origin-width=&quot;1595&quot; data-origin-height=&quot;1026&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 54.3968%;&quot; data-widthpercent=&quot;55.04&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0VFwn/btsL2fJ8bO6/iRy7MSSCPPfi5JLurKWUSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0VFwn%2FbtsL2fJ8bO6%2FiRy7MSSCPPfi5JLurKWUSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1595&quot; height=&quot;1026&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;방열 케이스와 쿨링 펜까지 장착한 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SD카드 대신 SSD&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 라즈베리파이는 MicroSD카드를 연결해서 사용하도록 설계되어있다. 하지만 파일 전송 속도가 100MB/s 에도 못 미치고, SSD와 비교했을 때, IOPS도 상대적으로 못 미치기에 서버 성능과 직결된다. 패키지 설치 속도 등에서 운영/배포에도 영향을 주고, DB를 운영할 때에도 쿼리속도에 영향을 주게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0lLM2/btsL1sKxIII/w2AuTTOPTCJXSCKm4M5Ds0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0lLM2/btsL1sKxIII/w2AuTTOPTCJXSCKm4M5Ds0/img.jpg&quot; style=&quot;width: 34.0475%; margin-right: 10px;&quot; width=&quot;328&quot; height=&quot;437&quot; data-origin-width=&quot;3000&quot; data-origin-height=&quot;4000&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;34.45&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0lLM2/btsL1sKxIII/w2AuTTOPTCJXSCKm4M5Ds0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0lLM2%2FbtsL1sKxIII%2Fw2AuTTOPTCJXSCKm4M5Ds0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3000&quot; height=&quot;4000&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnDAs1/btsL01svHcb/n9Uw9wlkxaqoI6WyYJnrQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnDAs1/btsL01svHcb/n9Uw9wlkxaqoI6WyYJnrQk/img.png&quot; style=&quot;width: 64.7897%;&quot; width=&quot;531&quot; height=&quot;372&quot; data-origin-width=&quot;2509&quot; data-origin-height=&quot;1758&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; data-widthpercent=&quot;65.55&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnDAs1/btsL01svHcb/n9Uw9wlkxaqoI6WyYJnrQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnDAs1%2FbtsL01svHcb%2Fn9Uw9wlkxaqoI6WyYJnrQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2509&quot; height=&quot;1758&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;SATA to USB 컨버터 &amp;amp; SSD&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라즈베리파이 5부터는 NVMe SSD를 쓸 수 있다고 하던데, 더 좋은 성능으로 구성할 수 있다. 하지만 비용을 고려해야하기에 SATA3을 지원하는 WD Blue 3D NAND SSD를 중고로 2만 원에 구매했다. (과거에 생산된 3D NAND라고 적혀있는 블루만 DRAM이 포함되어 있다는 점을 유의하자, 최근에 생산된 WD Blue 제품에는 SATA/NVMe 모두 DRAM이 빠진 걸로 알고 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라즈베리파이에는 USB로 연결해야하기에 SATA to USB 컨버터도 쿠팡에서 7,000원에 구매했다. (다른 블로그에서 평이 좋은 MBF사 제품으로 구매) 참고로 라즈베리파이에 USB 3.0으로 연결하게되면 5Gbps가 최대이고, SATA3는 6Gbps여서 USB로 컨버트해서 연결하면 SATA3도 가능한 최고속도에 도달한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tkX2Z/btsL19pUt6A/h1yThepkpIN6f3yVprTlGk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tkX2Z/btsL19pUt6A/h1yThepkpIN6f3yVprTlGk/img.png&quot; data-alt=&quot;WD 자체 모니터링 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tkX2Z/btsL19pUt6A/h1yThepkpIN6f3yVprTlGk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtkX2Z%2FbtsL19pUt6A%2Fh1yThepkpIN6f3yVprTlGk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;690&quot; height=&quot;390&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1342&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;WD 자체 모니터링 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아래는 추후에 라즈베리파이에 SSD를 연결하고 벤치마크를 돌려본 결과이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bewQ2B/btsL26eVz3y/nVvy3NVVBAZAisLkNphSF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bewQ2B/btsL26eVz3y/nVvy3NVVBAZAisLkNphSF1/img.png&quot; data-alt=&quot;https://github.com/TheRemote/PiBenchmarks&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bewQ2B/btsL26eVz3y/nVvy3NVVBAZAisLkNphSF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbewQ2B%2FbtsL26eVz3y%2FnVvy3NVVBAZAisLkNphSF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1156&quot; height=&quot;414&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://github.com/TheRemote/PiBenchmarks&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;타 블로그에서 MicroSD 카드에서 돌린 결과와 비교해보면&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;(완벽한 변인통제가 이뤄지진 않았기에 참고용으로만!) 읽기 속도는 3배 정도, 쓰기 속도는 5배 정도 빠른 걸 확인할 수 있었다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;운영체제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;OS는 데비안 기반 라즈베리파이 공식 OS인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Raspbian 64bit로 설치했다. 라즈베리파이 4b부터는 &lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;EEPROM안에 부트로더를 내장시킬 수 있다고 한다. 설치&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;과정을 간략히 만 요약하면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;1. SD카드에 USB 부트로더 다운로드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;2. 최초 1회 SD카드를 라즈베리파이에 연결 후 부팅해서 USB 부트로더를 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;3.&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;SD 카드 제거 후&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Raspbian&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;OS를 설치한 SSD를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;연결하여 라즈베리파이 부팅&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;최종 구성된 모습&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I0y1w/btsL2HfpzxC/LbykQtlSnx4ck0ZprPnUHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I0y1w/btsL2HfpzxC/LbykQtlSnx4ck0ZprPnUHk/img.png&quot; data-origin-width=&quot;2873&quot; data-origin-height=&quot;2079&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; style=&quot;width: 45.3946%; margin-right: 10px;&quot; data-widthpercent=&quot;45.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I0y1w/btsL2HfpzxC/LbykQtlSnx4ck0ZprPnUHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI0y1w%2FbtsL2HfpzxC%2FLbykQtlSnx4ck0ZprPnUHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2873&quot; height=&quot;2079&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QZjgR/btsL1iU8fJF/A76nTd6Xnno6bRMwkRtmVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QZjgR/btsL1iU8fJF/A76nTd6Xnno6bRMwkRtmVk/img.png&quot; data-origin-width=&quot;2019&quot; data-origin-height=&quot;1241&quot; data-is-animation=&quot;false&quot; data-filename=&quot;blob&quot; width=&quot;579&quot; height=&quot;356&quot; data-widthpercent=&quot;54.07&quot; style=&quot;width: 53.4426%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QZjgR/btsL1iU8fJF/A76nTd6Xnno6bRMwkRtmVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQZjgR%2FbtsL1iU8fJF%2FA76nTd6Xnno6bRMwkRtmVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2019&quot; height=&quot;1241&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;네트워크 구성&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;네트워크 구성은 아래와 같다. 공유기와 모뎀에서 포트포워딩을 통해 외부 IP로 접속했을 때 포트별로 어느 단말기로 붙을지 제어하게 된다. 지금은 RDP로 붙어서 쓰는 개발용 PC, 파일 저장용 NAS, 홈 서버로 쓸 라즈베리파이를 물려서 쓰고 있는데, 차차 라즈베리파이를 추가해서 쓰기 위해 스위치허브를 구매할 생각이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;외부에서 라즈베리파이로 들어오는 http/https 요청은 Nginx 리버스 프록시를 이용해서 각 WAS 서버에 로드밸런싱을 하고, SSL 종점을 제공한다. MySQL DB의 경우 개발용 데스크톱과 Docker Network 내부의 WAS에서만 접속을 허용하여 보안성을 높였다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;이때 Nginx, WAS, MySQL은 모두 docker 위에서 실행되며, 코드로 관리해서 Github Actions에 의해 자동으로 인프라 배포가 되도록 구성할 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OCJBY/btsL3rXpc96/KbethLUux7Y5SuifpAixKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OCJBY/btsL3rXpc96/KbethLUux7Y5SuifpAixKk/img.png&quot; data-alt=&quot;현재 홈 네트워크 세팅&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OCJBY/btsL3rXpc96/KbethLUux7Y5SuifpAixKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOCJBY%2FbtsL3rXpc96%2FKbethLUux7Y5SuifpAixKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;507&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;현재 홈 네트워크 세팅&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;총비용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라즈베리파이 4B RAM 2GB 모델 본체 : 54,000원 (45$인데, 요즘엔 환율 때문에 7만원 대...)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라즈베리파이 4 전용 올인원 방열 케이스 : 15,000원&amp;nbsp; &lt;br /&gt;엠비에프 SATA to USB 컨버터 : 7,200원 &lt;br /&gt;WD Blue 3D NAND SSD 250GB (중고) : 20,000원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;총 10만 원 정도로 홈 서버를 구성할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;클라우드 요금과 비교&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS에서 EC2, RDS 요금을 계산해 보면 데이터 통신 제외하고, 프리티어가 아닐 때 단일 AZ 서울 리전 기준.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 온디멘드 t3.micro : 약 9.5$ (13,300원)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS for MySQL 온디멘드 &lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: left;&quot;&gt;db.t3.micro : 약 18.7$ (26,180원)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #16191f;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Public IPv4 : 약 3.6$ (5,040원)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: left;&quot;&gt;물론 1년 동안은 IPv4 요금만 내면 프리티어로 사용할 수 있겠지만 서버 스펙을 높이거나 프리티어 기간이 끝나게 되면 전기세를 고려하더라도 3달 만에 온프레미스로 홈 서버를 구축하는 것이 가격 측면에서 유리하다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: left;&quot;&gt;물론 클라우드에서 제공하는 편의성과 네트워크/전력 공급 측면의 안정성은 엄청난 장점이지만, 실사용자가 있는 프로덕션 환경이 아닌 개발 환경이나, 사이드 프로젝트에서는 충분히 구축해볼 만한 가치가 있다고 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;내가 구매한 제품은 아래 링크에서 구매할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://link.coupang.com/a/cbOelp&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://img4a.coupangcdn.com/image/affiliate/banner/f78591f1f27d54811fc013514953c8f2@2x.jpg&quot; alt=&quot;엠비에프 SATA to USB 컨버터 SSD 외장하드 연결 케이블 MBF-U3SATA-BK, 1개, 25cm&quot; width=&quot;120&quot; height=&quot;240&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;https://link.coupang.com/a/cbOeFF&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://image2.coupangcdn.com/image/affiliate/banner/7ab8d6235e5aba5984cf49ea4027fb07@2x.jpg&quot; alt=&quot;라즈베리파이 4 전용 올인원 방열 케이스[무광 블랙 바디]&quot; width=&quot;120&quot; height=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&quot;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&quot;&lt;/span&gt;&lt;/p&gt;</description>
      <category>홈 네트워크 &amp;amp; 서버</category>
      <category>라즈베리파이 4b ssd</category>
      <category>라즈베리파이 docker</category>
      <category>라즈베리파이 nginx</category>
      <category>라즈베리파이 sata ssd</category>
      <category>라즈베리파이 네트워크</category>
      <category>라즈베리파이 방열 케이스</category>
      <category>라즈베리파이 포트포워딩</category>
      <category>라즈베리파이 홈 서버</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/121</guid>
      <comments>https://pypystory.tistory.com/121#entry121comment</comments>
      <pubDate>Mon, 27 Jan 2025 21:30:54 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - DB 파티셔닝, 샤딩 (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXpdXQ/btsLBgw2GSC/Wog3OJdo8yQKGJcBEkNmP1/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXpdXQ/btsLBgw2GSC/Wog3OJdo8yQKGJcBEkNmP1/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXpdXQ/btsLBgw2GSC/Wog3OJdo8yQKGJcBEkNmP1/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXpdXQ%2FbtsLBgw2GSC%2FWog3OJdo8yQKGJcBEkNmP1%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ea8Vd/btsLC1rthpy/vhSIoIMOuPHKIe2iD275Uk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ea8Vd/btsLC1rthpy/vhSIoIMOuPHKIe2iD275Uk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ea8Vd/btsLC1rthpy/vhSIoIMOuPHKIe2iD275Uk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEa8Vd%2FbtsLC1rthpy%2FvhSIoIMOuPHKIe2iD275Uk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;329&quot; height=&quot;329&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;파티셔닝&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파티셔닝이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티셔닝: 거대 테이블을 여러 개의 테이블로 분할하고, WHERE 절에 따라 어떤 테이블 또는 파티션에 접근할지 결정하는 기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실제 데이터가 담기는 테이블을 TEMP_100K, TEMP_200K, TEMP_300K... 이런 식으로 나누고, TEMP(master table) 테이블은 실제 데이터는 갖고 있지 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) TEMP로 id = 210,001에 대한 조회 쿼리가 오면 DB는 TEMP_200K에서 찾아서 주는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 아래와 같은 방식으로 파티셔닝 된 table 생성, grades_parts로 INSERT되면 DB는 g 값에 따라 알아서 row가 속하는 파티션을 결정해 줌.&lt;/p&gt;
&lt;pre id=&quot;code_1735640174720&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;CREATE TABLE grades_parts (id serial not null, g int not null) partition by range(g);

CREATE TABLE g0035 (like grades_parts including indexes);
CREATE TABLE g3560 (like grades_parts including indexes);
...

ALTER TABLE grades_parts attach partition g0035 fro values from (0) to (35);
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- index를 걸고 싶으면 각 파티션 테이블에 거는 게 아니라, master(leader) 테이블에만 만들어주면 각 파티션 테이블에 인덱스가 걸림(^postgres12)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티셔닝 해서 인덱스 걸면, row가 많아져도 각 테이블의 index 크기가 작아지기 때문에 속도 측면에서도 유리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 켜져 있겠지만 'partition pruning' 옵션이 켜져 있는지 확인해야 함.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수평 파티셔닝 vs 수직 파티셔닝&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수평 파티셔닝: 행 단위로 나누는 것(range or list로 파티션을 나눌 수 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수평 파티셔닝: 열 단위로 파티션을 나눈 것&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ Blob(binary large object)과 같은 large column 일 때, 그 blob 문서를 거의 쿼리 하지 않을 때 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 이런 상황에서 Blob table은 slow access drive에 넣고, 나머지는 SSD에 넣으면 공간과 액세스 속도를 절약할 수 있음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파티셔닝 유형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- By Range: 연도 등 이용 아카이브 lifecycle에도 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- By List: 이산적인(discrete) 값 사용, ex_나라명 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- By Hash: 해시 함수 이용&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파티셔닝 vs 샤딩&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;수평 파티셔닝&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동일한 DB 내에 여러 테이블로 분할하며, DB가 분할의 관리를 담당, client 입장에서는 추상화되어 있어서 알 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블 명이 변경됨&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 샤딩&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;nbsp; 큰 테이블을 여러 개의 테이블로 분할 후 다른 서버에 배치, 본질적으로 분산 처리를 위함.(레이턴시 절감 등), client 입장에서 인지하고 있어야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블 명은 유지됨, 쿼리를 실행하는 서버가 변경될 뿐&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파티셔닝 장단점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리 성능 개선(특정 상황에서 순차 스캔 대신 분산된 인덱스 스캔)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쉬운 대량 로딩 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- easy attach partition(일례로 mysql에서는 수억 개의 csv 파일을 파티션으로 이용하고, DB에서 CSV를 가리키는 테이블을 만들 수 있음)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- old data 아카이브(테이블 별 HDD/SSD 구분 등)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 파티션으로 이동시키는 업데이트는 느림(값이 바뀌어서 다른 파티션으로 옮겨가는 경우)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비효율적 쿼리는 모든 파티션을 조회할 수 있음. 단일 테이블보다 성능 하락&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스키마 변경이 어려움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;샤딩&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;샤딩이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;필요성:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;하나의 DB에서 데이터가 많아질수록 쿼리가 느려짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤딩: 데이터를 여러 DB 인스턴스에 분산하여 파티션으로 세분화하는 프로세스, 시스템의 쿼리 속도 향상 및 확장성 확보 목적&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블을 분할해서 다른 DB 인스턴스에 넣는데, 특정 필드나 열을 파티션 키(단축키)로 하여 이를 기반으로 여러 테이블에 넣음&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Consistent Hashing(일관된 해싱)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 입력을 일관되게 해싱하여 서버를 결정 -&amp;gt; 동일한 입력 쿼리에 대해 항상 같은 서버로 보낼 것을 보장하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) 문자열이면 아스키코드로 변환 후 모듈러 연산, Hash(&quot;Input1&quot;) % n&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수평 파티셔닝 vs 샤딩&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수평 파티셔닝: 테이블 이름은 다른 곳에 저장되지만 client가 알 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;샤딩: 모든 것이 동일하지만 다른 서버에 저장됨&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장단점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 확장성을 얻을 수 있음, data &amp;amp; memory&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안 수준 제어 가능, 데이터 분산&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- index 크기가 줄어들어 최적화됨&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 복잡해짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드 간 트랜잭션에 대한 문제.. 서버가 달라지면 별개의 원자성을 갖기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 롤백이 어려워짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스키마 변경이 어려워짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 조인 수행의 어려움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키와 상관없는 column을 조회할 때의 어려움&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DB 샤딩을 하는 시점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 방법을 다 사용하고 최대한 마지막에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복잡한 작업과 아키텍처를 요구함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인덱스, 파티셔닝, 레플리카, 캐싱 등을 사용하고 최후에 사용... 오버 엔지니어링하지 않도록 주의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤딩은 클라이언트 단에서도 지식이 있어야 하지만, 파티셔닝은 최근 DB에서는 활성화만 하면, 클라이언트는 알 필요 없도록 자동으로 동작함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 요즘은 vitesse와 같은 미들웨어가 샤딩을 도와주긴 함. (하지만 정말 필요한가에 대해서는 한번 더 고민해 볼 것)&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>consistent hashing</category>
      <category>partition pruning</category>
      <category>partitioning</category>
      <category>postgres partitioning</category>
      <category>샤딩</category>
      <category>수평 파티셔닝 vs 수직 파티셔닝</category>
      <category>파티셔닝</category>
      <category>파티셔닝 vs 샤딩</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/120</guid>
      <comments>https://pypystory.tistory.com/120#entry120comment</comments>
      <pubDate>Wed, 1 Jan 2025 20:54:13 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - B-Tree, B+Tree (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1NVz5/btsLAuaVkiR/BwDcVTKGI52vJ1u3V57JR0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1NVz5/btsLAuaVkiR/BwDcVTKGI52vJ1u3V57JR0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1NVz5/btsLAuaVkiR/BwDcVTKGI52vJ1u3V57JR0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1NVz5%2FbtsLAuaVkiR%2FBwDcVTKGI52vJ1u3V57JR0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vblM9/btsLCsCA5Jr/0xkFY3Q703YSWkNcX14ovK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vblM9/btsLCsCA5Jr/0xkFY3Q703YSWkNcX14ovK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vblM9/btsLCsCA5Jr/0xkFY3Q703YSWkNcX14ovK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvblM9%2FbtsLCsCA5Jr%2F0xkFY3Q703YSWkNcX14ovK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;297&quot; height=&quot;297&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;B-Tree&lt;/b&gt;&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;B-Tree&amp;nbsp;&lt;/b&gt;&lt;b&gt;필요성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Full Table Scans: large tables를 읽는 것은 느림... 모든 page를 읽으면 많은 디스크 IO 발생&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;B-Tree란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 빠른 탐색을 위해 만들어진 균형잡힌 데이터 구조로 검색 공간을 최소화하는게 목표&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-tree는 노드로 구성되어 있음, m이라는 차수를 가짐... 차수는 기본적으로 각 노드가 가질 수 있는 자식 노드의 수에 해당됨,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- m degree 트리의 노드는 m-1 elements를 가짐... 각 element는 key-value를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - value는 row를 가리키는 포인터(data pointer), key는 검색하는 대상&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - data pointer는 PK or Tuple(internal tuple id)을 가리킬 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Root Node: top node, Internal Node: 중간 단계, Leaf Node: 끝에 있는 노드(no child)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;A node == disk page&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;성능&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-tree 구조의 모든 노드에 key와 value가 존재함(메모리 효율성을 위해 중요)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- element가 추가되면 m 값에 따라 page가 분할 될 수 있음. 너무 잦은 분할은 cost가 많이 듬&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;한계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 노드의 모든 요소가 키와 값을 모두 저장한다는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 더 많은 공간을 차지하고, 더 많은 IO를 발생시켜 순회 속도를 늦출 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 범위 쿼리가 랜덤 액세스 때문에 느림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~5 사이의 값을 가져오려면 앞뒤로 왔다갔다해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;B+Tree로 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;B+Tree&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;B+Tree란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-Tree와 동일하지만 키를 internal 노드와 root에만 저장(data page와 value가 없으니 슬림해져서 한 노드에 더 많은 키를 넣을 수 있게 된 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 값은 leaf 노드에만 저장(leaf node 키는 internal 노드와 중복 될 수 있음... leaf 노드에서 모든 값을 가져야하기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 노드를 가져오려면 하나의 IO가 필요한데, B-tree에 비해 한 노드에 더 많은 요소와 키를 저장할 수 있게 되었음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- leaf node는 'linked' 되어서 범위쿼리를 도움. 한번 키를 찾으면 앞 뒤에 것에도 접근할 수 있게 된 것&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DBMS 고려사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- leaf pointer의 cost에 대한 고려 (범위 쿼리가 쓰일지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- internal node는 인메모리에 위치, leaf node는 힙 내의 데이터 파일에 저장될 수 있음(값이 클 수 있으니... 포인터 크게에 따라 달라짐)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MySQL vs Postgres 에서의 B+Tree 저장 cost&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B+Tree의 보조 인덱스 value는 직접 tuple을 가리키거나(postgres), PK를 가리킬 수 있음(mysql)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 보조 인덱스가 튜플을 가리킨다면, 튜플의 크기는 작기에 문제가 되지 않지만, PK의 경우 UUID일 경우에 문제가 될 수 있음... 삽입이 매우 느려짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL(InnoDB)에는 리프노드에 전체 행이 포함되어 있음... IOT/ 클러스터형 인덱스 이기 때문(테이블 자체가 인덱스라고 볼 수도 있음)&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>B+Tree</category>
      <category>B-Tree</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/119</guid>
      <comments>https://pypystory.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 30 Dec 2024 20:40:00 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - 데이터베이스 Indexing (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dGcsmm/btsLAto9IWu/6SbNOIT47ekSLBGq1gJgDk/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dGcsmm/btsLAto9IWu/6SbNOIT47ekSLBGq1gJgDk/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dGcsmm/btsLAto9IWu/6SbNOIT47ekSLBGq1gJgDk/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdGcsmm%2FbtsLAto9IWu%2F6SbNOIT47ekSLBGq1gJgDk%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sVN8R/btsLCnA2T7x/z06WIk9u898GGYwHJZPdJk/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sVN8R/btsLCnA2T7x/z06WIk9u898GGYwHJZPdJk/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sVN8R/btsLCnA2T7x/z06WIk9u898GGYwHJZPdJk/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsVN8R%2FbtsLCnA2T7x%2Fz06WIk9u898GGYwHJZPdJk%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;305&quot; height=&quot;305&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인덱싱 시작하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- explain analyze로 실행계획(쿼리계획)을 분석할 수 있음&lt;/p&gt;
&lt;pre id=&quot;code_1735387784995&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;explain analyze select * from temp;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Index only scan : Heap에서 fetch할 필요 없어 제일 빠르고 좋은 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Parallel seq scan : 전체를 다 훑어야해서 최악의 경우.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- create index로 인덱스 생성 가능&lt;/p&gt;
&lt;pre id=&quot;code_1735387859929&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;create index temp_t on temp(t);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- where 문으로 특정하였을 때 효과있지만, LIKE 문과 같이 특정하지 못하면 index 쓰는 의미가 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SQL 쿼리 플래너&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735388387436&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ex1
explain select * from temp;
                          QUERY PLAN
--------------------------------------------------------------
 Seq Scan on temp  (cost=0.00..14425.01 rows=1000001 width=4)&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1735389154702&quot; class=&quot;sql&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;sql&quot;&gt;&lt;code&gt;# ex2
explain select * from temp order by t;
                                    QUERY PLAN
----------------------------------------------------------------------------------
 Index Only Scan using temp_t on temp  (cost=0.42..18420.44 rows=1000001 width=4)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Seq Scan: 테이블 전체 순차 탐색&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0.00: 첫 페이지를 가져오는데 걸리는 시간 ms&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;14425.01: DB가 예상하는 총 ms&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;rows: 가져올 행의 수 (추정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;width: 모든 열의 바이트 합계&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행 계획(추정)일 뿐 실제 수행 시간 아님&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;비트맵 인덱스 스캔 vs 인덱스 스캔 vs 테이블 스캔&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Postgres는 where 문을 범위로 잡더라도 테이블 스캔을 할지 인덱스 스캔을 할지 자가판단 가능&lt;/p&gt;
&lt;pre id=&quot;code_1735392714269&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;explain select t from temp where t &amp;gt;10;
                         QUERY PLAN
-------------------------------------------------------------
 Seq Scan on temp  (cost=0.00..16925.01 rows=895509 width=4)
   Filter: (t &amp;gt; 10)

explain select t from temp where t &amp;lt;10;
                                  QUERY PLAN
-------------------------------------------------------------------------------
 Index Only Scan using temp_t on temp  (cost=0.42..1866.06 rows=89008 width=4)
   Index Cond: (t &amp;lt; 10)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Postgres는 특정 상황에서 Bitmap Index Scan을 할 수 있음. Index 스캔을 해서 페이지를 파악하고, bitmap을 작성해서 한 번에 힙으로 이동하여 해당하는 모든 페이지를 가져올 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;식별자 vs 비식별자 열 데이터베이스 인덱싱&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러개의 column이 있을 때, index에 비식별자를 추가할 수 있고, 추가된 비식별자 col을 조회했을 때는 Heap을 읽을 필요 없기에 빠르게 조회할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1735394764427&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;create index g_idx on students(g) include(id);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이런 방식으로 조회할 column 자체를 index에 포함해두면, 조회 시에 Heap fetch를 하지 않고 index only scan을 해서 cost를 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;+ 인덱스 크기가 크면 Disk IO가 생길 수 있는데, cost가 늘어날 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Index scan vs Index only scan&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Index only scan은 테이블을 조회하지 않아도 되는 것... Non-Key column을 포함하는 인덱싱을 잘 활용할 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;성능 개선을 위한 DB 인덱스 결합&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1735473808481&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;create table temp(a int, b int, c int);
insert into temp(a) select random()*100 from generate_series(0, 1000000);
insert into temp(b) select random()*100 from generate_series(0, 1000000);
insert into temp(c) select random()*100 from generate_series(0, 1000000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이런 형태의 테이블이 있을 때...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. a, b 각각에 대해서 index를 생성 &amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1735473962931&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;explain analyze select c from temp where a=70; -&amp;gt; Index Scan
explain analyze select c from temp where b=70; -&amp;gt; Index Scan
explain analyze select c from temp where a=100 and b=70; -&amp;gt; 각각에 대해서 Index Scan 
explain analyze select c from temp where a=100 or b=70; -&amp;gt; 각각에 대해서 Index Scan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;a, b 에 대해 복합 인덱스 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;create index on temp (a, b); 로 복합 인덱스 생성 가능&lt;/p&gt;
&lt;pre id=&quot;code_1735474018236&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;explain analyze select c from temp where a=70; -&amp;gt; Index Scan
explain analyze select c from temp where b=70; -&amp;gt; Parallel Seq Scan
explain analyze select c from temp where a=100 and b=70; -&amp;gt; Index Scan
explain analyze select c from temp where a=100 or b=70; -&amp;gt; Parallel Seq Scan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인덱스 생성시에 left side인 a에 대해서만 Index Scan이 돌아감. 단, a and b에 대해서는 우수한 성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. a,b 복합 인덱스 + b에 대해 index 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최상의 시나리오&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DB 옵티마이저가 인덱스 사용 여부 결정하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 행의 수가 적다면 인덱스를 쓰는 게 cost 손해일 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB는 테이블의 통계를 유지함(대략 몇 개의 행이 있고 값이 있는지 등), 이런 통계 정보를 활용해서 사용여부를 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 통계를 업데이트 하지 않거나, 통계를 벗어나는 대량의 값이 삽입된 직후에 쿼리가 실행되었다면, 최적이 아닌 방법으로 실행될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 이럴 때는 데이터베이스 Hint를 통해 해결할 수 있음. DB의 통계보다 hint를 반영하게 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;동시에 인덱스 생성&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인덱스를 생성할 때 기본적으로 읽기는 가능하지만 쓰기는 block 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- postgres에서는 동시 인덱스(concurrently) 사용할 수 있음&lt;/p&gt;
&lt;pre id=&quot;code_1735477661224&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;create index concurrently idx_a on temp(a);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이렇게 하면 여러 번의 스캔을 수행하고 index 작업 완료 전 write 트랜잭션을 기다리게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Bloom filters&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- A가 DB에 있는지 확인이 필요할 때, DB에 바로 요청하면 시간이 많이 걸리고, Redis와 같은 외부 인메모리 DB를 쓰면 cost가 낭비됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- '블룸 필터'는 인메모리의 표현을 이용하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 예를 들어 64bit 메모리에 Hash(A) % 64 값을 기록하고, A 유무에 대한 질의가 왔을 때 해당 bit에 기록되어있지 않다면, 쿼리를 하지 않고도 DB에도 없는 것을 빠르게 확정 지을 수 있음 (불필요한 쿼리 방지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1 Billion Row table&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대용량 데이터를 다루는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 테이블을 처리하거나 작업하는 과정에서 무차별 대입 방식 사용 - 테이블을 조각으로 나누고 병렬 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 모든 테이블을 처리하지 않고 subset만 처리하는 방법 - 인덱싱, 파티셔닝, 샤딩&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 큰 테이블을 가지지 않도록 DB 디자인 단계에서 아예 피하는 것 - ex) JOIN 대신 팔로워 자체를 JSON column으로 만들어버리는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>bloom filters</category>
      <category>create index concurrently</category>
      <category>EXPLAIN ANALYZE</category>
      <category>sql 쿼리 플래너</category>
      <category>데이터베이스 indexing</category>
      <category>복합 인덱스</category>
      <category>비식별자 인덱스</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/118</guid>
      <comments>https://pypystory.tistory.com/118#entry118comment</comments>
      <pubDate>Sun, 29 Dec 2024 23:01:50 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - DB 내부의 이해, Index, Heap, Key (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/117</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JU6KE/btsLx0nwr28/jT5vqAYztCSfpc7jz1nGRk/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JU6KE/btsLx0nwr28/jT5vqAYztCSfpc7jz1nGRk/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JU6KE/btsLx0nwr28/jT5vqAYztCSfpc7jz1nGRk/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJU6KE%2FbtsLx0nwr28%2FjT5vqAYztCSfpc7jz1nGRk%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TxOFF/btsLzB8wz4y/O8dknaQT3YQPpGLyzoyHs0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TxOFF/btsLzB8wz4y/O8dknaQT3YQPpGLyzoyHs0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TxOFF/btsLzB8wz4y/O8dknaQT3YQPpGLyzoyHs0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTxOFF%2FbtsLzB8wz4y%2FO8dknaQT3YQPpGLyzoyHs0%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;333&quot; height=&quot;333&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;테이블과 인덱스가 저장되는 방식&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;논리적 테이블 -&amp;gt; 열과 행(혹은 document)으로 이뤄져 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Row_ID&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 행 ID를 고유하게 식별(Postgres에서는 tuple ID)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL에서는 기본 키가 사실상 가짜(sudo) 행 ID가 됨, 다른 DB에서는 별개의 새로운 행 ID가 열에 생성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Page&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 행은 논리적 페이지에 저장됨, 기술적으로 한 페이지에 많은 행이 들어갈 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 페이지는 고정된 크기(MySQL는 16kb)의 메모리 위치로, 디스크 위치로도 변환되는 일련의 바이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 디스크는 RAM처럼 특정 ID의 행만 읽을 수 없음. 디스크는 페이지를 읽음.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IO를 실행하면 하나 이상의 페이지를 얻게됨(단, 이건 HDD/SSD 포멧 방식 등에 영향을 받음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 예를 들어 페이지에 3개의 row가 저장될 수 있다면 1000개의 row는 page 0~333에 저장되는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 쿼리 속도에 영향을 줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;+ 페이지 크기: 소형 페이지는 페이지 크기가 미디어 블록 크기와 비슷할 경우 RW가 더 빨라지지만, 페이지 헤더 메타데이터의 오버헤드 비용이 높아질 수 있음. 대형 페이지의 경우 메타데이터 오버헤드와 페이지 분할이 최소화되지만 느리고 읽기 및 쓰기 비용이 높아짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IO&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IO는 디스크를 읽는 요청을 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IO를 줄일 수록 쿼리가 빨라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IO는 단일 행을 읽는게 아닌 여러 행이 담긴 페이지를 읽음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OS에 따라 일부 IO는 OS 캐시로 이동(특히 Postgres는 운영 체제 캐시에 크게 의존함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Heap&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 테이블을 가리키는 페이지의 모음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블 자체에 대한 모든 정보가 담겨있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 힙에서 데이터를 바로 찾으면 비용이 많이 듬. 그래서 인덱스가 필요한데, 인덱스는 힙에서 정확히 어떤 부분을 읽어야하는지 알려줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Index&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 효과적으로 데이터를 가져올 수 있도록 힙으로 이동할 정확한 위치를 파악하는데 도움을 주는 것으로 포인터(행 ID를 가리키고 있음)를 갖고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나 이상의 열을 효과적으로 인덱싱할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- B-tree 라는 데이터 구조를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인덱스도 페이지로 저장되며, 인덱스 항목을 가져오려면 IO 비용이 발생함&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인덱스가 작을 수록 메모리에 fit하기에 빠르게 검색할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Note&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 때로는 힙 테이블이 단일 인덱스를 기준으로 구성될 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클러스터 인덱스 : 힙은 인덱스를 기준으로 정렬될 수 있음. 기본 키는 특별히 지정하지 않는 한 클러스터 인덱스로 취급됨(단, Postgres의 기본 키는 보통 보조 키여서 해당되지 않지만, MySQL의 경우 항당 기본 키를 가져서 클러스터형 인덱스를 가지고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 타입에도 유의해야하는데, 예를들어 클러스터 인덱스에 UUID를 사용하는 것은 쓰기 성능을 저하시킴. UUID를 기본 키로 쓰면, 힙은 무작위 UUID를 기준으로 구성되는데, 연속되지 않고 무작위 page에 행이 들어가기 때문에 많은 비용을 발생시킴킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;행 기반 vs 열 기반 DB&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;행 기반 DB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블이 디스크에 행으로 저장됨&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HDD/SSD에서 block 단위로 IO read를 하게 되는데, 여러 행을 한 블록에서 가져올 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 과정에서 필요없는 열을 가져오면서 많은 낭비된 읽기가 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 무언가를 찾은 후 추가 열을 요청하는 것은 저렴함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;열 기반 DB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블이 디스크에 열로 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 열별로 모든 값을 가져와서 연속된 값으로 디스크에 저장함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 저장될 때, 행 ID가 열(블록)마다 중복되게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 열은 1개 이상에 블록에 나눠서 저장되게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장단점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 행 기반 : RW에 최적화, OLTP(온라인 트랜잭션 작업), 압축/집합 효과적이지 않음, 다중 열에서 효과적 쿼리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 열 기반 : 쓰기가 느림, OLAP(온라인 분석 작업), 단일 열 압축/집합, 집계작업에 효과적임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;기본 키 vs 보조 키&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 행에서는 순서를 강제하지 않음. 데이터는 힙이라고 불리는 디스크에 특정 공간에 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본 키(primary key)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본 키의 개념이 추가되면 테이블에 클러스터링이라는 작업을 수행 함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;* 클러스터링 : 그 키를 중심으로 테이블을 구성하는 개념. 즉, 순서가 생기는 것이고, 순서와 관련된 추가 비용이 발생하는 것. 테이블 자체의 인덱스라고 볼 수 있음.(클러스터형 인덱스 혹은 IOT(인덱스로 조직화된 테이블)이라함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 추가 비용이 발생함에도, 클러스터형 인덱스는 범위 쿼리에서 속도가 빨라지는 장점이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 만약 기본키가 랜덤으로 있다면, 무작위성 때문에 힙을 왔다갔다하게 됨. DB가 이러한 행을 삽입하기 위해 수행하는 메모리 캐싱의 이점을 누릴 수 없게됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;보조 키&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보조키는 자체적으로는 아무 순서도 없지만, 다른 구조에서 순서가 있음. 즉, 인덱스를 위한 별도의 구조를 유지하고 있는 것(보조 인덱스)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 검색 시에는 먼저 이 인덱스로 이동해서 검색을 수행하고, 원하는 튜플이나 페이지를 수집해야함(인덱스 자체에서는 모든 정보를 포함하지 않기 때문)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 이 방식을 사용하면 인덱스에서 찾고 실제 data를 얻기 위해서 이동을 해야되서 비효율이 발생할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>db index &amp;amp; heap</category>
      <category>db io</category>
      <category>db page</category>
      <category>PRIMARY KEY</category>
      <category>행 기반 열 기반 db</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/117</guid>
      <comments>https://pypystory.tistory.com/117#entry117comment</comments>
      <pubDate>Fri, 27 Dec 2024 14:39:01 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 이론 정리 - ACID (Fundamentals of Database Engineering)</title>
      <link>https://pypystory.tistory.com/116</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDYPf4/btsLrh3fOWE/AZpBzlWrS46GZZKsQs2CS0/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDYPf4/btsLrh3fOWE/AZpBzlWrS46GZZKsQs2CS0/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDYPf4/btsLrh3fOWE/AZpBzlWrS46GZZKsQs2CS0/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDYPf4%2FbtsLrh3fOWE%2FAZpBzlWrS46GZZKsQs2CS0%2Ftfile.dat&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;239&quot; data-filename=&quot;data servers.webp&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 'Fundamentals&amp;nbsp;of&amp;nbsp;Database&amp;nbsp;Engineering'에 관한 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/database-engines-crash-course&quot;&gt;https://www.udemy.com/course/database-engines-crash-course&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n1Ga1/btsLsd0hnyS/AYQjaI1xKAFnmXOIyk0j10/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n1Ga1/btsLsd0hnyS/AYQjaI1xKAFnmXOIyk0j10/img.webp&quot; data-alt=&quot;ACID by GPT&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n1Ga1/btsLsd0hnyS/AYQjaI1xKAFnmXOIyk0j10/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn1Ga1%2FbtsLsd0hnyS%2FAYQjaI1xKAFnmXOIyk0j10%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;290&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ACID by GPT&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;트랜잭션&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;트랜잭션이란?&lt;/b&gt; : 하나의 작업 단위로 취급되는 한 개 이상의 쿼리 모음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;트랜잭션 수명 : BEGIN -&amp;gt; COMMIT -&amp;gt; ROLLBACK(when crash)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;트랜잭션의 본질: 데이터를 변경하고 수정하는데 사용, 읽기 전용일 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;읽기 트랜잭션: 무언가가 동시 트랜잭션 때문에 바뀌어도 신경쓸 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;트랜잭션은 항상 BEGIN 해야하고, 그렇지 않을시 DB에서 암묵적으로 BEGIN을 실행함... 항상 트랜잭션 안에 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;원자성(Atomicity)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;원자성 정의&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션 내의 모든 쿼리는 성공해야한다 - 하나의 쿼리가 실패하면, 즉시 롤백되어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 DB를 선택할까와도 연결됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB에 따라 커밋하기 전에 디스크에 기록하는 경우도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어떤 DB는 커밋은 메모리에서 빠르게 일어나고, 디스크에 플러시할 때 느림, 대신 롤백은 매우 빠름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;원자성 부족으로 일관성을 잃을 수 있음 -&amp;gt; DB는 재시작하면서 정리를 해야함... 긴 트랜잭션에선, 롤백이 오래걸릴 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;고립성(Isolation)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러 트랜잭션이 변경하거나 읽으려고 경합하는 상황에 고립성이 필요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Read phenomena&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Dirty reads&lt;/b&gt;: 현재 실행 중인 트랜잭션에서 발생하는 읽기 현상&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 트랜잭션이 쓴 내용을 읽지만 실제로 아직 커밋되지 않은 것을 읽는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;* Dirty : 완전히 커밋되지 않은.. flush 되지 않은 것을 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Non-repeatable reads(중복되지 않은 읽기)&lt;/b&gt;: 트랜잭션 중에 값을 읽은 후, 동일 트랜잭션에서 다시 그 값을 읽을 때, 그 값이 변경되어 있는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB 종류에 따라 다름 Postgres는 버전 포인터를 유지해서 동일한 상황에서 원본 버전을 읽을 수 있지만, mysql은 기본적으로 원본 버전을 읽을 수 없고, 별도의 undo 로그를 열어서 확인해야하기에 장기 실행 트랜잭션에 대해 많은 비용이 들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Phantom reads&lt;/b&gt;: 아직 존재하지 않아서 실제로 읽을 수 없는 것들&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 범위 쿼리에서 새로운 행을 삽입했을 때, 다시 읽으면 유령인 새 행을 읽음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 범위쿼리에서 발생하게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. Lost updates&lt;/b&gt;: 커밋하기 전에 내가 쓴 것을 읽으려고 함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쓰자마자 읽었는데, 다른 트랜잭션이 내가 쓴걸 바꿨을 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 동시에 트랜잭션이 발생해서 10인 값을 +5 +10했다면, 25가 되는게 아닌 먼저 커밋되는 쪽으로 write가 되어서 15가 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 행 레벨 잠금으로 해결가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Isolation Levels - &lt;/b&gt;&lt;b&gt;트랜잭션의 고립 수준&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Read uncommitted&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL Server를 제외한 나머지 DB는 지원하지 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- No Isolation의 의미로 내가 읽는 모든 것은 다른 이들이 변경하는 것들도 모두 보이게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- dirty read 를 포함한 모든 읽기 현상이 발생할 수 있음. 대신 빠름.. 아무것도 유지할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Read committed&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가장 인기있는 고립 수준으로 많은 DB가 엔진을 커밋된 읽기 워크로드에 최적화하고 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션 내의 각 쿼리는 트랜잭션에 의해 커밋된 변경사항만을 볼 수 있음. 다른 트랜잭션이 변경을 수행하는 동안, 해당 트랜잭션이 커밋되지 않는 이상 변경을 볼 수 없음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장기 실행 트랜잭션이 있다면 다 실행되고 나서야 확인할 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 읽기 현상 중 Dirty read만 방지 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Repeatable Read&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 반복되지 않는 읽기를 해결하기 위해 고안된 고립수준... 읽기를 반복 가능하게 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동일한 트랜잭션 상에서 읽고 다시 읽어도 값이 변경되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션은 쿼리가 행을 읽을 때, 해당 행이 변경되지 않도록 보장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 읽기 현상 중 유령 읽기 빼고는 방지 가능... 단, postgres는 RR에서도 유령 읽기를 막아줌 MVCC 덕분&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. Snapshot&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 쿼리는 트랜잭션의 시작 시점까지 커밋된 변경 사항만을 볼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 읽기 현상을 제거하는 것을 보장함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Postgres의 반복가능한 읽기는 사실 스냅샷 고립임(모든 것이 버전을 관리함... 트랜잭션을 시작하면 어떤 버전에 있는지 타임 스탬프로 표시)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5. Serializable(직렬화)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 가장 느린 것으로 거의 물리적으로 각 트랜잭션이 데이터베이스에 연이어 직렬화 된 것처럼 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 아예 동시성 자체를 없애버림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB가 트랜잭션 순서를 정하고, 거의 동일한 결과를 얻을 수 있도록 노력하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 의존성을 가지는(동시에 같은 행을 수정하는 등) 2개의 고립수준이 직렬화인 트랜잭션이 있다면, 하나는 실패할 준비를 해야함. 실패하고 다시 재시도하는 방식. 직렬화를 안쓰려면 비관적으로 잠그는 방법으로 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터베이스의 고립성 구현&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 각 DBMS는 고립 수준을 서로 다르게 구현함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Pessimistic(비관적 접근 방식): 비관적 동시성 제어로 잠금(행 수준, 테이블, 페이지 잠금)을 활용하는 것.. 잠금 하는 동안 다른 트랜잭션은 pending 상태가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Optimistic(낙관적 접근 방식): 잠금을 쓰지 않아 대기 중인 트랜잭션이 없음. 비용이 많이 드는 잠금 관리를 안해도됨. 실제로 잠금을 하지 않고, 상황에 맞게 하다가 실제로 충돌이 나면, 그때는 실패시키는 것(이때는 그냥 다시 시도시킴, nosql에서 선호하는 방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 직렬화는 일반적으로 적극적 동시성 제어로 구현됨. 실제로 직렬화를 하면 DB가 너무 느려지기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;일관성(Consistency)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 데이터 자체의 일관성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 현재 유지되고 있는 데이터의 상태를 나타냄. 실제 디스크에 있는 것과 데이터 모델이 일치하는지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DBA와 같은 DB 설계 사용자에 의해 정의됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 참조 무결성과 외래키를 강제하는 것이 중요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원자성과 고립성이 깨지면, 일관성이 깨짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 읽기의 일관성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기는 여러 인스턴스가 동기화되지 않아 일관성을 잃을 수 잇음, 시스템 전체에 적용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB에 커밋을 실행한 후 즉시 읽기를 실행해서 변경사항이 보이지 않는다면, 실제로 일관성이 없는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;궁극의 일관성(Eventual Consistency)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) 읽기 레플리카가 있을 때, 변경되기전에 레플리카를 읽는 경우 or Redis와 같은 캐시가 있는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 대부분의 데이터베이스는 불일치로부터 최종 일관성을 통해 회복됨... 복제 프로세스 후에는 일관성 유지하며, 동기 복제로 강제할 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 하나의 데이터베이스에서는 일관되지만, 두 개이상의 데이터베이스가 하나의 시스템으로 묶여있을 때, 사용자 입장에서는 전체 시스템이 일관되지 않음.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 궁극적 일관성은 시간이 지나면 최종적으로 DB 간 동기화가 되면서 일관성을 유지 한다는 것... 마케팅 용어에 불과할 수 있지만, SW엔지니어 입장에서는 그것이 용인될 수 있는지 결정해야함.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;지속성(Durability)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객이 DB에 만든 권한을 비휘발성 시스템 저장소에 지속시키는 과정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전력 소실이나, 트랜잭션을 완료한 후 클라이언트 충돌이 발생하더라도 돌아와서 변경 사항을 볼 수 있는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커밋된 트랜잭션에 의해 변경된 것들은 비휘발성 저장소에 저장되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지속성 기술&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. WAL(write ahead log)&lt;/b&gt; : 디스크에 쓰는건 느린 작업임. 그래서 쓰기 전용 log인 WAL에 즉시 먼저 기록된 후, 이것을 즉시 디스크에 플러시하여 지속성 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 변경사항의 버전을 압축하여 WAL(write-ahead-log segments)로 만들어 로그 세그먼트만을 기록하여 지속시킴(이 값을 이렇게 변경했다~ 에 대한 정보를 압축한 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;OS 캐시&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- OS에 쓸 때 DB가 디스크에 쓰도록 OS에 요청하면 디스크에 쓰지 않고 자신의 메모리 캐시에 씀&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 대부분 애플리케이션이 많은 쓰기를 수행하고 한번에 디스크로 flush하려고 하는데, 성능상 이유로 이런 쓰기를 일괄 처리하는 것(I/O가 줄어들기 때문)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 다만 이 과정에서 DB가 커밋해서 WAL이 디스크에 쓰인줄 알았지만, 실제로는 OS 단에서 캐시(RAM)에만 기록하고 디스크에 쓰였다고 알려줄 수 있음. 이때 crash가 일어나면 데이터를 잃어버림&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 이걸 방지하기 위해 DB에서 OS에 강제로 캐시없이 디스크에 flush하도록 명령할 수 있음(Fsync 명령), 대신 느림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 비동기 스냅샷 or 동기화 스냅샷&lt;/b&gt; : 우리가 쓰는 동안에 모든 것을 메모리에 유지함, 백그라운드에서 비동기적으로 한꺼번에 모든 것을 디스크에 스냅샷함.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. AOF &lt;/b&gt;: 변경사항을 추적하고 이러한 사항을 기록함. 데이터를 매우 가벼운 방식으로 매우 빠르게 저장하는 것을 보장, 충돌이 발생해도 항상 다시 읽고 테이블의 상태를 완전히 복원할 수 있으며, 모든 것을 저장할 필요 없이 변경 사항만 저장. 최종적으로 이것을 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Redis가 비동기 스냅샷과 WAL을 이용함&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>acid</category>
      <category>Atomicity</category>
      <category>consistency</category>
      <category>Durability</category>
      <category>isolation</category>
      <category>고립성</category>
      <category>원자성</category>
      <category>일관성</category>
      <category>지속성</category>
      <category>트랜잭션</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/116</guid>
      <comments>https://pypystory.tistory.com/116#entry116comment</comments>
      <pubDate>Fri, 20 Dec 2024 23:30:49 +0900</pubDate>
    </item>
    <item>
      <title>[트러블슈팅] aws-lambda-power-tuning으로 AWS Lambda 실행시간/비용 최적화하기</title>
      <link>https://pypystory.tistory.com/114</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caCx4K/btsLjF3SFn3/JrqNPuYz9oOevksSb4B85k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caCx4K/btsLjF3SFn3/JrqNPuYz9oOevksSb4B85k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caCx4K/btsLjF3SFn3/JrqNPuYz9oOevksSb4B85k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaCx4K%2FbtsLjF3SFn3%2FJrqNPuYz9oOevksSb4B85k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;189&quot; height=&quot;189&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;애플리케이션을 개발하면서 발생한 Lambda 비용 최적화 문제와 해결 과정을 정리해보았습니다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서비스 개발도중 AWS Lambda와 API Gateway를 이용해 REST API를 배포할 일이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Python 3.10 환경에서 동작하며, 웹사이트의 url을 입력으로 받으면 크롤링으로 단어를 추출하고, 토큰화 등 전처리 과정을 거쳐서 응답하는 프로그램이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;47&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zZE9c/btsLbNf2ckN/EnNBk7Yovmhngc4YtjR0Tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zZE9c/btsLbNf2ckN/EnNBk7Yovmhngc4YtjR0Tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zZE9c/btsLbNf2ckN/EnNBk7Yovmhngc4YtjR0Tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzZE9c%2FbtsLbNf2ckN%2FEnNBk7Yovmhngc4YtjR0Tk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;380&quot; height=&quot;47&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;47&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;로컬환경에서 테스트 했을 때는 실행에 3초 정도가 소요되어, UX에 크게 문제를 주지 않을 것이라 생각했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그런데... production 환경에서 실행 시간이 10~20초 정도 걸리고, 심지어 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;특정 URL에 대해서는 Timeout이 나는 문제가 발생했습니다.&lt;/span&gt; Timeout이 발생했다는 것은 Lambda의 기본 제한 시간인 29000ms를 넘었다는 의미입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;185&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/El1z4/btsLa3jB7e2/T7tGO6CfSlH44lQkodSvkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/El1z4/btsLa3jB7e2/T7tGO6CfSlH44lQkodSvkk/img.png&quot; data-alt=&quot;Lambda의 기본 제한 시간&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/El1z4/btsLa3jB7e2/T7tGO6CfSlH44lQkodSvkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEl1z4%2FbtsLa3jB7e2%2FT7tGO6CfSlH44lQkodSvkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;185&quot; height=&quot;214&quot; data-origin-width=&quot;185&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Lambda의 기본 제한 시간&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 문제의 원인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일단 원인 자체는 간단했습니다. lambda의 메모리 기본값은 128MB로, 로컬 환경에 비해서 부족했던 것입니다. (해당 프로그램 실행 시간에는 메모리보다는, CPU 성능이 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;직접적으로 영향을 주지만, lambda에서는 CPU 성능&lt;/span&gt;도 메모리에 비례해서 상승합니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;*2. 임시방편(번외)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정확하게 필요한 메모리를 측정하기 전에 일단 production 환경에서 Timeout이 나지 않도록 제한 시간을 늘렸습니다. 기본 lambda 웹 콘솔에서는 29000ms로 제한되어 있지만 Service Quotas에서 최대 할당량 값을 계정 수준에서 증가 요청하면 즉시 할당량을 상승 시킬 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1631&quot; data-origin-height=&quot;751&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzHeNA/btsLbMIeNVw/yyGoWtiC7iB5b5sgvD5tJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzHeNA/btsLbMIeNVw/yyGoWtiC7iB5b5sgvD5tJk/img.png&quot; data-alt=&quot;Service Quotas&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzHeNA/btsLbMIeNVw/yyGoWtiC7iB5b5sgvD5tJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzHeNA%2FbtsLbMIeNVw%2FyyGoWtiC7iB5b5sgvD5tJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;373&quot; data-origin-width=&quot;1631&quot; data-origin-height=&quot;751&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Service Quotas&lt;/figcaption&gt;
&lt;/figure&gt;
&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;b&gt;3. 문제의 해결&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-1. 메모리를 늘려가며 수동 테스트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Lambda는 함수가 실행된 시간과 할당된 메모리에 비례해서 비용을 지불하게 됩니다. 직접 웹 콘솔에서 수동으로 메모리를 늘려가며 청구 기간을 비교해보았습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rSU5S/btsLbSIqSBg/msevLooazkxCXleIOEN4m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rSU5S/btsLbSIqSBg/msevLooazkxCXleIOEN4m1/img.png&quot; width=&quot;238&quot; height=&quot;279&quot; data-origin-width=&quot;155&quot; data-origin-height=&quot;182&quot; data-is-animation=&quot;false&quot; style=&quot;width: 32.084%; margin-right: 10px;&quot; data-widthpercent=&quot;32.85&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rSU5S/btsLbSIqSBg/msevLooazkxCXleIOEN4m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrSU5S%2FbtsLbSIqSBg%2FmsevLooazkxCXleIOEN4m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;155&quot; height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeRelF/btsLao26vIT/oimYqFyiXJiBDoNkHFuaK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeRelF/btsLao26vIT/oimYqFyiXJiBDoNkHFuaK0/img.png&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;183&quot; data-is-animation=&quot;false&quot; style=&quot;width: 33.1439%; margin-right: 10px;&quot; data-widthpercent=&quot;33.93&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeRelF/btsLao26vIT/oimYqFyiXJiBDoNkHFuaK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeRelF%2FbtsLao26vIT%2FoimYqFyiXJiBDoNkHFuaK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;161&quot; height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8925a/btsLaDlrVl8/3modGeWaG29KC0nkWhUqzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8925a/btsLaDlrVl8/3modGeWaG29KC0nkWhUqzK/img.png&quot; data-origin-width=&quot;149&quot; data-origin-height=&quot;173&quot; data-is-animation=&quot;false&quot; data-widthpercent=&quot;33.22&quot; style=&quot;width: 32.4465%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8925a/btsLaDlrVl8/3modGeWaG29KC0nkWhUqzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8925a%2FbtsLaDlrVl8%2F3modGeWaG29KC0nkWhUqzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;149&quot; height=&quot;173&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;왼쪽부터 128MB, 512MB, 1024MB 메모리 설정 후 동일 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예상대로 메모리에 반비례해서 청구 기간은 줄어드는 모습입니다. 무조건 메모리를 높이면 UX에는 도움이 되겠지만, 비용면에서 비효율적일 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실제로 위 측정 결과에서도 128에서 512로 메모리가 4배 늘어났지만, 청구 기간은 1/4배보다는 긴 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3-2. aws-lambda-power-tuning으로 최적화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;lambda 최적화를 위해 AWS 공식 Docs에서는 아래와 같은 방법을 제시하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;기능에&amp;nbsp;적합한&amp;nbsp;메모리&amp;nbsp;구성을&amp;nbsp;찾으려면&amp;nbsp;오픈&amp;nbsp;소스&amp;nbsp;AWS&amp;nbsp;Lambda&amp;nbsp;Power&amp;nbsp;Tuning&amp;nbsp;도구를&amp;nbsp;사용하는&amp;nbsp;것이&amp;nbsp;좋습니다.&amp;nbsp;이&amp;nbsp;도구는&amp;nbsp;AWS&amp;nbsp;Step&amp;nbsp;Functions를&amp;nbsp;사용하여&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;메모리&amp;nbsp;할당에서&amp;nbsp;Lambda&amp;nbsp;함수의&amp;nbsp;여러&amp;nbsp;동시&amp;nbsp;버전을&amp;nbsp;실행하고&amp;nbsp;성능을&amp;nbsp;측정합니다.&amp;nbsp;입력&amp;nbsp;함수는&amp;nbsp;AWS&amp;nbsp;계정에서&amp;nbsp;실행되어&amp;nbsp;라이브&amp;nbsp;HTTP&amp;nbsp;호출&amp;nbsp;및&amp;nbsp;SDK&amp;nbsp;상호&amp;nbsp;작용을&amp;nbsp;수행하고&amp;nbsp;라이브&amp;nbsp;프로덕션&amp;nbsp;시나리오에서&amp;nbsp;예상&amp;nbsp;성능을&amp;nbsp;측정합니다.&amp;nbsp;또한&amp;nbsp;이&amp;nbsp;도구를&amp;nbsp;사용하도록&amp;nbsp;CI/CD&amp;nbsp;프로세스를&amp;nbsp;구현하여&amp;nbsp;배포한&amp;nbsp;새&amp;nbsp;기능의&amp;nbsp;성능을&amp;nbsp;자동으로&amp;nbsp;측정할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Lambda를 메모리 별로 실행하고, 자동으로 최적화된 메모리 값을 그래프와 함께 제한해주는 오픈소스 툴 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 아래 페이지로 들어가 Deploy를 클릭합니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UWt6n/btsLiH9uDKj/dkoDlrC92Wp5ipyhBpKt40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UWt6n/btsLiH9uDKj/dkoDlrC92Wp5ipyhBpKt40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UWt6n/btsLiH9uDKj/dkoDlrC92Wp5ipyhBpKt40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUWt6n%2FbtsLiH9uDKj%2FdkoDlrC92Wp5ipyhBpKt40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;795&quot; height=&quot;366&quot; data-origin-width=&quot;1213&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:451282441545:applications~aws-lambda-power-tuning&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:451282441545:applications~aws-lambda-power-tuning&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 하단에 IAM 역할 생성에 동의하기를 체크하고 배포해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgymyB/btsLj07Cpw5/KJD9knVQ4Tr9AMkvTUJhhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgymyB/btsLj07Cpw5/KJD9knVQ4Tr9AMkvTUJhhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgymyB/btsLj07Cpw5/KJD9knVQ4Tr9AMkvTUJhhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgymyB%2FbtsLj07Cpw5%2FKJD9knVQ4Tr9AMkvTUJhhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;289&quot; data-origin-width=&quot;662&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Step Function으로 들어와 배포한 상태머신을 선택합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvU7W5/btsLj9DqGvt/4g71cPp95PpisW1dk6g27K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvU7W5/btsLj9DqGvt/4g71cPp95PpisW1dk6g27K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvU7W5/btsLj9DqGvt/4g71cPp95PpisW1dk6g27K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvU7W5%2FbtsLj9DqGvt%2F4g71cPp95PpisW1dk6g27K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;727&quot; height=&quot;137&quot; data-origin-width=&quot;1004&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 우측 상단에 실행 시작을 클릭하고, 아래 형식으로 JSON을 입력합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bllWCx/btsLj4oEaJ0/7prCm9Z75PlTzIzpGweHv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bllWCx/btsLj4oEaJ0/7prCm9Z75PlTzIzpGweHv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bllWCx/btsLj4oEaJ0/7prCm9Z75PlTzIzpGweHv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbllWCx%2FbtsLj4oEaJ0%2F7prCm9Z75PlTzIzpGweHv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;722&quot; height=&quot;261&quot; data-origin-width=&quot;1916&quot; data-origin-height=&quot;692&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1734269155982&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;lambdaARN&quot;: &quot;측정할 lambda의 ARN&quot;,
  &quot;powerValues&quot;: [
    128,
    256,
    512,
    1024,
    2048
  ],
  &quot;num&quot;: 10,
  &quot;payload&quot;: {
    // 본인 lambda 코드에 맞춰서 수정
  },
  &quot;parallelInvocation&quot;: true,
  &quot;strategy&quot;: &quot;cost&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 payload는 lambda에 입력되는 테스트 이벤트를 JSON 형식으로 입력할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwk73I/btsLkrw5yz2/m1f6kTPlHySU6kVk3wiD9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwk73I/btsLkrw5yz2/m1f6kTPlHySU6kVk3wiD9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwk73I/btsLkrw5yz2/m1f6kTPlHySU6kVk3wiD9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbwk73I%2FbtsLkrw5yz2%2Fm1f6kTPlHySU6kVk3wiD9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;753&quot; height=&quot;261&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행 결과 탭에서 최적화된 메모리 size를 알 수 있고, 좌측 상태 출력에 visualization에 웹사이트 주소에서 아래와 같이 측정 값을 그래프로 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;769&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c96FSO/btsLjrSbSeX/kPM68IPNiXuywRarG5JAyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c96FSO/btsLjrSbSeX/kPM68IPNiXuywRarG5JAyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c96FSO/btsLjrSbSeX/kPM68IPNiXuywRarG5JAyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc96FSO%2FbtsLjrSbSeX%2FkPM68IPNiXuywRarG5JAyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;824&quot; height=&quot;366&quot; data-origin-width=&quot;1730&quot; data-origin-height=&quot;769&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;해당 프로그램은 512MB로 메모리를 설정했을 때, 4초 정도 실행 시간이 소요되고 비용 최적화가 된다는 것을 확인할 수 있었습니다. aws-lambda-power-tuning를 사용하여 예산과 UX에 맞는 효율적인 의사 결정을 하는데 도움을 받을 수 있었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-memory.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/configuration-memory.html&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://github.com/alexcasalboni/aws-lambda-power-tuning&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/alexcasalboni/aws-lambda-power-tuning&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:451282441545:applications~aws-lambda-power-tuning&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:451282441545:applications~aws-lambda-power-tuning&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발/트러블슈팅</category>
      <category>AWS Lambda</category>
      <category>aws-lambda-power-tuning</category>
      <category>lambda 29000ms 제한</category>
      <category>lambda cost optimization</category>
      <category>lambda 메모리 최적화</category>
      <category>lambda 비용 최적화</category>
      <category>lambda 소요시간</category>
      <category>lambda 최적화</category>
      <category>Service Quotas</category>
      <category>람다 최적화</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/114</guid>
      <comments>https://pypystory.tistory.com/114#entry114comment</comments>
      <pubDate>Sun, 15 Dec 2024 22:36:41 +0900</pubDate>
    </item>
    <item>
      <title>[Jenkins] Jenkins+AWS CodeDeploy를 이용해서 Nest.js 프로젝트를 EC2에 배포하는 CI/CD 구축하기</title>
      <link>https://pypystory.tistory.com/113</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;jenkins_logo_icon.webp&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lDfQB/btsKKigbebP/TOdEPDTUDp8yKdQFoaWqNK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lDfQB/btsKKigbebP/TOdEPDTUDp8yKdQFoaWqNK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lDfQB/btsKKigbebP/TOdEPDTUDp8yKdQFoaWqNK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlDfQB%2FbtsKKigbebP%2FTOdEPDTUDp8yKdQFoaWqNK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;227&quot; height=&quot;227&quot; data-filename=&quot;jenkins_logo_icon.webp&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;그동안 프로젝트를 배포할 때 Github Action을 이용해서, Build, Test 후 배포를 해왔는데, Jenkins를 써서 CI/CD 파이프라인을 구성해 보면서 공부한 내용을 정리하고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;프로젝트는 NestJS 기본 템플릿을 사용하고, 빌드를 성공하고 테스트를 통과하면 AWS CodeDeploy를 이용해서 EC2에 배포하는 파이프라인을 만들고, 나아가 단일 EC2가 아닌 target group 내에 여러 EC2에 동시에 배포되도록 구성해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;환경&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;로컬 환경&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;OS : Win10&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Docker Desktop : 4.30.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Nest : 10.3.2&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Node : 20.11.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;Jenkins : 2.479.1&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;AWS EC2 환경&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;OS : &lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;span&gt;Amazon Linux 2023 AMI&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;span&gt;Node : 22.11.0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #16191f; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #14141f; text-align: center;&quot;&gt;&lt;span&gt;production에서는 Nest 프로젝트 자체를 docker로 감싸서 EC2(ECS)에 배포함으로써 버전에 일관성을 챙기면 좋겠지만, 이 글에서는 편의상 EC2에서 pm2로 바로 실행하겠습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Jenkins 세팅&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;635&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXE0ru/btsKJEj0vHv/AWVkSOhc8xGE1IjyKomFoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXE0ru/btsKJEj0vHv/AWVkSOhc8xGE1IjyKomFoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXE0ru/btsKJEj0vHv/AWVkSOhc8xGE1IjyKomFoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXE0ru%2FbtsKJEj0vHv%2FAWVkSOhc8xGE1IjyKomFoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1920&quot; height=&quot;635&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;635&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Jenkins 설치에 관해서는 많은 블로그에서 다루고 있기에 생략하겠습니다.&amp;nbsp;본인은 윈도우 PC 로컬 환경에서 Docker를 이용해 Jenkins를 세팅했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1731570789881&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker pull jenkins/jenkins:lts
docker run -d -p 18080:8080 -v C:\docker\jenkins:/var/jenkins_home jenkins/jenkins --name jenkins-container -u root jenkins/jenkins:lts&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이때 docker run 명령어 실행 전에 로컬 파일 탐색기에서 C:\docker\jenkins 폴더를 만들고 `-v` 옵션으로, docker가 꺼졌다 켜져도 jenkins 설정이나 플러그인이 저장될 수 있도록 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Jenkins Plugin 설치&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1881&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lwW3g/btsKMDdUP52/kSNCdsJrpNtzQkvvzH9goK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lwW3g/btsKMDdUP52/kSNCdsJrpNtzQkvvzH9goK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lwW3g/btsKMDdUP52/kSNCdsJrpNtzQkvvzH9goK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlwW3g%2FbtsKMDdUP52%2FkSNCdsJrpNtzQkvvzH9goK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1881&quot; height=&quot;611&quot; data-origin-width=&quot;1881&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 3개의 플러그인을 설치해 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1731679323025&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Generic Webhook Trigger
GitHub Integration
AWS CodeDeploy&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Nest.js 프로젝트 생성 + github 설정&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Nest.js 프로젝트 및 Github Repo 생성&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1731570996946&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nest new jenkins-test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;새로운 NestJS 프로젝트를 만들어주고, github private repository도 만들어줬습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;308&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jjgvv/btsKJOzVItX/8OcnPyVdgPOQuetpveZMmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jjgvv/btsKJOzVItX/8OcnPyVdgPOQuetpveZMmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jjgvv/btsKJOzVItX/8OcnPyVdgPOQuetpveZMmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJjgvv%2FbtsKJOzVItX%2F8OcnPyVdgPOQuetpveZMmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;252&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;308&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Github Token 생성 및 Jenkins에 등록&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFd2B8/btsKMaQNh7K/KFQhstmuCJZA8K3jJiAYb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFd2B8/btsKMaQNh7K/KFQhstmuCJZA8K3jJiAYb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFd2B8/btsKMaQNh7K/KFQhstmuCJZA8K3jJiAYb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFd2B8%2FbtsKMaQNh7K%2FKFQhstmuCJZA8K3jJiAYb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1117&quot; height=&quot;262&quot; data-origin-width=&quot;1117&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Github에서 토큰을 발급받아줍니다. 이때 권한은 아래와 같이 넣어주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lZbiu/btsKL0nbJGM/c6emKfPE0ZgLyuqliSZlM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lZbiu/btsKL0nbJGM/c6emKfPE0ZgLyuqliSZlM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lZbiu/btsKL0nbJGM/c6emKfPE0ZgLyuqliSZlM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlZbiu%2FbtsKL0nbJGM%2Fc6emKfPE0ZgLyuqliSZlM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;433&quot; data-origin-width=&quot;778&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;생성하면 ghp_************************************* 이런 식으로 token을 주는데 잘 복사해 둡시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Jenkins로 돌아와서 관리 &amp;gt; Credentials로 들어갑니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvobC2/btsKLd8kTfG/KS5AvL0SK8p4SkZ5Bshq2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvobC2/btsKLd8kTfG/KS5AvL0SK8p4SkZ5Bshq2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvobC2/btsKLd8kTfG/KS5AvL0SK8p4SkZ5Bshq2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvobC2%2FbtsKLd8kTfG%2FKS5AvL0SK8p4SkZ5Bshq2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;165&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 글로벌을 클릭하고, Add Credentials를 눌러 방금 발급받은 token을 등록합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;Username에는 깃헙 계정명&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;password에 발급받은 토큰&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;ID는 원하는 식별자를 넣어주면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1757&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MIl7b/btsKIVfJMqp/60aZYSekOW8Mm4CWWUG3kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MIl7b/btsKIVfJMqp/60aZYSekOW8Mm4CWWUG3kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MIl7b/btsKIVfJMqp/60aZYSekOW8Mm4CWWUG3kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMIl7b%2FbtsKIVfJMqp%2F60aZYSekOW8Mm4CWWUG3kK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1757&quot; height=&quot;817&quot; data-origin-width=&quot;1757&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Jenkins 관리 &amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;System에서&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;스크롤을 내려보면 Github Server 부분이 있는데 여기에 Credentials 부분에 방금 만든 식별자를 선택하고, 하단에 Test connetion을 눌렀을 때, 'Credentials verified for user americano212, rate limit: 4999' 이렇게 나오면 성공입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRafGY/btsKLlSM24Q/h3kcMmpjMtX3pKQHKRzCDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRafGY/btsKLlSM24Q/h3kcMmpjMtX3pKQHKRzCDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRafGY/btsKLlSM24Q/h3kcMmpjMtX3pKQHKRzCDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRafGY%2FbtsKLlSM24Q%2Fh3kcMmpjMtX3pKQHKRzCDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1731&quot; height=&quot;717&quot; data-origin-width=&quot;1731&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Github Webhook 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;785&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTGExn/btsKMCF1ADu/pMVkRtrnqM0wlq2qqxjOpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTGExn/btsKMCF1ADu/pMVkRtrnqM0wlq2qqxjOpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTGExn/btsKMCF1ADu/pMVkRtrnqM0wlq2qqxjOpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTGExn%2FbtsKMCF1ADu%2FpMVkRtrnqM0wlq2qqxjOpK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;758&quot; height=&quot;540&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;785&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Github repository &amp;gt; Settings &amp;gt; Webhooks에서 새로운 webhook을 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Payload URL에 Jenkins가 돌아가고 있는 서버 URL을 입력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;형식은 http://{서버 주소}:{Jenkins 포트}/github-webhook/ 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;191&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KlegA/btsKMfRVKZK/eFlhpMaaQiF8JOD3QURyQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KlegA/btsKMfRVKZK/eFlhpMaaQiF8JOD3QURyQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KlegA/btsKMfRVKZK/eFlhpMaaQiF8JOD3QURyQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKlegA%2FbtsKMfRVKZK%2FeFlhpMaaQiF8JOD3QURyQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;164&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;191&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;성공하면 녹색 체크 표시가 들어옵니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;필자는 Jenkins를 local에서 실행했고, docker에서 기본 8080 포트를 18080 포트로 변환해서 listen 하고 있습니다. 추가로 집 안에 있는 공유기와 모뎀에서 18080을 포트포워딩하고 있고, 집으로 들어오는 공인 IP에 연결된 DNS 주소도 있는 상태입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이런 설정이 어려운 환경이라면 또 다른 EC2에서 Jenkins를 띄워서 연습해 보는 게 편할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS EC2, S3 생성 및&lt;span&gt; CodeDeploy 설정 + IAM&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM 역할 + 사용자 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. EC2용 IAM 역할을 생성합니다. 부여 정책은 아래 참조.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOYokg/btsKL9Elavp/qtnI27gkCx0KHYOavteZv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOYokg/btsKL9Elavp/qtnI27gkCx0KHYOavteZv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOYokg/btsKL9Elavp/qtnI27gkCx0KHYOavteZv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOYokg%2FbtsKL9Elavp%2FqtnI27gkCx0KHYOavteZv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;224&quot; data-origin-width=&quot;677&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. CodeDeploy용 IAM 역할을 생성합니다. 부여 정책은 아래 참조.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwxXqz/btsKLgD2yCH/rhikv9DZoez5djusfgMvp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwxXqz/btsKLgD2yCH/rhikv9DZoez5djusfgMvp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwxXqz/btsKLgD2yCH/rhikv9DZoez5djusfgMvp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwxXqz%2FbtsKLgD2yCH%2Frhikv9DZoez5djusfgMvp1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;197&quot; data-origin-width=&quot;679&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3. IAM 사용자를 생성합니다. 부여 정책은 아래 참조.&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/W6Ttw/btsKLx6BIvM/KtiesDpY2kE0siQtSYwJQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/W6Ttw/btsKLx6BIvM/KtiesDpY2kE0siQtSYwJQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/W6Ttw/btsKLx6BIvM/KtiesDpY2kE0siQtSYwJQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FW6Ttw%2FbtsKLx6BIvM%2FKtiesDpY2kE0siQtSYwJQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;239&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;303&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자격증명으로 액세스 키를 만들고, Access/Secret Key를 잘 기록해 둡니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;339&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ChPYb/btsKMDdVXXF/UJfKzgjJq6GvgmxvSG7JyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ChPYb/btsKMDdVXXF/UJfKzgjJq6GvgmxvSG7JyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ChPYb/btsKMDdVXXF/UJfKzgjJq6GvgmxvSG7JyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FChPYb%2FbtsKMDdVXXF%2FUJfKzgjJq6GvgmxvSG7JyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1269&quot; height=&quot;339&quot; data-origin-width=&quot;1269&quot; data-origin-height=&quot;339&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. AWS에서 EC2를 생성합니다. Amazon Linux AMI를 t2.micro 인스턴스 유형으로 시작했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dq6n7t/btsKMEDQDx9/jdGGGVf7EywvmjkGGkgTik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dq6n7t/btsKMEDQDx9/jdGGGVf7EywvmjkGGkgTik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dq6n7t/btsKMEDQDx9/jdGGGVf7EywvmjkGGkgTik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdq6n7t%2FbtsKMEDQDx9%2FjdGGGVf7EywvmjkGGkgTik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;597&quot; height=&quot;393&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. CodeDeploy에서 식별할 태그를 지정해 줍니다. 편의상 Name 태그를 사용하겠습니다. 이렇게 설정하면 jenkins-demo라는 Name을 가진 모든 EC2에 배포하게 됩니다. 단, 로드밸런싱이나 ASG는 따로 설정해야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbgHcf/btsKMOztuT1/kZnbt0Lxzym0o5yj3tzqA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbgHcf/btsKMOztuT1/kZnbt0Lxzym0o5yj3tzqA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbgHcf/btsKMOztuT1/kZnbt0Lxzym0o5yj3tzqA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbgHcf%2FbtsKMOztuT1%2FkZnbt0Lxzym0o5yj3tzqA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;131&quot; data-origin-width=&quot;580&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 위에서 만든 EC2용 IAM역할을 연결합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uwskD/btsKMDybZgP/LOI0rVmgTAOhbVMnr2UEXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uwskD/btsKMDybZgP/LOI0rVmgTAOhbVMnr2UEXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uwskD/btsKMDybZgP/LOI0rVmgTAOhbVMnr2UEXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuwskD%2FbtsKMDybZgP%2FLOI0rVmgTAOhbVMnr2UEXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;610&quot; height=&quot;189&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 보안 그룹은 nest.js 기본 포트인 3000 포트와 ssh 접속을 위한 22 포트를 개방합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o9iSo/btsKLq0ML4H/KvHhNsqEx0RIYlsetvsBnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o9iSo/btsKLq0ML4H/KvHhNsqEx0RIYlsetvsBnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o9iSo/btsKLq0ML4H/KvHhNsqEx0RIYlsetvsBnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo9iSo%2FbtsKLq0ML4H%2FKvHhNsqEx0RIYlsetvsBnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1810&quot; height=&quot;357&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2에 CodeDeploy Agent + node 설치&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. ssh로 EC2에 접속하고 CodeDeploy Agent를 설치합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1731682181934&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum install -y ruby 
sudo yum install -y aws-cli
cd /home/ec2-user/
wget https://aws-codedeploy-ap-northeast-2.s3.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto

sudo service codedeploy-agent status&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;'sudo service codedeploy-agent status'를 입력했을 때 아래와 같이 뜨면 성공입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H7BkD/btsKKohWwdC/0Hp216QF6ncilMNcEpjBWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H7BkD/btsKKohWwdC/0Hp216QF6ncilMNcEpjBWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H7BkD/btsKKohWwdC/0Hp216QF6ncilMNcEpjBWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH7BkD%2FbtsKKohWwdC%2F0Hp216QF6ncilMNcEpjBWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;34&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. node를 설치해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1731683404203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install --lts
node -e &quot;console.log('Running Node.js ' + process.version)&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/setting-up-node-on-ec2-instance.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. pm2를 설치해 줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1731683477977&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install -g pm2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b549ZH/btsKL8yICvr/ohn0q7ktYFcodxSQky1ek1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b549ZH/btsKL8yICvr/ohn0q7ktYFcodxSQky1ek1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b549ZH/btsKL8yICvr/ohn0q7ktYFcodxSQky1ek1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb549ZH%2FbtsKL8yICvr%2Fohn0q7ktYFcodxSQky1ek1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;326&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 설정 안 건들고 생성만 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CodeDeploy 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 애플리케이션 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH6ocL/btsKLbJB2ML/wqIvgKHnwL3GnwQX1ecX9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH6ocL/btsKLbJB2ML/wqIvgKHnwL3GnwQX1ecX9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH6ocL/btsKLbJB2ML/wqIvgKHnwL3GnwQX1ecX9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH6ocL%2FbtsKLbJB2ML%2FwqIvgKHnwL3GnwQX1ecX9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;412&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 배포 그룹 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bX2ERf/btsKL7GBBCA/y1P3k9SMUA8GUpCp7IF811/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bX2ERf/btsKL7GBBCA/y1P3k9SMUA8GUpCp7IF811/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bX2ERf/btsKL7GBBCA/y1P3k9SMUA8GUpCp7IF811/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbX2ERf%2FbtsKL7GBBCA%2Fy1P3k9SMUA8GUpCp7IF811%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;523&quot; data-origin-width=&quot;807&quot; data-origin-height=&quot;696&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 환경 구성에서 EC2인스턴스를 선택하고 Name 키로 아까 만든 EC2의 value를 선택합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgRsOJ/btsKML3OIj4/OHr11ip3EXd6nKhEsxJ3k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgRsOJ/btsKML3OIj4/OHr11ip3EXd6nKhEsxJ3k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgRsOJ/btsKML3OIj4/OHr11ip3EXd6nKhEsxJ3k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgRsOJ%2FbtsKML3OIj4%2FOHr11ip3EXd6nKhEsxJ3k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;601&quot; height=&quot;304&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;411&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 일단은 단일 EC2에 배포할 거면 로드밸런싱은 꺼두면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDsrmr/btsKLaKJv5p/CRqz8U5fJ5dmfkQDKCKKrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDsrmr/btsKLaKJv5p/CRqz8U5fJ5dmfkQDKCKKrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDsrmr/btsKLaKJv5p/CRqz8U5fJ5dmfkQDKCKKrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDsrmr%2FbtsKLaKJv5p%2FCRqz8U5fJ5dmfkQDKCKKrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;664&quot; height=&quot;150&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;새로운 Jenkins Item 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;884&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yUplv/btsKMLQhXxv/SBtEP8kNHWqcHKoRggZvzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yUplv/btsKMLQhXxv/SBtEP8kNHWqcHKoRggZvzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yUplv/btsKMLQhXxv/SBtEP8kNHWqcHKoRggZvzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyUplv%2FbtsKMLQhXxv%2FSBtEP8kNHWqcHKoRggZvzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1374&quot; height=&quot;884&quot; data-origin-width=&quot;1374&quot; data-origin-height=&quot;884&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;메인화면에서 New Item을 누르고 원하는 Item 이름을 넣은 뒤 Freestyle project를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. General &amp;gt; GitHub project 선택 후 url 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dex3eF/btsKK9SyQDJ/vw7TQLjIHEgi6R2G5FxMjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dex3eF/btsKK9SyQDJ/vw7TQLjIHEgi6R2G5FxMjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dex3eF/btsKK9SyQDJ/vw7TQLjIHEgi6R2G5FxMjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdex3eF%2FbtsKK9SyQDJ%2Fvw7TQLjIHEgi6R2G5FxMjk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1264&quot; height=&quot;441&quot; data-origin-width=&quot;1264&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 소스 코드 관리 &amp;gt; Git 선택 후 URL, Credentials, Branch 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XJ4iM/btsKLiaDxe4/nYKkVJk8cvYQgdhwlVfJ91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XJ4iM/btsKLiaDxe4/nYKkVJk8cvYQgdhwlVfJ91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XJ4iM/btsKLiaDxe4/nYKkVJk8cvYQgdhwlVfJ91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXJ4iM%2FbtsKLiaDxe4%2FnYKkVJk8cvYQgdhwlVfJ91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1271&quot; height=&quot;718&quot; data-origin-width=&quot;1271&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 빌드 유발 'GitHub hook trigger for GITScm polling' 선택&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLbiIS/btsKKRq67w8/JQ2xpoQPKiTx055jyDlsSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLbiIS/btsKKRq67w8/JQ2xpoQPKiTx055jyDlsSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLbiIS/btsKKRq67w8/JQ2xpoQPKiTx055jyDlsSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLbiIS%2FbtsKKRq67w8%2FJQ2xpoQPKiTx055jyDlsSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;330&quot; height=&quot;321&quot; data-origin-width=&quot;330&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. Build Steps &amp;gt; Execute shell 선택 후 npm install, npm run build 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3XOSy/btsKK0nRPgD/RZLKuJCs5h1F3VXTGsj9Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3XOSy/btsKK0nRPgD/RZLKuJCs5h1F3VXTGsj9Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3XOSy/btsKK0nRPgD/RZLKuJCs5h1F3VXTGsj9Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3XOSy%2FbtsKK0nRPgD%2FRZLKuJCs5h1F3VXTGsj9Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1258&quot; height=&quot;454&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. 빌드 후 조치 &amp;gt; AWS CodeDeploy 선택 후 아까 만든 CodeDeploy 애플리케이션 이름, 배포 그룹, 배포 리전, S3 버킷 명을 입력해 줍니다. (원한다면 include 할 폴더를 지정할 수 있습니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9KjTI/btsKMna8BpA/k1SzdnrEFguy8LxBAtpNNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9KjTI/btsKMna8BpA/k1SzdnrEFguy8LxBAtpNNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9KjTI/btsKMna8BpA/k1SzdnrEFguy8LxBAtpNNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9KjTI%2FbtsKMna8BpA%2Fk1SzdnrEFguy8LxBAtpNNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1258&quot; height=&quot;572&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;6. 하단에 Access Key, Secret Key에 아까 만든 IAM 사용자 자격 증명 입력&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UAWF2/btsKKHa3ZSm/4yNIkjh9p4hVK9ppjrg3V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UAWF2/btsKKHa3ZSm/4yNIkjh9p4hVK9ppjrg3V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UAWF2/btsKKHa3ZSm/4yNIkjh9p4hVK9ppjrg3V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUAWF2%2FbtsKKHa3ZSm%2F4yNIkjh9p4hVK9ppjrg3V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1224&quot; height=&quot;338&quot; data-origin-width=&quot;1224&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&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;b&gt;로컬 코드에 appspec.yml + script 파일 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;CodeDeploy에서 실행될 스크립트를 작성합니다. appspec.yml에 명세하게 되는데, 정해진 format과 lifecycle이 있으니 자세한 사항은 AWS 공식 문서를 참고하면 좋을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;appspec.yml 파일 생성&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1731683100298&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;version: 0.0
os: linux
files:
  - source: /
    destination: /home/ec2-user/jenkins-test
    overwrite: yes

hooks:
  BeforeInstall:
    - location: scripts/clean.sh
      timeout: 300
      runas: ec2-user
  ApplicationStart:
    - location: scripts/start.sh
      timeout: 300
      runas: ec2-user&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;script 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;clean.sh&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1731683254590&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
# 기존의 node_modules와 package-lock.json을 삭제하여 충돌 방지
echo &quot;Cleaning up old dependencies...&quot;

# 기존 디렉토리와 파일 삭제
sudo rm -rf /home/ec2-user/jenkins-test/node_modules
sudo rm -f /home/ec2-user/jenkins-test/package-lock.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; start.sh&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1731683271947&quot; class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#!/bin/bash
cd /home/ec2-user/jenkins-test
pm2 stop all
pm2 start dist/main.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 만약 pm2를 찾지 못한다는 에러가 뜬다면 start.sh를 아래와 같이 수정&lt;/p&gt;
&lt;pre id=&quot;code_1731685480879&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
export NVM_DIR=&quot;$HOME/.nvm&quot;
[ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/nvm.sh&quot;  # This loads nvm
[ -s &quot;$NVM_DIR/bash_completion&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/bash_completion&quot;  # This loads nvm bash_completion

sudo npm install -g pm2

cd /home/ec2-user/jenkins-test

pm2 stop all
pm2 start dist/main.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/46048453/aws-codedeploy-command-not-found&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://stackoverflow.com/questions/46048453/aws-codedeploy-command-not-found&lt;/a&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;b&gt;동작 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 정상적으로 동작하는지 확인을 위해 로컬에서 Github로 코드를 push 해봅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Jenkins에서 Github webhook을 트리거로 반응하여 동작합니다. Jenkins에서 Test와 Build 가능 여부, lint 등을 검사하고 나서, 빌드된 코드를 zip 형태로 S3로 보냅니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xu6WG/btsKKHWpxC4/UQvLFWiiR6GbtVWa2F9Chk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xu6WG/btsKKHWpxC4/UQvLFWiiR6GbtVWa2F9Chk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xu6WG/btsKKHWpxC4/UQvLFWiiR6GbtVWa2F9Chk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxu6WG%2FbtsKKHWpxC4%2FUQvLFWiiR6GbtVWa2F9Chk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;652&quot; height=&quot;320&quot; data-origin-width=&quot;821&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. S3에서 객체를 확인할 수 있고, CodeDeploy 콘솔에서도 성공 유무를 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNmKoo/btsKLm5bEOS/QwQ2EqFjAr0PcRCpMLol8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNmKoo/btsKLm5bEOS/QwQ2EqFjAr0PcRCpMLol8K/img.png&quot; data-alt=&quot;S3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNmKoo/btsKLm5bEOS/QwQ2EqFjAr0PcRCpMLol8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNmKoo%2FbtsKLm5bEOS%2FQwQ2EqFjAr0PcRCpMLol8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;759&quot; height=&quot;151&quot; data-origin-width=&quot;924&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;S3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ti7rO/btsKLeMXks2/AWEdNigclOTxh77g6ANG01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ti7rO/btsKLeMXks2/AWEdNigclOTxh77g6ANG01/img.png&quot; data-alt=&quot;CodeDeploy&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ti7rO/btsKLeMXks2/AWEdNigclOTxh77g6ANG01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTi7rO%2FbtsKLeMXks2%2FAWEdNigclOTxh77g6ANG01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1186&quot; height=&quot;186&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CodeDeploy&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. EC2의 공인 IP 주소로 접속해 보면 정상적으로 배포된 것 확인&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eATlB8/btsKMboE7Tf/Y0fojIiAGtPjX1BfqzKHZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eATlB8/btsKMboE7Tf/Y0fojIiAGtPjX1BfqzKHZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eATlB8/btsKMboE7Tf/Y0fojIiAGtPjX1BfqzKHZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeATlB8%2FbtsKMboE7Tf%2FY0fojIiAGtPjX1BfqzKHZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;415&quot; height=&quot;179&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;그동안 Beanstalk을 써서 배포할 때 잊고 있었던 서버 설정을 오랜만에 만지다 보니, 권한이나 shell script 설정 등 손이 많이 가는 작업이었습니다. 비슷하게 설정 중이신 많은 분들께 도움이 되었으면 합니다 :)&lt;/p&gt;</description>
      <category>인프라/Jenkins</category>
      <category>AWS CodeDeploy</category>
      <category>codedeploy nestjs</category>
      <category>jenkins</category>
      <category>jenkins aws ec2</category>
      <category>jenkins aws iam 설정</category>
      <category>jenkins codedeploy</category>
      <category>jenkins github</category>
      <category>jenkins github webhook</category>
      <category>jenkins nest.js 배포</category>
      <category>젠킨스</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/113</guid>
      <comments>https://pypystory.tistory.com/113#entry113comment</comments>
      <pubDate>Sat, 16 Nov 2024 00:53:58 +0900</pubDate>
    </item>
    <item>
      <title>AWS SAA-C03 합격 후기 &amp;amp; 공부방법 + 공부기간 + 꿀팁 (900점 대 합격 요약 정리 pdf 공유)</title>
      <link>https://pypystory.tistory.com/112</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;aws-certified-solutions-architect-associate.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ORtb/btsKzjHhxut/mBBFo3G2U4IwQgxYrEvgLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ORtb/btsKzjHhxut/mBBFo3G2U4IwQgxYrEvgLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ORtb/btsKzjHhxut/mBBFo3G2U4IwQgxYrEvgLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ORtb%2FbtsKzjHhxut%2FmBBFo3G2U4IwQgxYrEvgLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;240&quot; data-filename=&quot;aws-certified-solutions-architect-associate.png&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS SAA(AWS Certified Solutions Architect &amp;ndash; Associate)에 합격했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;단순히 자격증을 따야겠다는 목적보다는, AWS에 대해서 더 공부하고, 실제로 최적화해서 사용해보고 싶었던 목적이 컸습니다. 또한, 'AWS에서 EC2, RDS, SQS... 서비스 써봤어'라고 열거하는 것보다, '나 AWS 이만큼 이해하고 쓸 수 있어'를 보다 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;객관적으로&lt;span&gt; 증명할 수 있겠다는 생각으로 본 자격증을 준비했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/be6ejL/btsKA7Gx0JZ/KRYBrrtUm1qvTV8N0nNOc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/be6ejL/btsKA7Gx0JZ/KRYBrrtUm1qvTV8N0nNOc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/be6ejL/btsKA7Gx0JZ/KRYBrrtUm1qvTV8N0nNOc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbe6ejL%2FbtsKA7Gx0JZ%2FKRYBrrtUm1qvTV8N0nNOc0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;787&quot; height=&quot;438&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;공부방법&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;1. 유데미 '그' 강의&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아마 여러 블로그 찾아보셨다면, 모두가 추천하는 강의인 듯합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;'【한글자막】 AWS Certified Solutions Architect Associate 시험합격!'이라는 제목으로 세일할 때 사면, 17,000원에 살 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Solutions Architect 쪽 &lt;b&gt;공부가 목적이면 무조건 사는 걸 추천&lt;/b&gt;합니다. 굉장히 귀에 쏙쏙 꽂히게 설명해 주고, 중간중간 문제들도 퀄리티 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본인은 1.75배속으로 듣고, 블로그 정리해 가면서 들었더니 &lt;b&gt;하루 3시간씩 한 달 정도&lt;/b&gt; 걸렸습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;2. 요약정리 노트 만들기&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;아래쪽에서&lt;b&gt; 요약 정리 pdf를 공유해 드리겠지만,&lt;/b&gt; 본인만의 언어로 정리하시는 걸 추천드립니다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;워낙 범위가 넓기에, &lt;b&gt;핵심 키워드 위주로 강의를 복습할 겸 정리해 봤던 게&lt;/b&gt; 많은 도움이 되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;3. Dump 밀고, 오답 노트 만들기&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;마지막으로 일주일정도는 Dump 문제를&amp;nbsp; 풀었습니다. 아마 1000문제 넘게 Dump문제가 쌓여있을 텐데, 저는 &lt;b&gt;800번까지 1 회독만&lt;/b&gt; 했고, 하루에 100문제씩 풀고 틀린 문제만 따로 정리했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;다른 블로그에서는 Dump 문제에서 50~80%까지도 출제된다고 하셨는데, 제가 본 &lt;b&gt;24년 11월 기준으로 20~30% 정도가 Dump에서 출제&lt;/b&gt;되었습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;구글번역 돌리면, 약간은 모호하게 번역되는 부분이 있어서 영어 지문도 같이 보는 걸 추천드립니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;실제 시험에서도 한국어로 신청하더라도, 영어 지문을 같이 볼 수 있습니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;a href=&quot;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730991138200&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Free &amp;amp; Accurate Amazon AWS Certified Solutions Architect - Associate SAA-C03 Practice Questions | ExamTopics&quot; data-og-description=&quot;Get ready to prepare like you&amp;rsquo;ve never prepared before As we often say at ExamTopics, work smarter not harder. You are about to see a study guide that took hours of hard collection work, expert preparation, and constant feedback. That&amp;rsquo;s why we know thi&quot; data-og-host=&quot;www.examtopics.com&quot; data-og-source-url=&quot;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&quot; data-og-url=&quot;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.examtopics.com/exams/amazon/aws-certified-solutions-architect-associate-saa-c03/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Free &amp;amp; Accurate Amazon AWS Certified Solutions Architect - Associate SAA-C03 Practice Questions | ExamTopics&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Get ready to prepare like you&amp;rsquo;ve never prepared before As we often say at ExamTopics, work smarter not harder. You are about to see a study guide that took hours of hard collection work, expert preparation, and constant feedback. That&amp;rsquo;s why we know thi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.examtopics.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;공부기간&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;본인은 자격증보다 AWS 서비스를 공부하고자 하는 목적이 컸기에 넉넉하게 기간을 잡고, 강의를 정리하면서 봤습니다. 저와 목적이 비슷하시다면 &lt;b&gt;하루 3시간 공부 기준으로 한 달 반 &lt;/b&gt;정도 잡으면 넉넉할 것 같습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;다만 빠르게 취득하셔야 되거나, 강의를 다 듣기에 부담스러운 분들은 'Dump 밀기 + 유튜브 3시간짜리 개념정리본'이면, 720점 넘기기 목표로 2~3주 컷도 가능할 것 같긴 합니다만 클라우드에 대한 어느 정도 사전지식이 필요할 것 같습니다.(개인적인 뇌피셜입니다)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;시험 팁 + 결과 발표&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;1. 할인 바우처&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;다른 일반적인 자격증에 비해서 시험 가격이 비쌉니다. 원가 기준 환율+해외결제 수수료까지 하면 20만 원이 넘어가는 가격입니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGwabc/btsKBbWoNUC/ikuagxJDKx2UAaG7Wvqti0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGwabc/btsKBbWoNUC/ikuagxJDKx2UAaG7Wvqti0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGwabc/btsKBbWoNUC/ikuagxJDKx2UAaG7Wvqti0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGwabc%2FbtsKBbWoNUC%2FikuagxJDKx2UAaG7Wvqti0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;249&quot; data-origin-width=&quot;1100&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS 자체적으로 자격증 챌린지 &lt;b&gt;50% 바우처&lt;/b&gt;를 주기 때문에 무조건 등록해서 사용하시길 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pages.awscloud.com/GLOBAL-ln-GC-Traincert-Associate-Certification-Challenge-Registration-2024.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://pages.awscloud.com/GLOBAL-ln-GC-Traincert-Associate-Certification-Challenge-Registration-2024.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1730992210518&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;company&quot; data-og-title=&quot;클라우드 서비스 | 클라우드 컴퓨팅 솔루션| Amazon Web Services&quot; data-og-description=&quot;&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://pages.awscloud.com/GLOBAL-ln-GC-Traincert-Associate-Certification-Challenge-Registration-2024.html&quot; data-og-url=&quot;https://aws.amazon.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fsFTB/hyXwrSbrFh/LmXnXcyKxkvQlksnSkYfDK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/e6alE/hyXwg4b2tW/JzVcUE1RjoJULumsUfeDk1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109&quot;&gt;&lt;a href=&quot;https://pages.awscloud.com/GLOBAL-ln-GC-Traincert-Associate-Certification-Challenge-Registration-2024.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pages.awscloud.com/GLOBAL-ln-GC-Traincert-Associate-Certification-Challenge-Registration-2024.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fsFTB/hyXwrSbrFh/LmXnXcyKxkvQlksnSkYfDK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/e6alE/hyXwg4b2tW/JzVcUE1RjoJULumsUfeDk1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;클라우드 서비스 | 클라우드 컴퓨팅 솔루션| Amazon Web Services&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 자격증 공부 팁&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Dump를 풀다 보면 아시겠지만, &lt;b&gt;반복되는 키워드&lt;/b&gt;가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;'특정 서비스 - 키워드'를 1:N으로 묶을 수 있는데, 이 부분에 집중해서 공부하면 수월할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예를 들어 'NLB - TCP/UDP, 정적 IP', 'Macie - PII, 민감정보' 이런 식으로 정리하면 문제 읽을 때 빠르게 핵심 키워드만 찾으면 풀 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개인적인 생각으로, &lt;b&gt;소거법&lt;/b&gt;으로 푸는 게 유리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보기가 다 &lt;b&gt;비슷비슷&lt;/b&gt;하고, &lt;b&gt;번역체&lt;/b&gt;이며, 실제 시험장에서는 &lt;b&gt;폰트 가독성&lt;/b&gt;도 안 좋기에 보기를 여러 번 읽게 되는데, 키워드 중심에 소거법으로 아니다 싶은 건 날리고, 남은 것 중에 고민하는 게 좋은 전략인 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 결과 발표&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본인은 12:30 시험 시작이었고, 합격 메일을 20:12에 받았습니다. Badge를 받았다는 제목으로 메일을 받을 수 있었고, 다른 메일에서 성적표 확인과 관련된 메일도 받을 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1442&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yuhRO/btsKBi2ihkk/x5O9QElFBQJ11OlCc1V3V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yuhRO/btsKBi2ihkk/x5O9QElFBQJ11OlCc1V3V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yuhRO/btsKBi2ihkk/x5O9QElFBQJ11OlCc1V3V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyuhRO%2FbtsKBi2ihkk%2Fx5O9QElFBQJ11OlCc1V3V0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1442&quot; height=&quot;640&quot; data-origin-width=&quot;1442&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;정리노트&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 요약정리 노트 pdf 공유해 드립니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/ce7XSO/btsKBg4t8Nn/ygdOcuWKKpw8RxOIHYXsSK/AWS_SAA-C03_%EC%9A%94%EC%95%BD%EC%A0%95%EB%A6%AC.pdf?attach=1&amp;amp;knm=tfile.pdf&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;AWS_SAA-C03_요약정리.pdf&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.38MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;개인적인 공부 용도로 사용하시고, 2차 가공이나 2차 배포를 금지합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;따로 비밀번호는 없으니, 유익하셨다면 블로그 좋아요/구독 부탁드립니다 :)&lt;/p&gt;</description>
      <category>IT/자격증</category>
      <category>aws saa-c03 dump</category>
      <category>aws saa-c03 공부 기간</category>
      <category>aws saa-c03 공부 방법</category>
      <category>aws saa-c03 요약 정리</category>
      <category>aws saa-c03 유데미 강의</category>
      <category>aws saa-c03 자격증</category>
      <category>aws saa-c03 합격 후기</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/112</guid>
      <comments>https://pypystory.tistory.com/112#entry112comment</comments>
      <pubDate>Fri, 8 Nov 2024 00:26:10 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 20편 CloudFormation, Amplify, AWS 기타 서비스 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/111</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHYrSb%2FbtsIZOVEjPA%2FAqQpg3htjNy83gupElccEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;CloudFormation&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대규모 인프라 배포 및 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스에 대해 인프라의 윤곽을 구분짓는 선언적 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정한 순서대로 인프라를 자동으로 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 환경, 지역, 계정에서 아키텍처를 반복해야할 때 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 인프라가 코드로 관리(IaC)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 수동으로 인프라를 생성할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 컨트롤하기 매우 좋음.. 코드 리뷰를 통한 검토... 리소스 생성 및 삭제가 쉬워짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용면에서 이득&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 스택 내의 각 리소스는 스택 내에서 만들어진 다른 리소스들과 비슷하게 태그됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 리소스 비용을 쉽게 예측할 수 있음&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 절약 전략을 세울 수 있음.. 특정 시간대에만 인프라 재생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 템플릿을 위한 다이어그램을 만들 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 선언적 프로그래밍 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전부 하나하나 만들 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 문서나 웹에 있는 템플릿 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 거의 대부분의 리소스를 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Application Composer&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudFormation 템플릿을 시각화할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudFormation - Service Role&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudFormation은 사용자를 대신하여 스택 리소스를 생성, 업데이트, 삭제 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- '&lt;b&gt;iam:PassRole&lt;/b&gt;' : 최소 권한 원칙 달성을 위해, 사용자에게 스택 리소스를 만들 수 있는 모든 권한을 부여하고 싶지 않고, CloudFormation에서 특정 서비스 역할을 호출할 수 있는 권한만 부여하고 싶은 경우... 사용자에게 PassRole 권한만 부여&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이후 CloudFormation 생성시 특정 서비스 관리 권한을 가진 IAM Role을 부여해주면됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SES&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이메일을 전 세계로 대규모로 안전하게 보낼 수 있는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SES API나 SMTP 서버로 SES에 요청을 보내면, SES가 메일을 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인바운드 메일도 허용하기 때문에 답장을 주고받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 열었는지 확인용 대시보드, 성과 인사이트, 스팸 방지 피드백 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이메일 통계 제공 : 배송, 반송, 피드백 루프백 결과, 이메일 열었는지&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DKIM, SPK 기능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유연한 배포 : 공유 IP, 전용 IP, 고객 소유 IP들이 있음 (특정 IP에서 이메일을 보내는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 콘솔, API, SMTP 프로토콜로 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 이메일 트랜잭션, 마케팅 이메일, 대량 이메일 커뮤니케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Pinpoint&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 확장 가능한 양방향 마케팅 커뮤니케이션 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이메일, SMS, push, voice, in-app 메시지 전송 지원... 답장 받기도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객에게 적합한 콘텐츠로 메시지 세분화+개인화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 마케팅 이메일 대량 전송, 트랜잭션 SMS 메시지 전송&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 응답하거나 성공한 이벤트를 SNS, KDF, CW Log로 전달 가능... 자동화 쉬워짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS/SES와 차이점 : 각 메시지의 대상, 내용, 전달 일정, 세그먼트 등을 관리하는 수고를 덜 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SSM(시스템 관리자 서비스)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Session Manager&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시스템 관리자의 SSM 세션 관리자 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스와 온프레미스 서버에서 보안 셸 시작 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSH 액세스, 배스천 호스트, SSH 키가 필요 없음.. 22 port 닫고도 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- linux, MacOS, Win 지원, 로그 데이터를 S3, CW로 보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;동작 원리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스에 SSM Agent 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Session Manager와 Agent 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자에게 Session Manager에 대한 IAM 인증&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Run Command&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- document(script)를 실행하는데 사용..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스 그룹을 사용하는 여러 인스턴스에서 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSH 필요 없음... SSM Agent 이용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행 결과는 S3나 CW로 보내지고, 실패가 일어나면 SNS로 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM &amp;amp; CloudTrail 과 통합됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EventBridge로 실행 명령 직접 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Patch Manager&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스 관리 과정 패칭을 자동화하는데 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OS, app, security 업데이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2와 온프레미스 서버도 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- linux, MacOS, Win 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유지 관리 기간이라는 것을 사용하여 패치 일정을 잡거나, 즉시 패치도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스를 스캔하여 패치 규정 준수 보고서 생성 가능... 패치 누락된 사람 체크 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Maintenance Windows&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유지 관리 기간.. 인스턴스에서 작업을 수행할 일정 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일정, 기간, 어느 인스턴스에 적용할지, 실행될 작업 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Automation&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동화... EC2 인스턴스나 기타 AWS 리소스에서의 명령 유지 관리 및 배포 작업 단순화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스들을 한 번에 다시 시작 가능, AMI 생성, EBS 스냅샷 생성 등의 작업 자동화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;자동화 런북&lt;/b&gt; : 문서로 미리 정의된 작업으로 사전 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;트리거&lt;/b&gt; : AWS Console/CLI/SDK, EventBridge, Maintenace Windows, AWS Config&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Cost Explorer&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용과 사용시간을 시각화하고 이해하며, 관리 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 정의 보고서로 비용과 데이터 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전체 계정 간 총 비용, 매 달, 시간, 혹은 리소스 레벨에서도 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최적의 절감형 플랜 선택 가능... 12개월 까지 예측 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 월별 비용, 시간 &amp;amp; 리소스 수준&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 절감형 플랜... 예약 인스턴스의 대용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 :&amp;nbsp; 과거 지출을 기반으로 청구서 예측&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;비용 이상 탐지, Cost Anomaly Detection&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용 및 사용량 데이터를 지속적으로 모니터링하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ML로 비정상적인 범위 탐지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일회성 비용 급증, 지속 비용 급증 탐지 가능... 임계값 설정할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서비스, 계정, 비용 할당 태그, 비용 범주를 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정에서 발생하는 문제에 대한 근본 원인 분석이 포함된 리포트를 받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS 일간/주간 요약, 개별 알람 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Batch&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 배치 처리 서비스, 어떤 규모의 배치도 처리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수십만 개 컴퓨터 배치 작업 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Batch는 동적으로 EC2 인스턴스나 스팟 인스턴스를 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배치 대기열을 처리할 수 있도록, 컴퓨팅&amp;amp;메모리 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배치 작업 : 도커 이미지와 ECS 위에서 실행될 수 있는 작업&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;배치 vs Lambda 차이&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Lambda&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 15분 제한, 디스크 공간 제한&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 몇몇 프로그래밍 언어만 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Batch&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시간 제한 없음, 스토리지 넉넉함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리형 서비스지만 EC2 인스턴스에 의존함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Amazon AppFlow&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SaaS 애플리케이션 및 AWS 사이에 데이터를 전송할 수 있는 완전 관리형 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Sources : Salesforce, SAP, Zendesk, Slack, ServiceNow&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 목적지 : S3, Redshift... Snowflake, Salesforce(비 AWS로도 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스케줄이나, 특정 이벤트에 대한 응답, 주문형으로 통합되도록 정의 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 변환 : 필터링, 유효성 검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호화되어 공용인터넷을 통하거나, PrivateLink를 이용해서 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 따로 통합에 사용할 필요 없이, API를 활용하여 바로 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Amplify&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 웹 및 모바일 애플리케이션 개발 도구(웹&amp;amp;모바일을 위한 Elastic Beanstalk)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS의 많은 스택을 한 곳에서 통합해서 웹 및 모바일 앱을 빌드 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amplify CLI를 활용해서 AWS 서비스로 백엔드 구성.. 인증, 스토리지, API, CI/CD, AI, 모니터링 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- github, gitlab, 직접 업로드 등의 방법으로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;소스코드와 연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- Amplify 프론트엔드 라이브러리를 추가해서 Amplify 백엔드와 연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이후 Amplify나 CloudFront에 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Well-Architected 프레임워크&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6개 원칙&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 운영 우수성,&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;보안,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;안정성,&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;성능 효율성,&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;비용 최적화,&lt;/span&gt;&lt;span&gt;&amp;nbsp;지속 가능성&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가이드라인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요한 용량을 추측하지말고, 가능한 오토스케일링 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로덕션 규모에서 시스템을 테스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동화를 사용하여 아키텍처 실험을 쉽게 만들어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 진화하는 아키텍처를 만들어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터로 아키텍처를 구동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 게임데이를 통해 발전할 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Well-Architected Tool&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 워크로드 선택 후 답변하면 6개 원칙으로 아키텍처 검토하고, 거기에 따른 조언을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 영상, 문서, 보고서, 대시보드 형태로 조언을 확인할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Trusted Advisor&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 아무것도 설치할 필요 없이, 계정에 대한 높은 수준의 계정 평가를 제공하는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 몇가지를 점검하고 조언을 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 카테고리 비용 최적화, 성능, 보안, 내결함성, 서비스 제한, 운영 우수성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비즈니스 &amp;amp; 엔터프라이즈 서포트 플랜 사용하면 전체 set에 대한 체크 가능 + AWS Support API 사용 가능&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Amplify</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>AWS SES</category>
      <category>aws 이메일 전송</category>
      <category>CloudFormation</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/111</guid>
      <comments>https://pypystory.tistory.com/111#entry111comment</comments>
      <pubDate>Sun, 20 Oct 2024 22:59:31 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 19편 재해복구, 마이그레이션 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/110</link>
      <description>&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHYrSb%2FbtsIZOVEjPA%2FAqQpg3htjNy83gupElccEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;br&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Disaster Recovery&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 재해: 회사의 사업 지속이나 재정에 부정적 영향을 미치는 이벤트&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재해 복구 유형&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 간 : 전통적인 DR로 매우 비쌈&lt;br&gt;- 온프레미스(기본) -&amp;gt; 클라우드 : 하이브리드 복구&lt;br&gt;- 모두 클라우드 : 리전 간 복구 수행&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RPO, RTO&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RPO(복구 시점 목표, Recovery Point Objective)&lt;/b&gt;&lt;br&gt;- 얼마나 자주 백업 수행할지... 시간상 어느 정도 과거로 되돌릴 수 있는지&lt;br&gt;- 데이터 손실을 얼마나 감수할지와 연결됨&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;RTO(복구 시간 목표, Recovery Time Objective)&lt;/b&gt;&lt;br&gt;- 애플리케이션 다운타임이 얼마나 되는지&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재해복구 전략&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;* 밑으로 갈수록 빠른 RTO&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;백업 및 복구&lt;/b&gt;&lt;br&gt;- 높은 RPO, 적은 비용(저장 비용만 발생)&lt;br&gt;- DC라면 AWS Snowball이나 AWS 스토리지 GW로 S3에 백업&lt;br&gt;- AWS 클라우드(EBS, Redshift, RDS)라면 정기적 스냅샷 예약 후 백업&lt;br&gt;- 재해 상황에 데이터를 전부 복구해야함으로 RTO는 커짐&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;파일럿 라이트&lt;/b&gt;&lt;br&gt;- 애플리케이션의 축소버전(크리티컬 코어)이 클라우드에서 항상 실행 중&lt;br&gt;- 백업 및 복구와 유사&lt;br&gt;- 재해 상황에 코어 시스템 외에 여타 시스템만 더해주면 되니까 복구 속도는 좀 더 빠름&lt;br&gt;- 사례 : 온프레미스에서 서버와 DB가 있을 때, DB만 RDS에 계속 복제하는 방법.. 재해 상황에 서버만 복구&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;웜 대기&lt;/b&gt;&lt;br&gt;- 시스템 전체를 실행하되, 최소한의 규모로 가동해서 대기하는 방법&lt;br&gt;- 재해 발생 시 프로덕션 로드로 확장 가능&lt;br&gt;- 사례 : 온프레미스에 앱 서버, 마스터 DB를 두고, 클라우드에 RDS Slave로 데이터 복제.. 이때 EC2 ASG로 최소한의 서버를 유지하고, ELB도 유지... 재해 상황에 Route53에서 경로만 바꿔서 페일오버되게함&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;핫 사이트 / 다중 사이트 접근&lt;/b&gt;&lt;br&gt;- 몇 분/초 단위로 RTO는 낮지만 비용이 높음&lt;br&gt;- AWS와 온프레미스에서 두 완전 프로덕션 스케일을 얻게됨&lt;br&gt;- 클라우드와 온프레미스 모두 active-active 상태를 유지하고, 온프레미스 DB - AWS RDS 사이 Master/Slave 관계 유지&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;다중 리전&lt;/b&gt;&lt;br&gt;- 모두 AWS에서 실행하고, 다른 리전에 위치하게 함&lt;br&gt;- Aurora Global로 DB 유지.. 페일오버 시 완전 프로덕션 스케일이 다른 리전에서 가능&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재해 복구 팁&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;백업&lt;/b&gt; :&amp;nbsp;AWS에서 EBS 스냅샷, RDS 자동 백업, S3 등에 푸시 / 수명 주기 정책 실행, Snowball&lt;br&gt;&lt;b&gt;고가용성&lt;/b&gt; : Route53으로 DNS를 다른 리전으로 옮기기, 다중 AZ 실행, VPN / DC 같이 사용&lt;br&gt;&lt;b&gt;복제&lt;/b&gt; : RDS 리전 간 복제, Aurora Global, 온프레미스에서 RDS로 복제&lt;br&gt;&lt;b&gt;자동화&lt;/b&gt; : CloudFormation, Elastic Beanstalk, CW, Lambda&lt;br&gt;&lt;b&gt;카오스 테스트&lt;/b&gt; : 사례) 넷플릭스는 프로덕션 EC2 인스턴스를 무작위로 종료&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Database Migration Service&lt;/b&gt;&lt;/h2&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DMS 특징&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스에서 AWS로 DB 마이그레이션 할 때, DMS 사용&lt;br&gt;- 빠르고 안전한 DB 서비스.. 복원력 있고 자가 치유 가능하다는 장점&lt;br&gt;- 마이그레이션해도 출발지 DB를 계속 쓸 수 있음&lt;br&gt;- 다양한 유형 엔진 지원 : Oracle 간, Postgre 간.. MS SQL Server에서 Aurora로 동종/이종 migration 가능&lt;br&gt;- CDC, Change Data Capture를 이용한 지속적 데이터 복제도 가능&lt;br&gt;- DMS 쓸려면 EC2 인스턴스를 만들고, EC2 인스턴스가 대신 복제 작업 수행&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DMS 소스와 타겟&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;출발지(소스)&lt;/b&gt; : 온프레미스/EC2 인스턴스 기반 DB인 Oracle, MS Server, MySQL... 등등 대부분 가능, Azure DB, S3, DocumentDB 가능&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;도착지(타겟) :&lt;/b&gt; 온프레미스/AWS 대부분 DB, Redshift, DynamoDB, S3, OpenSearch, KDS, Apache Kafka, DocumentDB, Neptune, Redis, Babelfish 가능&lt;br&gt;(다 외울 필요 없음)&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`Schema Conversion Tool&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- SCT는 소스와 타겟 간, DB 엔진이 다를 때 사용&lt;br&gt;- 사례 : OLTP(SQL Server, Oracle)에서 MySQL, PostgreSQL, Aurora로 마이그레이션 시 사용&lt;br&gt;- SCT는 DMS와 같이 EC2 인스턴스에서 실행&lt;br&gt;- 동종 간 마이그레이션 시에는 사용할 필요 없음&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지속적 복제 방법&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;1. 온프레미스에 Oracle DB, AWS에 MySQL RDS 위치&lt;br&gt;2. 먼저 온프레미스 서버에 AWS SCT 설치 후, RDS에 스키마 변환&lt;br&gt;3. 이후 EC2에 DMS 복제 인스턴스를 생성해서 Full load와 CDC하도록 함&lt;br&gt;4. 지속적으로 온프레미스 DB에서 EC2를 거쳐서 RDS로 마이그레이션 됨&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;멀티 AZ 배포&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 AZ에 각각 DMS 인스턴스를 두고, 동기화 복제해두면 StandBy Replica로 동작&lt;br&gt;- 장점 : AZ 장애시 회복력을 가짐, 데이터 리던던시를 가짐, I/O 멈춤 현상 없어짐, 레이턴시 스파이크 최소화&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;RDS, Aurora Migrations&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RDS MySQL을 Aurora MySQL로 마이그레이션 하는 방법&lt;/b&gt;&lt;br&gt;1. RDS 스냅샷을 생성하고, MySQL Aurora DB에서 복원하는 방법(다운타임 발생)&lt;br&gt;2. MySQL 읽기 복제본을 Aurora에서 생성하는 것.. 지연시간이 0일 때, 복제본을 DB 클러스터로 승격&lt;br&gt;&amp;nbsp; &amp;nbsp; - 다운타임은 없지만, 시간이 오래걸리고, 네트워크 비용 발생 가능성&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;MySQL DB가 외부에 있을 때&lt;/b&gt;&lt;br&gt;1. Percona XtraBackup 기능을 사용해서 백업 후 S3에 옮겼다가, S3에서 Aurora로 가져옴&lt;br&gt;2. mysqldump 기능으로 내보내고, Aurora에서 출력값을 불러옴(단 시간이 많이 듬)&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;공통적으로 DMS 써서 지속적 복제 가능&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`AWS를 통한 온프레미스 전략&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;Amazon Linux 2 AMI를 다운&lt;/b&gt;(.iso 파일) 받아서, 온프레미스에서 VM으로 로드 가능&lt;br&gt;&amp;nbsp;&lt;br&gt;- &lt;b&gt;VM을 EC2 인스턴스로 마이그레이션&lt;/b&gt; 할수도 있음&lt;br&gt;- 온프레미스 VM으로, DR 리포지토리 전략을 만들 수도 있음&lt;br&gt;&amp;nbsp;&lt;br&gt;- &lt;b&gt;AWS Application Discovery Service&lt;/b&gt;는 온프레미스 정보를 모아주고 마이그레이션을 계획할 수 있게 해주는 서비스.. 서버 사용량과 종속성 매핑 정보 제공... 온프레미스에서 클라우드로 대량 마이그레이션에 유용&lt;br&gt;- &lt;b&gt;AWS Migration Hub&lt;/b&gt;로 마이그레이션 추적 가능&lt;br&gt;&amp;nbsp;&lt;br&gt;- &lt;b&gt;DMS&lt;/b&gt;로 온프레미스, AWS 간 어떠한 조합이든 DB 마이그레이션 가능&lt;br&gt;&amp;nbsp;&lt;br&gt;- &lt;b&gt;AWS Server Migration Service&lt;/b&gt;로 온프레미스 라이브 서버를 AWS로 복제 가능.. AWS로 볼륨을 직접 복제도 가능... 증분 복제&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Backup&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형, AWS 서비스 간의 백업을 중점적으로 관리하고 자동화 가능&lt;br&gt;- 중앙 시스템이 없고, 사용자 지정 스크립트나 메뉴얼 필요 없음&lt;br&gt;- 지원 서비스 : EC2, EBS, S3, RDS, Aurora, DynamoDDB, DocumentDB, Neptune, EFS, FSx, Storage GW&lt;br&gt;- 리전/계정 간 백업 지원&lt;br&gt;&amp;nbsp;&lt;br&gt;- PITR(지정 시간 복구) 지원&lt;br&gt;- 온디맨드와 함께 예약 백업 지원&lt;br&gt;- 태그 기반 백업 정책으로 프로덕션 태그 있는 서비스만 백업도 가능&lt;br&gt;- 백업 플랜을 만들어서 백업 빈도, 백업을 콜드 스토리지로 이전할지, 백업 보유 기간 등 설정&lt;br&gt;&amp;nbsp;&lt;br&gt;- AWS 백업은 플랜을 만들면 그에 따라 주요 리소스들을 자동으로 S3 내부 버킷에 백업&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;Vault 잠금&lt;/b&gt;&lt;br&gt;- WORM 정책 시행시, 백업 볼트에 저장한 백업 삭제 불가... 루트 사용자도 삭제 못함&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Application Migration Service(MGN)&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 DC에서 클라우드로 마이그레이션 계획을 도와줌&lt;br&gt;- 서버를 스캔하고, 마이그레이션에 중요한 서버 설치 데이터 및 종속성 매핑에 대한 정보 수집&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마이그레이션 방법&lt;/b&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Agentless Discovery&lt;/b&gt;&lt;br&gt;- Connector를 사용... VM, 구성, CPU/RAM/DISK 사용량과 같은 성능 기록에 대한 정보 제공&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;2. Agent-based Discovery&lt;/b&gt;&lt;br&gt;- VM 내에서 더 많은 업데이트와 정보를 얻을 수 있음&lt;br&gt;- 시스템 구성, 성능, 프로세스, 시스템 사이 NW 연결 등 종속성 맵핑 정보 얻음&lt;br&gt;&amp;nbsp;&lt;br&gt;결과 데이터를 AWS Migration Hub 서비스에서 볼 수 있음&lt;br&gt;&amp;nbsp;&lt;br&gt;- MGN을 이용해서 쉽게 어플리케이션을 AWS로 마이그레이션하는 리호스팅(lift and shift) 가능&lt;br&gt;- MGN으로 적은 비용의 EC2와 EBS로 데이터를 지속적 복제하고, '컷오버'를 수행해서 프로덕션용 EC2, EBS로 높임... 다운 타임 적음&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;대규모 데이터 전송&lt;/b&gt;&lt;/h2&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;상황: 200GB 데이터 옮기고 싶은데, 지금 인터넷 연결 100Mbps&lt;/h4&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 공용 인터넷 쓰기, Site-to-Site VPN 설치&lt;/b&gt;&lt;br&gt;- 즉시 설정할 수 있지만, 데이터 보내는데 반 년이 걸림&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;2. DC를 통해 1Gbps로 보내기&lt;/b&gt;&lt;br&gt;- 초기 설치에 시간이 오래 걸림, 연결 후에 18일 걸림&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;3. Snowball&lt;/b&gt;&lt;br&gt;- 2, 3개 스노우볼 필요하고 병렬 주문으로 동시에 도착하게 함&lt;br&gt;- 1주일 정도 종단간 전송 필요&lt;br&gt;- DB 있다면 DMS로 전송&lt;br&gt;- 1회성 전송&lt;br&gt;&amp;nbsp;&lt;br&gt;지속적 복제 : Site-to-Site VPN or DX with DMS or DataSync&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VMware Cloud on AWS&lt;/b&gt;&lt;/h2&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;상황 : 온프레미스에 DC있을 때 VMware Cloud로 DC 관리하는 경우, 고객은 DC 용량을 AWS로 늘리고, 클라우드와 AWS를 둘 다 쓰고 싶음, 하지만 VMware Cloud SW를 계속 쓰고 싶음&lt;br&gt;&amp;nbsp;&lt;br&gt;- VMware Cloud on AWS를 쓰면 VMware 하위서비스(vSphere, cSAN, NSX 등)에서 사용 가능&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;사례&lt;/b&gt;&lt;br&gt;1. 컴퓨팅 성능 확장해서 DC에서 클라우드뿐 아니라 스토리지까지 컴퓨팅 가능해져, VMware 기반 워크로드를 AWS로 마이그레이션하기&lt;br&gt;2. 프로덕션 워크로드를 여러 DC간 실행&lt;br&gt;3. 재해 복구 전략으로 사용&lt;br&gt;4. 다양한 AWS 서비스를 활용&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Backup</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws db migration</category>
      <category>aws dms</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 재해복구</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/110</guid>
      <comments>https://pypystory.tistory.com/110#entry110comment</comments>
      <pubDate>Sun, 20 Oct 2024 11:09:15 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 18편 네트워킹, VPC - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/109</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHYrSb%2FbtsIZOVEjPA%2FAqQpg3htjNy83gupElccEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;CIDR, IP&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CIDR&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Classless Inter-Domain Routing, 클래스 없는 도메인 간 라우팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단순한 IP 범위를 정의하는데 도움을 줌 (ex. 192.168.0.0/26 =&amp;gt; 162.168.0.0 ~ 192.168.0.63)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CIDR 구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Base IP : 범위 시작이나 범위 내부의 IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Subnet Mask : IP에서 변경가능한 비트의 개수를 정의 (두가지 표현법 /8 &amp;lt;-&amp;gt; 255.0.0.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Subnet Mask&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- /32는 2^0으로 한개의 IP만 나타냄... /31은 2^1개 IP 즉, 2개 IP 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- /16은 2^16으로 65,536개의 IP를 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공용/사설 IP&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IANA에서 IPv4 블록을 공용/사설로 확립해둠&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Private IP &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 10.0.0.0/8 : 대형 네트워크에서 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 172.16.0.0/12 : AWS 기본 VPC 범위&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 192.168.0.0/16 : 홈 네트워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;나머지 IP는 공용 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본 VPC&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 계정을 시작하면 AWS에 VPC가 하나 생김&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기본 VPC는 기본적으로 인터넷에 연결되어 있어서, 내부 EC2 인스턴스를 생성하면 공용 IPv4 주소를 얻게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 기본 VPC에는 서브넷이 3개 있고 각자 다른 AZ에 위치하고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본 VPC에는 모든 트래픽이 인터넷 Gateway로 들어오게 라우팅 테이블이 설정되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;VPC 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Virtaul Private Cloud&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 한 리전에 5개까지 VPC를 생성할 수 있음.. 늘릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC마다 할당된 CIDR는 5개&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 각 CIDR의 최소 크기는 /28(최소 IP 16개), 최대 크기는 /16(최대 IP 65,536개)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC는 사설 네트워크이므로 사설 IP 주소만 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, VPC CIDR가 다른 네트워크(협력사 등)의 주소와 겹치지 않도록 주의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Tenancy : VPC 내에서 EC2 인스턴스가 실행되는 방법 정의(전용, 공유(기본) 하드웨어)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서브넷&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;nbsp; VPC 내부에 있는 IPv4 주소의 부분 범위&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS가 서브넷마다 IP주소 5개(처음 4개, 마지막 1개)를 예약함...할당이나 사용못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 10.0.0.0 : 네트워크 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 10.0.0.1 : VPC 라우터용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 10.0.0.2 : Amazon 제공 DNS에 매핑&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 10.0.0.3 : 지금은 사용 X, 나중을 위한 예약&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 10.0.0.255 : VPC에서 브로드캐스트를 지원하지 않기 때문에, 브로드캐스트 IP는 막혀있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- AWS에서 29개 IP 주소가 필요할 때 subnet 사이즈로 /27은 선택 못함.. 32 - 5 &amp;lt; 29&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;인터넷 Gateway &amp;amp; 라우팅 테이블&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 내 리소스를 인터넷에 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수평으로 확장되고 가용성과 중복성이 높음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC와는 별개로 생성해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC는 IGW 하나에만 연결.. 반대의 경우도 동일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IGW 자체는 인터넷 연결을 허용하지 않아서, 라우팅 테이블을 수정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Bastion 호스트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배스천 호스트는 EC2 인스턴스로 퍼블릭 서브넷에 위치하고, 프라이빗 서브넷에 있는 EC2 인스턴스에 액세스할 수 있게 해줌.. 프라이빗 인스턴스에 ssh로 액세스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배스천 호스트의 SG는 반드시 인터넷 액세스를 허용해야하는데, 보안상 기업의 퍼블릭 CIDR나 사용자의 인터넷 액세스만 허용하는 등 제한하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NAT 인스턴스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NAT, Network Address Translation (구형이지만 시험에 나옴)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Private 서브넷에 있는 EC2인스턴스가 인터넷에 연결되도록함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NAT 인스턴스는 public subnet에서 실행되고, 공용/사설 서브넷을 연결함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 세팅에서 Source/Destination Check을 비활성화해야함... 네트워크 패킷의 출발지 IP가 NAT로 재작성되기 때문..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고정된 탄력적 IP가 연결되어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성이 높지않고, 초기화 설정으로 복원할 수 없고, EC2 인스턴스 대역폭에 의존적임... NAT Gateway로 대체&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 관리형 NAT 인스턴스로 높은 대역폭 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용량 및 대역폭에 따라 청구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NATGW는 특정 AZ에서 실행되고 탄력적 IP를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스와 같은 서브넷에서 사용할 수 없음.. 다른 서브넷에서 액세스할 때 도움됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 라우팅 Private Subnet -&amp;gt; NATGW -&amp;gt; IGW&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대역폭은 5GBps고 45GBps까지 자동으로 늘어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안그룹을 관리할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고가용성 : 단일 AZ에서 복원 가능하고, 다중 NATGW를 여러 AZ에 배포 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NAT 인스턴스와 비교&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성 : 여러 AZ에 만들어두면 가용성이 높음.. NAT 인스턴스는 장애조치 스크립트로 관리해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대역폭 : 45Gbps... NAT 인스턴스는 인스턴스 타입에 의존&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용 : 사용시간+데이터 전송량... NAT 인스턴스는 인스턴스 사용량과 EC2 밖으로나가는 네트워크 비용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NATGW는 보안그룹 설정 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NAT 인스턴스는 필요한 경우 Bastion 호스트로도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;NACL &amp;amp; SG&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NACL이란&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 요청이 서브넷 내부로 들어오기 전 NACL에서 요청이 허용되지 않으면 내부로 들어올 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서브넷 레벨의 방화벽과 비슷, 서브넷마다 하나의 NACL, 새로운 서브넷에는 기본 NACL이 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL 규칙에는 우선순위 숫자가 1~32766까지 있음.. 탑다운으로 먼저 걸리는 룰부터 평가됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 규칙 숫자를 100씩 증가시키는걸 권장(가운데 들어갈 수도 있으니까)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례: 서브넷 수준에서 특정한 IP주소 차단&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL은 무상태, SG는 상태 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;들어오는 요청의 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG의 경우 인바운드로 허용되어서 들어갔으면, 아웃바운드(Stateful)는 무조건 허용되어 전부 나올 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL의 경우 아웃바운드룰(Stateless)에 걸리면 요청이 통과하지 못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;나가는 요청의 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG의 경우 아웃바운드 룰에서 허용되어서 나갔으면, 인바운드는 무조건 허용되어 들어올 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL의 경우 인바운드룰에서 평가됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`기본 NACL&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 연결된 서브넷을 가지고, 인바운드 아웃바운드 모든 요청을 허용하는 특수성을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본 NACL을 수정하지 않는 것을 추천.. 기본 NACL이 서브넷과 연결되어 있다면 다 허용을 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NACL 유의점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;임시 포트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 서버로 부터 응답을 받을 때는, 자체적으로 특정한 임시 포트를 열게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트-서버간 연결이 되어있을 때만 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OS에 따라 범위가 다름(Win10 : 49152~65535, Linux : 32768~60999)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL 설정시 임시포트를 고려해서 In/Out바운드의 허용 포트를 구성해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;다중 NACL/서브넷 구성시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 NACL의 조합이 NACL 내에서 허용되어야함... 서브넷 마다 고유의 CIDR를 사용하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL에 서브넷을 추가하면, NACL 규칙도 업데이트해서 연결 조합이 가능한지 확인해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SG vs NACL&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG는 인스턴스 수준에서 작동, NACL은 서브넷 수준(하위 인스턴스 모두에 적용)작동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG는 허용 규칙 제공, NACL은 허용/거부 규칙 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG는 상태 유지(규칙과 무관하게 트래픽 허용), NACL은 무상태(인바운드, 아웃바운드 규칙이 매번 평가.. 그래서 임시포트 고려해야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG는 모든 규칙이 평가, NACL은 우선순위 높은 규칙이 먼저 평가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC Peering&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC를 생성하고 서로 다른 지역, 서로 다른 계정 접속 시, 동일한 지역에 있는 것처럼 연결하기를 원할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 간에는 CIDR 충돌이 일어나면 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 피어링은 두 VPC간에 설정할 수 있으며 전이되지 않음... 서로 통신하려는 각 VPC에는 VPC 피어링이 활성화 되어 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC a,b,c가 있을 때, a-b, b-c간 피어링 설정을 하더라도 a-c 연결하려면 따로 a-c 피어링 설정을 해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 VPC의 EC2끼리 통신하려면, 각 VPC의 서브넷들의 모든 라우팅을 업데이트 해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 같은 리전의 다른 계정 내 VPC끼리 피어링 설정을 할 때, VPC의 보안그룹을 참조하는 것도 가능함... 출발지를 CIDR나 IP로 할필요없이 SG로 하면되기 때문에 강력함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC 엔드포인트&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 퍼블릭 인터넷을 거치지 않고, DynamoDB 등 인스턴스에 액세스하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 엔드포인트는 VPC 내에 배포됨... NAT Gateway를 통하면 네트워크 비용발생하는데, 이렇게하면 다이렉트로 연결하는것이라 괜찮음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 중복과 수평 확장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IGW, NATGW 없이 AWS 서비스에 액세스 가능.. 네트워크 인프라 간단해짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 문제 발생시 VPC에서 DNS 설정 해석이나 라우팅 테이블 확인하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;유형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;인터페이스 엔드포인트(PrivateLink 활용)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ENI를 프로비저닝, ENI는 VPC의 프라이빗 IP 주소이자 AWS의 엔트리 포인트임...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ENI가 있으나 SG를 연결해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 모든 서비스를 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시간 단위 + 데이터 GB 단위로 요금 청구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;게이트웨이 엔드포인트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 게이트웨이를 프로비저닝, 게이트웨이는 반드시 라우팅 테이블의 대상이 되어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 라우팅 테이블의 대상이 될 뿐, SG는 사용안함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대상으로는 S3, DynamoDB 두 가지뿐(시험에서 이걸로 예시 나오면 게이트웨이 선택)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점 : 무료, 라우팅 테이블 액세스일 뿐이기에 자동으로 확장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 온프레미스에서 접속해야할 때나, 다른 VPC/리전에서 접속할 때는 인터페이스 엔드포인트가 유리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC Flow Logs&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인터페이스로 들어오는 IP 트래픽에서 정보를 포착 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC, Subnet, ENI 수준에서 포착 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 연결 문제 모니터링 및 해결에 유용함... 네트워크 패킷의 메타데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로그를 S3, CloudWatch Logs, KDF에 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 문법 : 버전, 인터페이스ID, 소스/대상주소, 소스/대상 포트, 프로토콜, 패킷, 바이트 수, 시작/끝, 액션, 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로그를 쿼리하려면 S3와 Athena 혹은 스트리밍 시 CW Insight 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ACTION 판단(들어오는 요청)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Inbound REJECT -&amp;gt; NACL or SG에서 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Inbound ACCEPT+Outbound REJECT -&amp;gt; NACL에서 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;아키텍처 사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1. CW Log를 거쳐 CW Contributor Insights와 연결해서 상위 10개 IP 추출 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 2. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;CW Log를 거쳐&lt;span&gt; 매트릭 필터로 특정 프로토콜을 검색해서 CW Alarm을 트리거 후 SNS로 알림&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 3. S3 버킷에 저장 후 Athena로 SQL문으로 분석 후 QuickSight로 시각화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Site-to-Site VPN, VGW, CGW&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Site-to-Site VPN&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객사 온프레미스 서버에 VPC 네트워크를 연결하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 퍼블릭 인터넷을 거치지만 VPN이라서 암호화되어있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;가상 사설 게이트웨이(VGW)&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPN연결에서 AWS 측에 있는 VPN concentrator(접선기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VGW는 생성되면&amp;nbsp; VPC에 연결됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASN 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Customer Gateway(CGW)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객 게이트웨이 : 갖춰야할 SW 혹은 물리적 장치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`구성 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객 게이트웨이 공용 IP나, 고객 NAT 측 공용 IP를 이용해서 VGW와 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서브넷의 VPC에서 라우트 전파를 활성화해야 실제로 작동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스에서 AWS로 EC2 상태를 진단할 때, SG 인바운드 ICMP 프로토콜 활성화 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;VPN CloudHub&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VGW가 갖춰져있고, 고객사마다 CGW가 있는 상황&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudHub는 여러 VPN연결을 통해 모든 사이트 간 안전한 소통 보장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- hub&amp;amp;spoke 모델 : VPN만을 활용해 서로 다른 지역 사이, 기본 및 보조 네트워크 연결성에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 VGW에 여러 고객사 CGW를 site-to-site VPN 연결하면 고객사끼리도 VPN연결로 소통 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 라우팅 테이블엔 동적 라우팅 활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : &lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;온프레미스 사이트들을 연결하기 위해 공용 인터넷을 사용하는 백업 연결을 생성하여, 제공 업체에 문제가 발생한 경우 장애 조치로 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Direct Connect(DX)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC로 전용 프라이빗 연결을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전용 연결 생성하고, AWS Direct Connect 로케이션을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC에는 가상 프라이빗 게이트웨이를 설정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 퍼블릭 S3와 프라이빗 EC2 사이도 동일하게 연결가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IPv4, IPv6 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호화 연결은 없지만 연결 자체가 프라이빗이기에 보안 유지 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 더 보안성 높이고 싶다면 VPN과 함께 써서 IPsec으로 암호화된 프라이빗 연결 가능&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사례&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대역폭이 증가할 때, 큰 데이터 세트를 처리할 때 속도 향상, 비용절감... 퍼블릭 인터넷을 거치지 않기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 퍼블릭 인터넷에 문제가 발생해도, Direct Connect를 사용하면 연결 상태 유지 가능.. 실시간 데이터 피드를 사용하는 애플리케이션에 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하이브리드 환경 제공... 온프레미스+클라우드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;아키텍처&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC 내 프라이빗 서브넷 내 EC2와 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. VPC 내 프라이빗 서브넷에서 VGW를 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 프라이빗 VIF(virtual interface)를 통해서 AWS Dircet Connect Location 內 DX Endpoint와 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. DX Location 내 DX Endpoint와 고객 라우터와 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 고객 온프레미스에서 라우터와 방화벽 설정하고 DX Location과 프라이빗 VIF로 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;S3/Glacier과 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 퍼블릭 리소스기 때문에 퍼블릭 VIF로 DX Endpoint와 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 위 (3), (4)와 동일하고, 퍼블릭 VIF로 연결되는것만 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Direct Connect Gateway&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 리전에 있는 하나 이상의 VPC와 연결시 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스와 게이트웨이를 연결하고, 게이트웨이에서 각 리전 內 VPC로 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DX 유형&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;전용 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 1, 10, 100Gbps 용량 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 물리적 전용 이더넷 포트 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;호스트 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 50Mbps, 500Mbps, ~ 10Gbps 용량 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요하면 용량을 추가하거나 제거할 수 있는 온디멘드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 선택한 로케이션에서 1,2,5,10 Gbps 이용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전용, 호스트 연결 둘 다 새 연결을 만들려면 리드 타임이 한달 이상 걸릴 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 시험에서 일주일밖에 시간이 없다면 DX는 못고름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`복원력&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 핵심 워크로드의 복원력 높이기 위해서 여러 DX를 설치하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 DX Location에 중복으로 연결해서 복원력을 높임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`최대로 복원력 높이기&lt;/b&gt; :&amp;nbsp;각 DX 로케이션에 독립적인 연결을 두 개씩 수립할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DX를 Primary Connection으로 두고, Site-to-Site VPN을 백업 연결로 둘 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DX를 여러개 두면 좋지만 비용이 많이 들기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Transit Gateway&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC가 많아지면 VPN peering도 늘어나고, 관리하기 어려운 토폴로지 구조가됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 수천개, Site-to-Site VPN, DX, 온프레미스&amp;nbsp; DC, hub-spoke 간 스타형 연결 사이에 '환승 피어링'이 생기는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 VPC를 피어링할 필요 없이, 환승 게이트웨이로 전이적으로 연결됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 VPC는 서로 연결되는데, 환승 게이트웨이에 DX 게이트웨이를 연결하면 DXG가 각기 다른 VPC에 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CGW에서 site-to-site VPN으로 환승 게이트웨이와 연결해도 동일하게 모든 VPC에 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리전 리소스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리전간 TGW를 피어링할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- TGW의 라우팅 테이블로 어느 VPC가 누구와 통신할지 트래픽 경로 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에서 유일하게 IP 멀티캐스트를 지원하는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`사례1&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Site-to-Site VPN 연결을 많이해서 AWS로의 대역폭을 늘리는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECMP(Equal-cost multi-path)를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 최적 경로를 통해 패킷을 전달하는 라우팅 전략&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1GB마다 요금 청구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;가상 프라이빗 게이트웨이 사용시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC마다 터널(연결) 하나가 생기고, 연결당 1.25Gbps 최대 처리량 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 연결은 2개의 터널을 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;환승 게이트웨이 사용시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Site-to-Site VPN 하나가 여러 VPC에 생성되고, ECMP 덕에 2.5Gbps 처리량을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Site-to-Site VPN을 여러개 추가할 수도 있어서, 연결할 때마다 2.5 * N으로 늘어남&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;사례2&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- DX연결을 여러 계정에서 공유할 때 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- TGW를 서로 다른 계정 VPC 두개에 모두 생성하고, DXGW와 VIF로 연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC 트래픽 미러링&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC에서 네트워크 트래픽을 수집하고 검사하되, 방해되지 않는 방식으로 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리 중인 보안 어플라이언스로 트래픽을 라우팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 출발지 ENIs를 설정하고, 목적지 ENI나 NLB를 설정함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필터를 걸 수도 있음, 여러개 ENI들과도 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 콘텐츠 검사, 위협 모니터링, 트러블슈팅 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;IPv6&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IPv4가 빠르게 고갈되어 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS의 모든 IPv6 주소는 공개되고 인터넷 라우팅이 가능해짐... 프라이빗 영역이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 형식 : x.x.x.x.x.x.x.x 로 x는 16진수 0000~ffff&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC에서 IPv6&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC에서 IPv6를 듀얼 스택 모드로 활성화 가능... 단, IPv4를 비활성화 할 수 는 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이런 VPC에서 EC2 인스턴스 생성시 사설 내부 IPv4와 공용 IPv6을 확보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IGW를 통해 IPv4, IPv6을 통해 인터넷과 통신 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`트러블슈팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) IPv6 지원 VPC가 있는데, 서브넷에서 EC2 인스턴스를 생성할 수 없는 경우?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 서브넷에 사용 가능한 IPv4가 없기 때문... 서브넷에 IPv4 CIDR를 생성하면 해결됨&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Egress-only Internet Gateway&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 송신 전용 인터넷 게이트웨이는 IPv6 트래픽에만 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NATGW와 비슷하지만 IPv6 전용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스에서 IPv6상 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;VPC&lt;span&gt; &lt;/span&gt;&lt;/span&gt;아웃바운드 연결을 허용하고, 인터넷이 인스턴스로 IPv6 연결을 시작하지 못하게 막음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 라우팅 테이블 업데이트해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Private Subnet 內 인스턴스에서 바로 Egress-only IGW타고 인터넷에 액세스해도, 역으론 액세스할 수 없어서 프라이빗 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Public EC2의 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IPv4, IPv6 모두 IGW통해서 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Private EC2의 경우&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IPv4는 NATGW-IGW 통해서 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IPv6은 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Egress-only IGW연결&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;VPC 요약&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CIDR&lt;/b&gt; : IP 범위&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC&lt;/b&gt; : 가상 프라이빗 클라우드, IPv4,6 CIDR 리스트 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Subnet&lt;/b&gt; : AZ에 묶이고, CIDR 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;IGW&lt;/b&gt; : VPC 수준에서, IPv4,6 인터넷 액세스 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Route Table&lt;/b&gt; : 네트워크가 VPC 내에서 흐르도록하는 키... 라우트 경로를 수정, IGW로의 경로들, VPC 피어링 연결, VPC 엔드포인트 등을 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Bastion Host&lt;/b&gt; : SSH에 들어갈 수 있던 퍼블릭 EC2 인스턴스.. 다른 프라이빗 서브넷 內 EC2 인스턴스들과 SSH 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NAT Instance&lt;/b&gt; : 퍼블릭 서브넷에 배포된 EC2 인스턴스로, 프라이빗 서브넷의 EC2 인스턴스에게 인터넷 접근 근 제공, 소스/대상 확인 비활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NAT Gateway&lt;/b&gt; : 요청 타겟이 IPv4일 때 사용.. 프라이빗 EC2에서 확장성있는 인터넷 접근 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NACL&lt;/b&gt; : 서브넷 수준에서 인바운드 아웃바운드 정의하는 방화벽 규칙...임시 포트 고려&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SG&lt;/b&gt; : Stateful 상태, EC2 인스턴스 수준에서 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC Peering&lt;/b&gt; : 두 개의 VPC 서로 연결.. CIDR 겹치지 않아야함.. 비전이적&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC Endpoint&lt;/b&gt; : 프라이빗 액세스 제공, VPC 내 어떠한 AWS 서비스도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;GW Endpoint&lt;/b&gt; : S3, DynamoDB에 특화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC Flow Logs&lt;/b&gt; : VPC 내 모든 패킷에 관련된 로그레벨의 메타데이터... VPC, Subnet, ENI 수준에서 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Site-to-Site VPN&lt;/b&gt; : VPC를 DC로 연결, 공공 인터넷을 이용함.. AWS에 가상 프라이빗 게이트웨이 생성 &amp;amp; DC에 고객 게이트웨이 생성 후 VPN 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS VPN CloudHub&lt;/b&gt; : 여러개의 VPN 연결시, hub-spoke VPN 모델을 만들어 사이트들 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Direct Connect&lt;/b&gt; : VPC를 DC로 연결, 연결히 완전히 프라이빗 상태.. 설립간 1달 이상 걸림, DC를 DX Location으로 연결해야 작동, 보안적으로 더 안전, 안정적 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Direct Connect Gateway&lt;/b&gt; : 다른 리전에 있는 여러 VPC들을 DX 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS Private Link / VPC Endpoint&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객 VPC에서 직접 생성한 VPC 내에서 서비스로 비공개적으로 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 피어링이나, 공공 인터넷이나, NATGW, 라우팅 테이블 요구 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 주로 NLB나 ENI와 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 내의 서비스를 노출시키지 않고, 수천 개의 고객 VPC에 노출 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Transit Gateway&lt;/b&gt; : VPC, VPN, DX를 위한 전송 피어링 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Traffic Mirroring&lt;/b&gt; : 네트워크 트래픽을 ENI에서 복사하여 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Egress-only IGW&lt;/b&gt; : IPv6, NATGW와 비슷&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 네트워킹 비용&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본적인 네트워킹 비용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. EC2 인스턴스로 들어오는 트래픽은 무료&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 같은 AZ 내 EC2 간의 트래픽(사설 IP통신)은 무료&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 다른 두 AZ에 있는 EC2 간 통신&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 공공 인터넷을 사용시 0.02$/GB... 트래픽이 나갔다 들어와야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사설 IP 사용시 0.01$/GB.. 지연시간도 줄고, 비용도 줄기에 가능하면 사설IP 써야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 다른 리전에 있는 EC2 간 통신 :&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;0.02$/GB&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;비용 아끼는 법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;송신 트래픽(아웃바운드, AWS에서 밖으로 나감)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수신 트래픽(인바운드, 밖에서 AWS로 들어옴) : 보통 무료임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대한 인터넷 트래픽을 AWS 안에 둬야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) DB에서 100MB를 가져와 온프레미스에서 쿼리해서 50kb로 줄이는 상황을, AWS EC2에서 쿼리해서 50kb치만 네트워크 비용으로 쓰는거&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DC를 써서 동일 리전안에 DC Location을 두고 통신하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 데이터 전송 비용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수신 트래픽 무료&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다운로드(송신)시 0.09$/GB... 전송 가속화 시 0.04~8$ 추가 비용 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에서 CloudFront까지 비용 무료&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudFront에서 인터넷으로 전송시 0.085$/GB... 요청을 보낼때마다 7배 저렴해짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리전간 복제 수행시 0.02$/GB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 프라이빗 서브넷 내 EC2에서 S3 버킷 접근 시 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 - NATGW - IGW - 인터넷 - S3 접근시... NATGW( 0.045$/h + 0.045$/GB )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC Endpoint 사용시 S3 버킷에 비공개로 데이터를 액세스... 동일리전에서 GW Endpoint(0.01$/GB)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Network FW&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NACL,&amp;nbsp;VPC SG, WAF, Shield &amp;amp; Shield Advanced, FW Manager 등 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전체 VPC를 보호할 수 있는 수준 높은 방법? Network Firewall 이용&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 수준에서 보호 3~7계층까지 보호&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 방향에서 들어오는 트래픽 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - VPC 간 트래픽&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 인터넷 아웃/인바운드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - DX, Site-to-Site VPN 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내부적으로 GWLB 사용.. 타사 어플라이언스가 아닌 AWS 자체 어플라이언스로 트래픽 관리하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 중앙 집중식으로 여러 계정과 VPC에 적용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 수준에서 수천 개의 규칙 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 수 만 IP/Port 별 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 프로토콜 별 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 도메인 별 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 정규표현식 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트래픽 허용, 차단, 알림 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 활성 플로우 검사로 침입 방지 능력 갖출 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 규칙 일치는 S3, CW Logs, KDF로 전송 후 분석 가능&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws fw</category>
      <category>AWS Private Subnet</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws subnet</category>
      <category>AWS VPC</category>
      <category>AWS VPN</category>
      <category>aws 네트워크 비용</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/109</guid>
      <comments>https://pypystory.tistory.com/109#entry109comment</comments>
      <pubDate>Fri, 18 Oct 2024 22:58:58 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 17편 보안 및 암호화, KMS, SSM - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/108</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHYrSb/btsIZOVEjPA/AqQpg3htjNy83gupElccEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHYrSb%2FbtsIZOVEjPA%2FAqQpg3htjNy83gupElccEk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;암호화&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;전송 중 암호화(TLS/SSL)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터가 전송되기 전에 암호화되고, 전송 후에 복호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- TLS 인증서.. HTTPS 프로토콜 사용로 중간자 공격 방어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;서버 측 암호화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버가 받은 뒤 암호화 시켜서 안전하게 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 해독은 클라이언트에게 돌려주기 전에 해독&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 키를 어딘가에 저장해두고, 서버가 이 키에 접근할 수 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;클라이언트 측 암호화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트 측에서 암호/복호화가 일어나며, 서버는 복호화할 수 없어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버를 신뢰할 수 없을 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;KMS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;KMS란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키 관리 서비스로 대신 암호화 키를 관리한다는 개념&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 승인에 관해 IAM과 완벽히 통합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- CloudTrail을 통해 키를 쓰는 API 호출을 감시할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS SDK, CLI로 API 호출을 해서 암호화한 뒤에 코드 내 환경 변수를 암호화 시킬 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- KMS 키는 리전에 한정됨.. 옮기고 싶으면 스냅샷 찍어서 다른 리전으로 옮기기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 리전으로 옮길 때 재 암호화는 AWS가 해줌&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;대칭 키 AES-256&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS가 통합된 모든 AWS 서비스는 대칭 키를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키 자체에는 절대 액세스 못함... API 호출로 그 키를 사용할 뿐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;비대칭 키 RSA &amp;amp; ECC&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호화할 때 공개 키, 복화화할 때 프라이빗 키&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호/복호화 또는 서명/확인 형태의 작업에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS로 부터 공개 키는 다운로드 가능, 프라이빗 키 액세스 못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : AWS 외부에서 API 호출 못하는 경우.. 공개키로 암호화하고, 내부에서 API 호출로 복호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;KMS 키 타입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS 소유한 키&lt;/b&gt; (무료) : SSE-S3, SSE-SQS, SSE-DDB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS 관리형 키&lt;/b&gt; (무료) : aws/서비스명.. ex) aws/rds, aws/ebs...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고객 관리형 키&lt;/b&gt; (1$/month)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고객 관리형 키 imported&lt;/b&gt; (1$/month)&amp;nbsp; + KMS API 호출 비용 (0.03$ / 10000 call)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;자동 순환 키&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS 관리형 키&lt;/b&gt; : 1년마다 순환&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고객 관리형 키&lt;/b&gt; : 자동 순환을 활성화해야함 (1년 단위).. import 한 키라면 수작업으로 순환&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;KMS 키 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS 키 정책이 없다면, 아무도 키에 접근할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;기본정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정한 커스텀 KMS 키 정책을 제공하지 않을 때 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정에 있는 모든 사람이 키에 액세스 하도록 허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;커스텀 KMS 키 정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 할 수 있는 사용자와 역할을 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키를 관리할 수 있는 사람을 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교차 계정 액세스를 하려는 경우 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 사례 : 스냅샷을 계정간 복제할 때 사용.. 암호화된걸 KMS키까지 같이 넘겨줘야하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;KMS 다중 리전 키&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 리전에 기본 키를 갖고, 다른 리전으로 복제되는 형태&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키 구성요소가 복제됨... Key ID 동일.. 서로 교차해서 사용 가능(A리전에서 암호화 후 B리전에서 복호화)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동으로 교체 후에도 복제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS 다중 리전 키는 글로벌이 아님.. 기본 키가 있고 복제본이 있는거임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 다중 리전 키는 자체 키 정책 등으로 독립적으로 관리됨.. 특정 사례 빼고는 권장되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 전역 클라이언트 측 암호화, DDB 전역 테이블, Global Aurora에서 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;DDB/Aurora 사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블만 암호화하는게 아닌, 테이블의 속성을 암호화하여 특정 클라이언트만 사용할 수 있게 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트 측에서 KMS API 호출로 미리 암호화하고 저장하는데, 이러면 DB 관리자도 값을 볼 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DDB가 Global 테이블이면 다른 리전에도 복제되고 이때 복호화하려면 KMS 키도 리전 복제되야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Aurora는 대부분 동일하고 특정 열만 암호화도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 암호화된 복제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 버킷에서 다른 버킷으로 복제 시 기본적으로 암호화되지 않은 객체와 SSE-S3로 암호화된 객체가 기본으로 복제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고객 제공 키인 SSE-C로 암호화된 객체도 복제 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSE-KMS로 암호화된 객체는 기본적으로 복제되지 않지만, 복제시 옵션 활성화로 어떤 KMS 키로 암호화했는지 지정을 해줘야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS 키 정책을 대상 키에 적용해야하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 복제 서비스를 허용하는 IAM 역할을 생성해서 소스 버킷의 데이터를 먼저 복호화한 뒤, 대상 KMS 키로 대상 버킷의 데이터를 다시 암호화함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 많은 암호/복호화가 발생하기에 KMS 스로틀릉 오류가 발생할 수 있는데, 이런 경우 서비스 할당량 요청을 해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이때 다중 리전 키를 쓰더라도, S3에서는 독립적인 키로 인식해서 복제 간 동일하게 암호/복호화 과정이 일어나게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`사례 : 암호화된 AMI 공유 프로세스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 계정 A에 있는 AMI(KMS로 암호화되어 있음)에서 B계정에 EC2 인스턴스 실행하려는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 시작 권한으로 AMI 속성 수정, B계정에서 AMI 시작하도록 허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. KMS 키를 공유해서 쓸수있도록 IAM 역할을 만들어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 계정 B에서 KMS와 AMI를 모두 쓸 수 있는, IAM 역할이나 사용자를 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. EC2를 AMI로 실행할 때, 계정 B에서 새로운 KMS 키로 볼륨 전체 재암호화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SSM 매개변수 저장소&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구성 및 암호를 위한 보안 스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구성을 암호화할지 선택 가능.. KMS 서비스 이용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스로 확장성과 내구성이 있음, SDK 사용도 용이함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 매개변수 업데이트시 구성과 암호의 버전 추적 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM을 통한 보안 제공, EventBridge로 알람 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudFormation과 통합되어 스택의 입력 매개변수로 활용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계층적 구조에 저장 가능.. 매개변수 구조화 가능... 구조화를 통해 IAM 정책 간소화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ ex) /my-app/dev/db-url , /my-app/dev/db-password&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 티어 : Standard(무료, 10000개, 용량 4kb), Advanced (유료, 100000개, 용량 8kb)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고급 티어에서는 매개변수 정책 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. ex) TTL할당으로 pw 삭제/변경 강제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 한번에 여러 정책 할당 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Secrets Manager&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호를 저장하는 최신 서비스... X일마다 강제로 암호를 교체하는 기능 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교체할 암호를 강제 생성 및 자동화 가능... 람다 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS 등 AWS 서비스와도 통합이 잘 됨... 자동으로 DB 암호 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS로 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;다중 리전 암호&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복수 리전에 암호를 복제... 기본 암호화 동기화된 읽기 전용 복제본을 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 리전에서 장애시 복제본을 독립 실행형 암호로 승격 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SSM 매개변수 저장소와 차이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교체, 관리 및 DB와의 긴밀한 통합 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 0.05$/10,000call&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Certifica&lt;/b&gt;&lt;b&gt;te Manager&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ACM은 TLS인증서를 AWS에서 프로비저닝, 관리 및 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 퍼블릭(무료), 프라이빗 TLS 인증서 모두 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동 갱신 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ELB, CloudFront, API Gateway와 통합 가능...단, EC2와는 통합 불가(퍼블릭 인증서는 추출이 불가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;과정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 인증서에 포함할 도메인 이름 나열.. FQDN(test.example.com), 와일드카드(*.example.com)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 유효성 검증 방법 선택.. DNS | Email 검증 방법... 자동 갱신하려면 DNS가 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. DNS 검증 사용시 DNS 레코드에 CNAME 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 유효성 검증 완료시 인증서 발급 + 퍼블릭 인증서도 자동 갱신 목록에 추가... 만료 60일전 갱신&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;인증서 만료&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ACM은 외부 인증서도 import 해올 수 있는데 이러면 자동 갱신은 안됨...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단, 만료 45일 전부터 EventBridge에 만료 이벤트 쏴줌... 람다 함수 등으로 연결해서 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아니면, AWS Config와 연결해서 acm-certificate-expiration-check라는 관리형 규칙으로 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;통합 과정&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;ALB&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ALB에서는 HTTP에서 HTTPS로 리디렉션 규칙 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTP로 요청시 HTTPS로 리디렉션..HTTPS로 다시 요청하면 ACM에서 나오는 TLS 인증서 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;API Gateway&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;엔드포인트 유형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 엣지 최적화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 서비스일 때...CloudFront 엣지 로케이션으로 요청을 라우팅.. 지연 시간 단축&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 리전에만 있는 API Gateway로 보내짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 리전&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 API Gateway와 같은 리전에 있을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자체 CloudFront와 연결해서 캐싱 및 배포 전략 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 프라이빗&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC ENI로 VPC 내부에서만 액세스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스를 정의하는 리소스 정책 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ACM과 통합시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 엣지 최적화와 리전 유형에서 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 사용자 지정 도메인 이름 이라는 리소스 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2-1. ( 엣지 최적화 엔드포인트 ) 요청이 CloudFront에서 라우팅.. 그런 다음 TLS 인증서가 CloudFront 배포에 연결됨... 따라서 CloudFront와 같은 리전인 us-east-1에 인증서가 구성되어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2-2. ( 리전 엔드포인트 ) : API Gateway와 리전이 같은 클라이언트를 위한 엔드포인트... API Gateway만 있기에 API Gateway와 같은 리전에 인증서 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WAF &amp;amp; Shield &lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Web Application Firewall&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 7계층(HTTP)에서 일어나는 일반적인 웹 취약점 공격으로부터 보호&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 타겟 : ALB, API Gateway, CloudFront, AppSync GraphQL API, Cognito User Pool... NLB에는 못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Web ACL 규칙 정의&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IP 주소를 기반으로 필터링.. IP 세트 정의 가능(한 IP 세트 당 10,000개 IP)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTP 헤더, 본문에 기반해 필터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- URI 문자열을 조건으로 두어, SQL 주입, XSS&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 용량 제한(ex 요청 최대 2MB)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지역 일치(특정 국가 허용/차단)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 속도 기반 규칙 : IP당 요청 수 확인 (DDoS 차단)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Web ACL은 리전에 적용되고, CloudFront만 글로벌로 정의됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 규칙 그룹 : 여러 웹 ACL에 추가할 수 있는 재사용 가능한 규칙 모음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 고정 IP를 쓰는 로드밸런서에 WAF를 쓰고 싶을 때...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NLB는 L4이기에 L7에 적용되는 WAF를 못 씀&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ALB는 고정 IP를 못씀&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Global Accelerator로 고정 IP를 할당받고, ALB에서 WAF를 활성화하면 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Shield&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 디도스로부터 보호&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS Shield Standard(무료) : SYN/UDP Floods, 반사 공격, L3/L4 공격으로부터 보호&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS Shield Advanced : 보다 정교한 디도스 공격 방어 (3,000$/month), EC2, ELB, CloudFront, Global Accelerator, Route53... 24/7 디도스 대응팀(DRP) 지원, 자동 애플리케이션 계층(L7) 디도스 완화... 자동으로 WAF 규칙을 생성, 평가, 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Firewall Manager&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 계정 규칙 동시 관리&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안 정책 설정 : 보안 규칙의 집합... 모든 방화벽 한번에 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- WAF rules : ALB, API Gateway, CloudFront&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- Shield Advanced : ALB, CLB, NLB, Elastic IP, CloudFront&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- SG : EC2, ALB, VPC의 ENI 리소스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- VPC 수준의 네트워크 방화벽&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- Route53 DNS 방화벽&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정책은 리전 수준에서 관리... 조직에 등록된 모든 계정에 적용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) 조직에서 ALB에 대한 WAF 규칙 생성 후, 새 ALB를 생성하는 경우, Firewall Manager에서 새 ALB에도 같은 규칙을 적용해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`WAF vs Firewall Manager vs Shield&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;WAF&lt;/b&gt; : 리소스별 보호를 구성하는데 적절&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; Firewall Manager&lt;/b&gt; : 여러 계정에서 WAF를 사용하고, WAF 구성 가속, 새 리소스 보호 자동화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Shield Advanced&lt;/b&gt; : 디도스 공격으로부터 보호, DRP 팀 지원, WAF 규칙 자동 생성, 고급 보고서&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GuardDuty&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지능형 위협 탐지... 머신 러닝 알고리즘으로 이상 탐지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Input Data&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudTrail Event Logs &lt;/b&gt;: 사용하지 않는 API, 인가받지않은 행위&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 관리형 이벤트 : VPC 생성 이벤트 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - S3 데이터 이벤트 : getObject, listObject 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;VPC Flow Logs&lt;/b&gt; : 비정상적인 인터넷 트래픽 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;DNS Logs&lt;/b&gt; : DNS 쿼리 안에서 인코딩된 데이터를 전송하는 인스턴스 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Optional&lt;/b&gt; : EKS 감사로그, RDS 로그인 이벤트 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EventBridge 규칙과 연결해서 자동 알림도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 암호화폐 공격을 방어하기 위한 아주 좋은 도구, 전문적인 탐지 기능 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Inspector&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동화된 보안 평가를 실행... CBE와 비교&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 작업 완료하면 AWS 보안 허브에 보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 결과 및 이벤트를 EventBridge로 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행 중인 EC2, ECR, lambda에 사용됨... 필요할 때 인프라만 지속적으로 스캔&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행될 때마다, 우선 순위를 정하기 위해 위험 점수가 모든 취약성과 다시 연관됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;대상&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 인스턴스 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시스템 관리자 에이전트 활용(SSM agent)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 의도되지 않은 네트워크 접근 가능성 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행 중인 OS에서 알려진 취약점 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ECR 푸시할 때&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨테이너의 알려진 취약점 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;람다 함수&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 함수 배포시 함수 코드 및 패키지 종속성에서 SW 취약점 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Macie&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완벽히 관리되는 데이터 보안 및 데이터 프라이버스 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ML과 패턴 매칭으로 민간데이터(PII, 개인 식별 정보) 발견 및 경보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) S3 내에 개인 민감정보 탐지&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS KMS</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws ssm</category>
      <category>aws 디도스</category>
      <category>aws 방화벽</category>
      <category>AWS 보안</category>
      <category>aws 정보보호</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/108</guid>
      <comments>https://pypystory.tistory.com/108#entry108comment</comments>
      <pubDate>Thu, 17 Oct 2024 00:55:56 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 16편 Organizations, IAM 고급 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/107</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZ1AQY/btsJ4tpIfaP/W8okNb9UgdQ53xN93w4XR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZ1AQY/btsJ4tpIfaP/W8okNb9UgdQ53xN93w4XR1/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZ1AQY/btsJ4tpIfaP/W8okNb9UgdQ53xN93w4XR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZ1AQY%2FbtsJ4tpIfaP%2FW8okNb9UgdQ53xN93w4XR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;AWS Organizations&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 서비스.. 다수의 AWS 계정을 동시에 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 조직의 메인 계정이&lt;b&gt; 관리 계정&lt;/b&gt;이 됨... 조직에서 생성하거나 추가된 계정은 &lt;b&gt;멤버 계정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 멤버 계정은 한 조직에만 들어가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 계정의 비용을 통합 결제할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 조직 계정을 쓰면 모든 계정에서 집계된 사용량에 기반한 비용 할인을 받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정 간에 예약 인스턴스와 Saving Plan 할인이 공유됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정 생성을 자동화할 수 있는 API 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;작동 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 루트 조직단위(OU, Organization Unit)이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 루트 OU 내에 관리 계정 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 서브 OU를 만들 수 있음.. ex) dev OU 만들고 안에 멤버 계정 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 서브 OU 안에 OU를 만들 수 있음.. 비즈니스 단위별로..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다수 VPC 가진 단일 계정보다, 보안이 뛰어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 청구 목적의 태그 기준 적용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 번에 모든 계정에 대해 CloudTrail을 활성화해서 중앙 계정 S3로 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CW Logs 중앙 로깅 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;보안 관점에서 SCP(Service Control Policy) 적용 가능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 OU 또는 계정에 적용되는 IAM 정책&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 해당 사용자와 역할 모두가 계정에서 할 수 있는 일을 제한할 수 있음.. 기본적으론 모두 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 영구적인 관리자 권한을 갖는 관리 계정에는 적용할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상위 정책에 명시적 거부가 하나라도 들어가면, 하위정책에서 허용해도 거부됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- '차단 목록'과 '허용 목록' 전략을 쓸 수 있음 (차단은 다 허용하고 차단할꺼만 정하기.. 허용은 반대)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;IAM 고급&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; IAM 조건 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 내부의 정책에 적용... ex) 특정 API 호출이 생성되는 클라이언트 IP를 제한되게 조건 걸기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 회사 네트워크 내에서만 가능하도록 조정 가능.. 혹은 API 호출 리전을 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서비스가 특정 태그가 있을 때만 동작하도록 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- S3 버킷에 대한 IAM 정책 : &lt;/b&gt;버킷 수준 권한은 리소스에 버킷 arn을 특정해야하고, 객체 수준 권한은 객체 리소스에 객체 arn을 특정해야함... 버킷/* 로 모든 권한을 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- PrincipalOrgID :&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;IAM 상태 키로&lt;span&gt; &lt;/span&gt;&lt;/span&gt;AWS 조직의 멤버 계정에만 리소스 정책이 적용되도록 제한 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RequestedRegion: IAM 상태 키로 특정 리전에서만 API 호출을 허용 가능&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM 역할 vs 리소스 기반 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교차 계정의 경우.. 특히 S3 버킷 교차 계정에서 API 호출을 수행하는 경우 두 가지 옵션이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;리소스 기반 정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 버킷의 S3 버킷 정책과 같은 것들&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스에 리소스 기반 정책이 걸려있는것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원칙이 역할을 가정하지 않기에, 권한을 포기할 필요가 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 지원되는 서비스 : S3 버킷, SNS, SQS, 람다 함수 등..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;역할 사용(자격 증명 기반 정책)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유저에게 역할이 부여되어 리소스에 접근할 수 있는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;차이&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EventBridge를 쓸 때 규칙이 있고,&amp;nbsp; 이 규칙들은 목표 대상에서 원하는 일을 수행하기 위한 권한이 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 목표 대상이 리소스 기반 정책을 지원 하는 경우, EventBridge 규칙이 필요로하는 작업을 수행할 수 있도록 대상 리소스의 리소스 기반 정책을 변경해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 그렇지 않은 경우(ex. KDS, ECS 등) IAM 역할을 EventBridge 규칙에 첨부해서 권한을 얻어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM 권한 경계&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Permissions boundary는 사용자와 역할만 지원하고 그룹은 지원하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 개체의 최대 권한을 정의하는 고급 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 리소스에만 접근할 수 있게 권한 경계를 설정하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 권한 경계 + IAM 정책을 같이 줘서 권한을 만듬... IAM 정책으로 아무리 높은 권한이 있어도 권한 경계에 한정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 조직 SCP와 같이 쓸 수 있음... 즉 SCP+권한경계-IAM 정책 의 교집합이 실제로 유의미한 권한이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 관리자가 아닌 사용자에게 권한 위임을 할 때, 권한 경계 내에서 IAM 사용자를 생성하거나, 개발자가 권한을 남용하는 것을 막기 위해 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM 정책 평가 논리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 가능한 모든 정책 중 명시적인 거부가 있으면 Deny&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 조직 SCP에서 허용되어 있는지 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 리소스 기반 정책에서 허용되는지 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 자격 증명 기반 정책에서 자격 증명이 있는지 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. IAM 권한 경계 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;6. 세션 정책 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;7. (1)~(6)에 안 걸리고 다 통과하면 허용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS IAM 자격 증명 센터&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한번만 로그인하면됨... 모든 AWS 계정/조직, 비즈니스 클라우드 애플리케이션(세일즈포스, MS365 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SAML2.0 통합이 가능한 어떤 애플리케이션도 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 윈도우 인스턴스도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 여러 AWS 계정에 한번에 로그인도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ID 공급자 : 이 로그인을 위해 사용자는 두 위치에 저장가능(내장 ID 저장소, 서드파티 ID 공급자(Active Directory, OneLogin, Okta 등))&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;로그인 흐름&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 브라우저 인터페이스에서 로그인 시 AWS IAM 자격 증명센터가 내장 ID 저장소나 서드파티 ID 공급자에 확인하고, SSO를 통해 AWS 조직이나 계정, 비즈니스 클라우드 앱, SAML2.0 지원하는 앱에 로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 자격 증명센터 안에 그룹을 만들고, 권한 셋을 만들어 OU와 연결 후 그룹에 할당하는 방식으로 권한 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;다중 계정 권한&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 조직에서 여러 계정에 대한 액세스 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 권한 셋으로 사용자를 그룹에 할당하는 하나 이상의 IAM 정책 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;애플리케이션 할당&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어떤 사용자 또는 그룹이 어떤 애플리케이션에 액세스할 수 있는지를 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요한 URL, 인증서, 메타데이터가 제공됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;속성 기반 액세스 제어&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Attribute-Based Access Control(ABAC)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 자격 증명 센터 스토어에 저장된 사용자 속성을 기반으로 세분화된 권한을 갖게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 사용자를 비용 센터에 할당, 주니어/시니어와 같은 직함 제공, locale로 특정 리전에만 액세스 제어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : IAM 권한 셋을 한번만 정의하고 이 속성을 활용하여, 사용자 또는 그룹의 AWS 액세스만 수정하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 디렉토리 서비스&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MS Active Directory(AD)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AD 도메인 서비스를 사용하는 모든 윈도우 서버에 사용되는 SW&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체의 데이터베이스로 객체는 유저 계정, 컴퓨터, 프린터, 파일 공유, 보안 그룹이 객체가 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 중앙 집중식 보안 관리로 계정 생성, 권한 할당 등의 작업 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 객체는 트리로 구성되고, 트리의 그룹을 포리스트(forest)라고 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 도메인 컨트롤러에 여러 윈도우 머신을 연결해서 하나의 계정으로 여러 머신에서 로그인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Directory Service&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에 액티브 디렉터리를 생성하는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. AWS 관리형 MS AD &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에 자체 AD를 생성하고 로컬에서 관리, MFA 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 독립 실행형 AD로 사용자가 있는 온프레미스 AD와 신뢰 관계 구축 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 즉, 서로 신뢰관계인 둘에서 양방향으로 인증을 지원하는 것... 온프레미스/AWS AD 모두 사용자가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. AD 커넥터&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 디렉터리 게이트웨이(프록시)로 온프레미스 AD에 리다이렉트하며 MFA 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자는 온프레미스에서만 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Simple AD&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MS 디렉터리를 사용하지 않고 온프레미스와도 결합하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 독립형으로 AWS에서 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 윈도우를 실행하는 EC2 인스턴스에 모든 로그인 정보와 자격 증명을 공유할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;IAM 자격 증명 센터와 AD와 통합 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; AWS 관리형 MS AD 쓸 때&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 자격 증명 센터를 AWS 관리형 MS AD에 통합하고 연결하도록 설정하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;온프레미스에 자체 관리형 AD가 있을 때&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 관리형 MS AD와 양방향 신뢰 관계 구축하고, 자격 증명 센터에서 싱글 사인온으로 통합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 혹은 AD 커넥터로 프록시만 하고, 자격 증명 센터와 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Control Tower&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모범 사례를 기반으로 안전하고 규정을 준수하는 다중 계정 AWS 환경을 손쉽게 설정 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 조직 서비스를 사용해 계정 자동 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클릭 몇번으로 환경 자동 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가드레일을 사용해 자동으로 지속 정책 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정책 위반 감지 및 자동 교정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대화형 대시보드로 모든 계정의 전반적인 규정 준수 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;가드레일&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 다중 계정 설정 시, 특정 항목에 관해 한번에 모두 제한하거나, 특정 유형의 규정 준수 사항을 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨트롤 타워 내 모든 계정에 관한 거버넌스 획득&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 예방 가드레일 : SCP를 사용해 모든 계정에 적용 (ex. 모든 계정 특정 리전에서만 접속)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 탐지 가드레일 : AWS Config 서비스로 탐지.. SNS를 트리거해서 메일이나 람다 함수로 넘기기도 가능&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>aws ad</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws iam</category>
      <category>AWS Organization</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 다중 계정</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/107</guid>
      <comments>https://pypystory.tistory.com/107#entry107comment</comments>
      <pubDate>Mon, 14 Oct 2024 12:00:00 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 15편 모니터링 및 감사 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/106</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh3giC/btsJ3fMSjKy/omZH1Egxc9iAPnEzsKcT11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh3giC/btsJ3fMSjKy/omZH1Egxc9iAPnEzsKcT11/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh3giC/btsJ3fMSjKy/omZH1Egxc9iAPnEzsKcT11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh3giC%2FbtsJ3fMSjKy%2FomZH1Egxc9iAPnEzsKcT11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;CloudWatch&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudWatch Metrics&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS의 모든 서비스에 대한 지표 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표 : 모니터링할 변수.. (ex. CPUUtilization, NetworkIn...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표는 이름공간(namespaces)에 속함.. 서비스 당 이름공간은 하나임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표의 속성으로 측정 기준이 있음.. 지표당 최대 측정 기준은 30개&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표는 타임스템프를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudWatch 대시보드에서 모든 지표를 한번에 볼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 지정 지표를 만들 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 'CloudWatch 지표 스트림'을 활성화하면 외부로 스트리밍 가능 (KDF, Datadog, Splunk 등 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 지표만 필터링해서 보낼 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudWatch Logs&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 로그 저장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;로그 그룹&lt;/b&gt; : 애플리케이션을 나타내는 이름으로 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;로그 스트림&lt;/b&gt; : 로그 그룹 내 다수의 로그 스트림을 가짐.. 특정한 로그 파일 또는 클러스터의 일부로서 갖고 있는 특정한 컨테이너를 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로그 만료 정책 정의 : 하루~10년, 만료되지 않음 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전송 가능 : S3(배치 형태), KDS, KDF, 람다, OpenSearch에 스트리밍도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 암호화되고, KMS로 암호화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; CloudWatch Logs Insights &lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 모인 로그는 CloudWatch logs Insights로 쿼리 가능... 시각적으로 볼 수 있고 대시보드에 추가 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;`- CloudWatch Logs Insights는 실시간 엔진이 아닌 쿼리 엔진.. 쿼리를 실행하면 과거 데이터만 쿼리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Sources&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SDK로 로그 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudWatch Logs Agent(deprecated)나 CloudWatch Unified Agent(최신)를 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Elastic Beanstalk, ECS, 람다, VPC Flow Logs, API Gateway, CloudTrail, Route53에서 직접 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Destinations&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 배치 내보내기로 최장 12시간까지 걸릴 수 있음.. 이건 실시간이나 근 실시간이 아님&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ CloudWatch Logs Subscriptions를 이용하면 로그 이벤트의 실시간 스트림을 처리 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ KDS, KDF, 람다 등에서 받을 수 있고, 필터 걸어서 받을 거만 받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서로 다른 여러 계정에서 로그를 받아서 KDS로 합쳐서 스트리밍 후 로그 집계도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- A계정에서 CloudWatch Log Subscriptions Filter로 스트리밍하면, B계정에서 CloudWatch Log Subscriptions Destination으로 액세스 정책(IAM 역할) 확인한 뒤 로그를 받아올 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Live Tail&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 로그 그룹/스트림에 대해서 필터에 맞는 로그를 실시간으로 보여줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudWatch Logs 디버깅할 때 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하루에 한시간은 무료&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudWatch Agent&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 EC2에서 어떤 로그도 CloudWatch로 옮겨지지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 Agent를 깔아서 푸시해야 로그를 보낼 수 있음(IAM 역할 필요)... 온프레미스에서도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudWatch Logs Agent&lt;/b&gt; : 오래되었고, CloudWatch 로그만 전송가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudWatch Unified Agent&lt;/b&gt; : 프로세스나 RAM 같은 추가적인 시스템 단계 지표를 수집 후 CloudWatch 로그에 전송.. SSM Parameter Store를 이용해서 에이전트를 쉽게 구성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- linux 서버에 Unified Agent 설치시 :&amp;nbsp;CPU, 디스크, RAM, Netstat, 프로세스, 스왑공간 등 세부지표 확득 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudWatch Alarms&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표에서 나오는 알람을 트리거.. 샘플링, 최대, 최소, % 등 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 3가지 상태 :&amp;nbsp;&lt;b&gt;OK&lt;/b&gt; 정상 / &lt;b&gt;INSUFFICIENT DATA&lt;/b&gt; 상태 결정하기에 데이터 부족 / &lt;b&gt;ALARM&lt;/b&gt; 한도값 초과&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기간 : 얼마동안 지표를 평가할지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;트리거 대상&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스 : 정지, 종료, 재부팅, 복구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASG 액션 : 스케일 인/아웃&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS 서비스에 알람 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;복합 알람&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다수의 메트릭을 사용.. 다른 알람을 AND OR로 결합해서 검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 알람 노이즈를 줄이는데 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 인스턴스 복구&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스 검사 = EC2 VM 검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시스템 검사 = 기본 하드웨어 검사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 알람 발생시 EC2 호스트를 옮기고, 동일한 Private/Public/Elastic IP, 메타데이터, 배치그룹을 얻고 SNS에 복구되었다는 걸 알릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudWatch Insights&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Container Insights&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨테이너로부터 지표와 로그를 수집, 집계, 요약&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS, EKS, k8s on EC2, Fargate에서 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨테이너화 된 버전의 CW써야 컨테이너 찾기 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Lambda Insights&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스 애플리케이션을 위한 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 함수 성능 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Contributor Insights&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기고자 데이터를 표시하는 시계열 데이터 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC, DNS 로그 등에서 작동... 불량 호스트를 찾을 수 있음(오류 많거나 트래픽 높은)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) 상위 10개 불량 IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Application Insights&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션의 잠재적 문제와 진행 중인 문제를 분리해 자동화된 대시보드 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백그라운드에서 SageMaker 머신러닝 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 상태 가시성을 높일 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 발견된 모든 문제는 EventBridge와 SSM OpsCenter로 전달됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EventBridge&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRON 작업 예약(특정 시간(스케줄), 이벤트 패턴 설정 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Source : EC2, S3, CodeBuild, CloudTrail, CRON...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소스로부터 들어올 때 필터 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Destination : 람다, Batch, ECS, SQS, SNS, KDS...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이벤트 버스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본 이벤트 버스 : 아마존 서비스로부터 이벤트를 전송하는 AWS 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;파트너 이벤트 버스 : datadog, zendesk 등에서 이벤트를 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자 지정 이벤트 버스 : 각자 애플리케이션에서 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스 기반 정책을 사용해 다른 계정의 이벤트 버스에 액세스 할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트 아카이빙도 가능... 보존 기간 설정 가능... 저장된 이벤트 리플레이도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;스키마 레지스트리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트 브릿지는 버스의 이벤트를 분석하고 스키마를 추론하는 능력이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스키마 레지스트리의 스키마를 이용하면 애플리케이션의 코드를 생성할 수 있고, 이벤트 버스의 데이터가 어떻게 정형화되는지 미리 알 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스키마 버저닝도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;리소스 기반 정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 이벤트 버스의 권한 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 리전이나 다른 계정 이벤트 승인/거부 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 여러 계정의 모음인 AWS Organizations의 중앙에 이벤트 버스를 두고 모든 이벤트를 모을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CloudTrail&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 계정의 거버넌스(관리), 컴플라이언스(법규 준수), 감사를 실현하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본값으로 활성화.. AWS 계정 안에서 일어난 모든 이벤트와 API 호출 이력을 콘솔, SDK, CLI, 다른 AWS 서비스로 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- trail을 생성해 모든 리전이나 하나의 리전에 적용해서 하나로 모을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 검사&amp;amp;감사 가능하고 90일 이상 보관하고 싶으면, 로그를 S3, CW Logs 등으로 넣을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ S3에 저장한 이벤트는 Athena로 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;이벤트 종류&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;관리 이벤트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 계정 안에서 리소스에 대해 수행된 작업(기본값으로 모든 관리 이벤트로깅)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기/쓰기 이벤트로 나뉨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;데이터 이벤트&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고용량 작업으로 기본값으로는 로깅 안함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) S3 객체 수준 활동.. Get/PutObject, 람다 함수 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudTrail Insights 이벤트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트를 알아서 분석하고 비정상적인 활동에 대한 탐지를 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정상관리 활동을 분석해서 기준선을 만들고, 지속적으로 올바른 이벤트인지 분석을 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EventBridge와의 통합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API 호출이 CloudTrail에 기록될 때, EventBridge가 가로채서 룰을 만들고 SNS로 넘겨서 alert를 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Config(구성)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 리소스에 대한 감사와 규정 준수 여부를 기록할 수 있는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구성과 구성의 시간에 따른 변화를 기록 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 빠르게 롤백하고 문제점 찾기 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ex) 허용되지 않은 SSH 접근이 가능한 SG가 있는지? 퍼블릭 액세스 되는 S3가 있는지? 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS 알림과 연결할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리전별 서비스로 모든 리전별로 구성해야함.. 계정과 리전간 데이터 통합은 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 저장 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- AWS Config는 뭔가 차단을 하지는 못하고 그저 규정 준수를 위한 평가만 가능... IAM 같은 보안 매커니즘과 다름&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 비용 발생 각 리전당 구성 항목별로 3센트 지불.. 리전당 규칙 평가별 0.1센트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;규칙&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS 관리형 규칙 : 75종&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;커스텀 룰 : 람다로 정의 ex) 각 Ec2가 t2.micro인지 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 몇몇 규칙은 구성이 변할때마다 평가/트리거 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) EBS 디스크가 새롭게 생길 때마다 평가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;수정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSM 자동화 문서를 이용해서 규정을 준수하지 않는 리소스 수정은 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) IAM 액세스 키 규정이 준수되지 않았을 때, IAM 비활성화 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계속 실행하고 싶으면 람다 함수를 실행하는 문서를 생성해서 원하는 작업 수행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 5번까지 수정 작업 재시도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;알림&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EventBridge를 이용해서 특정 이벤트 필터링해서 미준수할 때마다 알림 보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CloudWatch vs CloudTrail vs Config&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudWatch&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지표, CPU, 네트워크 등의 성능 모니터링과 대시보드 만들 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트와 경보 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로그 집계 및 분석 도구도 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;CloudTrail&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정 내에서 만든 API에 대한 모든 호출을 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 리소스에 대한 추적 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Config&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구성 변경을 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 규정 준수 규칙에 따라 리소스를 평가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 변경과 규정 준수에 대한 타임라인을 보여줌&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS CloudTrail</category>
      <category>AWS CloudWatch</category>
      <category>AWS Config</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 로깅</category>
      <category>aws 알림설정</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/106</guid>
      <comments>https://pypystory.tistory.com/106#entry106comment</comments>
      <pubDate>Sun, 13 Oct 2024 17:01:51 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 14편 머신러닝 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/105</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc9TNC/btsJ3sdZPyd/BWnkSRcrwcNmrgI2nDXLkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc9TNC/btsJ3sdZPyd/BWnkSRcrwcNmrgI2nDXLkk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc9TNC/btsJ3sdZPyd/BWnkSRcrwcNmrgI2nDXLkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc9TNC%2FbtsJ3sdZPyd%2FBWnkSRcrwcNmrgI2nDXLkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;Rekognition&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ML로 객체, 사람, 텍스트를 이미지와 비디오에서 장면을 찾는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 얼굴 분석으로 사용자 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 익숙한 얼굴 저장으로 자체 DB 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 촬영한 사진, 비디오의 라벨링, 콘텐츠 조정, 텍스트 탐지, 얼굴 탐지 및 분석, 얼굴 검색 확인, 스포츠 경기 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 콘텐츠 조정 기능 : 부적절하거나 원치않는 이미지 탐지.. 안전한 사용자 경험을 위함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동작 : 이미지를 분석하고 플래그를 띄우도록 최소 신뢰도 임곗값을 설정 가능(퍼센트 낮을 수록 매칭되는것 많아짐)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- A2I로 인적 검토 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Transcribe&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 음성을 텍스트로 변환.. ASR 딥러닝 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Redaction을 사용하여 개인 식별 정보(PII)를 자동으로 제거 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다국어 오디오를 자동으로 언어식별 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : AS 전화의 대본을 자동으로 자막으로 만들기, 미디어 자산에 대한 메타데이터 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`Polly&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 텍스트를 음성으로 변환.. Lexicon &amp;amp; SSML 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;lexicons&lt;/b&gt; : 발음어휘 목록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 지정 발음도 생성 가능(AWS를 Amazon Web Service로 읽게 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 업로드해서 SynthesizeSpeech 작업에 쓰도록 하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SSML&lt;/b&gt; : 음성 합성 마크업 언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 단어나 구절 강조&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 음성학적 발음 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 숨소리를 넣거나 속삭이듯 말할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Translate&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 언어 번역 기능 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 해외 사용자들을 위한 웹사이트와 애플리케이션 등에 적용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대량 텍스트를 효율적으로 번역 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Lex + Connect&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Amazon&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; Lex&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Alexa 장치를 구현하는 기술과 같음(시리, 빅스비 같은것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASR로 음성을 텍스트로 변환 후 자연어 이해를 통해 말의 의도를 파악&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 챗봇이나 콜 센터 봇 구축에 도움이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Amazon Connect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가상 고객 센터.. 전화를 받고 고객 응대 흐름 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRM이나 다른 AWS와 통합 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기존 고객 센터에 비해 초기 비용 없고 스마트 고객 센터 구축 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;흐름 : 고객 전화시 Connect가 전화 받고 Lex로 스트리밍, Lex는 람다를 부르고 CRM과 연결&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Comprehend&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이해하는 서비스.. 자연어를 처리하는 NLP 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 텍스트에서 인사이트와 관계를 도출&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 감정분석, 특정 키워드 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 토큰화와 품사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 주제에 따라 정리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 구조화 되지 않은 데이터를 구조화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 고객과 상호작용 분석.. BI를 얻을 수 있음, 문서를 그룹화하여 주제 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Comprehend Medical&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비정형 의료 데이터에서 유용한 정보를 탐지해서 반환하는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 의사 소견서, 퇴원 요약서, 검사 결과서 등에서 NLP로 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SageMaker&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 머신러닝 모델을 만들고 구축할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 라벨링, 모델 구축, 훈련 및 조정 및 배포까지 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Forecast&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 예측을 도와주는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 서비스로 데이터만 보는것보다 50%이상 정확.. 예측 시간을 몇 달에서 몇 시간으로 줄임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 예측이 필요한 모든 사례&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Kendra&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 문서 검색 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 문서 : text, pdf, HTML, PPT, Word, FAQ 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 문서를 인덱싱하여 ML로 작동되는 지식 인덱스를 내부적으로 구축&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 증분식 학습 가능 : 사용자의 상호 작용 및 피드백에서 학습하고 선호되는 답변을 내놓음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 검색 결과 파인튜닝 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Personalize&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실시간 맞춤화 추천&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 맞춤화된 제품 추천, 재순위화, 맞춤화된 마케팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 검색, 구매, 관심 내역으로부터 추천&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에서 데이터를 가져오거나 Amazon Personalize API를 이용해 실시간 데이터를 받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 제공되는 번들을 그대로 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Textract&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 텍스트를 추출.. 텍스트, 손글씨, 스캔을 한 문서의 데이터를 추출&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 폼, 테이블, PDF, 이미지로 부터 추출 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 금융 서비스(면허증 인식 등)&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws ml</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 머신러닝</category>
      <category>sagemaker</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/105</guid>
      <comments>https://pypystory.tistory.com/105#entry105comment</comments>
      <pubDate>Sun, 13 Oct 2024 00:28:54 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 13편 AWS Database, 데이터 및 분석 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/104</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmH8eF/btsJ344Rjpw/d3FPbVxDLtLzrql1jcn8vK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmH8eF/btsJ344Rjpw/d3FPbVxDLtLzrql1jcn8vK/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmH8eF/btsJ344Rjpw/d3FPbVxDLtLzrql1jcn8vK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmH8eF%2FbtsJ344Rjpw%2Fd3FPbVxDLtLzrql1jcn8vK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS DB 종류&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Database Types&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RDBMS&lt;/b&gt;(= SQL/OLTP(온라인트랜잭션)) : RDS, Aurora - 조인에 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NoSQL&lt;/b&gt; : DynamoDB(JSON), ElastiCache(key-value), Neptune(graphs), DocumentDB(for MongoDB), Keyspaces(for Apache Cassandra)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Object Store&lt;/b&gt; : S3(for big objescts) / Glacier(for backups)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Data Warehouse&lt;/b&gt; (=SQL 분석 / BI(비지니스 인텔리전스)) : Redshift(OLAP), Athena, EMR&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Search&lt;/b&gt; : OpenSearch(JSON) - 자유로운 텍스트, 비정형 데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Graphs&lt;/b&gt; : Neptune - 데이터 간의 관계 표시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Ledger&lt;/b&gt;(원장 DB) : Quantum Ledger DB - 트랜잭션 목록과 원장을 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Time series&lt;/b&gt;(시계열 DB) : Timestream&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리형 PostgreSQL, MySQL, Oracle, SQL Server, DB2, MariaDB, Custom&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS 인스턴스 크기와 EBS 볼륨 유형 및 크기 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지 계층에 대한 자동 확장 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 전용 복제본... 분석 시 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Muti AZ.. 고가용성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM으로 보안 관리, SG, KMS, 전송중 암호화 SSL&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동 백업 옵션.. 최대 35일(언제든 시점 복원 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수동 데이터베이스 스냅샷으로 더 길게 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 예정된 유지보수 작업이 DB에 Downtime을 가져올 수 있음.. 프로비저닝 및 업데이트 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 인증을 지원.. RDS 프록시로 이를 강제 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SM으로 자격 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 관계형 데이터베이스 저장, RDBMS, OLTP 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Aurora&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- PostgreSQL, MySQL과 호환&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Aurora는 스토리지와 컴퓨팅이 분리되어있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;스토리지&lt;/b&gt; : 3개 AZ에 6개 레플리카에 저장됨, 가용성, 자가복구, 오토스케일링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;컴퓨팅&lt;/b&gt; : 원한다면 여러개 AZ에도 가능하고 모여있기도 가능, 읽기 전용 복제본 포함 오토스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;클러스터&lt;/b&gt; : DB에 읽기 쓰기를 하기 위해, 사용자 정의된 엔드포인트 필요(리더, 라이터 엔드포인트 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS와 동일한 엔진을 쓰기에 보안 모니터링 및 유지 기능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업과 복구 옵션&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;추가 옵션&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;Aurora Serverless&lt;/b&gt; - 예측할 수 없는, 간헐적인 워크로드가 있을 때 사용, 용량 계획 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;Aurora Global&lt;/b&gt; - 글로벌 서비스에서 사용, 각 리전에 16개의 DB 읽기 인스턴스 제공.. 스토리지 복제는 1초 미만의 시간에 리전 간에 일어남, 주요 리전에 문제가 있을 때 , 두번째 리전을 새로운 주요 리전으로 승급&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;Aurora ML&lt;/b&gt; - SageMaker와 Comprehend를 오로라에서 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;Aurora DB Cloning&lt;/b&gt; - 테스트 DB나 stage DB를 쓰고 싶을 때, 빠르게 새로운 Aurora 클러스터 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : RDS와 사례는 같지만 보수는 적고 유연성은 높고, 고성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ElastiCache&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리형 Redis / Memcached.. RDS와 비슷하지만 캐싱에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 읽을 때 1ms미만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스 타입을 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클러스터 생성, 다중 AZ, 샤딩을 위한 읽기 복제본&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SG, IAM, KMS, Redis Auth로 보안 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업, 스냅샷, 지정 시간 복구 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리된 예약된 유지 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- RDS가 결합된 DB에서 캐싱 작업을 하려면 애플리케이션 코드가 ElastiCache를 활용하도록 코드 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 키-값 저장, 자주 읽는 데이터, 웹사이트 세션 데이터 저장, ElastiCache에서는 SQL 사용불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DynamoDB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 고유 기술.. ms 단위의 레이턴시 제공, 관리형 서버리스 NoSQL&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 용량 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 프로비저닝된 용량 : 시간 지나면서 점진적 증가 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 온디맨드 용량 : 프로비저닝 없이, 자동 스케일링... 워크로드 예측 어렵거나 수요 급상승할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- key-value 저장소로 ElastiCache 대체 가능(세션 데이터 저장 좋음, TTL 기능 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성 높음, 멀티 AZ, 읽기/쓰기가 완전히 분리, DynamoDB 테이블 외에도 트랜잭션 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DAX 클러스터로 DDB와 완벽히 호환되는 읽기 캐시 생성 가능.. ms 단위 읽기 레이턴시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안 인증 모두 IAM 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DDB Stream으로 이벤트 프로세싱 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 테이블 : 다수 리전에 걸쳐 active-active 복제 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업옵션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 자동 옵션 : PITR 활성화, 최장 35일까지 어떤 테이블도 복구 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 온디맨드 백업 : 백업을 장기간 보관&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- PITR 기간 안에 RCU 안쓰고도&amp;nbsp; S3로 내보내기 가능, S3에서 WCU안쓰고도 새로운 테이블로 복구 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점 : 빠르게 스키마 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 서버리스 애플리케이션 개발할 때, 각 데이터가 작을 때, 분산형 서버리스 캐시가 필요한 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키/값 으로 저장.. 객체가 클 때 유용, 여러 작은 객체들에는 별로임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스로 확장성 무한함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체 최대 크기는 5TB, 시간에 따라 계속 버저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지 계층 : 스탠다드, IA, Intelligent, Glacier... 수명 주기 정책 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;기능&lt;/b&gt; : 버저닝, 암호화, 복제, MFA-삭제, 액세스 로그&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;보안&lt;/b&gt; : IAM, 버킷 정책, ACL, 액세스 포인트, 오브젝트 람다, CORS, Object/vault Lock&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;암호화&lt;/b&gt; &lt;b&gt;매커니즘&lt;/b&gt; : SSE-S3, SSE-KMS, SSE-C, 클라이언트 측, 전송중 TLS, 기본 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;배치 작업&lt;/b&gt; : S3 버킷 암호화, 다른 버킷으로 복제 등 각 객체에 대해 작업할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;성능&lt;/b&gt; : 파일 병렬식 업로드(멀티파트 업로드), 전송 가속화(다른 리전으로 더 빠르게 전송), S3 Select(필요한 데이터만 검색)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;자동화&lt;/b&gt; : S3 이벤트 알림 (SNS, SQS, Lambda, EventBridge)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;사례&lt;/b&gt; : 정적파일, 큰 파일의 키-값 저장, 웹사이트 호스팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DocumentDB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MongoDB의 Aurora버전... NoSQL DB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MongoDB는 JSON 데이터를 저장, 쿼리, 인덱스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Aurora와 비슷한 배포 개념을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형 DB,유용성 높고 3개 AZ에 나눠서 복제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동으로 10GB까지 확장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 수백만개의 요청을 작업할 수 있도록 확장되도록 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Neptune&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 그래프 DB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소셜 네트워크와 같은 그래프 데이터 세트를 다룰 때, 훌륭한 DB 선택이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 3개의 AZ에 걸쳐 최대 15개의 읽기 전용 복제본 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고도로 연결된 데이터 세트 애플리케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복잡하고 어려운 쿼리를 그래프 데이터 세트 위에서 실행하도록 최적화되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB에 수십억 개의 관계를 저장하고 ms 단위의 지연시간으로 그래프를 쿼리할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지식 그래프를 저장하는데도 적합(위키피디아 DB.. 모든 위키피디아 문서가 서로 연결)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;사례&lt;/b&gt; : 사기 탐지, 추천 엔진, 소셜 네트워킹&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Neptune Stream&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 그래프 데이터 변경에 대해, 실시간을 정렬된 데이터 시퀀스 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 변경사항이 즉시 Neptune 스트림에 반영됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 해당 스트림에는 중복이 없고, 변경 사항이 엄격하게 순서대로 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스트림 데이터는 HTTP REST API를 통해 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;사례&lt;/b&gt; : 그래프 데이터에서 일부 변경 사항이 발생할 때 알림을 보냄, 데이터를 다른 데이터 저장소와 동기화할 때 사용, 냅튠 클러스터의 데이터를 여러 지역에 걸쳐 복제할 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Keyspaces&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS의 관리형 Apache Cassandra를 보조(* Cassandra는 오픈 소스 NoSQL 분산 DB)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스, 확장성과 가용성 높고, AWS 완전 관리형&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 트래픽에 따라 테이블 자동 확장/축소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 AZ에 걸쳐 세 번 복제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CQL이라는 카산드라 쿼리 언어로 쿼리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연 시간 10ms 미만으로 짧고, 초당 수천 건의 요청 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 용량 모드 : 프로비저닝 모드, 온디멘드 모드 (DynamoDB와 동일)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호화, 백업 기능, PITR 최대 35일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : IoT 장치 정보, 시계열 데이터 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;QLDB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Quantum Ledger DB(* Ledger(원장) 금융 트랜잭션을 기록하는 장부)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형, 서버리스, 가용성, 3개 AZ에 복제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 데이터를 시간에 따라 모든 변경 내역을 검토하는데 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 불변 시스템(쓰면 수정 삭제 불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내부적으로 저널 존재.. 저널에는 수정 시퀀스가 있음.. 수정될 때마다 암호화 해시가 계산됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 금융 트랜잭션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반 원장 블록체인 프레임워크보다 2-3배 성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL로 데이터 관리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon 관리형 블록체인과 차이점 : QLDB는 탈중앙화의 개념이 없음(중앙 DB에서만 저널작성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Timestream&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시계열 DB (* 시계열 : 시간정보를 포함하는 포인트들의 모음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형, 빠르고, 확장성 있는 서버리스 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB의 용량을 자동으로 확장 축소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 매일 수조건의 데이터 분석/저장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시계열 데이터에 대해서 훨씬 빠르고 저렴함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리를 예약하고, 다중 척도 레코드도 얻을 수 있음, SQL과 완벽히 호환됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최신 데이터는 메모리에 저장, 과거 데이터는 스토리지 계층에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시계열 분석 기능으로 거의 실시간으로 데이터 분석 및 패턴을 찾음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전송 중 암호화, 저장 암호화 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : IoT 애플리케이션, 운영 애플리케이션, 실시간 분석 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;아키텍처 &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. AWS IoT(사물인터넷)에서 데이터를받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Kinesis Data Stream의 데이터도 람다를 통해서 받을 수 있음, Prometheus, telegraf도 연결 가능, Kinesis Data Analytics For Apache Flink를 통해서도 전달 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Timestream은 QuickSight, SageMaker, Grafana 등 표준 JDBC, SQL과 호환 가능한 애플리케이션에 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;데이터 &amp;amp; 분석&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Athena&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 버킷에 저장된 데이터 분석에 사용하는 서버리스 쿼리 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 표준 SQL 언어로 파일을 쿼리해야함(Presto 엔진에 빌드됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 버킷에 데이터가 올라가면, 데이터를 옮기지 않고, Athena로 S3에서 데이터를 쿼리하고 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CSV, JSON, ORC, Avro, Parquet 등 다양한 형식을 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스캔된 데이터 TB당 5$ 고정가격&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon Quicksight와 같이 쓸 일 많음.. 보고서와 대시보드 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 임시쿼리수행, BI 분석 및 보고, AWS 서비스에서 발생하는 모든 로그를 쿼리하고 분석 가능( VPC 흐름 로그, LB 로그, CloudTrail 추적 등 해당)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 서버리스 SQL 엔진을 사용한 S3 데이터 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`성능 향상&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용을 지불할 때, 열 기반 데이터를 쓰면 필요한 열만 스캔하기에 비용 절감 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Apache Parquet or ORC가 권장됨... 성능도 향상됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Glue를 쓰면 CSV와 Parquet 간의 데이터를 변환하는데 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 압축해 더 적게 검색해야 비용 절감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 열을 항상 쿼리한다면, 데이터 세트를 파티션하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - *파티션 : S3버킷에 있는 전체 경로를 슬래시로 분할&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 각 슬래시에 다른 열 이름을 붙여, 열별로 특정 값을 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 정확히 어느폴더에서 데이터를 가져올지 알 수 있음.. 폴더 이름을 연/월/일 로 나누는 느낌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 큰 파일(&amp;gt;128MB)을 사용해서 오버헤드를 최소화하면 성능 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;연합 쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Athena는 S3 뿐 아니라 어떤 SQL 쿼리든 사용 가능... 관계/비관계형, 객체, 온프레미스 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 원본 커넥터를 이용하면됨.. 원본 커넥터는 람다 함수로 다른 서비스에서 연합 쿼리 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - CloudWatch Logs, DynamoDB, RDS 등에서 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 쿼리를 조인할 수도 있음.. 결과를 S3에 저장도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Redshift&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB인 동시에 분석 엔진임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- PostgreSQL에 기반해있지만, OLTP에는 사용되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OLAP(온라인 분석 처리)유형의 DB.. 분석과 데이터 웨어하우징에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 데이터 웨어하우스보다 10배 좋은 성능, PB의 데이터로 확대가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Redshift에 데이터 넣으면 순식간에 무작위화 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 열 기반(Columnar) 스토리지로 사용... 행 기반과 달리 병렬 쿼리 엔진이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Redshift 클러스터에 공급한 인스턴스만큼 비용을 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리 수행을 위해서 SQL 문장을 곧바로 사용하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Quicksight나 Tableau 같은 BI 툴은 Redshift와 통합됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Athena와 달리 Redshift는 S3로부터 모든 데이터를 로드해야하고, 로드 후에는 쿼리가 더 빠름.. 더 빠른 조인 가능... Redshift에는 인덱스가 있고, 고성능 데이터 웨어하우스를 위해 인덱스를 빌드함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3의 ad hoc(즉석) 쿼리라면 Athena가 좋고, 집중적인 데이터 웨어하우징(복잡한 쿼리, 조인 집합)에는 Redshift가 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redshift 클러스터&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;리더 노드 : 쿼리 계획과 결과 집합을 시킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;계산 노드 : 쿼리를 수행하고 결과를 리더에게 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 노드 사이즈를 사전에 공급해야하고, 비용 절감을 위해 예약 인스턴스 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스냅샷과 DR&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대부분 클러스터에 대해 싱글 AZ이지만, 특정 클러스터 유형에 대해 멀티-AZ 모드 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 싱글AZ일 때는 피해복구를 위해 스냅샷 사용 권장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷은 S3에 내부적으로 저장되고 증가함(변화만 저장)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷 모드 : 수동 / 자동(8시간 마다 / 5GB 마다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷을 자동으로 복사하도록 구성 가능(해당 클러스터에서 다른 AWS 리전으로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;데이터 수집 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Kinesis Data Firehose&lt;/b&gt; : S3에 데이터가 저장되고, Frehose가 자동적으로 S3 복사명령을 내려서 Redshift로 옮김&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;S3 COPY 명령&lt;/b&gt; : S3에서 바로 IAM 역할을 이용해서 Redshift로 복사(데이터 이동은 인터넷/VPC 둘다 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 인스턴스 JDBC 드라이버&lt;/b&gt; : EC2에서 바로 작성.. 이때는 큰 묶음의 데이터를 작성하는 것이 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Redshift Spectrum&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 데이터가 있을 때, Redshift로 로드하지 않고 분석만 하고 싶을 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 더 많은 처리량을 갖고 싶을 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리를 시작할 수 있는 Redshift 클러스터가 이미 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리를 시작하면 쿼리가 S3에 있는 데이터로 쿼리를 수행할 수천개의 Redshift Spectrum 노드로 제출됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리 - Redshift 클러스터 - 리더 노드 - 계산 노드 - Redshift Spectrum - S3 순서로 전달되고, 결과는 다시 병합되어 역순으로 돌아옴... 데이터 로드가 필요없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OpenSearch(ElasticSearch)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB에서 DB의 기본키나 인덱스만을 이용해서 쿼리를 할 수 있었는데, OpenSearch에서는 어떤 필드로도 찾기를 할 수 있고, 부분 매칭도 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션에서 검색 기능을 제공하는 방식 널리 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 분석적 쿼리에도 사용 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Kinesis Data Firehose, AWS IoT, CloudWatch Logs 또는 커스텀 빌드 앱 등 다양한 데이터 받기 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 보안 : Cognito, IAM, KMS, TLS 지원&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- OpenSearch 대시보드로 데이터 시각화 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;클러스터 모드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 관리형 클러스터 모드 : 실제 물리적인 인스턴스가 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 서버리스 클러스터 : 스케일링부터 운영까지 모두 AWS에서 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자체 쿼리 언어 존재.. 플러그인으로 SQL 호환 활성화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;아키텍처 예시 패턴1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. DynamoDB에 사용자들이 데이터를 CRUD&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. DynamoDB Stream에 전송되고, 람다 함수가 그걸 잡아서 OpenSearch에 삽입&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 애플리케이션에서 OpenSearch를 이용해서 특정한 항목 검색 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 항목 ID를 획득하면 그걸 DynamoDB에 호출해서 실제로 그 항목을 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; 아키텍처 예시 패턴 2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. CloudWatch Logs에서 Subscription Filter로 람다 함수 or Kinesis Data Firehose에 전송 후 실시간으로&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;OpenSearch에 주입&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 이 과정에서 Firehose를 이용하면 람다를 붙여서 데이터 변환도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EMR&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EMR (Elastic MapReduce) : 빅데이터 작업을 위한 하둡 클러스터 생성에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하둡 클러스터는 수백개의 EC2 인스턴스로 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EMR는 여러 빅데이터 전문가 도구의&amp;nbsp; 프로비저닝과 구성 제공(Apache Spark, HBase, Presto Flink)..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전체 클러스터를 오토스케일링, 스팟 인스턴스와도 통합되어 가격 할인 해택 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 데이터 처리, ML, 웹 인덱싱, 빅데이터&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;노드 유형&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마스터 노드: 클러스터 관리, 다른 노드의 상태 조정, 장기 실행 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;코어 노드 : 태스크 실행, 데이터 저장, 장기 실행 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;태스크 노드 : 태스크만 실행, 보통 스팟 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구매 옵션&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;온디멘드&lt;/b&gt; : 신뢰할 수 있고, 예측 가능한 워크로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;예약&lt;/b&gt; : 비용 절약 가능.. 가능한 경우 자동으로 예약 인스턴스 사용.. 마스터나 코어 노드에 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;스팟&lt;/b&gt; : 태스크 노드에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EMR에서 배포할 때는 장기 실행 클러스터를 사용해서 예약 인스턴스를 사용하거나, 임시로 사용하고 분석 완료되면 삭제할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;QuickSight&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스 ML 기반 BI 서비스.. 대화형 대시보드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 빠르게 오토스케일링 가능, 웹사이트에 임베드 가능, 세션 당 비용지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 비즈니스 분석, 시각화, 임시분석, 데이터로 BI 획득&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다양한 데이터 소스와 연결, salesforce/Jira 등 서드파티 SW와도 통합, teradata와 같은 JDBC 프로토콜 쓰는 타사 DB와도 통합됨, excel, csv, json 과 같은 데이터 소스 가져올 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SPICE 엔진 : 인메모리 연산 엔진으로 QuickSight로 데이터를 직접 가져올 때 사용.. 다른 DB에 연결되있을 때는 사용 안함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 권한이 없는 사용자에게 특정 열이 표시되지 않게 열 수준 보안(CLS) 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;대시보드 &amp;amp; 분석&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 정의(스탠다드 버전), 그룹 정의(엔터프라이즈 버전)... IAM 사용자와 다르고 QuickSight에 한정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대시보드는 읽기 전용 스냅샷.. 분석을 위해 필터, 매개변수 제어, 정렬 옵션 등이 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 사용자 또는 그룹과 대시보드 공유.. 권한에 따라 기본 데이터 볼 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Glue&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 추출과 변환, 로드(ETL) 서비스를 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 분석을 위해 데이터를 준비하고 변환하는데 매우 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 서버리스 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 사례1 : S3/RDS에 있는 데이터를 Redshift로 로드할 경우 Glue로 변환해서 로드 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 사례2 : 데이터를 Parquet(열 기반 데이터) 형식으로 변환.. Athena 등에서 효율적으로 사용하기 위함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Glue Data Catalog&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 세트의 카탈로그는 Glue 데이터 크롤러를 실행해 S3, RDS, DDB, JDBC 호환 DB에서 데이터 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 크롤러는 모든 메타데이터를 Glue 카탈로그에 기록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Athena/Redshift Spectrum/EMR에서 데이터와 스키마를 검색할 때, 백그라운드에서 Glue Data Catalog를 활용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`Glue Job Bookmarks&lt;/b&gt; : 새 ETL 작업 시작시, 이전 데이터의 재처리를 방지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Glue Elastic View&lt;/b&gt; :&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL을 사용해 여러 데이터 스토어의 데이터를 결합하고 복제함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) RDS, Aurora, S3에 걸친 뷰(가상테이블)를 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 커스텀 코드 지원 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Glue가 원본 데이터의 변경 사항을 모니터링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Glue DataBrew&lt;/b&gt; : 사전 정의된 변환을 사용해 데이터 정리 및 정규화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Glue Studio&lt;/b&gt; : Glue에서 ETL 작업을 생성, 실행, 모니터링하는 GUI&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Glue Streaming ETL&lt;/b&gt; :&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Apache Spark Structured Streaming을 위해 빌드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ETL 작업을 배치 작업이 아닌 스트리밍 작업으로 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kinesis Data Streaming, Kafka, MSK에서 이걸로 데이터를 읽을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lake Formation&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 레이크 생성을 도움 (*데이터 레이크 : 데이터 분석을 위해 모든 데이터를 한곳으로 모아주는 중앙 집중식 저장소)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 검색, 정제, 변환, 주입을 도움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 수집, 정제, 카탈로깅, 복제 같은 복잡한 수작업을 자동화하고, ML 변환 기능으로 중복제거를 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정형/비정형 데이터 소스 통합 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 블루프린트 제공(마이그레이션 도와줌) : S3, RDS, 온프레미스 관계형 DB, NoSQL 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션에서 행, 열 수준의 세분화된 액세스 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Lake Formation은 AWS Glue 위에 빌드되는 계층&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Lake Formation 내에는 '소스 크롤러', 'ETL 및 데이터 준비 도구', '데이터 카탈로깅' 도구 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Athena, Redshift, EMR, Apache Spark 등에서 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 장점 : 중앙화된 권한을 가짐.. 데이터 소스와 분석도구 사이에서 '액세스 제어 기능'과 '열 및 행 수준 보안'을 제공하기에 읽기 권한 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Kinesis Data Analytics&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SQL 애플리케이션용 - 레거시로 KDF 읽을 때 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kinesis Data Streams/Firehose에서 데이터를 읽어온다음 SQL 문을 적용하여 실시간 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 위 과정에서 S3 참조 데이터를 조인할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 결과를 KDF로 보내면 S3, Redshift, OpenSearch 에 보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 결과를 KDS에 보내면 EC2 애플리케이션이나 람다로 보내서 실시간 처리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 시계열 분석, 실시간 대시보드, 실시간 지표&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Apache Flink용 - 권장&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Flink에서는 Java, scala, SQL로 스트리밍 데이터를 처리, 분석할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Flink는 코드로 작성해야하는 애플리케이션임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KDS나 MSK로부터 데이터를 받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 클러스터로 Apache Flink 애플리케이션 실행 가능.. 자동 프로비저닝, 병렬연산, 오토스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 체크포인트와 스냅샷 백업 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 표준 SQL보다 강력해서 고급 쿼리 능력이 필요하거나, 스트리밍 데이터를 읽어야할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, KDF 데이터를 읽지 못함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MSK&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon Managed Streaming for Apache Kafka.. Kafka는 Amazon Kinesis의 대안.. 데이터를 스트리밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 카프카 클러스터... 그때그때 클러스터를 생성, 업데이트, 삭제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MFK는 클러스터 내 브로커 노드와 Zookeeper 브로커 노드를 생성하고 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고가용성을 위해 VPC의 클러스터를 최대 3개의 멀티-AZ로 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반 카프카 장애를 자동 복구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EBS 볼륨에 데이터 저장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;MSK 서버리스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버 프로비저닝이나 용량 관리 필요없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Apache Kafka란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 스트리밍하는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kafka 클러스터는 여러 브로커로 구성되고, 데이터를 생산하는 생산자(Kinesis, IoT, RDS 등)는 데이터를 클러스터에 주입함... Kafka 주제로 데이터를 전송하면, 해당 데이터는 다른 브로커로 완전 복제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kafka 주제는 데이터를 스트리밍하고, 소비자는 데이터를 소비하기 위해 주제를 폴링함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터는 EMR, S3, SageMaker, Kinesis, RDS 등으로 보내짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Kinesis과의 차이점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Kinesis Data Streams&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1MB 메시지 크기 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드로 데이터를 스트리밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 용량을 확장하려면 샤드 분할.. 축소하려면 샤드 병합을 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- TLS 전송 중 암호화.. KMS 저장데이터 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Amazon MSK&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1MB가 기본값, 더 큰 메시지 보존을 위해 늘릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티션을 이용한 Kafka 주제를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티션 추가로 주제 확장만 가능.. 제거는 불가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 평문과 TLS 전송 중 암호화.. KMS 저장데이터 암호화&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws kafka</category>
      <category>aws neptune</category>
      <category>aws opensearch</category>
      <category>aws redshift</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 데이터 분석 도구</category>
      <category>aws 데이터베이스 종류 비교</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/104</guid>
      <comments>https://pypystory.tistory.com/104#entry104comment</comments>
      <pubDate>Sat, 12 Oct 2024 23:43:19 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 12편 서버리스, lambda, DynamoDB, API Gateway, Cognito - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/103</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Oyu8G/btsJ2Tb72fU/5VwWrNecTK4aKP8tQawHM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Oyu8G/btsJ2Tb72fU/5VwWrNecTK4aKP8tQawHM0/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Oyu8G/btsJ2Tb72fU/5VwWrNecTK4aKP8tQawHM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOyu8G%2FbtsJ2Tb72fU%2F5VwWrNecTK4aKP8tQawHM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;서버리스&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 개발자가 서버를 관리할 필요 없음(서버가 없는건 아님)... 코드(함수)만 배치하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원래는 FaaS를 의미.. AWS lambda로 시작된 서버리스는 현재 원격 관리되는 모든 것을 포함(서버를 프로비저닝 하지 않는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다, DynamoDB, Cognito, API Gateway, S3, SNS &amp;amp; SQS, Kinesis Data Firehose, Aurora Serverless, Fargate 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Lambda&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;lambda란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다는 가상의 함수로 서버를 관리할 필요없이 코드를 프로비저닝하면 함수가 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행 시간 제한 (최대 15분) 이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온디맨드로 실행 - 필요할 때만 실행되고, 함수가 실행되는 동안만 비용 청구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동화된 스케일링.. AWS가 자동으로 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 요금 계산 쉬움.. 호출 횟수와 컴퓨팅 시간으로만 청구(프리티어에서도 넉넉함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 언어 지원, 여러 AWS 서비스와 통합됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모니터링 쉬움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 함수당 10GB 램을 추가로 프로비저닝할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RAM을 늘리면 CPU와 네트워크의 품질이 함께 향상됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;지원하는 언어&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 웬만한 언어 다 가능, Custom Runtime API있어서 오픈 소스로 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- lambda 컨테이너 이미지 지원... 컨테이너 이미지가 람다 런타임 API를 구현해야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 보통은 ECS나 Fargate에서 컨테이너 실행&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AWS 서비스와 통합&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- API Gateway : REST API를 생성하고 람다 함수를 호출&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Kinesis : 람다로 데이터를 변환&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- DynamoDB : 트리거를 생성할 때 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- S3 : 람다함수의 트리거로 작동&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CloudFront : lambda+edge&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- EventBridge : 자동화를 실행&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CloudWatch logs&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- SNS, SQS : 소비자로 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Cognito : 사용자가 OO에 로그인할 때마다 트리거&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사례&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;서버리스 썸네일 생성 - 반응형 아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;1. S3버킷에 새 이미지가 업로드되면 람다함수를 트리거&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;2. 람다 함수에서 썸네일 생성&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;3. 다른 S3 버킷에 생성된 썸네일 푸시 + DynamoDB에 메타데이터 저장&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;서버리스 cron 작업&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;1. EventBridge 규칙 생성&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;2. N 시간마다 람다 함수 실행&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lambda 한도&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;실행 한도&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 메모리 할당량 : 128MB~10GB&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 최대 실행 시간 : 15분&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 환경변수 : 4KB&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- /tmp 디스크 용량 : 최대 10GB&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 1000개까지 동시 실행 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;배포 한도&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 압축 시 50 MB / 압축 안하면 250MB 까지&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 시작할 때 큰 파일이 있으면 /tmp 디렉터리 이용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 환경변수 : 4KB&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lambda SnapStart&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;-&amp;nbsp; 함수 성능을 높이기 위해 사용.. 자바 11 이후 버전에 대해 무료로 10배 이상 성능 향상&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- SnapStart 없다면 자바로된 함수 실행시 '코드 초기화 - 호출 - 종료'의 단계&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- SnapStart 활성화 시 함수가 미리 초기화된 상태에서 호출됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;원리&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 람다가 함수를 초기화 한 뒤, 메모리와 초기화된 함수의 디스크 상태의 스냅샷 생성&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 스냅샷이 저지연 액세스를 위해 캐시됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lambda@Edge &amp;amp; CloudFront 함수&lt;/b&gt;&lt;/h3&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;엣지 사용자 지정&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CloudFront를 사용하면 특정 리전이 아닌 엣지 로케이션을 통해 콘텐츠를 배포함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 애플리케이션에 도달하기 전에 엣지에서 로직을 실행하도록 요구하는 경우가 있는데, 이때 엣지함수를 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ CloudFront 배포시에 연결 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사용자 근처에서 실행되어 지연 시간 줄이는 목적&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CloudFront 함수와 Lambda@Edge 2가지 종류가 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사례 : CDN 컨텐츠를 사용자 지정 하는 경우&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;세부사례&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 웹사이트 보안과 프라이버시&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 엣지에서의 동적 웹 애플리케이션&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 검색 엔진 최적화&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 오리진 및 데이터 센터 간 지능형 경로에 활용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 엣지에서 봇 완화&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 엣지에서 실시간 이미지 변환&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- A/B 테스트&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사용자 인증 권한 부여&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사용자 우선순위 지정&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사용자 추적 및 분석&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CloudFront 동작원리&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;1. client가 CloudFront에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;뷰어 요청&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;2. CloudFront가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;오리진 요청&lt;/b&gt;을 오리진 서버에 전송&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;3. 서버가 CloudFront에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;오리진 응답&lt;/b&gt;을 보냄&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;4. CloudFront가 클라이언트에게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;뷰어 응답&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;전송&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CloudFront 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- JS로 작성된 경량 함수 뷰어 요청과 뷰어 응답을 수정할 때 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 확장성 높고 지연시간에 민감한 CDN 사용자 지정에 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 시작 시간 1ms 미만.. 초당 백만 개의 요청 처리&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CloudFront의 네이티브 기능으로 코드가 CloudFront에서 관리됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사례 : 캐시 키를 정규화, 요청/응답에 HTTP 헤더를 삽입/수정/삭제, URL을 다시 쓰거나 리디렉션, JWT 생성 혹은 검증&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Lambda@Edge&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- NodeJS나 Python으로 작성&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 초당 수천개 요청 처리&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 모든 CloudFront 요청 및 응답 변경 가능(뷰어 요청/응답, 오리진 요청/응답)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 함수는 us-east-1에서만 작성 가능 (CloudFront 배포를 관리하는 리전임)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 작성하면&amp;nbsp; CloudFront가 모든 리전에 해당 함수 복사&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 실행 시간은 상대적으로 김(몇 ms)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- CPU 메모리 증가로 여러 라이브러리 로드 가능.. 타사 라이브러리에 코드 의존 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 네트워크 액세스를 통해 외부 서비스에서 데이터를 처리 가능... 대규모 데이터 통합 수행 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 파일 시스템이나 HTTP Body에도 직접 액세스 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Lambda VPC&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 기본적으로 람다 함수 실행시 VPC 외부에서 실행... VPC 內 리소스 액세스 권한 없음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- DynamoDB와 같은 퍼블릭 리소스에는 기본적으로 접근 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- VPC에서 람다를 시작하면 내부 리소스에 접근할 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - VPC ID, 서브넷, SG 설정&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 서브넷에 ENI 생성해서 람다와 연결해야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사례 :&amp;nbsp;RDS 프록시&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 그냥 lambda에서 VPC 연결만하고 RDS를 바로 붙여서 쓰면, lambda가 생겼다 없어졌다 하면서 DB 커넷션이 늘어나서 로드가 커짐&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 이때, RDS 프록시를 이용해 연결하면, 연결을 한 곳으로 모으고 문제 해결 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- RDS 프록시는 퍼블릭 연결이 안되서 람다함수를 꼭 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;VPC 안에서&lt;span&gt; &lt;/span&gt;&lt;/span&gt;실행해야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;장점&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 연결의 풀링과 공유를 통해 확장성 향상&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 장애 발생시 페일오버 가능 및 연결성 보장(RDS, Aurora 둘다 가능)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- RDS 프록시 수준에서 IAM 연결 강제로 보안 향상&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS &amp;amp; Aurora와 Lambda 함수의 통합&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- DB 인스턴스 안에서 발생하는 '데이터 이벤트'로 람다를 직접 호출할 수도 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- RDS PostgreSQL &amp;amp; Aurora MySQL에서 지원됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- RDS DB 인스턴스로부터 람다 함수로 오는 인바운드 트래픽을 허용해줘야함(Public NAT GW, VPC 엔드포인트 등을 활용)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 네트워크 연결성이 중요 &amp;amp; 올바른 권한 필요&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- RDS Event 알림과 완전히 다름... 이 알림들은 AWS 안에서 이뤄지고 DB 인스턴스 자체에 대한 정보를 알려주는 알람이 있음(ex. 생성/정지/시작 시간 등)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- DB안에 데이터 자체에 대한 정보는 받지못함&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- DB 인스턴스, DB 스냅샷, 파라미터 그룹, 보안 그룹, 프록시, 커스텀 엔진 버전에 관한 이벤트를 구독 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 최대 5분인 근 실시간 이벤트를 받고, 그걸 SNS에 전송하거나 EventBridge를 이용할 수 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`DynamoDB&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 DB, 데이터가 다중 AZ에 복제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라우드 네이티브 NoSQL DB, AWS 독점 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트랜잭션 지원 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 수 백만 요청 처리, 수조 개의 행, 수백 TB 스토리지를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 성능은 한자리수 ms.. 일관성도 높음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM과 통합, 보안 권한부여&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 오토스케일링 가능.. 유지관리, 프로비저닝 필요없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스가 빈번한 데이터에는 Standard 클래스, 액세스가 빈번하지 않으면 IA 테이블 클래스에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블로 구성되며 DB 생성할 필요 없음, 이미 DB가 존재하는 서비스임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블을 생성하면 각 테이블에 기본 키가 부여됨... 기본 키는 생성시 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블에 무한히 행을 추가할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 항목은 속성을 가지며 속성은 열에 표시됨(속성은 나중에 추가하거나 null도 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB 항목의 최대 크기는 400KB(큰 객체 저장시엔 적합하지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다양한 타입 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 스칼라타입 - string, number, binary, boolen, null&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 문서 타입 - list, map&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 집합 타입 - string set, number set, binary set&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 스키마를 빠르게 전개해야할 때 DynamoDB 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;R/W 용량 모드 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 프로비저닝된 모드(기본)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 미리 용량 프로비저닝&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 RW 요청 수를 예측해서 미리 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로비저닝된 RCU와 WCU만큼의 비용을 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로비저닝되어 있어도 오토스케일링 가능(production 환경에서 이렇게 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 로드 예측되고, 서서히 증가하며 비용 절감을 원할 때 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 온디맨드 모드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RW 용량이 워크로드에 따라 자동으로 확장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RCU, WCU 개념 자체가 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정확히 사용한 만큼의 비용을 지불... 모든 RW에 비용 지불(2,3배 비쌈)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 워크로드를 예측할 수 없거나, 급격히 증가하는 경우에 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 수 천개의 트랜잭션을 수백만개로 1분만에 확장해야한다면 온디맨드 모드 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;심화 기능&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DynamoDB Accelerator(DAX)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB를 위한 고가용성의 완전 관리형 구결절 인메모리 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB 테이블에 읽기 작업이 많을 때, DAX 클러스터를 생성하고 데이터 캐싱하여 읽기 혼잡 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ms 수준의 지연시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DAX 클러스터는 기존 DynamoDB API와 호환됨.. 애플리케이션 로직 변경 안해도됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 캐시 TTL 변경 가능(기본 5분)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ElastiCache 아니라 DAX 사용 이유 : DAX는 DynamoDB 앞에서 개별 객체 캐시와 쿼리와 스캔 쿼리를 처리하는데 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 집계 결과를 저장할 때는 ElastiCache가 좋고, DAX는 대용량의 연산을 저장할 때 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;스트림 처리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 테이블의 모든 수정사항 스트림 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB 테이블의 변경 사항에 실시간으로 반응하는데 활용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 새로운 사용자 등록시 환영 이메일 보내기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 실시간 사용량 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 파생 테이블 삽입&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 리전간 복제(스트림에서 DynamoDB가 변경 로그를 가져오고, 이를 사용해 다른 AWS 리전에 있는 복제 테이블이 서로의 데이터를 복제할 수 있는 기능이 활성화되는 원리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. 람다함수 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 스트림 처리 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. DynamoDB Streams&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보존 기간 24h, 소비자 수 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 트리거와 함께 사용하면 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자체적으로 읽기 실행하려면 DynamoDB Stream Kinesis 어댑터 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Kinesis Data Streams&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보존 기간 1년, 소비자 수 늘어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 처리하는 방법이 많아짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;글로벌 테이블&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여러 리전 간에 복제가 가능한 테이블(양방향 복제 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복수 리전에서 짧은 시간에 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다중 활성 복제... 애플리케이션이 모든 리전에서 테이블을 읽고 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB 스트림을 활성화해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TTL 기능&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 만료 타임스탬프가 지나면 자동으로 항목을 삭제하는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 최근 항목만 저장, 규정 준수, 웹 세션 핸들링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;재해 복구&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;지정 시간 복구(PITR) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지속적인 백업 가능...&amp;nbsp;35일간 지속&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복구하면 새로운 테이블 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;온디맨드 백업&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 삭제할 때까지 보존&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DynamoDB 성능에 영향 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업을 좀 더 제대로 관리하려면 AWS Backup이용(수명 주기 정책 활성화 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리전 간 백업 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;S3와의 통합&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 테이블을 내보낼 수 있음(지정 시간 복구 기능 활성화)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon Athena 엔진으로 S3에서 쿼리 호출 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 35일 이내 어떤 시점이라도 내보낼 수 있고, 읽기 용량이나 성능에 영향 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내보내기 하여 데이터 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다시 불러오기 전에 데이터 ETL 등 대규모 변경 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내보낼 때는 DynamoDB JSON이나 ION 포멧 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;S3에서 import&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CSV, DynamoDB JSON or ION 형식으로 내보내고 새로운 테이블 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;API Gateway&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 lambad 함수를 invoke(지연 호출)하려면...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 클라이언트에 IAM 권한 부여&amp;nbsp; &amp;nbsp; 2. 로드밸런서로 HTTP 엔드포인트 제공&amp;nbsp; 3. API Gateway&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API Gateway : AWS의 서버리스 서비스로 REST API 생성 가능(클라이언트가 퍼블릭 액세스 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- lambda 함수에 요청을 프록시함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기능&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다와 통합시 인프라 관리가 필요없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- websocket 지원... 두 가지 방법의 실시간 스트리밍 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API 버저닝 핸들&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 환경 핸들링(dev, test, prod)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안에도 활용( 인증 권한부여 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API 키 생성, 클라이언트 요청이 과도할 때 요청 스로틀링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Swagger / Open API 와 같은 공통 표준을 사용하여 신속히 API 정의 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API 게이트웨이 단계에서 요청 transform 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SDK나 API 스팩을 생성, API 응답을 캐시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;통합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다를 사용하는 REST API 서버리스 애플리케이션&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTP 엔드포인트.. 속도제한, 캐싱, 유저 인증, API 키 등 기능 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어떠한 AWS API도 노출시킬 수 있음... AWS 단계 함수 워크플로우, SQS에 메시지 게시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;엔드포인트 유형&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 엣지 최적화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 클라이언트로 모든 요청이 CloudFront 엣지 로케이션을 통해 라우팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 CloudFront 리전에서 특정 리전에 있는 API Gateway에 액세스 가능&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 리전 배포&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 사용자는 API Gateway를 생성한 리전과 같은 리전에 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자체 CloudFront 배포를 생성할 수도 있음.. 이러면 엣지 최적화와 같은효과 + 캐싱 전략, CloudFront 설정에 더 많은 권한 가짐&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 프라이빗&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 내에서만 액세스... ENI 같은 VPC 엔드포인트 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;보안&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용자 식별&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM Roles : 내부 애플리케이션에서 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Cognito : 모바일/웹 애플리케이션의 외부 사용자에 대한 보안 조치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 지정 권한 부여자 : 자체 로직 실행.. 람다 함수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;HTTPS 보안&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS ACM과 통합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 엣지 최적화면 인증서는 us-east-1에 위치, 리전 배포면 인증서 리전과 그 리전이 같아야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CNAME이나 A별칭으로 도메인과도 통합해줘야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Step Function&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서버리스 워크플로를 시각적으로 구성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 함수 오케스트레이션에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시퀀싱, 병행 실행, 조건 실행, 타임아웃, 에러처리하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 람다 뿐만 아니라 EC2, ECS, 온프레미스 서버, API 게이트웨이, SQS 등 다양한 서비스와 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 워크플로우에 개입해서 승인해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 주문 이행, 데이터 처리, 웹 애플리케이션 등 구성하기 복잡한 워크플로를 시각적으로 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Cognito&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자에게 웹 및 모바일 앱과 상호작용할 수 있는 자격 증명을 부여&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반적으로 사용자들은 AWS 계정 외부에 있음... 모르는 사용자에게 자격 증명을 부여해 사용자를 인식(Cognito)할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM과 달리 Cognito는 AWS 외부 사용자를 대상으로 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 키워드 : 수백명의 사용자, 모바일 유저, SAML로 인증&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Cognito 사용자 풀&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 앱 사용자에게 가입 기능을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API Gateway 및 애플리케이션, 로드밸런서와 원활히 통합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Cognito 자격 증명 풀 (페더레이션 자격 증명)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 앱에 등록된 사용자에게 임시 AWS 자격 증명을 제공해서, 일부 AWS 리소스에 직접 액세스할 수 있도록 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Cognito 사용자 풀과 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;원활히 통합&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Cognito User Pools(CUP)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 웹/앱을 대상으로 하는 서버리스 사용자 DB&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 사용자 이름 또는 이메일, PW의 조합으로 로그인 절차 정의&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- PW 재설정 기능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 이메일 및 전화번호 검증&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- MFA&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- 소셜로그인 가능(googlem, fb)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;- API Gateway와 ALB와 연결 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ex) 유저는 Cognito에서 인증 토큰을 받고, API Gateway에 요청할 때 같이 전달.. API Gateway에서 확인하고, 사용자 자격 증명으로 변환되어 백엔드에 전달됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex2) Cognito에서 인증하고 ALB에 리스너와 룰을 이용해서 TG에 자격 증명과 함께 추가 헤더 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Cognito 자격 증명 풀 (페더레이션 자격 증명)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자에게 자격 증명을 제공함, 임시 AWS 자격 증명을 사용해 AWS 계정에 직접 액세스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자는 Cognito 사용자 풀 內 사용자일 수도 있고, 타사 로그인이 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API Gateway나 ALB 안거치고도 직접 AWS 서비스에 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자격 증명이 적용되는 IAM 정책은 Cognito 자격 증명 풀 서비스에 사전 정의&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본 IAM 역할 정의 가능.. 로그인 안되면 기본 IAM 역할 상속 받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : DynamoDB 행 수준 보안 설정 가능&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>Amazon Cognito</category>
      <category>aws api gateway</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws dynamodb</category>
      <category>AWS Lambda</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>AWS 서버리스</category>
      <category>lambda+api gateway</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/103</guid>
      <comments>https://pypystory.tistory.com/103#entry103comment</comments>
      <pubDate>Fri, 11 Oct 2024 22:41:41 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 11편 컨테이너, ECS, Fargate, ECR, EKS - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/102</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/com6ne/btsJ0OBB8ek/He8lG2iaKRL6ksr7NholIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/com6ne/btsJ0OBB8ek/He8lG2iaKRL6ksr7NholIK/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/com6ne/btsJ0OBB8ek/He8lG2iaKRL6ksr7NholIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcom6ne%2FbtsJ0OBB8ek%2FHe8lG2iaKRL6ksr7NholIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;Docker&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 앱 배포를 위한 소프트웨어로 컨테이너 기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨테이너는 앱을 패키징.. 표준화 되어 있어서 아무 OS에나 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OS와 상관없이 동일하게 실행됨.. 호환성 문제 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : MSA&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;동작 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 도커 에이전트 실행 시 Docker 컨테이너 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다수의 컨테이너가 동시에 실행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 도커 이미지는 도커 리포지토리에 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - DockerHub : 공개 리포지토리, 많은 기본 이미지를 찾을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ECR : 기본적으로 비공개 리포지토리, ECR Public Gallery라는 공개 옵션도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;도커와 가상 머신 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;도커&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 정확히 가상화 기술은 아님&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스가 호스트와 공유되어, 한 서버에서 다수의 컨테이너 공유 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 도커는 Host OS 위에 도커 데몬이 있고, 그 위에 컨테이너가 올라감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가볍게 실행되는 컨테이너라 공존 가능.. 네트워크나 데이터 공유 가능(보안 측면에선 덜 안전)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;가상머신&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가상머신은 Host OS위에 하이퍼바이저가 있고, 그 위에 게스트 OS가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 머신은 하이퍼바이저에서 실행되는 가상 머신&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가상 머신의 EC2인스턴스는 각자 분리되어 있음... 리소스 공유 안함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Dockerfile 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Build 하여 도커 이미지 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Docker 리포지토리에 푸시 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. Docker 리포지토리에서 pull 받아서 실행하면 도커 컨테이너가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS에서 도커 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ECS : 아마존 고유의 컨테이너 플랫폼&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EKS : 쿠버네틱스의 관리형 버전.. 오픈 소스 프로젝트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Fargate : 서버리스 컨테이너 플랫폼.. ECS / EKS 함께 작동 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ECR : 컨테이너 이미지 저장에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ECS&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실행시 ECS 클러스터에 ECS 테스크를 실행하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Launch Type&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 시작 유형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 클러스터가 여러 EC2 인스턴스로 구성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인프라를 직접 프로비저닝하고 유지해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각각 ECS 에이전트를 실행하는데, ECS 에이전트가 각 EC2 인스턴스를 ECS 서비스와 지정된 ECS 클러스터에 등록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 테스크를 실행하면, AWS가 컨테이너를 시작/중지 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`Fargate 시작 유형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인프라를 프로비저닝 하지 않음.. 서버리스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 태스크 정의만 있으면, 필요한 CPU, RAM에 따라 ECS 태스크를 AWS가 실행해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 확장하려면 태스크 수만 늘리면되고, EC2인스턴스를 관리할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ECS IAM Role&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 인스턴스 프로파일 역할&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 시작유형에서는 EC2 인스턴스 프로파일을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ECS agent 만이 EC2 인스턴스 프로파일을 이용해 ECS 서비스에 API 호출을 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ECS 서비스가 CloudWatch 로그에 API 호출을 해서 로깅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ECS 서비스가 ECR로부터 도커 이미지를 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 필요에 따라 시크릿 매니저나 SSM에서 민감 데이터를 참고하기도 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ECS 태스크 역할&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 태스크는 ECS 태스크 역할을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - EC2, Fargate 공통&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 각 태스크마다 각자의 특정 역할을 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 역할을 각자 만드는 이유는, 각 역할이 다른 ECS 서비스에 연결할 수 있게 하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - ECS 서비스의 '태스크 정의'에서 태스크 역할을 정함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;로드밸런서 통합&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTP나 HTTPS 엔드포인트로 ECS 태스크를 활용하기 위해 ALB 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 사용자가 ALB 사용하면 백엔드의 ECS 태스크에 직접 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NLB는 고성능을 요구하거나, AWS Private Link를 만들 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ELB(구세대)는 사용할 수는 있지만 권장되지 않음... 고급기능X, Fargate 지원 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터 볼륨(EFS)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EFS를 쓰면 둘다 호환되고, EC2 태스크에 파일시스템을 직접 마운트 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어느 AZ에서 실행되더라도 EFS에 연결되어 있다면 데이터를 공유할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Fargate + EFS로 서버리스에서 파일 시스템 지속성 확보 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : EFS+ECS로 다중 AZ가 공유하는 컨테이너의 영구 스토리지&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- * S3는 ECS에 파일 시스템으로 마운트 될 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ECS 오토스케일링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 태스크 수를 자동으로 줄이거나 늘릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 사용할 수 있는 지표 : ECS 서비스 CPU/메모리 사용률, ALB 타겟당 요청 수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대상 추적 스케일링, 단계 스케일링, 예약 스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 시작 유형이라면.. ECS 서비스 오토스케일링(태스크 레벨) != EC2 오토스케일링(EC2 인스턴스 레벨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 오토스케일링이 필요없다면, Fargate를 사용하는 것이 서비스 오토스케일링에 도움이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 시작 유형에서 EC2 인스턴스 스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASG 스케일링 : CPU 사용률 등에 맞춰 스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 클러스터 용량 공급자 사용(권장) : 새 태스크를 실행할 용량이 부족하면 자동으로 ASG 확장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ 용량 공급자는 ASG와 함께 사용, CPU/RAM이 부족할 때 EC2 인스턴스 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사례&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;EventBridge에 의해 호출된 ECS 태스크&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 사용자들이 객체를 S3 버킷에 업로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. S3버킷의 모든 Event는 EventBridge로 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. EventBridge는 ECS 태스크를 실행하기 위한 규칙 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. ECS 태스크 역할로 S3: GetObject와 DynamoDB에 결과를 전송하는 역할을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;EventBridge 스케줄러를 이용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. EventBridge는 1시간마다 ECS 태스크 생성 트리거&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. S3에 배치 프로세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SQS 큐&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 메시지가 SQS 큐로 들어오면, ECS 서비스 자체가 메시지 폴링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. SQS 큐 내 메시지 수에 따라 ECS 태스크 오토스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;EventBridge를 사용하여 ECS 클러스터 안에서 이벤트 가로채는 형태&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. ECS 태스크가 삭제될 때 이벤트 트리거&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. SNS로 관리자에게 경보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ECR&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에 도커 이미지를 저장할 수 있음... DockerHub 등 온라인 저장소 대용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Private / Public 옵션 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECR은 ECS와 완전히 통합되어 있고, 이미지는 백그라운드에서 S3에 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS 클러스터 內 EC2 인스턴스에서 ECR 이미지를 pull 해올 때는 IAM 역할 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단순히 리포지토리 기능뿐만 아니라, 이미지의 취약점 스캐닝, 버저닝, 태그 및 수명 주기 확인 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EKS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EKS란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리형 쿠버네티스 클러스터 실행하는 서비스&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 오픈소스 시스템으로 Docker로 컨테이너화한 애플리케이션의 자동 배포, 확장, 관리 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS(오픈소스 아님)와 유사하지만 사용하는 API가 다름... k8s는 여러 제공자가 지원하기에 표준화 기대&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;실행모드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 시작 모드 : EC2 인스턴스에서처럼 작업자 모드를 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Fargate 모드 : EKS 클러스터에 서버리스 컨테이너를 배포할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 회사가 온프레미스나 클라우드에서 k8s나 k8s API를 쓰고 있을 때, k8s 클러스터를 관리할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- k8s는 클라우드 애그노스틱으로 (애저, 구글 등 모든 클라우드에서 지원).. 다른 클라우드와 마이그레이션 시 솔루션이 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;형태&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 內 각 AZ에서 public/private 서브넷이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 private 서브넷 안에 여러 EKS 노드 들이 EKS Pods(ECS 태스크와 유사)를 이루고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EKS Pods는 ASG로 관리가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서로 웹에 연결해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;노드 유형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;관리형 노드 그룹&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS로 노드, 즉 EC2 인스턴스를 생성하고 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 노드는 EKS 서비스로 관리되는 ASG 그룹의 일부&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온디맨드/스팟 인스턴스 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;자체 관리형 노드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 직접 노드 설정하고 EKS 클러스터에 등록 후 ASG의 일부로서 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사전 빌드된 AMI인 Amazon EKS 최적화 AMI를 사용하면 시간절약 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온디맨드/스팟 인스턴스 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS Fargate&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유지 관리 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 노드 관리 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EKS에서 컨테이너만 실행하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터 볼륨&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- StorageClass 매니패스트(manifest, 명백한)를 지정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- CSI(컨테이너 스토리지 인터페이스)라는 규격 드라이버 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EBS나 Fargate모드가 작동하는 EFS를 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon FSx for Lustre, NetApp ONTAP 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS App Runner&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형 서비스로 규모에 따라 웹 애플리케이션, API 배포를 도움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인프라나 컨테이너, 소스 코드 등을 알 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소스 코드나 Docker 컨테이너 이미지로 원하는 구성 설정하면 App Runner가 알아서 웹 앱을 빌드하고 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API나 웹 앱이 배포된 다음엔 URL로 바로 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 오토스케일링 가능, 가용성 높음, 로드 밸런싱 및 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메시지 대기열, DB, 캐시에 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 빨리 배포해야하는 웹 앱, API, MSA... 신속한 프로덕션 배포 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에 프로덕션 애플리케이션 컨테이너를 배포할 수 있는 강력한 올인원 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;+ 그냥 코드만 올려도 빌드해서 도커 이미지로 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;+ Elastic Beanstalk이 보다 많은 설정과 유연성 제공하지만, App Runner는 &lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;모범 사례를 따라 가장 쉬운 방식으로 배포 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;+ lambda는 이벤트 기반 코드에 적합, App Runner는 지속적인 코드에 적합&lt;/span&gt;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS App Runner</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws docker 배포</category>
      <category>aws ecr</category>
      <category>aws ecs</category>
      <category>aws fargate</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 쿠버네티스</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/102</guid>
      <comments>https://pypystory.tistory.com/102#entry102comment</comments>
      <pubDate>Thu, 10 Oct 2024 21:03:36 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 10편 SQS, SNS, Kinesis, Amazon MQ - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/101</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfSns4/btsJYGKH6U2/h8Uxv9Vnb4YJtR503bbDQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfSns4/btsJYGKH6U2/h8Uxv9Vnb4YJtR503bbDQ1/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfSns4/btsJYGKH6U2/h8Uxv9Vnb4YJtR503bbDQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfSns4%2FbtsJYGKH6U2%2Fh8Uxv9Vnb4YJtR503bbDQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&lt;/p&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;b&gt;메시징&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러개의 애플리케이션을 배포할 때, 서로가 통신할 방법이 필요함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동기 : 직접적으로 연결, 트래픽이 늘면 동기일 때 문제가 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비동기 / 이벤트기반 : 직접적으로 소통 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서비스 종류&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS : 대기열 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS : pub/sub 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kinesis : 실시간 스트리밍, 대용량 데이터&lt;/p&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;b&gt;SQS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;표준 큐 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS 대기열에는 메시지가 들어감... 큐는 생산자와 소비자를 분리하는 버퍼 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자(Producer) : SQS 대기열에 메시지를 보내는 주체, 여러개 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자(Consumer) : 메시지를 폴링(수신) 하는 대상&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;표준 대기열용 SQS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에서 가장 오래된 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형 서비스로 애플리케이션을 분리하는데 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 무제한 처리량을 얻을 수 있음, 처리량과 대기열에 있는 메시지 수에 제한이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 메시지는 수명이 짧음(기본 4일, 최대 14일)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기간 내에 소비하고 삭제해야하는데, 안쓰면 소실됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연시간 짧음 10ms 미만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메시지 당 256KB 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 중복 메시지가 있을 수 있음(적어도 한 번의 전송)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최선의 오더 메시지를 보냄(품절된 메시지를 보낼 수도 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;생산자&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SDK를 사용해서 메시지를 보냄(SendMessage API)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메시지에는 주문 ID, 소비자 ID, 기타 속성이 포함됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;소비자&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스, 온프레미스 서버, 람다 함수 등에서 읽어감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자는 SQS 메시지를 폴링함(자기 앞으로 온 메시지가 있는지 질의, 한번에 최대 10개의 메시지를 받음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자는 메시지 처리 후 DeleteMessage API로 대기열에서 삭제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자는 수평 확장을 해서 처리량을 개선할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASG와 조합이 좋음 (대기열의 길이로 CloudWatch 알람을 설정해서 스케일링)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;아키텍처 예시&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;요청 - 프론트엔드 ASG - SQS로 SendMessage - 백엔드 프로세싱 어플리케이션 ASG에서 polling - S3 넣기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SQS 보안&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전송 중 암호화 HTTPS API&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS key로 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트 측 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Access Controls : IAM 정책&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS 액세스 정책 : S3 정책과 유사함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`메시지 가시성 시간 초과&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자가 메시지를 폴링하면 다른 소비자들에게 보이지 않게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 '가시성 시간 초과'는 30초로 30초 동안 처리되어야한다는 뜻, 이 동안은 다른 소비자들은 못봄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이 시간이 지나면 다시 대기열에 메시지를 넣음(즉, 2번 처리될 수도 있는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자가 이 메시지를 처리하는데 시간이 더 필요한 걸 알고 있다면, 'ChangeMessageVisibility API'를 호출해서 시간을 더 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;롱 폴링&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;*롱 폴링 : 소비자가 대기열에 메시지를 요청했는데 아무것도 없다면 대기하게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 목적 : 지연 시간 줄이기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~20초로 구성가능.. 길수록 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;구성방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 대기열 레벨에서 구성하여 폴링하는 아무 소비자로부터 롱 폴링 활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 소비자가 스스로 WaitTimeSeconds를 지정하여 롱 폴링하도록 선택 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;FIFO 큐&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 선출선입.. 순서가 확실하게 보장됨, 소비자가 정확히 동일한 순서로 메시지를 받게해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 처리량에 한계가 있음.. 묶음이 아닐 때 300msg/s, 묶음일 때 3000msg/s&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 중복을 제거하여 정확히 한번만 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이름에 .fifo를 붙여야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SQS+ASG&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS+ASG 조합에서 ASG 內 EC2에서 메시지를 폴링함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대기열 크기에 따라 스캐일링을 하기 위함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 사례 : 수많은 주문을 DB에 저장할 때, 빠른 속도로 쓰여야하는데, SQS를 버퍼로 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 앞뒤로 ASG를 넣어서 쓰기 속도를 조정하고, 안정적으로 DB에 쓸 수 있음.. 쓰기가 성공한걸 확인하고, 큐에서 지우면 되기 때문에 확인작업도 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 사례2 : 디커플링 어플리케이션 티어... 프론트 - SQS - 백엔드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SNS&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메시지 하나를 여러 수신자에 보낼 때, 직접 통합을 쓸 수 있음..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Pub / Sub (게시/구독) 패턴을 써서 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메시지를 SNS 주제로 게시 -&amp;gt; 주제에는 많은 구독자가 있음 -&amp;gt; SNS 주제에서 해당 메시지를 수신&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon SNS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트 생산자는 오직 한 SNS 주제(topic)에만 메시지를 보냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이벤트 소비자(구독자)는 알람을 받으려는 사람... 해당 주제로부터 모두 메시지를 받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 주제별로 최대 1,200만 이상의 구독자 가능, 계정당 10만개 주제 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 구독자 : 이메일, SMS, 모바일 알람, HTTPS 엔드포인트, SQS, 람다, Kinesis Data Firehose&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자 : AWS에서 알람이 발생할 만한 거&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SDK로 주제 배포 : 주제 생성 - 구독 생성 - SNS 주제에 게시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모바일앱 SDK로 직접 배포 : 플랫폼 애플리케이션 - 플랫폼 엔드포인트 - 플랫폼 엔드포인트에 게시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ Google, GCM, Apple ARNS, Amazon ADM&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안 : 전송 중 보안(https), KMS 키, 클라이언트 측 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 제어 : IAM 정책 중심&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SNS 액세스 정책 : S3 정책과 유사함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Fan Out(팬아웃) 패턴&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다수의 SQS 대기열로 메시지를 보내려할 때, 개별적으로 전송하지 않고, SNS 토픽으로 한 번 메시지를 전송하고, SQS 큐들을 메시지를 받는 구독자로 두는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전히 분리된 모델, 데이터 손실없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS로 데이터 지속성, 지연 처리, 작업 재시도 효과&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요에 따라 SQS 대기열을 SNS 주제의 구독자로 더 추가 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS 대기열 접근 정책을 SNS 토픽이 '쓰기' 할 수 있도록 허용해둬야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교차 리전 배송 : 한 리전의 SNS 토픽이 다른 리전의 SQS 대기열에 메시지를 보내는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : S3 이벤트(접두사에 따라 한 개의 이벤트 규칙만 가능함) 를 여러 대기열로 보낼 때, 이벤트를 SNS 주제로 보내고, 여러 대기열이 팬 아웃 패턴으로 구독하게 하면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례2 : Kinesis Data Firehose로 SNS에서 S3로 직접 데이터를 보낼 수 있음.. SNS가 KDF와 직접적으로 통합되어 있기 때문에 SNS-KDF-S3 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; FIFO 주제 &lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 순서대로, 중복제거 가능, SQS FIFO 큐와 통합하여 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS FIFO와 동일한 처리량&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;메시지 필터링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- JSON 필터링 정책 적용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각각의 구독자에 특정 메시지만 들어가도록 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`Kinesis&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실시간 스트리밍 데이터를 손쉽게 수집하고, 처리하여 분석 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 실시간 데이터 : 애플리케이션 로그, 계측, 웹사이트 클릭 스트림, IoT 원격 측정 데이터...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4가지로 구성됨&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Kinesis Data Streams : 데이터 스트림을 수집하여 처리하고 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Kinesis Data Firehose : 데이터 스트림을 AWS 내부/외부의 데이터 저장소로 읽어드림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. Kinesis Data Analytics : SQL 언어나 Apache Flink를 활용하여 데이터 스트림 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. Kinesis Video Stream : 비디오 스트림 수집,처리,저장 (시험X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Kinesis Data Streams &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시스템에서 큰 규모의 데이터 흐름을 다루는 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러개의 샤드로 구성(1~N번까지 번호가 매겨짐.. 사전에 프로비저닝)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터는 모든 샤드에 분배됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드는 데이터 수집률이나 소비율 측면에서 스트림 용량을 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;성능&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자는 레코드를 전달함 (레코드는 파티션 키(이용할 샤드 결정)와 최대 1MB의 데이터 블롭(값 자체)으로 구성)... 샤드 당 1MB/s 혹은 1000메시지/s 를 전달가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자는 레코드를 받음 (파티션 키, 시퀀스 번호(샤드에서의 위치 정보), 데이터 블롭으로 구성)... 2MB/s로 모든 소비자가 공유 혹은 소비자마다 샤드당 2MB/s 받기 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보존 기간은 1일~365일... 데이터를 다시 처리하거나 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 불변성, 한번 Kinesis로 데이터가 들어오면 삭제할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 스트림으로 메시지를 전송하면 파티션 키가 생기는데, 파티션 키가 같으면 같은 샤드로 들어가서 키를 기반으로 데이터 정렬 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자는 SDK, KPL(Kinesis Producer Library), Kinesis Agent로 데이터 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자는 KCL, SDK로 직접 작성 / 람다, Kinesis Data Firehose, Kinesis Data Analytics 활용도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;용량 유형&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 프로비저닝 유형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로비저닝할 샤드 수를 정하고, API로 수동 조절&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 샤드는 초당 1MB 혹은 1,000개 레코드 받고, 초당 2MB 출력 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드를 늘리면 비용 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 온디멘드 유형&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시간에 따라 용량이 조정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 초당 4MB 혹은 4,000개의 레코드 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 30일 동안 관측한 최대 처리량에 기반하여 자동으로 조정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시간당 스트림당 송수신 데이터양에 따라 비용 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;보안&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 정책으로 샤드를 생성하거나 샤드에서 읽는 권한 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTPS 전송중 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS 미사용 데이터 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트 측 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 엔드포인트를 쓸 수 있어서, 프라이빗 서브넷 인스턴스에서 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- API 요청을 CloudTrail로 감시 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Kinesis Data Firehose&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자로부터 레코드를 받고, 원한다면 람다함수로 데이터를 변환하여, 일괄적으로 작성(소비)함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 수신처 : S3, RedShift(웨어하우징 데이터베이스.. S3에 먼저 작성하고 복사 명령이 실행됨), OpenSearch&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ 서드파티도 가능 : datadog, splunk, mongoDB...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ HTTP 엔드포인트가 있는 커스텀 수신처&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특징&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전 관리형, 자동 스케일링, 서버리스&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 AWS 수신처로 보낼 수 있고, 타사 파트너나 HTTP 엔드포인트로 보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Firehose를 통과하는 데이터에 대해서만 비용 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 거의 실시간으로 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버퍼 인터벌을 0초~900초로 설정 가능, 버퍼 크기도 1MB 이상 설정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; * 버퍼 : 대상을 전송하기 전에 쌓아놓는 기능.. 버퍼 차면, 한번에 모아보내기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 데이터 형식과 전환, 변환, 압축 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실패한 모든 데이터를 S3 백업 버킷으로 보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`KDS vs KDF&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;KDS&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대규모 데이터를 수집하는데 사용되는 스트리밍 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 생산자와 소비자를 위한 사용자 지정 코드를 직접 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실시간(~200ms)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스케일링 관리(샤드 분할/병합)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로비저닝한 용량에 따라 비용 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~365일 동안 데이터 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 소비자가 동일 스트림에서 읽을 수 있게하며, 재사용 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;KDF&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 수집 서비스로 데이터를 S3, RedShift, OpenSearch, 서드파티, HTTP로 스트리밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형, 서버리스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 근 실시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동 스케일링&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KDF를 통과하는 것만 비용 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 스토리지 없어서, 리플레이는 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Kinesis와 SQS FIFO에서 정렬 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Kinesis&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티션 키를 이용.. 같은 파티션 키를 지정하면 해당 키가 항상 동일한 샤드로 전달&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파티션 키가 직접 샤드에 연결된건 아니고, 파티션 키를 해시해서 어느 샤드로 보낼지 결정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SQS&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS 스탠다드는 순서가 없고, SQS FIFO만 순서가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 그룹 ID를 쓰지 않으면, 메시지는 보내진 순서대로 소비되고, 소비자는 하나만 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자 수를 늘리려면 그룹 ID를 사용해야함.. 정의한 그룹마다 소비자를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`차이점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;100개의 메시지, 5개의 kinesis 샤드, 1개 SQS FIFO 일 때...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Kinesis&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드당 20개 메시지를 가짐.. 메시지는 각 샤드에 순서대로 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 소비자 개수 5개 뿐... 샤드마다 하나의 소비자가 필요하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 최대 5MB 데이터 수신&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SQS FIFO&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 트럭 ID에 상응하는 그룹 ID 100개 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자도 최대 100개가 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 300개.. 배치를 쓰면 3,000개의 메시지를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;SQS vs SNS vs Kinesis&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SQS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소비자가 대기열에 메시지를 요청해서 데이터를 가져오는(pull) 모델&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 처리 후 소비자가 대기열에서 삭제해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 작업자나 소비자 수는 제한이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리된 서비스, 처리량 프로비저닝할 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FIFO 큐를 쓰면 순서 보장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 메시지에 지연 기능으로 일정 시간 뒤에 대기열에 나타나게 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SNS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 게시/구독 모델, 다수의 구독자에게 데이터를 푸시하면 메시지의 복사본을 받게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 주제별로 1,250만 명의 구독자까지 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터가 한 번 SNS에 전송되면 지속되지 않음(제대로 전달되지 않으면 데이터 유실)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 10만 개의 주제로 확장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 처리량 프로비저닝 필요 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요에 따라 SQS와 결합하여 팬 아웃 패턴 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Kinesis&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 두 가지 소비 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 표준 모드 : 소비자가 Kinesis로부터 데이터 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 샤드당 2MB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 향상된 팬 아웃 모드 : 소비자에게 데이터를 푸시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 샤드 당 소비자 당 2MB (더 처리량 많음, Kinesis 스트림에서 더 많은 애플리케이션 읽기 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Kinesis 데이터 스트림에선 데이터가 지속됨(리플레이 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 실시간 빅데이터 분석, ETL 등에 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드레벨에서 순서보장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 미리 Kinesis 데이터 스트림마다 원하는 샤드 양을 지정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 샤드를 직접 확장해서 데이터가 언제 만료될지 정해야함(1~365일)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 두 가지 용량 모드&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 프로비저닝 용량 모드 : Kinesis 데이터 스트림으로부터 원하는 샤드 양 미리 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 온디맨드 용량 모드 : 샤드 수가 자동으로 조정됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Amazon MQ&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS, SNS는 AWS의 독점 기술.. 클라우드 네이티브 서비스임 -&amp;gt; 각자 API 형식 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스에서 기존 애플리케이션을 실행하는 경우 개방형 프로토콜인 MQTT, AMQP, STOMP, Openwire 등을 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라우드에 마이그레이션할 때는, SQS/SNS 프로토콜 혹은 API를 기존에 온프레미스에서 쓰던 프로토콜과 연결하기 위해 Amazon MQ를 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon MQ란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RabbitMQ와 ActiveMQ 두 가지 기술을 위한 관리형 메시지 브로커 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 온프레미스 기술로 개방형 프로토콜 액세스를 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon MQ는 확장성이 크지는 않음(SQS/SNS는 무한확장)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Amazon MQ는 서버에서 실행되기에 서버 문제가 있을 수 있기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고가용성, 페일오버를 위해 다중 AZ 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQS와 같은 단일 큐 기능과 SNS처럼 보이는 주제 기능을 단일 브로커의 일부로 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`MQ의 고가용성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 AZ에 Amazon MQ 브로커 추가(Active-StandBy 상태)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장애 조치를 위한 백엔드 스토리지로 EFS 정의(다중 AZ에 마운트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트는 Active 브로커를 바라보다가 문제가 생기면 StandBy쪽으로 페일오버 되는데 이때 EFS로 네트워크 파일 공유를 하고 있기에 유실없이 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>amazon mq</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws kinesis</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws sns</category>
      <category>aws sqs</category>
      <category>sqs sns 차이</category>
      <category>sqs standard vs fifo</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/101</guid>
      <comments>https://pypystory.tistory.com/101#entry101comment</comments>
      <pubDate>Wed, 9 Oct 2024 15:57:40 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 9편 AWS Snow Family, 스토리지 추가 기능 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/100</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IQeWW/btsJXtcUtr1/2uBmxkmGWPVt916HSTsYdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IQeWW/btsJXtcUtr1/2uBmxkmGWPVt916HSTsYdK/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IQeWW/btsJXtcUtr1/2uBmxkmGWPVt916HSTsYdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIQeWW%2FbtsJXtcUtr1%2F2uBmxkmGWPVt916HSTsYdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;AWS Snow Family&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;엣지에서 데이터를 수집 및 처리하거나, AWS 내부 및 외부로 데이터를 마이그레이션하는데 사용되는 안전한 휴대용 장치(실제 물리적 장치를 받음, 데이터 넣어서 AWS로 보내는 방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터 마이그레이션을 위한 'Snowcone', 'Snowball Edge', 'Snowmobile'&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;엣지 컴퓨팅을 위한 'Snowcone', 'Snowball Edge'&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터 마이그레이션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;목적 : 네트워크를 통해 많은 데이터를 전송하려면 시간이 많이 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연결성과 대역폭이 제한되고, 비용이 발생하거나, 대역폭을 차지할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Snowball Edge&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 커다란 박스 TB/PB 단위 데이터를 옮길 때 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 스토리지 최적화 80TB HDD or 210TB NVMe, 블록 볼륨이나 S3 호환 객체 스토리지에 적합&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 컴퓨트 최적화 42TB HDD or 28TB NVMe&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 사례 : 대규모 데이터 클라우드 마이그레이션, 데이터센터 폐기, 재해 복구&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Snowcone&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 2.1kg으로 가볍고 견고함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 8TB HDD, 14TB SSD&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 공간이 제한된 환경에서 스노우콘 사용.. 배터리, 케이블 직접 준비&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 오프라인으로 배송하거나, 인터넷이 가능한 데이터 센터에 이 장치를 연결한 다음 AWS DataSync 로 전송&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Snowmobile&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 실제로 데이터를 전송할 트럭&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- EB(엑사바이트) 규모의 데이터를 옮길 수 있음, 한 대에 100PB&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 높은 보안 : 온도컨트롤러, GPS, 24시간 비디오 감시&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 10PB이상의 데이터를 전송할 때 스노우볼보다 더 나은 사용 사례&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Snowball 디바이스를 주문하여 배송받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Snowball 클라이언트를 설치하거나, AWS OpsHub를 서버에서 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 스노우볼을 서버와 연결하고 클라이언트에서 파일 복사를 시작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 장치를 반송.. 데이터가 올바른 AWS 시설로 바로 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. 데이터는 S3 버킷으로 옮겨지고, 스노우볼은 완전히 삭제&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;엣지 컴퓨팅&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 엣지 컴퓨팅 : 엣지 로케이션에서 데이터가 생성되는 동안 데이터를 처리하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ * 엣지 로케이션 : 실제로 인터넷이 없거나 클라우드에서 멀리 떨어진 곳&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 배 위나 광산 등이 해당되며, 데이터 전송은 안되고 생산만 되는 곳&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Snowball Edge나 Snowcone 주문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 데이터를 전처리하고, 엣지에서 머신러닝을 하는 것... 클라우드로 돌아가지 않아도, 주요 스트림을 미리 트랜스코딩하고, 필요에 따라 다시 AWS로 전송할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Snowcone : 2 CPU, 4GB 메모리, USB-C파워, 베터리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Snowball Edge : 104 vCPU, 416GB 램, GPU 추가 가능, 28TB NVMe or 42TB HDD 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 16개의 노드까지 클러스터링하여 스토리지 확장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 장치는 EC2 인스턴스와 람다 기능을 실행할 수 있음 (AWS IoT Greengrass 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1년/3년으로 장기 배치 옵션이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OpsHub&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 모든 스노우 패밀리에는 OpsHub가 포함되어 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 과거에는 CLI가 필요했음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 컴퓨터에 AWS OpsHub를 깔고 스노우 장치에 연결하면 사용할 수 있는 GUI를 제공&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`Snowball에서 Glacier까지&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Snowball에서 바로 Glacier로 데이터를 보낼 순 없음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- S3를 사용해서 수명 주기 정책을 생성해서 Glacier로 객체를 전송해야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Amazon FSx&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형 서비스로 타사 고성능 파일 시스템을 실행시킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS에서 AWS MySQL이나 Postgres를 실행하는 것과 같은 개념(RDS가 FSx와 대응됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) FSx에서 윈도우 파일 서버(이외에도 Lustre, NetApp ONTAP, OpenZFS 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`사례&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 윈도우 파일 서버&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SMB 프로토콜, NTFS를 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MS 액티브 디렉토리와 통합됨... ACL, 사용자 보안 추가 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 윈도우 OS 뿐만아니라 리눅스에서도 마운트 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스에 MS 파일 서버가 있는 경우, 분산파일시스템(DFS) 기능을 사용해서 파일 시스템을 그룹화 할 수 있음... 온프레미스와 FSx 파일서버가 결합되는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 초당 수십 GB, 수백만 IOPS, 수백 PB의 데이터까지 확장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSD로 지연시간이 짧아야하는 DB, 미디어 처리, 데이터 분석 등 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HDD로 스펙트럼 워크로드 사용가능.. 홈디렉토리 or CMX&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프라이빗 연결로 온프레미스에서 연결 가능함(VPN이나 다이렉트 커넥트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다중 AZ로 구성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 매일 백업 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Lustre&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Lustre는 원래 분산 파일 시스템으로 &lt;b&gt;대형 연산&lt;/b&gt;에 사용.. ML, &lt;b&gt;HPC&lt;/b&gt; 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리눅스와 클러스터 합성어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 동영상 처리, 금융 모델링, 전자 설계 자동화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 확장성 높음 100GB/s, 수백만 IOPS로 확장되고 ms보다 짧은 지연 시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- S3와 무결절성 통합 가능.. FSx로 S3를 읽을 수 있고, FSx의 연산 출력 값을 S3에 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPN과 직접연결을 통해 온프레미스 서버에서 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;스크래치 파일 시스템&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 임시 스토리지로 데이터가 복제되지 않음.. 기저 서버 오작동시 파일 유실됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 최적화로 높은 버스트 사용 가능.. 영구 파일 시스템 6배(200MB/s per TiB)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 단기처리 데이터에 사용.. 비용 최적화 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;영구 파일 시스템&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 장기 스토리지&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 동일 AZ에 복제됨.. 장애나도 대체됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 민감데이터의 장기처리 및 스토리지에 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. NetApp ONTAP&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;NFS, SMB, iSCSI 프로토콜&lt;/b&gt;과 호환됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스나 나스에서 실행중인 워크로드를 AWS로 옮길 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리눅스, 윈도우, 맥 등 다양한 OS 호환 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지는 오토스케일링, 복제 스냅샷 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 적은 비용으로 데이터 압축, 데이터 복제 제거 등 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 지정 시간 복제 기능(새 워크로드 등 테스트할 때 유용).. 신속히 복제되고 스테이징 파일 시스템 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. OpenZFS&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러버전의 NFS와 호환됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ZFS에서 돌아가는 워크로드를 AWS로 옮길 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다양한 OS에서 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 성능 우수.. 백만 IOPS, 지연시간 0.5ms 이하&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷, 압축 지원, 저비용... 단, 데이터 중복제거는 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지정 시간 복제 기능 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;스토리지 Gateway&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;하이브리드 클라우드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS는 하이브리드 클라우드를 권장함(일부는 AWS, 나머지는 온프레미스에 두는 방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라우드 마이그레이션이 오래걸리거나, 보안 또는 규정 요건이 있는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 엘라스틱 워크로드만 클라우드를 사용하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3는 독자적인 기술로, NFS를 준수하는 EFS와는 다름... S3 데이터를 온프레미스에 둘때 스토리지 게이트웨이가 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;AWS 스토리지 클라우드 네이티브 옵션&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 블록 스토리지 : EBS, EC2 인스턴스 스토어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 파일 시스템 : EFS, FSx&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 객체 수준 스토리지 : S3, Glacier&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스토리지 게이트웨이란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 - 클라우드 사이 가교 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 재해복구 목적 백업, 스토리지 확장 / 클라우드에는 콜드데이터, 온프레미스에는 웜데이터를 두고 티어 스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일 엑세스 시간을 줄이기 위해, AWS 스토리지 게이트웨이를 온프레미스 캐시로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. S3 파일 게이트웨이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Glacier 빼고 나머지에 대해서 사용 가능..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스에서 S3 데이터를 사용할 때, 표준 파일 시스템을 사용하려할 때 사용 (&lt;b&gt;NFS, SMB&lt;/b&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체를 아카이브 할 때는 수명 주기 정책으로 Glacier에 넣으면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터는 신속한 액세스를 위해서 파일 게이트웨이에 캐시로 저장됨(최근에 사용한 파일만)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 파일 게이트웨이마다 IAM 역할을 생성해야 버킷에 접근가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 윈도우에서 SMB 프로토콜 쓸 때, 사용자 인증을 위해 액티브 디렉토리와 통합해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. FSx 파일 게이트웨이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FSx 윈도우 파일 서버에 대해서 네이티브 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 처럼 접근 가능하지만, 자주 액세스하는 데이터의 로컬 캐시를 확보하기 위해 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SMB, NTFS, 액티브 디렉토리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 그룹 파일 공유나, 온프레미스를 연결할 홈 디렉토리로 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 볼륨 게이트웨이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 블록 스토리지로 iSCSI 프로토콜 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 볼륨이 EBS 스냅샷으로 저장되어, 필요시 온프레미스 볼륨 복구 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 캐시 볼륨 : 최근 데이터 액세스시 지연 시간 낮음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 저장 볼륨 : 데이터 세트 전체가 온프레미스에 있으며 주기적으로 S3에 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. 테이프 게이트웨이&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 물리적으로 테이프 백업 시스템이 있는 회사가 백업을 테이프 대신에 클라우드를 이용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VTL(가상 테이프 라이브러리)는 S3와 Glacier 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- iSCSI 프로토콜 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;*게이트웨이는 회사 서버에 설치되어 운영해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단, 온프레미스에 서버가 없는 경우 '스토리지 게이트웨이 하드웨어 어플라이언스'를 사용할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 미니 서버가 될 하드웨어를 amazon.com에서 주문해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ 사례 : 소규모 데이터센터나 일일 NFS 백업처럼, 적은 데이터에 가상화가 없을 때 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 전송 제품군&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3나 EFS의 데이터를 S3 API나 EFS없이, FTP 프로토콜로 옮길려할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 완전관리형, 고가용성, 확장성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 요금 : 시간당 프로비저닝된 엔드포인트 비용+안팎으로 전송된 데이터의 GB당 요금&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유저의 자격증명을 저장하거나 관리할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MS Active Directory, LDAP, Okta, Cognito와 같은 기존 인증 시스템과 통합 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 파일 공유, 공개 데이터셋, CRM, ERP 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FTP client - Route53(옵션) - 전송 제품군 서비스 - S3, EFS(IAM Role로 접근)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;지원 프로토콜&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FTP, 파일 전송 프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FTPS, SSL을 통한 파일 전송 프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SFTP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`DataSync&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 동기화하며, 대용량의 데이터를 한 곳에서 다른 곳으로 옮길 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ 온프레미스나 다른 클라우드에서 AWS 서비스로 옮길 수 있음 (단, 옮길 위치에 에이전트가 있어야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; ㄴ AWS에서 AWS서비스로 옮기기 (에이전트 없어도됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동기화 가능한 곳&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 모든 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;S3, Glacier를 포함하여 모든 스토리지 클래스&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. EFS 네트워크 파일 시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. FSx&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일정을 지정하여 DataSync가 매 시간, 매일, 매주 복제 가능...(지연은 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- &lt;b&gt;파일 권한과 메타데이터는 보존&lt;/b&gt;됨, 보안과 연결 (NFS POSIX, SMB 권한 준수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 에이전트 태스크가 초당 10GBps까지 사용 가능, 대역폭에 제한을 걸 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 만약 DataSync로 옮기려할 때 네트워크 용량이 따라주지 못한다면?? -&amp;gt; Snowcone 장치 사용(DataSync 사전 설치되어 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`스토리지 옵션 비교&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;S3 : 객체 스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;S3 Glacier : 객체 아카이브&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 볼륨 : 한번에 한 개의 EC2 인스턴스에 연결할 때(io 1,2는 다중연결지원)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인스턴스 스토리지 : EC2 인스턴스와 물리적으로 연결됨 (높은 IOPS)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EFS : 다중 가용 영역 간 마운트해야하면서 POSIX 파일 시스템을 쓸 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FSx for Windows : 윈도우 서버 파일 시스템을 필요로 할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FSx for Lustre : 고성능 연산 리눅스 파일 시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FSx for NetApp ONTAP : 높은 OS 호환성, 네트워크 파일시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FSx for OpenZFS : 관리형 ZFS 파일 시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Storage Gateway :&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; S3 &amp;amp; FSx 파일 게이트 웨이 : 온프레미스와 S3 or FSx에 파일을 동기화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 볼륨 게이트웨이(캐시&amp;amp;저장) : 온프레미스 서버에 볼륨을 마운트, 클라우드 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 테이프 게이트웨이 : 테이프 형식으로 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전송 제품군 : S3나 EFS에 전송할 때 FTP, FTPS, SFTP 인터페이스를 필요로 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DataSync : 일정에 따라 데이터 동기화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Snow 제품군 : 데이터를 옮기는데 쓸 네트워크 용량이 없으나, 물리적으로 대용량 데이터 옮길 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Database : 데이터 저장이 가능하고 인덱스와 쿼리 작업을 필요로하는 특수한 워크로드 존재&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>Amazon FSx</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>AWS Snow Family</category>
      <category>aws 스토리지 gateway</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/100</guid>
      <comments>https://pypystory.tistory.com/100#entry100comment</comments>
      <pubDate>Mon, 7 Oct 2024 20:55:45 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 8편 CloudFront, Global Accelerator - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/99</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHUFx/btsJWSWTt17/7fhzyZPEST94eZR5nBOrOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHUFx/btsJWSWTt17/7fhzyZPEST94eZR5nBOrOk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHUFx/btsJWSWTt17/7fhzyZPEST94eZR5nBOrOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHUFx%2FbtsJWSWTt17%2F7fhzyZPEST94eZR5nBOrOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;CloudFront&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CloudFront란&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* CDN : 컨텐츠 전송 네트워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 웹사이트의 컨텐츠를 서로 다른 엣지 로케이션(전세계 216개)에 미리 캐싱하여 읽기 성능을 높이는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자들은 낮은 레이턴시로 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 컨텐츠가 분산되어 있어 DDoS 공격에서 보호받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;원본&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. S3 버킷&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일 분산 및 캐싱 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷에는 CF만 접근할 수 있게 보장, 이는 OAC(원본 접근 제어)로 기존의 OAI를 대체&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CF로 버킷에 데이터를 보낼 수도 있음(ingress라고함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 커스텀 원본&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) HTTP 백엔드 :&amp;nbsp;ALB, EC2, S3 웹사이트 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 웹사이트의 경우 버킷을 정적 웹 사이트로 설정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;작업 방식&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;클라이언트가 요청을 보내면, CF는 캐싱되어있는지 확인하고, 없으면 AWS 내부 네트워크를 이용해 원본에서 요청결과를 가져옴... 결과를 가져오면서 이를 로컬 캐시에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CloudFront와 CRR(교차 리전 복제)간의 차이&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CF는 엣지 로케이션을 이용해 TTL(하루)동안 파일을 캐싱함.. 전세계를 대상으로 한 정적 컨텐츠일 때 용이&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRR는 특정 리전을 지정해야함(전세계X).. 파일은 실시간으로 갱신됨(캐싱의 개념이 아님).. 읽기 전용으로만 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일부 리전을 대상으로 동적 컨텐츠를 낮은 지연 시간으로 제공할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ALB를 원본으로 쓸 때&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2나 ALB를 원본으로 쓰려면 그 대상이 퍼블릭으로 설정되어 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지리적제한&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 국가에 따라 접근할 수 있도록 승인 국가 목록 정의 가능(차단 목록도 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 국가는 서드파티 Geo-IP DB에 따라 맵핑됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 콘텐츠에 대한 접근을 제한하는 저작권법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`고급 옵션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 요금 :&amp;nbsp;엣지 로케이션마다 가격이 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 가격등급 : 비용절감을 위해 CF를 분산할 엣지 로케이션 수를 줄일 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Price Class All : 모든 로케이션에 배포, 최고 성능 최대 비용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Price Class 200 : 대부분 배포되지만 가장 비싼 리전 제외&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Price Class 100 : 가장 싼 곳들만 사용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;캐시 무효화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CF가 원본의 업데이트 사항을 알 수 없을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 캐시를 모두 날릴 수 있음 TTL과 상관없이 새로고침할 수 있음.. 강제로 원본으로 업데이트&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 파일 경로를 설정해서 무효화 시킬 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Global Accelerator&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용목적&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌 애플리케이션을 호스팅할 때, 공용인터넷을 이용하면 많은 hop을 거쳐야해서 지연시간 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연시간 최소화를 위해 AWS 네트워크를 통하는 것이 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애니케스트 IP의 개념을 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;* Unicast IP vs Anycast IP&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유니캐스트 IP : 하나의 서버가 하나의 IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애니캐스트 IP : 모든 서버는 동일한 IP를 가지고, 클라이언트는 가장 가까운 서버로 라우팅됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션을 라우팅하기 위해 AWS 내부 글로벌 네트워크를 활용.. 즉 바로 ALB로 트래픽이 오는게 아니라, 엣지 로케이션 거쳐서 AWS 내부 네트워크 통해서 ALB로 옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션을 위해 &lt;b&gt;두개의 고정 애니케스트 IP&lt;/b&gt;가 생성됨(글로벌함).. 사용자와 가장 가까운 엣지 로케이션으로 트래픽을 직접 전송&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 훨씬 안정적이고 지연시간이 적은 효과&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;특징&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대상&amp;nbsp; : 탄력적 IP, EC2, ALB, NLB와 함께 사용됨 (공용 사설 무관)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지능형 라우팅으로 지연 시간이 짧고, 빠른 장애조치가 이뤄짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 캐싱을 하지 않기 때문에 클라이언트 캐시와도 문제가 없음(IP는 바뀌지 않기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태확인 : 애플리케이션이 글로벌하게 만들어줌... 한 리전의 장애가 확인되면 1분안에 정상 엔드포인트로 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보안 : 2개의 외부 IP만 존재하기에 보안 측면에서 우수, AWS Shield로 DDoS로부터도 보호됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Global Accelerator vs CloudFront&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공통점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 둘다 동일한 글로벌 네트워크 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS가 생성한 엣지 로케이션 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DDoS 보호를 위해 AWS Shield와 통합됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;차이점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CloudFront&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이미지나 비디오와 같은 캐시 가능한 내용과, API 가속 및 동적 사이트 전달 같은 동적 내용 모두에 대해 성능을 향상시킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내용은 엣지 로케이션으로부터 제공됨(대부분 캐시된 내용을 엣지로 부터 가져옴)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 엣지 로케이션은 원본으로부터 가끔 내용을 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`Global Accelerator&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- TCP나 UDP 상의 다양한 애플리케이션 성능을 향상시킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 패킷은 엣지 로케이션으로부터 하나 이상의 AWS 리전에서 실행되는 애플리케이션으로 프록시됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 요청이 애플리케이션 쪽으로 전달됨... 캐싱 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 게임, IOT, VoIP등 비 HTTP를 사용할 경우에 매우 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 글로벌하게 고정 IP를 요구하는 HTTP를 사용할 때도 유용함&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS CDN</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS Cloudfront</category>
      <category>aws cloudfront 캐시무효화</category>
      <category>aws global accelerator</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>s3  속도 향상</category>
      <category>s3 웹사이트 호스팅</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/99</guid>
      <comments>https://pypystory.tistory.com/99#entry99comment</comments>
      <pubDate>Fri, 4 Oct 2024 23:33:26 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 7편 Amazon S3 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/98</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8ImD3/btsJUkGQfwX/pV5LWVM6DYFpGuIX47tiR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8ImD3/btsJUkGQfwX/pV5LWVM6DYFpGuIX47tiR1/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8ImD3/btsJUkGQfwX/pV5LWVM6DYFpGuIX47tiR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8ImD3%2FbtsJUkGQfwX%2FpV5LWVM6DYFpGuIX47tiR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;Amazon S3 소개&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사용사례&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업과 스토리지, 파일용, 디스크용, 재해 복구 용도, 아카이브 용도, 하이브리드 클라우드 스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 호스팅, 동영상/이미지 등 미디어 호스팅, 정적 웹사이트 호스팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 빅데이터 저장 분석&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Nasdap은 7년 간의 데이터를 S3 Glacier에 저장 -&amp;gt; Amazon S3의 아카이브 서비스와 유사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;버킷&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3는 파일을 버킷에 저장함.. 버킷은 상위 레벨 디렉토리로 표시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 내 파일은 객체라고함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷은 계정 내에 생성됨. 버킷은 전역적으로 고유한 이름이 있어야함(모든 리전과 AWS 존재하는 모든 계정에서 유일해야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷은 리전 수준에서 정의됨(버킷 이름이 전역적인것과 무관)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;버킷 명명 규칙&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 이름에는 대문자나 밑줄 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 3~63자 사이&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IP는 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소문자나 숫자로 시작.. 문자 숫자 하이푼만 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- xn과 같은 접두사 제한&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;객체&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체의 키는 파일의 전체 경로가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키는 접두사와 객체이름으로 구성됨... 접두사 이전 경로(폴더명)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 그 자체로는 디렉토리의 개념은 없음... 핵심은 키&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 키는 긴 이름으로 접두사와 객체 이름으로 만들어지고 &quot;/&quot;로 구분됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 값은 본문의 내용으로 최대 크기는 5TB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 5GB보다 파일이 크다면 '멀티파트 업로드'를 사용해서 파일을 쪼개서 업로드해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;메타데이터&lt;/b&gt; : 객체의 키-값 쌍 리스트 를 의미... 시스템이나 사용자에 의해 설정되어, 파일에 관한 요소나 메타데이터를 나타낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;태그&lt;/b&gt; : 유니코드 키-값 쌍으로 최대 10개까지 가능...보안과 수명주기에 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;버전 ID&lt;/b&gt; : 버전 관리를 활성한 경우에 가지게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 보안&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사용자 기반&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 정책으로 어떤 API 콜이 허용될지 승인해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 권한이 허용하거나 리소스 정책이 허용하는 경우에 특정 API 호출시 S3 객체에 액세스 할 수 있는 것.. 명백한 거부는 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM&amp;nbsp;정책&amp;nbsp;내의&amp;nbsp;명시적인&amp;nbsp;부인(DENY)은&amp;nbsp;S3&amp;nbsp;버킷&amp;nbsp;정책보다&amp;nbsp;우선적으로&amp;nbsp;고려됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;리소스 기반 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 정책 : 가장 일반적으로 특정 사용자나 다른 계정의 사용자를 허용할 수 있음(교차 계정이라 함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체 ACL(객체 액세스 제어 목록) : 세밀한 보안 가능, 비활성화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 ACL : 덜 일반적, 비활성화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;암호 키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;암호 키로 객체를 암호화함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;블록 공개 액세스&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기업 데이터 유출을 방지하기 위한 추가 보안 계층&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷이 공개되어 있어도, 이 설정이 활성화 되어있다면 공개되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정 레벨에서 설정가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;S3 버킷 정책&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;JSON 기반의 정책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리소스 : 정책이 적용되는 버킷과 객체&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 결과(Effect) : 허용/거부&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 작업(Action) : 허용하거나 거부할 수 있는 API 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원칙(Princial) : 정책을 적용할 계정 또는 사용자&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사례 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷에 대한 공개 액세스 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 업로드 시 객체를 강제로 암호화&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 계정으로의 액세스를 허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정적 웹 사이트 호스팅&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인터넷에서 접속 가능한 웹 사이트를 호스팅할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;웹 사이트 URL은 생성하는 AWS 리전에 따라 달라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공개를 허용하는 버킷에 html을 포함한 파일을 넣으면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;버전 관리&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 안전한 방법으로 업데이트할 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 수준에서 '버전 관리' 설정을 활성화 시킬 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자가 파일을 업로드할 때마다 선택 키에서 버전이 관리됨.. 이때 동일 키를 업로드하고 덮어쓰면, 버전이 생성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 의도치 않은 삭제를 보호해주고, 쉽게 롤백할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;주의사항&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버전 관리가 활성화 되어 있지 않은 모든 파일은 Null 버전을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버전 관리를 중단해도 이전 버전을 삭제하지는 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버전 관리를 하면 삭제를 해도 delete marker를 남기고 soft delete 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 복제&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRR(교차 리전 복제), SRR(동일 리전 복제)로 나뉨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소스 버킷과 복제 대상 버킷 둘다 버전 관리 활성화되어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서로 다른 AWS 계정간에도 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복제는 백그라운드에서 비동기식으로 이루어짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 올바른 IAM 권한(읽/쓰기)이 있어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 복제를 활성화한 후에는 새로운 객체만 복제 대상이 됨... 설정 전 객체는 기본적으로 복제안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기존 객체를 복제하려면 'S3 배치(batch) 복제 기능'을 사용해야함 &amp;lt;- 복제랑은 다른거임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 기존 객체부터 복제에 실패한 객체까지 복제할 수 있는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 작업을 삭제시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 소스 버킷에서 대상 버킷으로 삭제 마커를 복제하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 버전 ID로 삭제하는 경우 버전 ID는 복제되지 않음(악의적으로 다른 버킷으로 ID 삭제 마커 복제 방지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 체이닝 복제는 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 1 -&amp;gt; 2 복제 2-&amp;gt; 3 복제 상황에서, 1이 3에 복제되지는 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 기본적으로 삭제 마커는 복제되지 않지만, '삭제 마커 복제 옵션'을 통해 삭제 마커도 복제 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사례&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CRR : 컴플라이언스(법규, 내부 체제 관리), 데이터가 다른 리전에 있어 발생하는 지연시간을 줄일 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SRR : 다수의 S3 버킷간의 로그를 통합, 개발 환경이 별도로 있어 운영과 개발 환경간 실시간 복제가 필요할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`S3 스토리지 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;객체를 생성할 때 클래스를 선택할 수 있고, 수동으로 수정할 수도 있음 &amp;amp; 수명주기를 설정해 스토리지 클래스 간 객체를 자동으로 이동할 수도 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;내구성&lt;/b&gt; :&lt;span&gt;&amp;nbsp;&lt;/span&gt;객체가 손실되는 횟수(9가 11개 99.99999999% 내구성 보장)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;가용성&lt;/b&gt; : 서비스가 얼마나 용이하게 제공되는지.. 스토리지 클래스마다 다름&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;ex) S3 스탠다드는 99.99% 가용성 == 1년에 53분은 서비스를 사용할 수 없음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Amazon S3 Standard&lt;/b&gt; - 범용적 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성 99.99%&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자주 액세스하는 데이터에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연시간이 짧고 처리량이 많음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 2개의 기능 장애를 동시에 버틸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 빅데이터 분석, 모바일&amp;amp;게임 애플리케이션, 콘텐츠 배포&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Amazon S3 Standard-Infrequent Access(IA)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성 99.9%&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자주 사용하진 않지만 필요한 경우 빠르게 액세스해야하는 데이터&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 스탠다드보단 적은 비용.. 단 검색 비용이 발생함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 재해복구와 백업에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Amazon S3 One Zone-Infrequent Access(IA)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가용성 99.5%&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단일 AZ내에서는 높은 내구성을 갖지만, AZ가 파괴되면 데이터를 잃게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 데이터를 2차 백업하거나 재생성 가능한 데이터를 저장함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Amazon S3 Glacier&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 콜드 스토리지로 아카이빙과 백업을 위한 저비용 객체 스토리지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지 비용과 검색 비용이 들어감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4.&amp;nbsp; Amazon S3 Glacier Instant Retrieval&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 밀리초 단위로 검색(분기에 한번 액세스하는 데이터에 적합)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최소 보관 기간이 90일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5. Amazon S3 Glacier Flexible Retrieval&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 조회시간에 따라 3개의 옵션 Expedited(1~5분), Standard(3~5시간), Bulk(5~12시간, 무료임)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최소 보관 기간 90일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;6. Amazon S3 Glacier Deep Retrieval&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 2개의 옵션 Standard(12시간), Bulk(48시간)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용이 가장 저렴, 최소 보관 180일&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;7. Amazon S3 Intelligent Tiering&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용 패턴에 따라 액세스된 티어간 객체를 이동할 수 있게 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 소액의 월별 모니터링 비용과 티어링 비용 발생... 단, 검색 비용은 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- FrequentAccess 티어(자동) : 기본티어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Infrequent Access 티어(자동) : 30일 동안 액세스하지 않는 객체 전용 티어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Archive Instant Access 티어(자동) : 90일 동안 액세스 하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Archive Access 티어(옵션) : 90~700일 이상 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Deep Archive Access 티어(옵션) : 180~700일 이상 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;알아서 객체를 이동시켜줘서 편하게 구성가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;고급 Amazon S3&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스토리지 클래스 간 이동&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자주 객체에 액세스하지 않을 걸 알고 있으면, Standard IA로 옮기고, 객체를 아카이브화 하려는 걸 알고 있다면 Glacier 티어나 Deep Archive 티어로 옮길 수 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 객체를 수작업으로 옮길 수도 있지만, 라이프사이클 규칙을 이용해서 자동으로 옮길 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;라이프 사이클 규칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Transition Actions : 다른 스토리지 클래스로 이전하기 위해 객체를 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- ex) 생성된지 얼마 뒤에 ~~로 옮겨라&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Expiration Actions : 일정한 시간 뒤에 만료되어서 객체를 삭제하도록 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- ex) 로그파일을 1년 뒤에 지우도록&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 모든 파일 버전을 삭제하도록 설정할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 특정 기간뒤에 완료되지 않은 멀티파트 업로드를 삭제하도록 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;규칙들은 버킷 전체나 특정한 객체 태그에 적용할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Amazon S3 Analytics&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 객체를 다른 클래스로 이전할 최적의 일 수를 결정하도록 도와줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Standard와 Standard IA에 대한 추천을 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- One-Zone IA나 Glacier와는 호환되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리포트는 매일 업데이트 되며, 데이터 분석 결과는 24~48h 후 볼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`S3 요청자 지불&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 버킷 소유자가 버킷과 관련된 S3 스토리지 및 데이터 전송 비용을 지불함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;요청자 지불을 설정하면 버킷 소유자가 아닌 요청자가 객체 데이터 다운로드 비용을 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 단, 요청자는 AWS에서 인증을 받은 사용자여야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 이벤트 알림&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 이벤트 : 객체의 생성/삭제/복구/복제 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : S3에 일어나는 특정한 이벤트에 자동으로 반응하려는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) S3에 업로드된 모든 이미지의 섬네일을 생성하려는 경우... 이벤트 알림을 만들고 대상에게 전송할 수 있음(SNS, SQS, 람다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원하는 만큼 S3 이벤트를 만들수 있고, 어떤 타깃에도 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 통상적으로 몇 초 내에 적용되지만, 몇 분이 걸릴 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;IAM 권한&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이벤트 알림이 작동하려면 IAM 권한이 필요함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;S3 버킷이 원하는 대상에 메시지를 직접 전송하도록 IAM 정책 설정(각 대상의 리소스 액세스 정책을 정의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Amazon EventBridge&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 이벤트는 이미지 브릿지로 감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이미지 브릿지에서는 18가지 AWS 서비스로 이벤트 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이를 이용하면 고급 필터 사용 가능 : 메타데이터, 객체 사이즈, 이름으로 필터링 후 다수의 대상에 전송 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 아카이빙, 이벤트 중계, 안정적 전달 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 퍼포먼스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본적으로 S3는 매우 높은 요청 수로 자동으로 스케일링됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에서 첫번째 바이트를 가져오는데 100~200ms의 지연시간을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 내에서 prefix(접두사)당 초당 3,500개의 PUT/COPY/POST/DELETE 또는 5,500개의 GET/HEAD 요청을 받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷의 prefix 수에는 제한이 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ex) 객체 경로 -&amp;gt; prefix&amp;nbsp; 버킷/?/?/?/파일이름 : 버킷과 파일이름 사이 모든 것이 prefix&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉 하나의 접두사마다 초당 5,500개 GET이기 때문에 접두사 모두에 균등하게 읽기를 분산하면 초당 22,000개도 읽어올 수 있다는 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`성능 최적화방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 멀티파트 업로드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 100MB 넘으면 권장됨, 5GB 넘으면 필수적...&lt;br /&gt;- 업로드를 병렬화 시켜, 전송속도를 높이고 대역폭을 최대화할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. S3 전송 가속화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 업로드 및 다운로드를 위한 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일을 AWS 엣지 위치로 전송하여 전송 속도를 높임... 그러면 데이터가 타겟 리전으로 전송됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 엣지 위치는 단순한 지역 이상으로, 200개 이상의 엣지 위치가 있으며 수가 늘어나고 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 멀티파트 업로드와도 호환됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 한국에서 미국 S3 버킷에 파일을 넣을 때, 한국에 있는 Edge Location까지 공용인터넷으로 빠르게 옮기고, 엣지 위치에서 프라이빗 AWS 네트워크로 S3로 옮김&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. S3 바이트-범위 가져오기(Range Fetches)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 파일의 특정 바이트 범위를 가져와 가져오기를 병렬화하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 바이트 범위를 가져오는데 실패시, 더 작은 바이트 범위를 재시도함(복원력 향상)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다운로드 속도 향상&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 파트만 필요할 때 빠르게 가져오기도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 Select &amp;amp; Glacier Select&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에서 파일을 검색할 때, 검색한다음 필터링하면 너무 많은 데이터를 가져와야함... 서버 측 필터링을 활용해 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL문에서 행과 열을 사용해 간단한 필터링 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 네트워크 전송도 줄어들고, 검색&amp;amp;필터링에 드는 클라이언트 측 CPU 비용도 줄어듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 속도 400% 향상, 비용 80% 절감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 Batch Operations&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단일 요청으로 기존 S3 객체에서 대량 작업을 수행하는 서비스'&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사례&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한번에 많은 S3 객체의 메타데이터와 프로퍼티 수정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 배치 작업으로 S3 버킷 간 객체 복사 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- 암호화되지 않은 모든 객체 암호화 가능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ACL이나 태그 수정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 Glacier에서 한번에 많은 객체 복원 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Lambda 함수를 호출해서, 사용자 지정작업 수행 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 작업은 객체의 목록, 수행할 작업, 옵션 매개 변수로 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 직접 스크립팅하는 것보다 재시도 관리할 수 있고, 진행상황 확인, 알림 생성, 보고서 생성이 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 Inventory라는 기능으로 객체 목록을 가져오고, S3 Select로 필터링하여, 배치 작업에 포함하려는 필터링된 객체 목록을 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 Storage Lens&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지 이해, 분석, 최적화에 도움을 줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스토리지 렌즈를 통해 이상 징후 파악, 비용 효율성 파악, 모범 사례 적용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 30일 사용량과 메트릭이 제공되어, 조직 / 특정 계정 / 지역 / 버킷 / 접두사 별로 데이터 집계가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대시보드와 보고서를 내줌 (기본 대시보드 삭제 불가.. 단 비활성화는 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 기본 대시보드에는 여러 계정과 여러 지역에 걸쳐 데이터가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에 의해 사전 구성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;매트릭 종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 요약 매트릭 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반적인 인사이트 제공, 스토리지 바이트, 객체 크기/수 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 빠르게 성장하거나 사용하지 않는 버킷, 접두사 등 식별 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 비용 최적화 지표&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최신 버전이 아닌 객체의 수, 실제로 차지하는 공간, 불완전한 멀티파트 업로드 등 파악 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어떤 객체를 더 저렴한 스토리지 클래스로 옮겨야하는지 파악 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 데이터 보호 지표&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 버킷이 버전 관리가 활성화되었는지 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 보호 모범 사례를 따르지 않는 것 식별 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4. 액세스 관리 매트릭&lt;/b&gt; : 어떤 객체 소유권이 지정되어 있는지 파악 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;5. 이벤트 매트릭&lt;/b&gt; : S3 이벤트 알림이 구성된 버킷의 수를 파악 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6. 성능 매트릭&lt;/b&gt; : &amp;nbsp;S3 전송 가속이 활성화된 버킷 수 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;7. 액티비티 매트릭&lt;/b&gt; : 스토리지 별 허용된 요청 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;8. 세부 상태 코드 매트릭&lt;/b&gt; :&amp;nbsp;HTTP 상태에 대한 인사이트 제공, 버킷의 사용 유형 파악 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`무료 vs 유료&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;무료지표 : 28개의 사용량 지표 포함, 14일동안 조회 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유료지표 : 고급 지표, 비용 최적화, 데이터 보호, 상태 코드 등 포함, CloudWatch에 퍼블리쉬되어 추가 비용없이 조회 가능, 접두사 수준에서 메트릭 수집 가능, 15개월동안 조회 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Amazon S3 보안&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 객체 암호화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 서버 측 암호화(SSE)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - S3-SSE :&lt;/b&gt; S3에서 관리하는 키를 이용한 서버 측 암호화 - 새 버킷/객체에 대해&amp;nbsp;&lt;b&gt;기본값&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 우리는 키에 액세스 할 수 없고 AWS에서 소유하고 있음, AES-256 메커니즘을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 업로드시 헤더에 &quot;x-amz-server-side-encryption&quot;:&quot;AES256&quot; 포함 필수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - SSE KMS&lt;/b&gt; : KMS 키를 이용해서 암호화 키를 관리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; KMS는 사용자가 키를 통제 할 수 있음 + CloudTrail을 이용해 키 사용을 검사할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 업로드시 헤더에 &quot;x-amz-server-side-encryption&quot;:&quot;aws:kms&quot; 포함 필수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 업로드할 때 GenerateDataKey라는 자체 KMS API 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 다운로드할 때 Decrypt KMS API로 복호화를 해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; API 호출할 때마다 KMS의 초당 API 호출 쿼터에 합산되고, 리전에 따라 초당 5,000~30,000까지 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ `너무 요청수가 많으면 KMS 스로틀링을 야기할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - SSE-C&lt;/b&gt; : 소비자가 제공하는 키를 이용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 키가 AWS 외부에서 관리됨.. 키를 AWS에 전송해주는 방식, S3는 제공받은 암호화키를 저장하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 키를 S3로 전송하기에 HTTPS를 사용해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 모든 요청에 HTTP 헤더의 일부로서 키를 전달해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 클라이언트 측 암호화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 클라이언트 측에서 먼저 데이터를 암호화한 다음 S3에 전송한다는 개념&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; 복호화도 클라이언트 측에서 수행&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 버저닝된 상태에서 암호화 방법을 바꾸면 새로운 버전의 파일이 생성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;전송 중 암호화( SSL/TLS )&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;S3에는 2개의 엔드포인트가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTP 엔드포인트 : 암호화 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTPS 엔드포인트 : 암호화 O &amp;lt;- 권장사항.. SSE-C를 사용한다면 필수적&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;전송 중 암호화 강제 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 버킷에 정책 설정 : Condition 탭에 추가해서 HTTPS 사용자만 허용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기본 암호화 vs 버킷 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본으로 버킷 생성시 SSE-S3 암호화가 됨.. 새로운 객체 저장시 SSE-S3로 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SSE-KMS 등 다른 암호화 방식을 기본 암호화로 바꿀 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버킷 정책을 이용해서 암호화를 강제하고, 올바른 암호화 헤더가 없으면 S3를 PUT하는 API 요청을 거절할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버킷 정책은 항상 기본값 암호화 설정 이전에 평가됨 &amp;lt;- 기본값과 상관없이 암호화를 강제할 수 있는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 CORS&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CORS란&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;교차 오리진 리소스 공유...&lt;b&gt; 오리진 = 체계(프로토콜) + 호스트(도메인) + 포트 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CORS는 웹 브라우저 기반 보안 메커니즘으로 메인 오리진을 방문하는 동안, 다른 오리진에 대한 요청을 허용하거나 거부함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 오리진이 같다? 프로토콜(https), 호스트(example.com), 포트(443)가 동일한 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ㄴ 오리진이 다른 곳으로 요청을 보내려면... 다른 오리진이 CORS 헤더를 사용해서 요청을 허용하지 않는한 요청은 이행되지않음 (ex: Access-Control-Allow-Origin)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 오리진이 요청을 허용해두었다면, 사전 연결 확인때 보낸 요청으로 허용하는 origin과 메서드를 응답함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;`S3에서 CORS 동작&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정확한 CORS 헤더를 활성화 해야함... S3에서 특정 오리진을 허용하거나 * 로 모든 오리진을 허용해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 MFA Delete&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;MFA Delete를 활성화하면 위험한 작업에 대해서 추가로 보안을 강화할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버킷 소유자인 루트 계정만이 활성화/비활성화를 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;MFA가 필요한 곳&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3에서 객체 버전을 영구적으로 삭제할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷에서 버저닝을 중단할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버저닝을 시작하거나 삭제된 버전을 나열하는 작업은 MFA 없어도됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 액세스 로그&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 감사 목적으로 S3 버킷에 대한 모든 액세스를 기록할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 승인/거부와 상관없이 S3로 온 모든 요청을 다른 S3 버킷(같은 AWS 리전에 있어야함)에 로깅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터 분석 도구로 분석할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 정책은 설정하면 자동으로 업데이트 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;주의사항&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로깅 버킷을 모니터링하는 버킷과 동일하게 설정X -&amp;gt; 무한 루프&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사전 서명된 URL&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 콘솔, CLI, SDK를 사용하여 생성할 수 있는 URL&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 만료 기간 있음 : 콘솔 : 12h, CLI 168h&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- URL을 생성할 때, URL을 받는 사용자는 URL을 생성한 사용자의 GET/PUT 권한을 상속받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다운로드/업로드 시 특정 파일에 임시로 액세스할 때 널리 사용되는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사례&lt;/b&gt; : 로그인한 사용자만 액세스할 수 있는 비디오 다운로드, 접근가능한 사용자 목록이 변해서 URL을 동적으로 생성해야하는 상황, 일시적으로 사용자가 S3 특정위치에 업로드할 수 있도록 허용해야하는 상황&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 잠금 정책 및 Glacier 볼트 잠금&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;S3 Glacier 볼트 잠금&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- WORM(한 번쓰고, 여러번 읽는다) 모델을 채택하기 위해 Glacier 볼트를 잠그는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;ㄴ 수정 삭제를 할 수 없도록 잠그는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 볼트 잠금 정책을 생성하고, 정책을 잠그면 누구도 변경/삭제 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 관리자나 AWS 서비스를 사용해도 삭제할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 규정 준수와 데이터 보존에 유용함, 법률적인 사항에 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;S3 객체 잠금&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버저닝 활성화 필수&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- WORM 모델을 채택하기 위해 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 버킷 수준의 잠금이 아닌 모든 객체에 각각 적용할 수 있는 잠금&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 시간동안 삭제되는 것을 차단할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 규정 준수 모드&lt;/b&gt; : S3 Glacier 볼트 잠금과 매우 유사, 사용자를 포함한 그 누구도 객체 버전을 덮어쓰거나 삭제할 수 없음. 보존 모드를 변경하거나 보존 기간을 변경할 수도 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 거버넌스 보존 모드&lt;/b&gt; : 대부분 유저는 객체 버전을 덮어쓰거나 삭제하거나, 로그 설정을 변경할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단, 일부 사용자는 IAM을 통해 부여받은 권한으로 깰 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;둘다 보존 기간을 설정해야함.. 원하는 만큼 연장 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 법적 보존&lt;/b&gt; : S3 버킷 내 모든 객체를 &lt;b&gt;무기한&lt;/b&gt;으로 보호함.. 보존 기간과는 무관함.. 영구적으로 보호됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단, 마찬가지로 IAM 권한으로 깰 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;S3 액세스 포인트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 포인트 정책을 사용해서 특정 접두어에 읽/쓰기 할 수 있는 권한 부여 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 포인트는 각각의 보안 정책을 가짐... 적절한 IAM 권한이 있는 사용자들이 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고유의 DNS 이름을&amp;nbsp; 가짐 (인터넷 오리진이나 VPC 오리진에 연결되도록 설정 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- VPC 오리진을 프라이빗 액세스가 가능하도록 정의할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- ex) VPC 내에 존재하는 EC2에서 퍼블릭 인터넷을 거치지 않고, 액세스 포인트로 S3 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;EC2 - VPC 엔드포인트 - Access Point VPC 오리진 - S3&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;S3 객체 람다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- S3 액세스 포인트의 활용 사례&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 호출자가 객체를 받기 직전에 그 객체를 수정하려는 경우&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 액세스 포인트를 만들고 람다 함수와 연결해서 1차 가공(추가/삭제) 후 객체 람다 액세스 포인트를 통해서 요청에 액세스할 수 있도록함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 따로 객체가 추가/삭제 된 버킷을 만들지 않고서 한 버킷에서 원하는대로 객체를 수정한 뒤 내보낼 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 분석시 개인식별정보를 삭제하려는 경우, 즉석해서 이미지 크기를 조정하거나 워터마크를 추가하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS S3</category>
      <category>aws s3 보안</category>
      <category>aws s3 암호화</category>
      <category>aws s3 퍼블릭 액세스</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>s3 버저닝</category>
      <category>s3 웹사이트 호스팅</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/98</guid>
      <comments>https://pypystory.tistory.com/98#entry98comment</comments>
      <pubDate>Thu, 3 Oct 2024 17:03:03 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 6편 Route53 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/97</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rQOTE/btsJSvuxpPb/rwFdZ4EaTRjRdcLZBq5D9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rQOTE/btsJSvuxpPb/rwFdZ4EaTRjRdcLZBq5D9K/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rQOTE/btsJSvuxpPb/rwFdZ4EaTRjRdcLZBq5D9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrQOTE%2FbtsJSvuxpPb%2FrwFdZ4EaTRjRdcLZBq5D9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;DNS란&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DNS(Domain Name System) 호스트 이름을 대상 서버 IP 주소로 번역해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DNS에는 계층적 이름과 구조가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.com - example.com &amp;nbsp;- www.example.com - api.example.com&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DNS 관련 용어&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;도메인 레지스트라(Registrar)&lt;/b&gt;&amp;nbsp;: 도메인 이름을 등록하는 곳.. AWS Route53, GoDaddy... etc&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;DNS 레코드&lt;/b&gt; : ex) A, AAAA, CNAME, NS ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;존 파일(Zone file)&lt;/b&gt; : 모든 DNS 레코드를 포함함, 호스트 이름과 IP 또는 주소를 일치시키는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;네임 서버&lt;/b&gt; : DNS 쿼리를 실제로 해결하는 서버&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최상위 도메인(TLD) : .com, .us, .gov, .org ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2단계 도메인(SLD) : example.com, google.com ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ex)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;http://api.www.example.com.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;. : Root&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.com : TLD&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.example : SLD&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.www : 서브 도메인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;api.www.example.com : 도메인 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;http : 프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전체 : FQDN, 전체 주소 도메인 이름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DNS 동작 방식&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자(브라우저)가 example.com에 접속하려고 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; local DNS Server에 질의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; 로컬에서 모르면 ICANN에 의해 관리되는 루트 DNS 서버에 질의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; Root DNS 서버도 example.com은 모르지만 .com은 안다고 답변. (*.com은 네임서버(NS) 레코드로 공인 IP로 가보라고 알려줌)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; 로컬 DNS 서버는 다시 IANA에 의해 관리되는 TLD DNS 서버에 질의&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; TLD DNS 서버도 example.com이 무엇인지는 모르지만 example.com 서버는 알고있음(NS레코드 답변)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; 로컬 DNS 서버는 도메인 레지스트라에 의해 관리되는 SLD DNS 서버에 질의&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; SLD DNS 서버는 example.com이 뭔지 알기 때문에 A레코드로 해당 서버의 공용 IP를 답변&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; 로컬 DNS 서버는 Cache 해두고, 브라우저에 답변을 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;gt; 브라우저는 이 IP 주소를 이용해 웹 서버에 접속 성공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Route53&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고가용성, 확장성을 갖춘 완전히 관리되며 권한있는 DNS&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;* 권한있다 == DNS 레코드를 우리가 직접 업데이트 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Route53 역시 '도메인 레지스트라'로 도메인을 등록해서 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Route53의 리소스 관련 상태 확인이 가능함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 100% SLA 가용성을 제공하는 유일한 AWS 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;레코드&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 레코드를 통해 특정 도메인으로 라우팅하는 방법을 정의함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 각 레코드는 도메인/서브도메인 이름과 같은 정보 포함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 레코드 타입 ex) (필수) A, AAAA, CNAME, NS / (고급) CAA, DS, MX, NAPTR, PTR, SOA, TXT, SPF, SRV&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 레코드 값 ex) 123.345.456.567&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 라우팅 정책 : Route53이 쿼리에 응답하는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - TTL : 레코드가 캐싱되는 시간&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`레코드 타입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- A : 호스트네임과 IPv4를 맵핑&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AAAA - 호스트네임과 IPv6 맵핑&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CNAME - 호스트네임을 다른 호스트네임과 맵핑&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 대상 호스트네임은 A나 AAAA 레코드가 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Route53에서 DNS 네임스페이스 (또는 Zone Apex)의 상위 노드에 대한 CNAME을 생성할 수 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;ex) example.com에 CNAME은 만들 수 없지만, www.example.com에 대한 CNAME레코드는 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- NS 호스트 존의 네임서버로, 서버의 DNS 이름 또는 IP 주소로 호스트 존에 대한 DNS 쿼리에 응답 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 트래픽이 도메인으로 라우팅되는 방식을 제어함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;호스트 존(Hosted Zones)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;레코드의 컨테이너로 도메인/서브도메인으로 가는 트래픽의 라우팅 방식을 정의함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;퍼블릭 호스팅 존 : 퍼블릭 도메인 이름을 살 때마다 퍼블릭 호스팅 존을 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프라이빗 호스팅 존 : 공개되지 않는 도메인명을 지원함.. VPC만이 URL을 리졸브 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 호스트 존이든 0.5$/m 를 지불해야 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TTL(Time To Live)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;클라이언트가 Route53에 DNS request를 날렸을 때, 레코드타입, IP주소와 함께 TTL을 알려줌.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TTL은 클라이언트에게 이 결과를 N 초만큼 캐싱하라고 알려주는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TTL이 높으면 : Route53에 트래픽이 적어질 것, 하지만 클라이언트가 오래된 레코드를 받을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TTL이 낮으면 : Route53에 들어오는 트래픽이 많아지고, 비용으로 연결됨, 레코드 변경이 빨라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;TTL전략&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: left;&quot;&gt;레코드 변경 전 TTL을 낮게 설정해 클라이언트가 변경된 레코드를 빠르게 캐시에 반영하도록 한 뒤, 레코드를 바꿔서 모든 클라이언트가 레코드가 업데이트 된 걸 확인하고, TTL을 높게 설정해서 트래픽을 줄이는 전략&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* TTL은 필수적이나 별칭 레코드에서는 제외됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`CNAME vs Alias(별칭)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;로드밸런서나 클라우드프론트를 사용하면 AWS 호스트네임이 노출됨.. 보유한 도메인에 호스트 이름을 매핑하고자할 때 두가지 옵션이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. CNAME : 호스트 이름이 다른 호스트 이름으로 향하도록 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 루트 도메인이 아닌 경우에만 가능해서 mydomain.com 앞에 뭔가를 붙여야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;** Apex 도메인을 CNAME 레코드에 쓰지못하는 이유 : &lt;a href=&quot;https://www.zodaland.com/tip/73&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.zodaland.com/tip/73&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. Alias : Route53에만 가능, 호스트이름이 특정 AWS 리소스로 향하게 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 별칭은 루트/비루트 모두 동작함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 무료이고, 자체적으로 상태 확인이 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- A, AAAA 레코드 타입을 쓰면되고, 콘솔에서 Route 대상에 Alias 체크해주면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Alias Record&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대상 : ELB / CloudFront / API Gateway / Elastic Beanstalk / S3 Websites / VPC Interface Endpoint / Global Accelerator / 동일 호스트 존의 Route53&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`* EC2의 DNS이름에 대해서는 별칭 레코드 설정 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;상태확인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Route53의 상태확인은 공용(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;public&lt;span&gt;) &lt;/span&gt;&lt;/span&gt;리소스에 대한 상태를 확인하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DNS의 장애 조치를 자동화하기 위한 작업으로 DNS에 연결된 대상(ALB 등..)의 상태확인을 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. public 엔드 포인트를 모니터링.. 서버, 애플리케이션&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 전 세계에서 온 15개의 상태 확인이 엔드 포인트의 상태를 확인하고 반환함, 비용에 따라 인터벌도 조정가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- HTTP/HTTPS/TCP 프로토콜을 지원&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 18% 이상 정상이라고 판단하면 Route53도 정상이라고 판단함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 상태 확인에 사용될 위치도 선택 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 2xx, 3xx를 응답으로 받아야 통과&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 텍스트 기반일 경우 상태확인은 처음 5,120바이트를 확인함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 상태 확인(Health Checker)가 엔드포인트에 접근가능해야함(public)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;2. 계산된 상태 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러개의 상태확인을 하나로 합쳐 줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- OR AND NOT으로 하위 상태 확인을 256개까지 합칠 수 있고, 상위 상태확인이 통과하기 위한 몇 개의 상태확인이 통과해야하는지 정할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 상태확인이 실패하는 일 없이, 상위 상태 확인이 웹사이트를 관리 유지하도록 하는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. CloudWatch의 모니터링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 개인 리소스를 모니터링 하려면? CloudWatch 메트릭(지표)/경보를 할당하는 식으로 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CloudWatch 경보를 개인 서브넷 안에 있는 EC2에 걸고, CloudWatch를 상태확인 하는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;라우팅정책&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라우팅정책은 Route53이 DNS 쿼리에 응답하는걸 도움&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Route53이 지원하는 라우팅 정책&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단순 / 가중치 기반 / 장애 조치 지연 시간 기반 / 지리적 / 다중 값 응답 / 지리 근접 정책&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 단순 라우팅 정책 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반적으로 트래픽을 단일 리소스로 보내는 방식&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동일 레코드에 여러개 값 저장 가능.. 여러 값 받으면 클라이언트에서 무작위 하나를 고름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 별칭 레코드는 하나의 AWS 리소스만 대상으로 지정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태확인 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 가중치 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가중치를 활용해 요청의 일부 비율을 특정 리소스로 보낼 수 있음(합이 100일 필요는 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DNS 레코드는 동일 이름과 유형을 가져야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서로 다른 지역에 로드 밸런싱&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나가 0이면 그쪽으로는 트래픽을 보내지 않지만, 다 0이면 동일 가중치로 받음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 지연 시간 기반&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연시간이 가장 짧은, 가장 가까운 리소스로 리다이렉팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지연시간에 민감한 애플리케이션일 때 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 유저가 가까운 AWS 리전에 연결하기까지 걸리는 시간으로 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 장애 조치 기반 (액티브-패시브)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필수적으로 Primary EC2의 상태확인과 레코드를 연결함, 상태확인이 비정상이면 Secondary로 넘겨줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기본과 보조가 각각 하나씩만 있을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 지리적 위치 기반&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자의 실제 위치를 기반으로 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Default 레코드를 무조건 만들어야함(매칭되는 로케이션이 없을 경우를 대비)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 사례 : 콘텐츠 분산을 제한, 로드밸런싱, 웹사이트 현지화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태 확인과 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 지리 근접 라우팅&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자와 리소스의 지리적 위치를 기반으로 트래픽을 리소스로 라우팅함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 편향값을 사용해 특정 위치를 기반으로 리소스를 더 많은 트래픽을 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 리소스에 더 많은 트래픽을 보내려면, 편향값을 증가시켜 확장할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 리소스면 AWS 리전으로 특정, 온프레미스 데이터 센터라면 위도 경도를 지정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 편향 활용을 위해 고급 Route53 트래픽 플로우를 사용해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 지리 근접 라우팅은 편향을 증가시켜, 한 리전에서 다른 리전으로 트래픽을 보낼 때 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. IP 기반 라우팅&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Route53에서 CIDR 목록을 정의함(클라이언트의 IP 범위)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- CIDR에 따라 트래픽을 보낼 로케이션을 정함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점 : IP를 미리 알고 있어 성능을 최적화할 수 있음, IP가 어디서 오는지 알기에 네트워크 비용을 줄일 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8. 다중 값&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 트래픽을 다중 리소스로 라우팅할 때 사용.. Route53은 다중 값과 리소스를 반환함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 상태확인과 연결하면, 정상 리소스에서만 값들을 받아오게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각각의 다중 값 쿼리에 최대 8개의 정상 레코드가 반환됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ELB와 유사하지만 ELB를 대체할 수는 없다... 이건 클라이언트 측면의 로드밸런싱인 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;도메인 레지스트라 VS DNS Service&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 도메인 이름 레지스트라를 통해 원하는 도메인 이름을 구입할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 타사에서 도메인을 구입하고, Route53으로 DNS records를 관리할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS Route53에서 호스팅존을 만들고, 네임서버를 타사 옵션에서 변경해주면 관리가능&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS Route53</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws 도메인</category>
      <category>aws 라우팅정책</category>
      <category>Route53</category>
      <category>route53 ttl 설정</category>
      <category>레코드 타입 종류</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/97</guid>
      <comments>https://pypystory.tistory.com/97#entry97comment</comments>
      <pubDate>Mon, 30 Sep 2024 20:50:58 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 5편 RDS, Aurora, ElastiCache - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/96</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mEabu/btsJAIodpns/8IPiaiGES2HN2ZAll9wWHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mEabu/btsJAIodpns/8IPiaiGES2HN2ZAll9wWHK/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mEabu/btsJAIodpns/8IPiaiGES2HN2ZAll9wWHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmEabu%2FbtsJAIodpns%2F8IPiaiGES2HN2ZAll9wWHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;RDS&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS: SQL을 쿼리언어로 사용하는 DB에 대한 관계형 데이터베이스 서비스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- Postgres, MySQL, MariaDB, Oracle, Microsoft SQL Server, IBM DB2, Aurora(AWS 독점 DB)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RDS를 사용하는 이유&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;관리형 서비스, DB 프로비저닝 자동화, OS 패치, 지속적 백업, 특정 시점 복원, 모니터 데시보드, Multi-AZ, 수평/수직 확장, EBS의 지원을 받음(gp2, io1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(단, SSH는 사용불가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`RDS 스토리지 오토스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS를 생성할 때 원하는 스토리지 용량을 지정해야함, RDS는 DB가 찬걸 감지하고, 자동으로 늘림 / 혹은 RW가 많아지면 자동으로 스케일링됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 저장 임계값을 설정해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 DB엔진이 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`RDS 읽기 전용 복제본 &amp;amp; 다중 AZ의 차이&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;읽기 전용 복제본&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기를 스케일링함, 15개까지 Read Replica를 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 동일 AZ도 가능하고, AZ나 리전을 걸쳐서 생성될 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비동기식(읽기가 일관적으로 유지되는 것)으로 동작함, 업데이트가 바로 이뤄지지 않을 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 만약 복제본 중 하나를 데이터베이스로 사용하고자 그에 대한 권한을 획득하면, 복제 메커니즘에서 탈피함. - 단 자체적인 생애 주기를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 전용 복제본을 사용할 때는, 애플리케이션의 모든 연결을 업데이트해 RDS 클러스터 상의 읽기 전용 복제본 전체 목록을 활용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사용 사례 :&lt;/b&gt; 평균적인 로드를 감당하는 DB가 있을 때, 보고/분석을 위해 애플리케이션을 개발하는 상황에서 메인 DB에 직접 연결하면, 오버로드가 발생하고 애플리케이션 속도가 느려짐, 이때 새로운 워크로드에 대한 읽기 전용 복제본을 생성하면, DB인스턴스와 읽기 전용 복제본 간 비동기식 복제가 발생함.. 이때 분석 애플리케이션이 읽기 작업과 분석을 실행하면 오버로드 없이 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;당연히 SELECT 명령문에만 사용 가능!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;네트워킹 비용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AZ간 이동을 해도 동일 리전에 있을 때는 비용을 내지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 리전에 존재할 경우 복제 비용이 발생함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;다중 AZ&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;주로 재해 복구에 사용(가용성을 높일 수 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동기식으로 다른 AZ에 스탠바이 인스턴스로 복제함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나의 DNS 이름을 갖고, 마스터에 문제가 생길 때도 자동으로 스탠바이 DB에 장애 조치가 수행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전체 AZ 또는 네트워크 손실에 대비한 장애조치&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자동으로 failover됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`원하는 경우 읽기 전용 복제본을 다중 AZ로도 설정할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`단일 AZ에서 다중 AZ로 RDS DB 전환이 가능함, 이때 다운타임이 전혀없음(무중단)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`내부적으로 기본 DB의 RDS가 자동으로 스냅샷을 생성하고, 새로운 스탠바이 DB에 복원됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이후 두 DB간 동기화가 설정되어, 다중 AZ 설정 상태가 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS 커스텀&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS에서는 기저 OS나 사용자 지정 기능에 엑세스할 수 없음.. RDS 커스텀에서는 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Oracle과 MS SQL Server를 다룸..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS를 통해 AWS의 DB 자동화 설정, 운영, 스케일링의 장점을 챙길 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기저 DB와 OS에 접근 가능, 내부 설정 구성, 패치 적용, 네이티브 기능 활성화 가능, SSH/SSM 세션 관리자로 RDS 뒤에있는 EC2 인스턴스에 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자 지정 설정을 사용하려면, RDS가 수시로 자동화, 유지 관리, 스케일링을 수행하지 않도록 자동화를 꺼두는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;쉽게 문제가 생길 수있으니 DB 스냅샷을 만들어 두면 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS: DB 전체를 관리해줌 OS 등 AWS에서 관리하고 아무것도 안해도됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RDS 커스텀 : Oracle, MS SQL Server에서만 사용가능, 기저 OS/DB에 대해 관리자 권한을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Amazon Aurora&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 고유 기술로 Postgres와 MySQL이 호환되게 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라우드에 최적화되어 MySQL보다 5배 높은 성능, Postgres보다 3배 높은 성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동으로 확장 가능 10GB에서 시작해서 128TB까지 커짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 15개의 읽기전용 레플리카 사용가능, 복제속도 더 빠름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Failover가 즉각적임, 다중 AZ나 MySQL RDS보다 훨씬 빠름. 가용성이 높음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비용은 RDS보다 20% 정도 더 비쌈&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;높은 가용성 &amp;amp; 읽기 스케일링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- Aurora는 무언가를 기록할 때마다 3개의 AZ에 걸쳐 6개의 사본을 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 쓰기에는 6개의 사본 중 4개만 있으면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 읽기에는 6개의 사본 중 3개만 있으면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 백엔드에서 P2P 프로세스를 통해 자가 복구 프로세스가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 단일 볼륨에 의존하지 않고, 수 백 개의 볼륨을 사용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RDS의 다중 AZ와 유사&lt;/b&gt; : 쓰기를 받는 인스턴스는 하나뿐이고, Aurora에도 &lt;b&gt;마스터가 하나 존재&lt;/b&gt;해 여기서 쓰기를 받음, 마스터가 동작하지 않으면 30s 내로 페일오버 시작. 마스터에 문제가 생기면 읽기 전용 복제본 중 하나가 마스터가 되어 대체함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;복제본들은 리전 간 복제를 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`Aurora DB 클러스터&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 마스터가 교체될 수 있음으로, Aurora에서는 &lt;b&gt;라이터(Writer) 엔드포인트&lt;/b&gt;를 제공함, 라이터는 DNS 이름으로 항상 마스터를 가리킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 전용 복제본은 오토스케일링 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 전용 복제본들에게 Client가 접근하기 위해서&lt;b&gt; Reader 엔드포인트&lt;/b&gt;를 제공함, 이는 연결 로드 밸런싱에도 도움을 줌.. 문(state) 레벨이 아닌 연결 레벨에서 로드밸런싱이 일어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Aurora 기능&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동 페일오버 / 백업, 복원 / 격리 및 보안 / 산업 규정 준수 / 버튼식 스케일링 / zero 다운타임 자동 패치 / 고급 모니터링 / 통상 유지관리 / 백트랙(과거 어떤 시점으로든 복원 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Aurora 고급 개념&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;복제본 오토스케일링&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) DB에 많은 읽기 요청이 와서 CPU 사용량이 증가 시 복제본 오토스케일링으로 레플리카들이 추가되고, Reader 엔드포인트는 새로운 레플리카를 위해 확장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사용자 지정 엔드포인트&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) Read 레플리카의 인스턴스 종류가 2가지라고 할 때, 읽기 레플리카 인스턴스의 부분집합을 커스텀 엔드포인트로 설정 가능... 더 인스턴스 성능이 좋은 특정 복제본들이 분석 쿼리를 담당하는 것이 나을 경우와 같을 때 사용...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자 지정 엔드포인트 정의후에는 Reader 엔드포인트 자체는 사용하지 않게됨(없어지는 건 아님), 각 업무마다 다양한 사용자 지정 엔드포인트를 만들어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aurora 서버리스&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;간헐적, 예측 불가 업무량에 대응 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 클라이언트는 Aurora가 관리하는 프록시 플릿(Proxy Fleet)에 연락함, 백엔드에는 많은 Aurora 인스턴스 생성(업무량에 기반해 자동 생성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;글로벌 Aurora&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;리전 교차 읽기 전용 복제본은 재해 복구나 실행에 간편함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 요즘은 &lt;b&gt;Aurora Global Database&lt;/b&gt;를 추천함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 읽기/쓰기가 일어나는 하나의 기본 리전이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 5개의 보조 읽기 전용 리전을 만들 수 있는데, 응답 지연이 1초 이하임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 보조 리전 당 최대 16개의 읽기 전용 복제본 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전 세계에서 오는 읽기 업무량에 따른 대기 시간을 줄일 때 도움을 줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 리전이 중단되어도 다른 리전을 진급(R/W 다 가능하도록)시키는데, 복구 시간이 1분미만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- 평균적으로 Aurora Global DB에서 한 리전에서 다른 리전으로 데이터를 복제하는 데에는 1초 이하의 시간이 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aurora Machine Learning&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SQL 인터페이스를 통해 응용프로그램에 기계 합습 기반의 예측을 추가할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Aurora와 다른 AWS ML 서비스 간의 간단하고 최적화된 안전한 통합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SameMaker(ML 모델 사용)와 Comprehend(감정 분석에 사용)이 통합 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 이상 행위 탐지, 광고 타겟팅, 감정 분석, 상품 추천&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 응용프로그램 - Aurora - Sagemaker - 결과 응답(예측치)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS &amp;amp; Aurora 백업과 모니터링&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RDS 백업&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; 자동화된 백업&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자동으로 전체 백업을 함, 5분마다 트랜잭션 로그가 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가장 빠른 백업은 5분 전의 백업(항상 5분전으로 복원 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~35일 동안 보관 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;수동 데이터베이스 스냅샷&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자가 수동으로 트리거함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백업을 원하는 기간동안 유지가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`사례 : 한 달에 2시간만 사용하는 DB가 있다면? 스냅샷을 만들어서 비용절감을 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aurora 백업&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;자동화된 백업&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~35일 동안 보관 가능(단, 비활성화 불가.. RDS는 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시점 복구 기능 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;수동 DB 스냅샷&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;lt;- RDS와 유사함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;?* 재해 복구 및 감사 목적으로 Aurora 데이터베이스에 대한 장기 백업을 저장시, Aurora DB 복제 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RDS &amp;amp; Aurora 복원 옵션&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS 또는 Aurora의 백업 또는 스냅샷은 그것들로 새 데이터베이스를 생성하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;S3로부터 RDS MySQL 복원하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온프레미스 DB를 생성하고, S3에 객체로 저장해두기&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS에는 S3에서 백업 파일을 복원하거나 새로운 RDS MySQL을 실행하는 옵션이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;S3로부터 Aurora &lt;b&gt;클러스터&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt; MySQL 복원하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 외부적으로 온프레미스 DB를 다시 백업하면됨, Percona XtraBackUp이라는 SW 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Percona XtraBackUp의 백업 파일을 S3로 보내, 거기서 백업을 복원할 수도 있음(MySQL을 실행하는 새 Aurora Cluster로 복원됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;차이점은, RDS 복원시에는 DB 백업만 있으면 되지만, Aurora에서는 ' Percona XtraBackUp'로 백업을 하고, S3에서 Aurora DB 클러스터로 백업해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Aurora Database 복제(cloning)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기존 DB 클러스터에서 새로운 Aurora DB 클러스터 생성가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 프로덕션 DB가 있고, 테스트를 실행하고 싶을 때, staging DB로 복사할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷 찍고 복제보다 빠름, 복제는 copy-on-write 프로토콜을 사용하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 처음 DB 복제본을 만들 때는, 원래 DB 클러스터와 동일한 데이터 볼륨을 사용하게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 데이터를 복사하지 않아 빠르고 효율적&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 프로덕션이나 스테이징 Aurora DB에 업데이트가 이뤄지면 새로운 추가 스토리지가 할당되고, 데이터가 복사 및 분리가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- DB 복제는 빠르고 비용 효율적이며, 프로덕션 DB에 영향을 주지 않고 복제하는데 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS &amp;amp; Aurora 보안&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;저장된 데이터 암호화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS를 사용해 마스터와 모든 복제본의 암호화가 이뤄짐, DB를 처음 실행할 때 정의됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 마스터가 암호화되지 않았다면, 읽기 복제본도 암호화 안됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 암호화되지 않은 DB를 암호화하고 싶다면, DB 스냅샷을 가져와서 암호화된 형태로 복원해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;클라이언트-DB간 전송 중 암호화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 클라이언트는 AWS에서 제공하는 TLS 루트 인증서를 사용해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;IAM 인증&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 이름과 PW라는 전통적인 방식도 있지만, AWS IAM 역할을 사용해서 DB에 접속할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #2d2f31; text-align: start;&quot;&gt;- &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;IAM을 이용한 웹 서버 인증은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #2d2f31; text-align: start;&quot;&gt;Postgres/MySQL에서 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;보안 그룹&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DB에 대한 네트워크 엑세스를 통제할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SSH 엑세스가 없음&lt;/b&gt;(단, AWS RDS 커스텀 서비스는 예외)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;감사 로그&lt;/b&gt;가 있어서 시간에 따라 어떤 쿼리가 생성되는지 기록(cloudwatch log로 보내면 장기보관 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RDS Proxy&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;완전 관리형 RDS DB 프록시도 배포 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS 프록시를 사용하면 애플리케이션이 DB 내에서 DB 연결 풀을 형성하고 공유할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션이 RDS DB 인스턴스에 일일이 연결하는 대신, 프록시에 연결하면 프록시가 하나의 풀에 연결을 모아 RDS DB 인스턴스로 가는 연결이 줄어듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- 연결이 줄어들면, DB CPU/RAM 사용률이 줄어들어 DB 효율성이 향상되고, 개방된 연결을 최소화하고 시간초과를 줄일 수 있음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- RDS 프록시는 서버리스로 오토스케일링, 다중 AZ를 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- 페일오버 발생시 대기 인스턴스로 실행되어, 장애 조치 시간을 66% 줄일 수 있음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - RDS 프록시가 페일오버가 발생한 RDS DB 인스턴스를 처리하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MySQL, PostgreSQL, MariaDB용 RDS를 지원 / MySQL, Postgres Aurora ㅣㅈ원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 어플리케이션 코드 수정없이, 연결을 RDS 프록시로 하기만 하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`-&amp;nbsp; DB에 IAM 인증을 강제함&lt;/b&gt;으로서, IAM 인증을 통해서만 연결할 수 있게하고, 자격증명은 AWS Secret Manager에 저장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- RDS 프록시는 퍼블릭 엑세스가 절대불가&lt;/b&gt;하고, VPC 내에서만 엑세스 가능(보안이 훌륭)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- lambda 함수를 사용할 때, RDS 프록시를 사용하면, lambda 함수의 연결 풀을 생성하고 lambda 함수가 RDS 프록시를 오버로드하여, RDS DB 연결을 줄일 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ElastiCache&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;캐싱 기술인 Redis 또는 Memcached를 관리할 수 있도록 도와줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 캐시란 매우 높은 성능과 짧은 지연 시간을 가진 인메모리 DB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 읽기 집약적인 워크로드에서 DB 로드를 줄여줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 일반적인 쿼리는 캐시에 저장되기 때문에 캐시만 사용하여 쿼리를 조회할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 상태를 비저장형으로 할 수 있게 도와줌, 상태를 ElastiCache에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 관리형으로 패치, 최적화, 설정, 구성, 모니터링, 장애복구, 백업 등 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션 코드를 많이 바꿔야함, DB를 쿼리하기 전/후에 캐시를 쿼리하도록 애플리케이션을 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 아키텍처 예시 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예시A : 애플리케이션은 ElastiCache에 먼저 쿼리함, 쿼리가 발생했는지 확인하고 이미 발생하여 캐싱되어있다면, 캐시 히트라고 함.(시간 절약) 캐시 미스 발생시 DB에서 데이터를 읽어와야하고, 쿼리가 반복되면 데이터를 캐시에 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;캐시 무효화 전략이 있어야함, 가장 최신 데이터만 사용되어야하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예시B : 사용자 세션을 캐시에 저장하는 것, 애플리케이션을 상태 비저장으로 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사용자가 로그인시 애플리케이션이 세션 데이터를 ElastiCache에 적음, 사용자가 다른 인스턴스로 리디렉션되면, 애플리케이션은 그 세션의 세션 캐시를 직접 검색할 수 있어서 로그인 상태가 유지됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;애플리케이션을 상태 비저장형으로 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Redis vs Memcached&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Redis&lt;/b&gt; : 다중 AZ, 읽기 복제본, AOF 지속성을 이용한 데이터 내구성, 백업/복원, 세트 및 정렬된 세트 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Redis는 복제되는 캐시라고 생각할 수 있음, 가용성과 내구성이 뛰어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Memcached&lt;/b&gt; : 데이터 분할을 위해 멀티 노드 사용(=샤딩), 고가용성이 없고, 복제가 일어나지 않으며, 영구 캐시가 아님, 백업/복원 X, 멀티스레드 아키텍처, 여러 인스턴스가 모두 샤딩을 통해 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`Redis는 고가용성, 백업, 읽기 복제본 등을 위해 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`Memcached는 분산된 순수 캐시로, 데이터가 손실되어도 괜찮음, 고가용성 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ElastiCache 보안&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Redis에서만 IAM인증을 지원, 나머지 경우에 사용자 이름과 PW를 사용하면됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM 정책을 정의하면, AWS API 수준 보안에만 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Redis AUTH라는 Redis 내 보안을 통해 PW와 토큰 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Redis 클러스터를 만들 때, 추가 보안 수준 제공 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - SSL 전송 중 암호화 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Memcached는 &lt;b&gt;SASL 기반&lt;/b&gt; 인증 제공(고급)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ElastiCache 데이터 load 패턴&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. Lazy 로딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 데이터가 캐시되고, 데이터가 캐시에서 지체될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션에서 캐시 히트가 있는 경우, 캐시에서 데이터를 가져옴.. 캐시 미스의 경우 DB에서 읽고, 캐시에 쓰게됨(캐시 히트가 없을 때만 load 되는 방식)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. Write Through&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DB에 데이터가 기록될 때마다 캐시에 데이터를 추가하거나 업데이트하는 것.. 데이터가 지체되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. Session Store&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유지 시간 기능을 통해 만료 설정 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Redis 사용 사례&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`실시간 리더보드 만들기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Redis에는 정렬된 세트(Sorted sets)가 있음, 고유성과 요소 순서를 모두 보장함.. 요소가 추가될 때마다, 실시간으로 순위를 매긴 다음 올바른 순서로 추가됨... ElastiCache에서 실시간으로 만들어주니, 애플리케이션 측에서 이 기능을 프로그래밍할 필요가 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;친숙한 포트(Well-Known)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;중요한 포트&lt;/b&gt; : FTP : 21 / SSH : 22 / SFTP : 22 / HTTP : 80 / HTTPS : 443&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;RDS DB 포트&lt;/b&gt; : PostgreSQL : 5432 / Mysql : 3306 / Oracle RDS : 1521 / MS Server : 1433 / MariaDB :3306&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- Aurora 포트 : PostgrSQL/MySQL을 따라감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/96</guid>
      <comments>https://pypystory.tistory.com/96#entry96comment</comments>
      <pubDate>Fri, 13 Sep 2024 00:56:36 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 4편 고가용성 및 스케일링성(ELB, ASG) - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djpn0Y/btsJrC8ANVy/kT6Qsa73G3IqHWYb0K5bo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djpn0Y/btsJrC8ANVy/kT6Qsa73G3IqHWYb0K5bo1/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djpn0Y/btsJrC8ANVy/kT6Qsa73G3IqHWYb0K5bo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdjpn0Y%2FbtsJrC8ANVy%2FkT6Qsa73G3IqHWYb0K5bo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;고가용성과 확장성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`확장성&lt;/b&gt; : 애플리케이션 시스템이 조정을 통해 더 많은 양을 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 수직 확장성&lt;/b&gt; : 인스턴스의 크기를 확장하는 것(scale up)... DB(RDS, ElastiCache)와 같은 분산되지 않는 시스템에서 사용... 하지만 하드웨어 한계로 고점 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 수평 확장성(탄력성)&lt;/b&gt; : 인스턴스나 시스템의 수를 늘리는 것(scale out), 분배 시스템이 있다는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`고가용성&lt;/b&gt; : 애플리케이션 또는 시스템이 둘 이상의 AZ나 데이터 센터에서 가동 중인 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 손실에서 살아남는게 목표&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 자동일 필요는 없음 '수동형'도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ELB&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;로드밸런서&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서버 혹은 서버셋으로 트래픽을 백엔드나 다수의 다운스트림 EC2 인스턴스 또는 서버로 전달하는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단일 엑세스 지점을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 인스턴스의 정기적 health check 진행 ( &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;장애를 원활히 처리할 수 있음 )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- SSL 종점을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿠키로 고정도를 강화할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라우드 내에서 개인 트래픽과 공공 트래픽 분리 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Elastic Load Balancer&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;관리형 로드 밸런서, AWS가 관리어떤 경우에도 작동할 것을 보장 : AWS가 업그레이드, 유지 관리 및 고가용성 책임짐 /&amp;nbsp;다수의 AWS 서비스와 통합... EC2, ASG, ECS, ACM...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Health Checks&lt;/b&gt; : 제대로 작동 안하는 EC2에 대해 트래픽을 보내지 않음.. port와 route(/health)로 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 200코드 미응답시, 상태가 좋지 않다 판단&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ELB 종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Classic Load Balancer(v1, 2009) - CLB : 사용 권장 안함 HTTP/HTTPS, TCP, SSL&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Application Load Balancer(v2, 2016) - ALB : HTTP/HTTPS, WebSocket&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Network Load Balancer(v2, 2017) - NLB : TCP, TLS, UDP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Gateway Load Balancer(2020) : GWLB : 3계층과 IP 프로토콜에서 작동&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일부 로드밸런서 내부에 설정할 수 있어, 네트워크의 개인적 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유저는 HTTP, HTTPS로 어디서든 LB에 접근가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SG 설정상 아래와 같은 형태가 되어야 강력한 보안을 가짐.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;유저 - LB : 80/443 ANYWHERE 허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;LB - EC2 : 80 LB에 대해서만 접근 허용(LB의 SG 자체를 Source로 설정)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ALB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;7계층, HTTP 전용 로드 밸런서로 target 그룹으로 묶인 머신들 간 다수 HTTP 애플리케이션의 라우팅에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동일 EC2 인스턴스 상의 여러 애플리케이션에 부하를 분산(컨테이너와 ECS 사용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;HTTP/2, WebSocket, redirects(HTTP로 들어오면 HTTPS로 트래픽 자동 리다이렉트) 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;경로 라우팅 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- URL 대상 경로에 기반한 라우팅&amp;nbsp; (ex. example.com/users &amp;amp; example.com/posts)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- URL 호스트 이름에 기반한 라우팅 (ex. one.example.com &amp;amp; two.example.com)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿼리 문자열과 헤더에 기반한 라우팅 ( example.com/users?id=1 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마이크로 서비스나 컨테이너 기반 애플리케이션에 가장 좋은 LB(Docker &amp;amp; EC2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 포트 매핑 기능이 있어, ECS 인스턴스의 동적 포트로의 리다이렉션이 가능하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나만으로 다수의 애플리케이션 처리 가능하단 장점&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ALB는 탄력적 IP 주소를 연결할 수 없어서, 만약 쓰고 싶다면 NLB를 써야함(ALB는 정적 DNS 이름만 사용가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Target Group&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스 (ASG에 의해 관리) - HTTP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ECS tasks (ECS에 의해 관리) - HTTP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Lambda function&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IP 주소 - 무조건 private IPs&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ALB는 여러 대상 그룹으로 라우팅할 수 있으며, health check는 TG 레벨에서 이뤄짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;고정호스트 이름이 부여됨 (ex. XXX.region.elb.amazonaws.com)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;애플리케이션 서버는 클라이언트의 IP를 직접 못 봄..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 클라이언트의 실제 IP는 X-Forwarded-For라는 헤더에 삽입됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- X-Forwarded-Port에서 포트, X-Forwarded-Proto에서 프로토콜이 삽입됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;리스너 규칙&lt;/b&gt;으로 조건을 추가해서 어떤 요청을 어디로 보낼지 설정할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) /error로 들어오는 요청을 다 고정응답으로 바꿀 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NLB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 4계층, L4 로드밸런서로 TCP/UDP 트래픽을 다룰 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고성능 로드밸런서, 초당 수백만 건 요청 처리 + 지연시간도 100ms로 ALB(400ms)에 비해 짧음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;nbsp;NLB는 AZ별로 하나의 고정 IP를 가짐, 탄력적 IP 주소를 각 AZ에 할당할 수도 있음, 여러 개의 고정 IP를 가진 애플리케이션을 노출할 때 유리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 1~3개의 IP로만 액세스할 수 있는 애플리케이션을 만들려면? NLB를 옵션으로 고려해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;NLB 키워드 : 고성능, TCP/UDP, 정적IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Target Group&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IP 주소 - 반드시 하드코딩 &amp;amp; private IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ALB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`상태확인 프로토콜&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;TCP / HTTP / HTTPS 프로토콜 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;GWLB&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;배포, 확장, 타사 네트워크, 가상 어플라이언스 플릿 관리에 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;네트워크 모든 트래픽이 방화벽을 통과하게 하거나, 침입 탐지 및 방지에 사용됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;VPC의 네트워크 라우팅 테이블이 업데이트 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 모든 사용자 트래픽은 GWLB를 통과&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 타겟그룹(서드파티 보안장비)로 트래픽이 분산됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 이상없으면 다시 GWLB로 보내지고, 최종적으로 어플리케이션으로 들어옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;L3, 네트워크 레이어에서 IP 패킷 단에서 동작&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;GWLB 역할&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 투명 네트워크 게이트웨이 :&amp;nbsp; VCP의 모든 트래픽이 GWLB라는 단일 엔트리와 출구를 통과하기 때문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 로드밸런싱 : 대상 그룹의 가상 어플라이언스 집합에 전반적으로 트래픽 분산&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`- UDP 6081번 포트 GENEVE 프로토콜 : 네트워크 가상화 지원하는 프로토콜로 GWLB가 이걸씀&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Target Group&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IP 주소 - 무조건 private IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Sticky Session&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;고정성&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서에 2가지 요청을 수행하는 클라이언트가 요청에 응답하기 위해 백엔드에 동일한 인스턴스를 갖는 것 (ex. A,B,C 유저가 있고 ALB로 묶인 인스턴스a,b가 있을 때, 유저A가 보낸 요청을 ALB가 인스턴스 a로 요청을 보냈다면, ALB에서 두번째 요청을 실행할 때도&amp;nbsp; 같은 인스턴스로 보내는 것.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿠키를 써서 고정성과 만료기간 컨트롤&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자 로그인과 같은 중요한 정보를 취하는 데이터를 잃지 않기 위해, 사용자가 동일한 백엔드 인스턴스에 연결되게함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 고정성을 활성화하면, 백엔드 EC2 인스턴스 부하에 불균형을 초래할 수 있는 단점 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;고정성에 사용되는 쿠기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 애플리케이션 기반 쿠키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사용자 정의 쿠키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 대상으로 생성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 애플리케이션에 필요한 모든 사용자 정의 속성 포함 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿠키 이름은 각 대상 그룹별로 개별적으로 지정해야함(단, AWSALB, AWSALBAPP, AWSALBBLG는 예약된 이름으로 사용 못함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;애플리케이션 쿠키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서 자체에서 생성 ( 생성된 쿠키이름 : AWSALBAPP )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 기간 기반 쿠키&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서에서 자체 생성 ( AWSALB, AWSELB )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정 기간을 기반으로 만료, 로드밸런서에서 정해줌.. (애플리케이션 기반 쿠키는 기간 지정 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Cross-Zone Load Balancing&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;교차 영역 로드 밸런싱 : 각각의 로드밸런서 인스턴스가 모든 가용 영역에 등록된 모든 인스턴스에 부하를 고르게 분배함 (ex. A 가용영역에 인스턴스 2개, B 가용영역에 인스턴스 8개 있을 때, 가용영역 상관없이 10%씩 트래픽을 받는 원리, 만약 안쓰면 A 가용영역 인스턴스는 25% 트래픽 부담, B 가용영역은 6.25%를 부담하는 원리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ALB&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 교차 영역 로드 밸런싱이 활성화 되어 있음(TG에서 비활성화 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터를 다른 AZ로 넘기는데 비용 안듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;NLB &amp;amp; GWLB&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 비활성화되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;활성화하면, AZ 사이 데이터를 넘겨야해서 비용 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SSL/TLS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SSL 인증서 : 클라이언트와 로드밸런서 사이에서 트래픽이 이동하는 동안 암호화해줌(전송 중 암호화라고 함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SSL이란 '보안 소켓 계층'을 의미하고 연결을 암호화하는데 사용함, TLS는 새로운 버전의 SSL로 '전송 계층 보안'을 의미. 최근에는 TLS가 많이 쓰이지만 편의상 SSL이라고 많이 부름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Public SSL 인증서는 CA(인증 기관)에서 발급함, 퍼블릭 SSL 인증서를 LB에 추가하면, 클라이언트와 로드밸런서 사이의 연결을 암호화할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SSL 인증서에는 만료 날짜가 있어서 주기적으로 갱신해서 인증 상태를 유지해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;동작원리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 유저가 HTTPS로 LB에 접속하면, LB는 SSL을 종료 시킴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 백엔드에서는 HTTP로 EC2인스턴스와 통신(어짜피 private VPC 네트워크기 때문에 안전하게 보호됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서는 X.509 인증서를 사용, SSL 또는 TLS 서버 인증서라고 부름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에는 ACM(AWS 인증서 관리자)가 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 원한다면 내가 가진 인증서를 ACM에 업로드도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- HTTPS 리스너 사용..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 다중 도메인 지원하려면 다른 인증서를 추가할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 클라이언트는 SNI(서버 이름 지정)를 써서 접속할 호스트의 이름을 알릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 원하는 보안 정책을 설정 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;SNI&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 개의 SSL 인증서를 하나의 웹 서버에 로드해, 하나의 웹 서버가 여러개의 웹 사이트 지원하게 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 확장된 프로토콜로, SSL 핸드쉐이크 단계에서 클라이언트가 서버의 호스트 이름을 지정하도록 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 클라이언트가 접속할 웹사이트를 말했을 때, 서버는 어떤 인증서를 불러올지 알 수 있게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;-&amp;nbsp;ALB &amp;amp; NLB &amp;amp; CloudFront에서만 동작함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ALB는 CLB와 다르게, SNI를 이용해 여러 개의 SSL 인증서를 두고, 다수의 리스너를 지원하게됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`Connection Draining&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;연결 드레이닝(등록 취소 지연 이라고도 함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스가 등록 취소, 비정상인 상태일 때, 인스턴스에게 시간을 주어 활성 요청을 완료할 수 있도록 하는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ELB는 등록 취소 중인 EC2 인스턴스로 새로운 요청을 보내지 않는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(ex. 특정 EC2에 대해 드레이닝 요청을 하면, 기존 연결 및 기존 요청을 완료하고 작업이 끝나면 LB와 연결이 정지됨, 이때 다른 유저가 LB로 접속해도 드레이닝 상태인 EC2 인스턴스에는 요청을 보내지 않음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1~3600초 사이의 값으로 설정(기본 300초).. 0으로 설정하면 비활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 교체 작업 등에 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ASG&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;오토스케일링 그룹&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스케일 아웃, 증가한 로드에 맞춰 EC2 인스턴스를 추가하거나, 스케일 인, 감소한 로드에 맞춰 EC2 제거&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ASG에서 실행되는 EC2에 최소 및 최대 개수를 보장하기 위해, 매개변수를 전반적으로 정의할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드밸런서와 연결하면 ASG 內 모든 EC2 인스턴스가 LB에 연결됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 비정상적인 인스턴스를 종료하고, 새 EC2 인스턴스를 생성함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;시작 템플릿&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인스턴스 속성 기반으로 ASG 생성시 '시작 템플릿'을 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AMI, 인스턴스 유형 / &amp;nbsp;EC2 사용자 데이터 / EBS 볼륨 / SG; / Key Pair / IAM / Network&amp;amp;서브넷 / LB...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최소용량, 희망용량, 최대용량&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스케일링 정책&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CloudWatch 경보와의 통합 : 경보를 기반으로 스케일 아웃 가능, 평균 CPU나 사용자 지정 metric으로 판별함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;온디멘드와 스팟 인스턴스 섞을 수도 있음&lt;/p&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스케일링 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 동적 스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 목표(대상) 추적 스케일링 : 'CPU 사용률/평균 연결 개수'과 같은 ASG 메트릭을 정의하고, 목표 값을 정하고 유지하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단순 / 단계 스케일링 : 클라우드와치 알람을 정의하여, ASG에 용량 단위를 추가 or 제거하고자 할 때 알람이 발생하게 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2. 예약 스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 알려진 사용 패턴을 기반으로 스케일링을 예상할 수 있음 (ex. 특정 시간에 사용자가 몰리는 것 활용)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3. 예측 스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 지속적으로 부하를 예측한 다음 미리 예약을 시작하는 경우, 반복되는 패턴이 있을 때 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 머신러닝 기반 과거 사례 분석으로 예측치를 생성하여 스케일링 작업을 예약함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;사례&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. CPU 활용도 : 모든 인스턴스 평균 CPU가 높다면 인스턴스 활용도가 높다는 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 타겟당 요청 수 : 미해결 요청의 개수로 판별&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 네트워크 사용량&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 사용자 지정 메트릭 : 애플리케이션 별 고유 메트릭 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;스케일링 쿨다운&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스케일링 작업(인스턴스 추가/제거) 이후에 기본적으로 5분 쿨다운 시간에 들어감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쿨다운 시간 동안 ASG는 추가 인스턴스를 개시하거나 종료하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 메트릭 안정화와 새로운 메트릭의 변화를 지켜보기 위함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AMI를 이용해 EC2 인스턴스 설정 시간을 줄임으로서, 요청을 더 빠르게 처리할 수 있게 하는 것이 좋음(쿨 다운 시간이 줄어듬)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS</category>
      <category>aws asg</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS ELB</category>
      <category>aws free tier</category>
      <category>aws saa 자격증</category>
      <category>aws 자격증 취득 후기</category>
      <category>로드밸런서</category>
      <category>오토스케일링</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/95</guid>
      <comments>https://pypystory.tistory.com/95#entry95comment</comments>
      <pubDate>Wed, 4 Sep 2024 16:15:51 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 3편 EC2 Instance Storage(EBS, EFS) - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/94</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwMfL0/btsI0IiNCnw/weeHoHSsRjvPyp4NKE1WTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwMfL0/btsI0IiNCnw/weeHoHSsRjvPyp4NKE1WTk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwMfL0/btsI0IiNCnw/weeHoHSsRjvPyp4NKE1WTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwMfL0%2FbtsI0IiNCnw%2FweeHoHSsRjvPyp4NKE1WTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&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;b&gt;EBS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS 볼륨&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Elastic Block Store : 인스턴스가 실행 중인 동안 연결 가능한 네트워크 드라이브&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인스턴스가 종료되어도, 데이터 지속 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 생성시 특정 AZ에서만 사용 가능 (단, 스냅샷을 이용하면 다른 AZ에 볼륨 옮길 수 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS... 네트워크 USB 스틱 같은것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프리티어에서는 매달 30GB까지 EBS를 쓸 수 있음(범용 SSD or 마그네틱 유형)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;*CCP 레벨 : 하나의 EBS는 하나의 EC2 인스턴스에 마운트 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;*어소시에이트 레벨 : 일부 EBS 다중 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스와 EBS 볼륨이 서로 통신하려면, 네트워크가 필요하고 지연이 생길 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 쉽게 땔 수 있어서, 페일오버 상황에서 유리함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 미리 크기를 정해둬야함.. 원하는 용량의 GB와 IOPS(초당 전송 수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`종료 시 삭제(Delete on Termination attribute) - 자유롭게 가능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- EC2 생성시, 기본적으로 루트 EBS 볼륨은 종료시 삭제 활성화 - 유지하고 싶으면 비활성화 해야됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 다른 EBS 볼륨은 기본적으로 종료 시 삭제 비활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS 스냅샷&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 볼륨의 특정 시점에 대한 백업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스에서 EBS 볼륨을 분리할 필요는 없지만, 권장사항&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 스냅샷은 다른 AZ나 다른 리전에도 복사(복원) 가능 : 재해 복구 전략이 필요한 경우 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 스냅샷 아카이브&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 75%까지 저렴한 아카이브 티어, 스냅샷을 옮길 수 있는 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 다른 스토리지 계층으로 이동 가능. 다른 가격 수준으로...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 아카이브를 복원하는데 24~72h 걸림(즉시 복원이 안됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EBS 스냅샷 휴지통&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 영구 삭제하는 대신, 휴지통에 넣으면 실수로 삭제하는걸 방지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 1일 ~ 1년사이로 보관 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;빠른 스냅샷 복원(FSR)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷을 완전 초기화해 첫 사용에서 지연시간을 완전히 없앰&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스냅샷이 아주 크거나, EBS볼륨이나 EC2 인스턴스를 빠르게 초기화해야할 때 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 비쌈&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS 볼륨 타입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(각 종류의 세부수치 보다는, 큰 틀에서 차이점 이해...)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 1. gp2, gp3 (SSD)&lt;/b&gt; : General Purpose, 범용 SSD 볼륨으로 다양한 워크로드에 대해 가격/성능의 균형 맞춤&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`비용 효율적인 스토리지, 낮은 대기 시간&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;제공&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`&amp;nbsp; - gp2&lt;/b&gt; : 구세대 볼륨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 시스템 부팅 볼륨, 가상 데스크톱, 개발 및 테스트 환경에서 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 1GB ~ 16TB&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 작은 gp2 볼륨은 최대 3000 IOPS 버스트 성능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 볼륨 크기와 IOPS는 &lt;b&gt;연관&lt;/b&gt;되어 있어 16000 IOPS까지 증가가능(5334GB 일 때..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp;- gp3&lt;/b&gt; : 최신 세대 볼륨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 기본적으로 3000 IOPS, 125MB/s 처리량&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 최대 16000 IOPS, 1000MB/s 처리량까지 &lt;b&gt;독립&lt;/b&gt;적으로 증가 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 2. io 1, io 2 Block Express (SSD)&lt;/b&gt; : Provisioned IOPS(PIOPS), 가장 높은 성능의 SSD 볼륨.. 미션 크리티컬, 저지연, 고처리량 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 16000 IOPS 이상이 필요할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터베이스 워크로드가 스토리지 성능과 일관성에 매우 민감한 경우 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EBS 다중 연결 기능 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - io 1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 4GB ~ 16TB까지 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`&amp;nbsp; - 최대 PIOPS : 64000(Nitro EC2 인스턴스), 32000(다른 인스턴스)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 스토리지 크기와 별도로 프로비저닝된 IOPS를 늘릴 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - io 2 Block Express&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 4GB ~ 64TB까지 지원&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 밀리초 단위 레이턴시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 최대 PIOPS : 256000... IOPS:GB == 1000:1&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 3. st 1 (HDD)&lt;/b&gt; : 처리량 최적화 HDD, 자주 액세스하고 처리량이 많은 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 빅데이터, 데이터 웨어하우징, 로그 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 최대 500MB 처리량, IOPS 500&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 4. sc 1 (HDD)&lt;/b&gt; : Cold HDD,가장 저렴함.. 액세스 빈도가 낮은 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 가능한 가장 낮은 비용이 필요할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- 최대 250MB 처리량, IOPS 250&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;크기, 처리량, 초당 입출력 작업 수(IOPS) 로 나뉨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;오직 SSD만 부팅 볼륨(OS root가 실행)으로 사용될 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS 다중 연결 기능&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하나의 EBS 볼륨을 같은 AZ에 있는 여러 EC2 인스턴스에 연결하게 해줌(무조건 같은 AZ안에서만 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;io 1,2 제품군에서만 사용할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 인스턴스는 고성능 볼륨에 대한 읽/쓰기 권한을 전부 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 애플리케이션 가용성을 높이기 위해 Teradata처럼 클러스터링된 Linux 어플리케이션, 애플리케이션이 동시 쓰기 작업을 관리해야할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`최대 16개의 EC2 인스턴스만 연결 가능&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;무조건 클러스터 인식 파일시스템을 써야함(XFS, EX4 등은 쓸 수 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS 암호화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;저장 데이터가 볼륨 내부에서 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인스턴스와 볼륨 간의 전송 데이터 역시 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 스냅샷과 스냅샷으로 생성된 볼륨도 암호화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 암호화와 복호화 메커니즘은 보이지 않고, 모두 백그라운드에서 처리됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`지연 시간에는 영향이 거의 없고, KMS에서 암호화 키를 생성해 AES-256 암호화 표준을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;스냅샷을 복사해 암호화를 푼 걸 다시 암호화 활성화를 하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EBS 암/복호화 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EBS 볼륨의 스냅샷 생성 -&amp;gt; 복사 기능을 통해 EBS 스냅샷 암호화 -&amp;gt; 스냅샷으로 새 EBS 볼륨 생성시 해당 볼륨도 암호화 -&amp;gt; 암호화된 볼륨을 인스턴스 원본에 연결&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;암호화되지 않은 EBS 볼륨은 스냅샷도 암호화되지 않음...&amp;nbsp;그래서 스냅샷을 복사할 때 암호화시켜서 동일 리전에 만들고, 그걸로 다시 볼륨을 만들면 암호화된 볼륨이 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;좀 더 빠르게 하려면, 비암호화된 스냅샷을 바로 볼륨으로 만들 때, 암호화 옵션을 선택해도 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AMI&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;Amazon Machine Image : EC2 인스턴스를 통해 만든 이미지를 통칭&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 커스터마이징 가능 : 원하는 SW, 설정 파일 추가, 별도의 OS, 모니터링 툴 등 설치가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 부팅 및 설정에 드는 시간 줄일 수 있음 : AMI가 미리 패키징해줌&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- AMI를 특정 지역에 구축하고, 다른 지역으로 복사할 수도 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 리전에 국한되어 다른 리전에서 바로 실행할 수는 없지만, AMI를 다른 리전으로 복사해서 생성하는 것은 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스 여러 방법 런치 가능&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Public AMI : AWS가 제공하는 것... ex) Amazon Linux 2&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- own AMI : 직접 만들고 유지보수 해야함... 자동 관리 도구 있긴함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- Marketplace AMI : 다른 사람이 구축한 이미지.. 구매해야함, 보통 기업에서 자사 SW 넣고 파는 형태&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;EC2에서 AMI Process&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스를 원하는대로 설정 -&amp;gt; 인스턴스를 중단해 데이터 무결성 확보 -&amp;gt; 이걸 빌드(구축)해서 AMI를 만듬.. 이 과정에서 EBS 스냅샷이 생성됨 -&amp;gt; 다른 인스턴스에서 AMI 사용&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;User Script를 쓰면, 인스턴스가 Running 되어도 초기 세팅을 하는데 시간이 소요되는데, AMI를 이용하면 부팅(부팅과 동시에 세팅)이 더 빠르게 됨&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 인스턴스 스토어&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;EBS는 네트워크 드라이브로 좋지만 성능에 한계가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;더 좋은 하드웨어 디스크를 원한다면, EC2 Instance Store를 이용해야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스 스토어 : EC2에 물리적으로 연결된 하드웨어 드라이브&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- I/O 성능 향상&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스를 종료하면, 스토리지가 손실됨.. 그래서 임시 스토리지라고 부름(장기적으로 데이터 보관X)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- 버퍼, 캐시, 스크래치 데이터, 임시 콘텐츠에는 좋은 보관 장소&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스가 장애 발생시 같이 장애가 발생하는 단점.. 데이터를 백업하거나 복제해둬야함&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;장기 저장 스토리지로는 EBS가 어울림&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;하지만 IOPS 64,000 넘어가면 무조건 이거 써야함... 이때 데이터 손실 방지책으로 아래 방법이 있음&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;1. 인스턴스 스토어가 있는 다른 EC2에서 복제 매커니즘 설정으로 대기 복사본 갖기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;2. 백업 매커니즘 설정하기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EFS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Amazon EFS - Elastic File System&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EFS는 관리형 NFS(네트워크 파일 시스템).. 많은 EC2 인스턴스에 마운트 될 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이때, EC2 인스턴스는 서로 다른 AZ에 있어도 됨&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;고가용성, 확장성 뛰어남, 비쌈(gp2에 3배 가격), 사용량에 따라 비용 지불(미리 용량을 프로비저닝할 필요 X)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 콘텐츠 관리, 웹 서빙, 데이터 공유, 워드프레스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 내부적으로 NFSv4.1 프로토콜을 쓰고, EFS에 대한 &lt;b&gt;액세스를 제어&lt;/b&gt;하려면 &lt;b&gt;SG&lt;/b&gt;로 함(EC2에서 마운트할 때 자동으로 SG 연결 옵션 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 리눅스 기반 AMI만 호환됨(윈도우 안됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- KMS를 사용해서 EFS 드라이브에서 암호화 활성화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리눅스 표준 파일 시스템인 POSIX 사용, 표준 파일 API가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 용량을 미리 계획할 필요가 없다는 장점.. 자동으로 확장되고 사용량에 따라 비용 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EFS - 성능 &amp;amp; 스토리지 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EFS Scale : 동시 NFS 클라이언트 수천 개와 10GB 이상의 처리량 확보&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- PB 규모 NFS 자동확장됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- &lt;b&gt;성능 모드 &lt;/b&gt;(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;EFS 생성시&lt;span&gt;&amp;nbsp;설정)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - General Purpose(권장) - 지연 시간에 민감한 사용 사례 : ex) 웹서버, CMS(콘텐츠관리 시스템) 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - MAX I.O : 지연시간은 더 길지만, 처리량 최대화.. 병렬성 높음 ex) 빅데이터, 미디어 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- 처리량 모드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Bursting : 1TB = 50MB/s + 100MB/s, 사용중인 스토리지 용량에 따라 처리량을 확장&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Provisioned : 스토리지 크기와 상관없이 처리량을 설정하고 싶을 때, 처리량을 미리 알고 있을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Elastic(권장) : 워크로드에 따라 처리량 자동 조정, 워크로드를 예측하기 어려울 때 유용, 쓴만큼만 냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Storage Classes&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 스토리지 계층(tier)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Standard : 자주 액세스하는 파일을 위한 티어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - IA(Infrequent Access) : 자주 액세스하지 않는 용도, 파일을 검색할 때 비용이 들지만, 저장하면 비용이 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Archive : 거의 액세스하지 않는 데이터, 1년에 몇번 액세스할 때...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; 수명 주기(Lifecycle) 설정해서 며칠 후에 어느 계층으로 이동시킬지 정의 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 가용성과 내구성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Standard(Regional) : 다중 AZ 설정이 있을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - One Zone : 개발만하고 하나의 AZ에 저렴하게 사용, 백업은 기본적으로 활성화, 액세스 빈도가 낮은 스토리지 계층과 호환됨(IA)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;올바른 EFS를 쓰면 최대 90% 비용 절감 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;`EBS vs EFS&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EBS&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 인스턴스에만 연결(단, io1,2 유형의 다중 연결 기능(동일 AZ)은 예외)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AZ level에 갇혀있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- gp2 : 디스크 크기 증가하면 IO 증가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- gp3&amp;amp; io 1 : 독립적으로 IO 증가 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AZ 간에 마이그래이션 하려면, 스냅샷 찍어서 EBS 스냅샷으로 옮기고, 다른 AZ에서 복원해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EBS 볼륨 백업은 많은 IO 사용하기 때문에, 애플리케이션이 많은 트래픽 처리하는 동안에는 성능에 영향을 줄 수 있어 지양해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2가 종료되면 기본적으로 루트 볼륨 종료되지만, 옵션을 바꿔 비활성화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EFS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 네트워크 파일 시스템으로 여러 AZ에 걸쳐 수백 개의 인스턴스에 연결하는 것이 목표&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 여러 인스턴스가 하나의 FS 공유 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 워드프레스와 같은 웹사이트 파일을 공유할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 리눅스 인스턴스만 가능.. POSIX 시스템 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EFS는 EBS보다 비싸지만, 스토리지 계층을 활용하여 비용절감 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;+ 인스턴스 스토어&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스에 물리적 연결 : EC2 인스턴스 종료시 같이 종료&lt;/p&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;</description>
      <category>인프라/AWS</category>
      <category>AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>AWS EBS</category>
      <category>aws ec2</category>
      <category>aws ec2 파일</category>
      <category>aws efs</category>
      <category>aws free tier</category>
      <category>aws saa 자격증</category>
      <category>aws 자격증 취득 후기</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/94</guid>
      <comments>https://pypystory.tistory.com/94#entry94comment</comments>
      <pubDate>Tue, 13 Aug 2024 01:22:09 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 2편 AWS Budget, EC2 - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/93</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BBSYY/btsI04x2k9k/v0kvqSQ3Og1HQue5lx26Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BBSYY/btsI04x2k9k/v0kvqSQ3Og1HQue5lx26Wk/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BBSYY/btsI04x2k9k/v0kvqSQ3Og1HQue5lx26Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBBSYY%2FbtsI04x2k9k%2Fv0kvqSQ3Og1HQue5lx26Wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 예산 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Billing and Cost Management : 초기에 IAM 유저가 못보게 제한되어 있음 -&amp;gt; Root 에서 권한을 풀어줘야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Bills : 서비스별 월 별 요금 확인 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Free Tier : 무료로 사용 가능한 양과 지금 쓴 양을 비교 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Budgets : 설정한 예산에 따라 이메일 오게 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EC2 기초&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2(Elastic Compute Cloud)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;IaaS... EC2는 하나의 서비스가 아닌 아래의 것들을 포함하는 개념.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 가상 머신을 EC2에서 임대할 수 있음 : EC2 인스턴스&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 데이터를 가상 드라이브에 저장 가능 : EBS 볼륨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드를 분산시킬 수 있음, 로드밸런싱 : ELB(일래스틱 로드 밸런서)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 서비스 확장 가능 : ASG(오토 스케일링 그룹)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;클라우드는 필요할 때마다 컴퓨팅을 대여할 수 있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2에서 선택할 수 있는 것&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;OS : 리눅스, Window, MAC&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CPU : compute power &amp;amp; cores&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RAM : memory 양&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;storage space : Network-attached( EBS &amp;amp; EFS ) / Hardware (EC2 Instance Store)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Network card : speed of the card, public IP&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Firewall rules : security group&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Bootstrap script (첫 시작 때 설정) : EC2 User Data&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;bootstrapping : 시작할 때 한번만 실행되는 commands로 EC2 User data script 를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- EC2 User Data Script는 root 계정에서 실행됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 instance type 선택 가능.. 본인 어플리케이션에 적합한 것으로 주문&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스 생성 : EC2 - Instances - launch an instance&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 키페어 : .pem(리눅스, win10+, mac) .ppk(win7,8)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 기본적으로 EBS는 인스턴스 삭제시 같이 삭제되게 세팅됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 사용자 데이터 : 시작할 때 세팅될 shell script임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Instance Stop 하면 AWS는 Stop한 시간에 대해서는 요금 부과 X.. 단, 다시 시작시 public IP는 바뀌게 됨(private IP는 안바뀜)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Terminate Instance 하면 삭제가 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`EC2 Instance Types - Overview&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 7개의 Instance Type이 있고, 각 Type에는 여러 제품 군이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- naming convention : ex) m5.2xlarge&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - m : instance class&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 5 : generation&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 2xlarge : instance class 안에서 크기(클 수록 더 많은 메모리와 CPU를 가짐)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;General Purpose(범용 인스턴스)&lt;/b&gt; : 웹 서버나 코드 저장소와 같은 다양한 작업에 맞음, 컴퓨팅/메모리/네트워크 간의 밸런스가 좋음 (ex. t2.micro)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Compute Optimized(컴퓨팅 최적화 인스턴스, 'C'로 시작하는 Naming)&lt;/b&gt; : 고성능 프로세서로 일부 데이터의 일괄처리(Batch processing), Media transcoding, 고성능 웹서버, 고성능 컴퓨팅(HPC), 머신 러닝, 전용 게임 서버&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Memory Optimized(메모리 최적화, 'R'로 시작하는 Naming+X1,Z1)&lt;/b&gt; : 대규모 데이터셋을 처리하는 유형에 빠른 성능을 가짐... 고성능의 관계형/비관계형 데이터베이스, 일라스틱 캐시(분산 웹스케일 캐시 저장소), BI(business intelligence), 대규모 비정형 데이터 실시간 처리&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Storage Optimized(스토리지 최적화, 'I', 'D', 'H1'으로 시작하는 Naming)&lt;/b&gt; : 로컬 스토리지에서 대규모의 데이터셋에 액세스할 때 적합함... 고주파 온라인 트랜잭션 처리(OLTP) 시스템, 관계형 &amp;amp; NoSQL 데이터베이스, in-memory DB(Redis), 데이터 웨어하우징 어플리케이션, 분산 파일 시스템&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Security Groups(보안 그룹)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;네트워크 보안의 기본, EC2 안밖으로 트래픽 허용방식 결정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- allow rule만 있음, IP나 다른 security group을 참조함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Inbound traffic (밖 -&amp;gt; 안) / Outbound traffic(안 -&amp;gt; 밖)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Ports, IP범위(IPv4, IPv6) 제어&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 0.0.0.0/0 는 모든 것 의미&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안그룹과 인스턴스 사이에는 N:M 관계&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;보안 그룹은 특정 지역과 VPC 조합에서만 제한됨 -&amp;gt; 다른 지역이나 VPC에서는 보안그룹을 다시 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SG는 EC2 밖에 있어서 트래픽이 차단되면 EC2인스턴스는 트래픽을 볼 수도 없음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- SSH 액세스를 위해서 별도의 보안 그룹을 하나 유지하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Time out 나면 SG 문제일 가능성 높음, 연결 거부되면 SG는 통과했고 내부 어플리케이션 error일 가능성 높음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;다른 SG를 참조하기&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스의 IP와 관계없이 올바른 보안 그룹을 연결해서 다른 인스턴스와 직접 통신 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) A인스턴스에서 SG1을 갖고 있고, SG1에서 SG1, SG2를 허용하고 있다면, SG2가 연결된 B인스턴스에서 인스턴스 IP와 관계없이 직접 통신이 가능함... SG1이 연결된 C인스턴스도 마찬가지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Well Known Ports&lt;/b&gt; : 22(SSH), 21(FTP), 22(SFTP, 안전한 파일전송 프로토콜), 80(HTTP), 443(HTTPS), 3389(RDP, 윈도우 인스턴스에 연결)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SSH 요약&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;터미널이나 명령줄을 이용하여 원격 머신이나 서버를 제어할 수 있게 해줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SSH : Mac, Linux, Win10+&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Putty : 모든 버전 Windows&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 Instance Connect : 모든 OS에서 웹 브라우저를 이용함(Amazon Linux에서만 동작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;접속 방법 : ssh -i key_pair.pem ec2-user@public_IP&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 초기에 Amazon Linux OS에는 ec2-user라는 사용자 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;* 이때 pem permission은 chmod 0400 으로 바꿔줘야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 Instance Connect 로 웹에서 접속도 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 인스턴스 IAM Role&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스 내부에서 aws configure를 통해 개인정보 입력시, 누구라도 EC2에 접속해서 자격 증명 정보를 획득할 수 있음 (즉, 좋지 않은 방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM Role을 부여해서 자격 증명을 할 수 있게 해야함&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;IAM Role 추가 방법 : EC2 - 인스턴스 선택 - Action(작업) - Security - IAM 역할 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 인스턴스 구매 옵션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;On-Demand 인스턴스&lt;/b&gt; : 단기적 워크로드에 좋음, 필요한 대로 인스턴스 실행, 비용 예측 가능, 초 단위 요금 지불&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- linux, windows : 1분 이후에 초 단위로 쓴만큼 청구됨 / 나머지 OS : 1시간 단위로 청구됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 초기 비용 X, 장기 약정도 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 단기적이고 중단없는 워크로드가 필요할 때, 애플리케이션의 거동을 예측할 수 없을 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Reserved 인스턴스 (예약 인스턴스)&lt;/b&gt; : 장기간의 워크로드를 위한 것, 오랫동안 DB를 실행할 계획&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 온디맨드에 비해 72% 할인 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 특정한 인스턴스 속성(type, region, tenancy, OS) 예약&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 1년/3년 단위로 선결제/부분선결제/선결제없음 선택할 수 있음, 전체 선결제시 최대할인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 범위를 특정 리전이나 zone으로 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 사용량이 일정한 DB와 같은 애플리케이션에 사용하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 마켓플레이스에서 사고 팔 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- &lt;b&gt;Convertible Reserved 인스턴스(전환형 예약 인스턴스)&lt;/b&gt; : 유연한 인스턴스 타입 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp; - 속성 변경 가능.. 할인은 약간 적음(최대 66%)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Saving Plans&lt;/b&gt;: 달러 단위로 특정한 사용량을 약정, 장기 워크로드(즉, 돈을 픽스해두는거)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 장기간 사용하면 72%까지 할인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 1 or 3년을 시간당 10$로 약정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 사용량이 한도를 넘으면 온디맨드 가격으로 청구&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 특정 인스턴스, 패밀리, 리전으로 고정됨 / instance size, os, tenancy는 전환 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Spot Instance&lt;/b&gt; : 초단기 워크로드, 저렴하지만, 인스턴스들이 손실될 수 있어 신뢰성 낮음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 최대 90%까지 할인&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Spot 인스턴스에 지불할 최대 가격을 정의하고, 만약 그 가격보다 높아지면 인스턴스 손시로딤&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가장 비용 효율적이고, 고장에 대한 회복력이 있다면 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Batch jobs, Data analysis, Image processing, 분산형 워크로드, 시작과 종료가 유연한 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`- 단 중요한 작업이나 DB에는 적절하지 않음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Dedicated Host(전용 호스트)&lt;/b&gt; : 물리적 서버 전체를 예약해서 인스턴스 배치를 제어 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온디맨드, 예약 둘 다 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가장 비싼 옵션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 활용 사례 : 라이센싱 모델과 함께 제공되는 SW의 경우 즉 BYOL(Bring Uour Own License, ex) 소켓, 코어, VM 소프트웨어 ), 법규를 반드시 준수해야하는 회사&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Dedicated Instance(전용 인스턴스)&lt;/b&gt;&amp;nbsp;: 다른 고객과 하드웨어를 공유하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 전용 하드웨어에서 실행.. 물리적 서버와는 다름&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 같은 계정에서 다른 인스턴스와 함께 하드웨어 공유 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스 배치에 관한 통제권이 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`Dedicated Host : 물리적 서버 자체에 대한 접근권을 갖고, 낮은 수준의 하드웨어에 대한 가시성 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`Dedicated Instance : 자신만의 인스턴스를 자신만의 하드웨어에 갖는다는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Capacity Reservations(용량 예약)&lt;/b&gt; : 원하는 기간 동안 특정 AZ에 용량 예약 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 필요할 때마다 용량에 접근 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 기간에 대한 약정은 없어서, 언제라도 용량을 예약하고 취소할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 청구할인도 없어서, 그저 용량을 예약하는게 유일한 목적임&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스 실행여부와 무관하게 온디맨드 요금 부과&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 할인받고 싶으면 예약 인스턴스나 절약 플랜과 결합해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 특정한 AZ에 있어야하는 단기적이고 중단없는 워크로드에 적합&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Spot Instance 요청&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최대 스팟 가격을 정의하고, 지금 가격이 그보다 낮다면 해당 인스턴스를 유지함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 시간당 스팟은 오퍼와 용량에 따라 달라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 만약 현재 스팟 가격이 최대 가격 초과시 2분의 유예기간을 주고 양자 택일 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 인스턴스를 중지(가격이 내려가면 다시 시작) / 인스턴스 종료(다음엔 새로운 EC2로 시작)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- [Deprecated] 스팟 인스턴스를 회수당하지 않으려면, 스팟 블록 이용 가능 : 스팟 블록은 지정 기간동안 스팟 인스턴스를 차단하는 것.. 1~6시간 까지 가능하고, 그동안 중단 없이 해당 블록 사용 가능, 드물게 회수되는 경우 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AZ에 따라 스팟 가격은 달라짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;스팟 인스턴스 종료 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;스팟 인스턴스는 일회성 요청을 하거나, 영구 인스턴스 요청을 할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;일회성 요청 : 스팟 요청 완료되는 즉시 인스턴스 시작(스팟 요청은 사라짐)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;영구 요청 : 스팟 요청이 유효한 기간 동안 스팟 인스턴스가 중단되어도 다시 스팟 요청이 생성됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;` - 영구요청시 스팟 인스턴스를 종료하는게 아닌, 스팟 요청을 먼저 취소하고나서 스팟 인스턴스를 종료해야 완전히 종료가 됨&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Spot Fleets&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; * 스팟 플릿을 사용하면 여러 개의 런치 풀과 여러 인스턴스 유형 정의 가능 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;스팟 인스턴스 세트를 정의하는 방법 (optional, + 온디멘드 인스턴스 세트도 같이 정의 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정의한 가격 제한으로 목표 용량을 줄이기 위해 노력함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 가능한 런치 풀을 정의 : instance type, OS, AZ&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 플릿이 가장 적합한 런치 풀을 선택함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 스팟 플릿이 예산에 도달하거나, 원하는 용량에 도달하면 인스턴스 시작을 중단함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 장점 : 스팟 플릿은 스팟 인스턴스를 기반으로 추가 비용 절감 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`스팟 플릿에 스팟 인스턴스를 할당하는 전략&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 1. lowestPrice(&lt;b&gt;최저가격&lt;/b&gt;)&lt;/b&gt;&amp;nbsp;: 스팟 플릿은 가장 낮은 가격인 풀에서 인스턴스를 시작 (비용 최적화, 워크로드가 짧을 때 좋은 옵션)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 2. diversified(* 다양한)&lt;/b&gt; 다양한 방법으로 스팟 인스턴스 실행 : 정의한 모든 풀에 분산 (가용성과 긴 워크로드에 적합.. 한 풀이 사라져도 다른 풀이 활성화되있기 때문)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 3. capacity Optimized(용량 최적화)&lt;/b&gt; : 원하는 인스턴스 수에 맞는 최적의 용량을 가진 풀을 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - 4. priceCapacity Optimized(가격 용량 최적화)&lt;/b&gt; : 먼저 사용 가능한 용량이 가장 큰 풀을 선택하고 그 중 가격이 가장 낮은 풀을 선택하는 방식(대부분 워크로드에서 적합한 방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* Spot Instance 요청 하는 경우&lt;/b&gt; : 원하는 인스턴스 유형과 AZ를 정확히 알고 있는 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;* Spot Fleets 요청하는 경우&amp;nbsp;&lt;/b&gt;: 조건(ex. 낮은 가격)을 만족하는 모든 인스턴스 유형과 모든 AZ를 선택하라는 것..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;spot instance는 온디맨드 만들 때처럼 하다가 옵션에서 spot instance 선택하면 되고, spot request에서 요청하면 Spot Fleet으로 요청됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;EC2 - SAA level&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공용 IP vs 사설 IP&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS는 IPv4, 6을 둘 다 지원함(IPv6은 주로 사물 인터넷에 많이 쓰임)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;IPv4는 3.7B(37억)개의 서로 다른 주소 허용.. 거의 고갈되어감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사설 네트워크 내에서는 사설 IP를 써서 서로 통신 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공용 게이트웨이인 인터넷게이트 웨이를 이용해서, 사설 망에서 www으로 액세스 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Public IP : 기기가 인터넷 상에서 식별될 수 있음을 의미, 전체 웹에서 유일함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Private IP : 오직 사설 네트워크 안에서 식별되고, 그 안에서만 유일하면 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- NAT 장치와 프록시 역할을 할 인터넷 게이트 웨이를 통해서 인터넷에 연결됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 지정된 범위의 IP만 사설 IP로 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Elastic IP&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 인스턴스를 시작하고 중지할 때 공용 IP를 바꿀 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스에 고정된 공용 IP를 쓰려면 Elastic IP(공용 IPv4)가 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 삭제하지 않으면 계속 유지되고, 한번에 한 인스턴스에서만 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 탄력적 IP 주소를 쓰면, 한 인스턴스에서 다른 인스턴스로 빠르게 이동시켜, 인스턴스나 소프트웨어의 오류를 마스킹할 때 사용 가능..&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 계정당 5개까지만 쓸 수 있음(AWS에 더 달라고 할 수 는 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Elastic IP는 지양하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 좋지않은 아키텍쳐 결정으로 언급됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 임의의 공용 IP를 써서 DNS 이름을 할당하는게 좋음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 로드 밸런서를 사용해서 공용 IP를 사용하지 않을 수도 있음(최상이 패턴)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;VPN이 없다면 공용 IP만 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기기가 멈췄다가 재시작하면 공용 IP가 바뀔 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 탄력적 IP는 이런 경우에 공용 IP를 유지할 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, 탄력적 IP는 쓰던 안쓰던 생성만해도 약 3.5$/월 의 비용발생(프리티어에서 1달 750시간은 무료)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 Placement Groups(배치 그룹)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스가 AWS 인프라에 배치되는 방식을 제어할 때 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;배치 그룹을 이용해서 전략 정의 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 1. Cluster(클러스터)&lt;/b&gt; : 단일 AZ에서 지연 시간이 짧은 하드웨어 설정으로 인스턴스를 그룹화&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 모든 EC2가 동일한 AZ에 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 장점 : 인스턴스간 좋은 네트워크가 장점(10Gbps 대역폭), 지연 시간이 짧고 처리량이 많은 네트워크 확보 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 단점 : AZ에 장애가 발생하면, 모든 인스턴스 동시에 장애&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 사례 : 빠른 네트워킹이 필요한 빅데이터 작업, 애플리케이션의 각 인스턴스 간 지연 시간이 매우 짧고 처리량이 많은 네트워크가 필요할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 2. Spread(분산)&lt;/b&gt; : 모든 EC2 인스턴스가 다른 하드웨어에 분산됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - AZ별로 분산된 배치그룹 당 7개의 인스턴스만 가질 수 있다는 제약 존재&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 크리티컬 애플리케이션이 있을 때, 분산 배치 그룹을 이용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 장점 : 동시 실패의 위험이 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;`&amp;nbsp; - 단점 : 배치 그룹의 AZ 당 7개의 인스턴스로 제한(배치 그룹 규모에 제한)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 사례 : 가용성 극대화, 위험 최소화 애플리케이션, 인스턴스 오류를 서로 격리해야하는 크리티컬 애플리케이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 3. Partition(분할)&lt;/b&gt; : 분산과 비슷하지만, 여러 파티션에 인스턴스가 분할되어 있고, 파티션은 AZ 내의 다양한 하드웨어 랙 세트에 의존하게 됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 인스턴스가 분산되어 있지만, 다른 실패로 부터 격리되지 않음, 하지만 파티션은 다른 오류 파티션과 격리됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - 그룹 당 수백 개의 EC2 인스턴스를 통해 확장 가능(하둡, 카산드라, 카프카와 같은 애플리케이션 실행 가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AZ 당 최대 7개의 파티션(=AWS의 HW 랙)이 있을 수 있음(파티션 안에 인스턴스 수는 100개+), 리전 내 여러 AZ에 생성 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- metadata 서비스를 이용해 각 인스턴스가 어느 파티션에 위치하는지 알 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : 파티션들 전반에 거렻 데이터와 서버를 퍼뜨려 두도록, 파티션 인식이 가능한 애플리케이션의 경우에 사용할 수 있음(HDFS, HBase, Cassandra, Apache Kafka : 빅데이터 어플리케이션)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;배치 그룹 사용 : EC2 - 배치 그룹 - 배치 그룹 생성.. - 인스턴스 - 인스턴스 생성 - 고급 - 배치 그룹 이름 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ENI(탄력적 네트워크 인터페이스)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;VPC의 논리적 구성요소이며, 가상 네트워크 카드를 나타냄&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ENI는 EC2 인스턴스가 네트워크에 액세스할 수 있게 함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ex) 한 AZ에 EC2 인스턴스가 기본 ENI인 Eth0에 연결되어, 사설 IP로 네트워크 연결을 제공함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;언제든지, 다른 사설 IP로 새로운 ENI인 Eth1 추가 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ENI 속성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- primary 사설 IPv4를 가지고, 하나 이상의 secondary IPv4를 가질 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 각 ENI는 사설 IPv4당 탄력적 IPv4를 갖거나, 하나의 공용 IPv4를 가질 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 즉, 사설/공용 IP가 하나씩 제공됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 개 이상의 SG를 연결할 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MAC 주소도 연결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 인스턴스와 독립적으로 ENI를 생성하고 즉시 연결하거나, 장애 조치를 위해 EC2 인스턴스에서 땔 수도 있다. ENI는 특정 AZ에 바인딩됨(다른 AZ에서는 못씀)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉, 장애가 생겼을 때 사설 IP 자체를 다른 인스턴스로 이동시킬 수 있는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사설 정적IP로 EC2에 접근할 때 장애 조치를 위해 유용함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EC2 Hibernate(절전모드)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 Stop : EBS 디스크는 다시 시작할 때까지 그대로 유지&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- EC2 Terminate : root 볼륨이 삭제되게 설정되었다면 삭제됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;EC2 최초 시작 : OS boots &amp;amp; EC2 User Data Script 런 -&amp;gt; 시간이 걸림&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;EC2 Hibernate&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인메모리(RAM) 상태가 보존됨 == 인스턴스 부팅이 더 빨라짐(OS가 멈추거나 재시작하는게 아니라 그대로 멈춘거임)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 백그라운드에서 RAM에 기록되었던 인 메모리 상태는 root 경로의 EBS 볼륨에 기록됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 루트 EBS 볼륨은 암호화됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단, RAM을 기록할만큼 EBS 용량 충분해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 과정 : EC2 중지 -&amp;gt; RAM 내용은 EBS 볼륨에 덤프됨 -&amp;gt; EC2 종료 -&amp;gt; 재시작시 디스크에서 RAM을 불러와 EC2 인스턴스 메모리로 가져옴&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사례 : long-running processing, RAM 상태를 저장하고 싶을 때, 빠르게 재부팅하고 싶을 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 많은 인스턴스 제품군에서 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 인스턴스 RAM 크기는 150GB 이하여야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 베어 메탈 인스턴스는 불가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AMI는 리눅스, 윈도우 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 루트볼륨은 무조건 EBS여야하고, 암호화 필요, 충분한 용량 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 온디맨드, 예약, 스팟 인스턴스 다 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 최대 60일까지 사용 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;인스턴스 생성시 Stop - Hibernate behavior을 활성화하고, EBS 볼륨의 암호화를 Yes해야 절전 모드로 둘 수 있음&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS</category>
      <category>AWS Budget</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws ec2</category>
      <category>AWS ENI</category>
      <category>AWS SAA</category>
      <category>aws saa 자격증</category>
      <category>aws 자격증 취득 후기</category>
      <category>awsebs</category>
      <category>ec2 절전모드</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/93</guid>
      <comments>https://pypystory.tistory.com/93#entry93comment</comments>
      <pubDate>Sun, 11 Aug 2024 19:01:22 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS 기술 정리 1편 리전과 AZ, IAM - (AWS SAA, Udemy 강의 정리)</title>
      <link>https://pypystory.tistory.com/92</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PfpXy/btsIX5LB0Hi/wLdOIAaCMGfUsyAXguAy0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PfpXy/btsIX5LB0Hi/wLdOIAaCMGfUsyAXguAy0K/img.png&quot; data-alt=&quot;https://aws.amazon.com/ko/certification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PfpXy/btsIX5LB0Hi/wLdOIAaCMGfUsyAXguAy0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPfpXy%2FbtsIX5LB0Hi%2FwLdOIAaCMGfUsyAXguAy0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;300&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://aws.amazon.com/ko/certification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;이 글은 24년 하반기 AWS Certified Solutions Architect - Associate(이하 AWS SAA-C03) 자격증 취득을 위해서 아래 유데미 강의를 보고, 공부한 내용을 정리하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.udemy.com/course/best-aws-certified-solutions-architect-associate&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS 시작하기&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;On-Premise : 물리적인 서버를 직접 설치하여 운영&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;On-Demand :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #4d5156; text-align: left;&quot;&gt;소비자가 있는 곳까지 찾아가서 상품과 서비스를 전달하는 것, 소비자의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; letter-spacing: 0px;&quot;&gt;요구 사항에 따라 즉시 제공하는 방식 (*demand : 수요)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; letter-spacing: 0px;&quot;&gt;리전 및 AZ&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Regions&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터 센터의 집합 (ex. us-east-1) 대부분의 서비스는 특정 리전에 연결되어 국한됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;A 리전에서 쓰던 서비스를 다른 리전에서 쓰려고하면 서비스를 처음 사용하는 셈이 되는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 리전 선택 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 법률 준수 : 특정 국가는 자국 내에 데이터를 둬야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 지연시간(latency) : 지리적으로 가까운 곳 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 서비스 유무 : 특정 리전엔 특정 서비스가 없을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 요금 : 리전마다 요금 차이가 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS Availablity Zones&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 리전은 3~6개의 AZ를 가짐 (ex. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ap-southeast-2a,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ap-southeast-2b,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;ap-southeast-2c)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 가용 영역은 여분의 전원, 네트워크, 통신을 가진 1,2개의 데이터 센터로 이뤄짐 -&amp;gt; 재난 발생에 대비해서 분리되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;데이터 센터끼리 높은 대역폭의 초저지연 네트워크로 서로 이어져있음 -&amp;gt; 합쳐져서 리전을 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Edge Location&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전송 지점, Points of Presence&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;40개 국가, 90+ 도시에, 400+ 전송지점을 가짐. 적은 latency를 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;글로벌 서비스 : ex) IAM, Route53, CloudFront, WAF&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;리전 국한 서비스 : ex) EC2, Lambda&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;b&gt;IAM (Identity and Access Management)&amp;nbsp;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Users &amp;amp; Groups&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Root account 계정 관리에만 사용해야하고,&amp;nbsp;Users를 생성해서 권한을 부여해 사용해야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 하나의 사용자는 조직 내의 한 사람에 해당, 그룹으로 유저를 묶을 수도 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 그룹에는 사용자만 배치가능, 그룹에 그룹 배치 불가, 어느 그룹에도 속하지 않는 유저 존재 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 사용자가 다수의 그룹에 존재 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Permissions&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- JSON 문서로 권한 정의, user가 aws 서비스를 이용하도록 허용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS에서는 least privilege principle(최소 권한의 원리) 적용.. 꼭 필요로 하는 권한 이상을 주지 않는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;유저 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;gt;&amp;gt; IAM - Users - IAM 사용자 생성 - 유저명 - IAM User 생성 - pw 추가 - 권한 추가 - tag추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(* tag는 리소스에 메타데이터를 제공할 수 있게 해줌)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;최초 계정 생성 이후 루트 계정 대신 &lt;b&gt;관리자 사용자 생성 (admin group - AdministratorAccess)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;gt;&amp;gt; Account Alias(account ID 대용으로 유일해야함) 생성 후 로그인 URL 간소화 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM Policies inheritance&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(* inheritance: 상속)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인라인 정책 - 특정 사용자에게 1:1로 연결되는 정책&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;정책 구조와 정책 명명법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Version : 보통 2012-10-17로 정책 언어 버전&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Id : 정책을 식별하는 id, optional&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Statement(문장) : 1&amp;lt;= n개로 이뤄짐, required&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Sid : 문장의 식별자, optional (ex. 1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;b&gt; - `Effect : 이 정책이 허용인지 거부인지 Allow, Deny 설정 (ex. Allow) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - `Principal : 이 정책이 적용될 사용자/계정/역할 로 구분 (ex. &quot;AWS&quot;: [&quot;arn:aws:iam::1234567890:root&quot;]) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - `Action : 이 정책에 의해 허용/거부 되는 API 호출의 목록 (ex. [&quot;s3:GetObject&quot;]) &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp; - `Resource : 적용될 action의 리소스의 목록 (ex. [&quot;arn:aws:s3:::mybucket/*&quot;])&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - Condotion : 문장이 언제 적용될지 결정, optional&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;IAM 실습&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;유저에게 권한 부여 : IAM - User - Add permissions - (그룹추가/권한복사/직접정책추가) - Permissions policies 중 선택.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그룹 생성 : IAM - Create user group - 유저 추가 유무 - 그룹 권한 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;admin IAM 의 policy 형태 (모든거에 full access)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;{&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &quot;Effect&quot;: &quot;Allow&quot;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &quot;Action&quot;: &quot;*&quot;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &quot;Resource&quot;: &quot;*&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;}&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Action 분석 예시 : &quot;iam:Get*&quot; : iam에서 Get으로 시작하는 모든 API 호출이 허용됨 GetUsers, GetGroups...&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;나만의 policy 생성가능, JSON이나 visualEditor로 생성가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM MFA&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;IAM-Password Policy&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- 최소 PW 길이나, 특정 문자형, PW만료기간, re-use 정책을 설정&amp;nbsp;가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;`MFA(Multi Factor Authentication)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- MFA = PW + Security device 이용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;- PW 도난이나, 해킹당해 잊어버린 경우에 계정 손상을 막아줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&amp;nbsp;- `종류&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- Virtual MFA device(하나의 전화기에서만 작동하는, Google Authenticator/Authy)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- U2F(Universal 2nd Factor) Security Key : ex) YubiKey(타사 제품 - USB형태 물리적장치로 단일보안키 지원)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- Hardware Key Fob MFA Device : ex) Gemalto(타사 제품 - TOTP물리적장치)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; &amp;nbsp;- AWS GovCload US를 이용한다면 : SurePassID에서 제공하는 TOTP물리적장치 보안토큰&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;MFA 설정 : Security Credentials - select MFA device &amp;lt;- 최대 8개의 MFA 등록 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS 액세스 키, CLI, SDK&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS 액세스하는 방법 3가지 : AWS Management Console(웹), AWS CLI(터미널), AWS SDK(코드)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Access Key, Secret Access Key 생성 가능...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;CLI를 사용하면 AWS서비스의 public APIs로 직접 접근 가능 -&amp;gt; Open Source&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS CLI는 사실 Boto라는 Python용 AWS SDK에 구축되어 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;AWS CLI에서 액세스 키(AK) / 시크릿 키(SK) 등록시&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. aws configure&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. AK, SK, default region 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;aws iam list-users 로 유저 리스트 확인 가능 (단 ListUsers 권한이 있어야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AWS CloudShell&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; * 단 특정 리전에서만 쓸 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- aws 에서 무료로 쓸 수 있는 터미널과 같음&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 단 Console에 로그인 되어있는 사용자의 permission을 따라감&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- '--region' 인자로 API 호출을 할 리전 설정 가능, default는 현재 로그인된 리전&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 저장소가 유지되어서 upload/dowload file 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;`IAM Roles for Services&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 몇몇의 AWS 서비스는 우리의 계정에서 실행되어야함, 사용자와 마찬가지로 권한부여 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM Role은 AWS 서비스에 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;AWS에서 작업을 수행할 수 있는 권한을 부여하는 것&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- IAM Role은 사용자와 같지만, 실제 사람이 아닌 AWS 서비스에 의해 만들어지는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- ex) EC2 인스턴스가 AWS에 있는 어떤 정보에 접근하려고 할 때, IAM Role 객체에 의해 권한을 부여받아야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp; - EC2, Lambda, CloudFormation 등에서 필요로함&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;role 생성 방법 : IAM Role - 신뢰할 수 있는 entity type 선택(AWS service) - Use case(적용할 서비스) - Add permission(예를들어 EC2가 IAM을 읽을 수 있게 하려면, 여기서 IAMReadOnlyAccess를 선택) - Role name&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;자격 증명 보고서(Credential report) - CSV 형태로 파일 얻을 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- MFA 활성여부, Access Key 여부, 마지막 PW 변경 일시 등 보안 측면 검토 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;IAM Access Advisor : 어떤 사용자가 언제 어떤 서비스에 접근했는지 확인 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자가 올바른 권한을 가지고 있는지 실제로 확인가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IAM 모범 사례&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- Root 계정은 계정 세팅 외에는 사용하지 않을 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 한 명의 AWS 사용자는 한 명의 물리적 사용자와 동일할 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 사용자를 생성하고, 그룹에 할당해서 보안이 그룹 수준에서 관리되도록 할 것&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 강력한 PW 정책과 MFA를 사용할 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- AWS 서비스에 권한을 부여할 때, 역할을 생성하고 사용할 것&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 프로그램에서 액세스할 땐 AK를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;- 자격 증명 보고서와 액세스 관리자로 권한을 감시할 것&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>AWS</category>
      <category>AWS Certified Solutions Architect - Associate</category>
      <category>aws edge location</category>
      <category>aws iam</category>
      <category>AWS SAA</category>
      <category>aws saa 시험준비</category>
      <category>aws saa 자격증</category>
      <category>aws saa-03 준비</category>
      <category>aws 가용 영역</category>
      <category>aws 리전</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/92</guid>
      <comments>https://pypystory.tistory.com/92#entry92comment</comments>
      <pubDate>Fri, 9 Aug 2024 23:56:32 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] SQS+Lambda로 task queue 만들기, 반복되는 Long-Run 작업 안정적으로 처리하기</title>
      <link>https://pypystory.tistory.com/89</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgpgdr/btsIiVoOzDj/fFgKAk9mpHSshkbXyLBKSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgpgdr/btsIiVoOzDj/fFgKAk9mpHSshkbXyLBKSk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgpgdr/btsIiVoOzDj/fFgKAk9mpHSshkbXyLBKSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdgpgdr%2FbtsIiVoOzDj%2FfFgKAk9mpHSshkbXyLBKSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;200&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;b&gt;사용목적&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;현재 이메일 분류 관련 프로젝트를 진행하고 있습니다. 이메일을 분류하는 AI 모델이 있는데, 문제는 분류에 1개의 메일 당 2초 이상 걸리게 되었습니다. 사용자가 요청했을 때 실시간으로 분류하기에 메일 당 2초도 너무 긴 시간이고,&amp;nbsp; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;실시간으로 서비스를 제공하지 않더라도, batch 작업에서 병목이 생기기엔 충분했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;처음에는 그냥 lambda에 cron 작업을 걸어서 돌릴 생각이었지만, 유저가 1명 가입할 때마다 평균 3000개 이상의 이메일 분류가 필요한데,&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;lambda에 최대 실행 시간이 15분으로 정해져있고, 여러 경로에서 이메일 분류를 요청하는 상황에서, 분류부터 DB 저장까지 안정적인 처리가 필요했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;725&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWT0bk/btsIjeIsRbm/vo3uZN6FD0kKxaxvYoa1P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWT0bk/btsIjeIsRbm/vo3uZN6FD0kKxaxvYoa1P1/img.png&quot; data-alt=&quot;아키텍처 구성도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWT0bk/btsIjeIsRbm/vo3uZN6FD0kKxaxvYoa1P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWT0bk%2FbtsIjeIsRbm%2Fvo3uZN6FD0kKxaxvYoa1P1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;427&quot; data-origin-width=&quot;1317&quot; data-origin-height=&quot;725&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아키텍처 구성도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙적으로 분류가 안된 email_id를 찾아서 SQS에 넘겨주면, Consumer가 DB에서 email_id에 대한 내용을 조회하고, 분류를 한 뒤 그 결과를 RDS에 update 하는 방식이며, Spring 백엔드에서는 유저의 최초가입 등 특수한 상황에서 간헐적으로 SQS에 분류 요청을 보내게 됩니다.&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;b&gt;실행환경&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lambda : Python 3.12, arm64&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SQS : standard&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;b&gt;구성과정&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Consumer Lambda 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- 이때 SQS 권한을 넣어줘야, 나중에 따로 IAM을 안만져도 됩니다. 그리고 새 역할을 만들어야 cloudwatch 등 lambda 필수 권한들도 default로 들어가게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMctdZ/btsIk205Cza/yQzd1XLk6mkCq4MLbsiDn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMctdZ/btsIk205Cza/yQzd1XLk6mkCq4MLbsiDn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMctdZ/btsIk205Cza/yQzd1XLk6mkCq4MLbsiDn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMctdZ%2FbtsIk205Cza%2FyQzd1XLk6mkCq4MLbsiDn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;581&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 SQS에서 주는 message는 아래와 같은 형식을 가집니다.&lt;/p&gt;
&lt;pre id=&quot;code_1719831932724&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;{
  &quot;Records&quot;: [
    {
      &quot;messageId&quot;: &quot;059f36b4-87a3-44ab-83d2-661975830a7d&quot;,
      &quot;receiptHandle&quot;: &quot;AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...&quot;,
      &quot;body&quot;: &quot;message123!@#&quot;,
      &quot;attributes&quot;: {
        &quot;ApproximateReceiveCount&quot;: &quot;1&quot;,
        &quot;SentTimestamp&quot;: &quot;1545082649183&quot;,
        &quot;SenderId&quot;: &quot;AIDAIENQZJOLO23YVJ4VO&quot;,
        &quot;ApproximateFirstReceiveTimestamp&quot;: &quot;1545082649185&quot;
      },
      &quot;messageAttributes&quot;: {},
      &quot;md5OfBody&quot;: &quot;098f6bcd4621d373cade4e832627b4f6&quot;,
      &quot;eventSource&quot;: &quot;aws:sqs&quot;,
      &quot;eventSourceARN&quot;: &quot;arn:aws:sqs:us-east-1:111122223333:my-queue&quot;,
      &quot;awsRegion&quot;: &quot;us-east-1&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 handler 함수를 만들면 body의 message123!@# 부분을 읽어올 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1719831869191&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def lambda_handler(event, context):
    records = event['Records']
    
    for record in records:
        recordBody = json.loads(record['body'])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. SQS 생성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로운 SQS를 만들어줍니다. 본인은 선입선출이 보장될 필요는 없어서, Standard Queue를 사용했습니다. 요금이나 각각의 장단점이 존재하니 각자 도메인에 맞는 queue를 선택하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;526&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biX4LV/btsIkrGUTEY/bZxezsy0Atj3qZQpTQMx10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biX4LV/btsIkrGUTEY/bZxezsy0Atj3qZQpTQMx10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biX4LV/btsIkrGUTEY/bZxezsy0Atj3qZQpTQMx10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiX4LV%2FbtsIkrGUTEY%2FbZxezsy0Atj3qZQpTQMx10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1314&quot; height=&quot;526&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;526&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. SQS 트리거 추가&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0OUVR/btsIjbE2UJf/kXqFhgxVk0j04F5KK0aMJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0OUVR/btsIjbE2UJf/kXqFhgxVk0j04F5KK0aMJk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0OUVR/btsIjbE2UJf/kXqFhgxVk0j04F5KK0aMJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0OUVR%2FbtsIjbE2UJf%2FkXqFhgxVk0j04F5KK0aMJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;813&quot; height=&quot;403&quot; data-origin-width=&quot;813&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lambda로 돌아와 '트리거추가'를 해줍니다. SQS를 고르고 (2)에서 만든 SQS 대기열을 선택해줍니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 연결되었는지 확인해보기 위해 테스트 메시지를 송신해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V5hdX/btsIidp1DaN/PE4Zv7eCG9Z1GucHpy0MI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V5hdX/btsIidp1DaN/PE4Zv7eCG9Z1GucHpy0MI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V5hdX/btsIidp1DaN/PE4Zv7eCG9Z1GucHpy0MI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV5hdX%2FbtsIidp1DaN%2FPE4Zv7eCG9Z1GucHpy0MI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1750&quot; height=&quot;490&quot; data-origin-width=&quot;1750&quot; data-origin-height=&quot;490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 SQS 메뉴를 보면, 웹 콘솔에서 메시지를 생성할 수 있습니다.&amp;nbsp;&lt;/p&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;b&gt;4. Producer lambda 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지를 넣어줄 producer를 만들어줍니다. consumer를 만들때와 동일하게 lambda를 생성해주면됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1719832720207&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;def lambda_handler(event, context):

	...
    
    for idx in range(0, len(lst), 10):
        result = {'email_id': lst[idx:idx+10]}
        msg_body = json.dumps(result)
        msg = send_sqs_message(os.environ['SQS_QUEUE'], msg_body)

def send_sqs_message(sqs_queue_url, msg_body):
    sqs_client = boto3.client('sqs')
    msg = sqs_client.send_message(QueueUrl=sqs_queue_url, MessageBody=msg_body)
    return msg&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 코드는 다음과 같습니다. boto3 라이브러리를 이용해서 쉽게 SQS에 메시지를 보낼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2jjaT/btsIjICxLmc/d9JZmoUkLlyBz0TdQq7Ox1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2jjaT/btsIjICxLmc/d9JZmoUkLlyBz0TdQq7Ox1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2jjaT/btsIjICxLmc/d9JZmoUkLlyBz0TdQq7Ox1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2jjaT%2FbtsIjICxLmc%2Fd9JZmoUkLlyBz0TdQq7Ox1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1613&quot; height=&quot;316&quot; data-origin-width=&quot;1613&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 생성한 SQS_QUEUE의 URL을 lambda 환경변수에 추가해줘야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SQS Permission Error&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;임의의 테스트를 만들어서 Producer에서 SQS로 메시지를 보냈지만 permission 에러가 났습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;219&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vEl5s/btsIgCvKbB1/XTT055fUIuwkvUbTbLncKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vEl5s/btsIgCvKbB1/XTT055fUIuwkvUbTbLncKK/img.png&quot; data-alt=&quot;[ ERROR ] ClientError: An error occurred (AccessDenied) when calling the SendMessage operation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vEl5s/btsIgCvKbB1/XTT055fUIuwkvUbTbLncKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvEl5s%2FbtsIgCvKbB1%2FXTT055fUIuwkvUbTbLncKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1343&quot; height=&quot;219&quot; data-origin-width=&quot;1343&quot; data-origin-height=&quot;219&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[ ERROR ] ClientError: An error occurred (AccessDenied) when calling the SendMessage operation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;IAM에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; Producer Lambda를 만들 때 생성된 role을 찾아줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y0bd9/btsIj7a62v5/x5bTOxJCaTd6QknnErZ86k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y0bd9/btsIj7a62v5/x5bTOxJCaTd6QknnErZ86k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y0bd9/btsIj7a62v5/x5bTOxJCaTd6QknnErZ86k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy0bd9%2FbtsIj7a62v5%2Fx5bTOxJCaTd6QknnErZ86k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;76&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;76&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 SQSFullAccess 권한을 넣어주도록 하겠습니다. 엄격하게 Role을 관리하고 싶다면, 아마 Full까진 아니더라도 Send 권한 등 일부만 넣어줄 수 있습니다.&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;b&gt;5. Amazon EventBridge 일정 생성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 Producer를 일정한 주기마다 호출해주기 위해서 EventBridge 일정을 생성해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;779&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rgcyS/btsIjyGNpjJ/BXCSHmFEnVr9htag11R9J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rgcyS/btsIjyGNpjJ/BXCSHmFEnVr9htag11R9J0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rgcyS/btsIjyGNpjJ/BXCSHmFEnVr9htag11R9J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrgcyS%2FbtsIjyGNpjJ%2FBXCSHmFEnVr9htag11R9J0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;539&quot; data-origin-width=&quot;808&quot; data-origin-height=&quot;779&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정 생성방법은 공식 사이트나 블로그에서 자세히 설명된 글이 많으니 생략하겠습니다. 각자 도메인 기호에 맞게 생성해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvMXFY/btsIkHpmHuS/EhuxjMkGWZJpT5aJT0wpDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvMXFY/btsIkHpmHuS/EhuxjMkGWZJpT5aJT0wpDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvMXFY/btsIkHpmHuS/EhuxjMkGWZJpT5aJT0wpDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvMXFY%2FbtsIkHpmHuS%2FEhuxjMkGWZJpT5aJT0wpDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1576&quot; height=&quot;629&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cloudwatch에서 lambda의 output 값을 모니터링 해보면 정상적으로 동작하는 것을 알 수 있습니다.&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;b&gt;참고 문서&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sqs-example.html#with-sqs-create-test-function&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sqs-example.html#with-sqs-create-test-function&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://devblog.kakaostyle.com/ko/2017-05-13-1-aws-serverless-1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devblog.kakaostyle.com/ko/2017-05-13-1-aws-serverless-1/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.youtube.com/watch?v=xyHLX1dUwuA&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=xyHLX1dUwuA&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/code-library/latest/ug/python_3_sqs_code_examples.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/code-library/latest/ug/python_3_sqs_code_examples.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sqs.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-sqs.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>aws sqs</category>
      <category>lambda</category>
      <category>lambda cron</category>
      <category>lambda python</category>
      <category>lambda queue</category>
      <category>sqs permission</category>
      <category>sqs python</category>
      <category>sqs+lambda</category>
      <category>task queue</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/89</guid>
      <comments>https://pypystory.tistory.com/89#entry89comment</comments>
      <pubDate>Mon, 1 Jul 2024 20:34:56 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] Docker 이미지로 Lambda 함수 배포, python AI model 배포하기, 트러블슈팅, 대용량 파일 배포, ECR, API Gateway</title>
      <link>https://pypystory.tistory.com/88</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnxiV6/btsHMRtam3I/2M4o70CZ3J3NyQcbhiikd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnxiV6/btsHMRtam3I/2M4o70CZ3J3NyQcbhiikd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnxiV6/btsHMRtam3I/2M4o70CZ3J3NyQcbhiikd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnxiV6%2FbtsHMRtam3I%2F2M4o70CZ3J3NyQcbhiikd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;197&quot; height=&quot;197&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;0. 개발환경&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 3.12&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Desktop 4.30&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;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트 중 파이썬으로 개발된 AI 기능을 배포해야할 일이 생겼습니다. 항상 유지해야하는 서비스가 아닌 특정 시점에 Batch로 돌아가면되는 기능이라 EC2서버보다 lambda를 이용한 배포를 선택했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(지금 생각해보니 spot instance로 특정시점에 자동으로 생성했다가 사용하고 지우는 사이클을 짜는게 비용이 더 저렴했을 수도..?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python으로 학습된 모델 파일의 사이즈는 650MB로 람다에서 허용하고 있는 패키지 파일의 크기를 훌적 넘었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yGMqv/btsHNszG6s1/kPMsJaFttOYbClSks1bw21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yGMqv/btsHNszG6s1/kPMsJaFttOYbClSks1bw21/img.png&quot; data-alt=&quot;AWS Lambda 할당량&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yGMqv/btsHNszG6s1/kPMsJaFttOYbClSks1bw21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyGMqv%2FbtsHNszG6s1%2FkPMsJaFttOYbClSks1bw21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;144&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS Lambda 할당량&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링을 해본 결과 2가지 해결방법이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 큰 파일은 S3에 올리고, 런타임에 S3에서 다운로드 해서 사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Docker 컨테이너로 감싸서 ECR에 올리고, 그 이미지로 lambda 함수 생성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임에 600MB라는 파일을 다운로드 받으면 당연히 그만큼 속도가 느려지고, S3 데이터전송 요금까지 이중으로 부과할 수 있습니다. 그렇기에 Docker로 감싸서 lambda에 올리는 방법을 선택했습니다.&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;b&gt;2. 구조분석&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 아키텍처는 아래와 같습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KanEv/btsHLMsCpar/jy6kcA7JMVCenhd17H5PkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KanEv/btsHLMsCpar/jy6kcA7JMVCenhd17H5PkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KanEv/btsHLMsCpar/jy6kcA7JMVCenhd17H5PkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKanEv%2FbtsHLMsCpar%2Fjy6kcA7JMVCenhd17H5PkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;730&quot; height=&quot;411&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;1080&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 개발된 모델과 lambda_function 파일을 local에서 Docker Image로 만들어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. AWS CLI를 이용해서 ECR에 이미지를 올려주고, 해당 이미지로 lambda 함수를 생성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 백엔드 서버(Spring)가 올라간 EC2에서 lambda함수를 실행할 수 있도록, API Gateway가 lambda 함수를 호출하는 REST API를 생성합니다.&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;b&gt;3. 문제의 원인 및 해&lt;/b&gt;&lt;b&gt;결&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. [Errno&amp;nbsp;30]&amp;nbsp;Read-only&amp;nbsp;file&amp;nbsp;system:&amp;nbsp;'/home/sbx_user1051'&lt;/h3&gt;
&lt;pre id=&quot;code_1717400459922&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;errorMessage&quot;: &quot;[Errno 30] Read-only file system: '/home/sbx_user1051'&quot;,
  &quot;errorType&quot;: &quot;OSError&quot;,
  &quot;stackTrace&quot;: [
    &quot;  File \&quot;/var/task/lambda_function.py\&quot;, line 61, in handler\n    model = inferenceModel()\n&quot;,
    
    ...
    
    &quot;  File \&quot;/var/lang/lib/python3.8/os.py\&quot;, line 223, in makedirs\n    mkdir(name, mode)\n&quot;
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;람다에서는 Write가 가능한 디렉토리를 /tmp 로 제한하고 있습니다. python 코드에 포함된 라이브러리에서 실행할 때 외부에서 download 받는 동작이 있는데, 그 과정에서 mkdir을 시도하니 file system permission에 막혀버린 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 코드에서 pretrain된 데이터를 내려받을 때, 그 위치를 '/tmp'로 설정해서 해결할 수 있었습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717401630889&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# lambda_function.py

self.tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased', cache_dir='/tmp')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &quot;errorMessage&quot;:&amp;nbsp;&quot;RequestId:&amp;nbsp;...&amp;nbsp;Error:&amp;nbsp;Runtime&amp;nbsp;exited&amp;nbsp;with&amp;nbsp;error:&amp;nbsp;signal:&amp;nbsp;killed&quot;&lt;/h3&gt;
&lt;pre id=&quot;code_1717404284842&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;errorType&quot;: &quot;Runtime.ExitError&quot;,
  &quot;errorMessage&quot;: &quot;RequestId: ... Error: Runtime exited with error: signal: killed&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda 함수 실행과정에서 발생한 에러입니다. 처음에 Timeout 문제로 제한 시간이 부족한 것 같아 최대 시간인 900s(15분)까지 늘려봤지만, 동일한 에러가 발생했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인해보니 제한 시간 뿐만아니라 메모리가 부족해도, 동일한 에러를 전시하는 것을 알 수 있었는데, 'lambda-구성-일반 구성' 설정값을 바꿔줄 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;222&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NGB4z/btsHNoYvdLB/ZYhRfulyzQqYUbLm3Du0xK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NGB4z/btsHNoYvdLB/ZYhRfulyzQqYUbLm3Du0xK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NGB4z/btsHNoYvdLB/ZYhRfulyzQqYUbLm3Du0xK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNGB4z%2FbtsHNoYvdLB%2FZYhRfulyzQqYUbLm3Du0xK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1340&quot; height=&quot;222&quot; data-origin-width=&quot;1340&quot; data-origin-height=&quot;222&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 lambda의 요금은 메모리와 사용 시간에 비례해서 부과되기 때문에 비용과 직결되는 부분입니다,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인은 2GB 메모리로도 병목이 생겨서 3000까지 늘렸고,&amp;nbsp; 아래 요금표를 참고해서, &lt;b&gt;메모리 X 시간&lt;/b&gt;의 비용이 가장 작아지는 메모리를 찾아서 설정해야 경제적으로 사용할 수 있을 것 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1vymw/btsHM2VG79e/XUzXbVKIWivGhg0ph4Hrbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1vymw/btsHM2VG79e/XUzXbVKIWivGhg0ph4Hrbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1vymw/btsHM2VG79e/XUzXbVKIWivGhg0ph4Hrbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1vymw%2FbtsHM2VG79e%2FXUzXbVKIWivGhg0ph4Hrbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;323&quot; height=&quot;296&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Incorrect path_or_model_id: '/tmp/model_pt'. Please provide either the path to a local folder or the repo_id of a model on the Hub.&lt;/h3&gt;
&lt;pre id=&quot;code_1717404380397&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;errorMessage&quot;: &quot;Incorrect path_or_model_id: '/tmp/model_pt'. Please provide either the path to a local folder or the repo_id of a model on the Hub.&quot;,
  &quot;errorType&quot;: &quot;OSError&quot;,
  &quot;requestId&quot;: &quot;184e0e09-d4b5-4931-b6d7-21d19b3330c5&quot;,
  &quot;stackTrace&quot;: [
    &quot;  File \&quot;/var/task/lambda_function.py\&quot;, line 59, in handler\n    model = inferenceModel()\n&quot;,
    &quot;  File \&quot;/var/task/lambda_function.py\&quot;, line 18, in __init__\n    self.model = BertForSequenceClassification.from_pretrained(\&quot;/tmp/model_pt\&quot;)\n&quot;,
    &quot;  File \&quot;/var/lang/lib/python3.12/site-packages/transformers/modeling_utils.py\&quot;, line 3051, in from_pretrained\n    resolved_config_file = cached_file(\n&quot;,
    &quot;  File \&quot;/var/lang/lib/python3.12/site-packages/transformers/utils/hub.py\&quot;, line 463, in cached_file\n    raise EnvironmentError(\n&quot;
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬 단에서 발생한 에러이지만 Docker와 밀접한 관련이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후술할 Dockerfile 설정과정에서의 에러인데, dockerfile에서 WORKDIR이 어디로 설정되어있는가와 관련되어있는 문제입니다. local에서 model_pt라는 디렉토리를&amp;nbsp; docker에 포함시키면, python에서는 어떤 path로 이 디렉토리를 찾을 수 있을까요? aws-lambda-base-images에서는 &lt;b&gt;WORKDIR /var/task&lt;/b&gt; 로 사전 설정이 되어있었습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717405259826&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Dockerfile 

COPY model_pt ./model_pt&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 local의 디렉토리를 docker image로 옮겼다면, 파이썬에서는 아래와 같이 /var/task 아래의 폴더로 경로를 지정해줘야합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717405317679&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# lambda_function.py

model_path = &quot;/var/task/model_pt&quot;        
self.model = BertForSequenceClassification.from_pretrained(model_path)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;os.listdir&lt;/b&gt;을 코드 중간에 넣어서 디버깅하면 편하니 참고하면 좋을 것 같습니다.&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;b&gt;4. 전체 설정 과정&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Dockerfile 생성&lt;/h3&gt;
&lt;pre id=&quot;code_1717405382198&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Dockerfile

FROM amazon/aws-lambda-python:3.12

RUN /var/lang/bin/python3.12 -m pip install --upgrade pip

COPY lambda_function.py ./
COPY requirements.txt ./
COPY model_pt ./model_pt

RUN pip install --no-cache-dir -r requirements.txt

CMD [&quot;lambda_function.handler&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws에서 제공하는 base image를 활용해줍니다. 필요한 파일을 로컬에서 COPY로 image에 포함시키고, requirements.txt에 기록된 라이브러리를 사전에 다운받아줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. lambda_function.py 생성&lt;/h3&gt;
&lt;pre id=&quot;code_1717405517424&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# lambda_function.py

...

class inferenceModel:
    def __init__(self):

	...
        
        self.tokenizer = BertTokenizer.from_pretrained('bert-base-multilingual-cased', cache_dir='/tmp')

        model_path = &quot;/var/task/model_pt&quot;        
        self.model = BertForSequenceClassification.from_pretrained(model_path)


   ...

def handler(event, context):
    try:
        body = event.get(&quot;body-json&quot;, {})
        data = body.get(&quot;data&quot;, &quot;&quot;)

        if not data:
            raise ValueError(&quot;No data provided&quot;)
        model = inferenceModel()
        _id, _mask = model.preprocess(data)
        result = model.inference(_id, _mask)[0]
        
        return {
            'statusCode': 200,
            'body': int(result)
        }
    except Exception as e:
        return {
            'statusCode': 400,
            'body': json.dumps(f&quot;Error: {str(e)}&quot;)
        }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lambda 양식에 맞춰서 handler 함수를 작성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. ECR(Amazon Elastic Container Registry) Repo 생성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ihebf/btsHLFgi9AB/EAzf9VOSIxjRAcUZFHvfo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ihebf/btsHLFgi9AB/EAzf9VOSIxjRAcUZFHvfo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ihebf/btsHLFgi9AB/EAzf9VOSIxjRAcUZFHvfo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIhebf%2FbtsHLFgi9AB%2FEAzf9VOSIxjRAcUZFHvfo1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;380&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 웹 콘솔에서 리포지토리를 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 로컬에서 Image build 및 AWS ECR 로그인 후 Push&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;* local 환경에 docker desktop이 설치되어 있어야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;* 미리 IAM 설정과 AWS CLI 로그인이 되어 있어야합니다. 관련해서는 다른 블로그에 많이 있으니 참고바랍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1717405799229&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;docker build -t &amp;lt;ECR Repo URI&amp;gt; .

aws ecr get-login-password --region &amp;lt;리전 코드&amp;gt; | docker login --username AWS --password-stdin &amp;lt;계정 ID&amp;gt;.dkr.ecr.ap-northeast-2.amazonaws.com

docker push &amp;lt;ECR Repo URI&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. Lambda 함수 생성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;734&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dLQyDL/btsHM3UGoKp/3WrkZL5sNbuHibK3n8upsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dLQyDL/btsHM3UGoKp/3WrkZL5sNbuHibK3n8upsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dLQyDL/btsHM3UGoKp/3WrkZL5sNbuHibK3n8upsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdLQyDL%2FbtsHM3UGoKp%2F3WrkZL5sNbuHibK3n8upsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;734&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;734&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 이미지로 lambda 함수를 생성합니다. 같은 리전이어야하고, 아키텍처가 일치해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. API Gateway 생성 및 lambda 와 연결&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgc9Hi/btsHMyHwf1a/YMKElmtgUjxnNDl8jZeG21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgc9Hi/btsHMyHwf1a/YMKElmtgUjxnNDl8jZeG21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgc9Hi/btsHMyHwf1a/YMKElmtgUjxnNDl8jZeG21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcgc9Hi%2FbtsHMyHwf1a%2FYMKElmtgUjxnNDl8jZeG21%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;810&quot; height=&quot;335&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;API Gateway에서 REST API를 구축해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;753&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZEWtd/btsHMN5y7qy/phSvVP0dZZpcyKOZ1kAZv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZEWtd/btsHMN5y7qy/phSvVP0dZZpcyKOZ1kAZv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZEWtd/btsHMN5y7qy/phSvVP0dZZpcyKOZ1kAZv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZEWtd%2FbtsHMN5y7qy%2FphSvVP0dZZpcyKOZ1kAZv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;665&quot; height=&quot;618&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;753&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 생성에서 원하는 메서드 유형으로 lambda 함수를 호출할 수 있도록 메서드를 만들어줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZWjsg/btsHMfappes/3ksHzx2jNh29yXH1tm8tr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZWjsg/btsHMfappes/3ksHzx2jNh29yXH1tm8tr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZWjsg/btsHMfappes/3ksHzx2jNh29yXH1tm8tr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZWjsg%2FbtsHMfappes%2F3ksHzx2jNh29yXH1tm8tr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;264&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우측상단에 API 배포를 해주면 Endpoint를 생성할 수 있고, postman과 같은 API 테스트 툴로 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTdDRa/btsHMuypeLT/v16TZcafcLI8hBeUqn8QcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTdDRa/btsHMuypeLT/v16TZcafcLI8hBeUqn8QcK/img.png&quot; data-alt=&quot;성공!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTdDRa/btsHMuypeLT/v16TZcafcLI8hBeUqn8QcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTdDRa%2FbtsHMuypeLT%2Fv16TZcafcLI8hBeUqn8QcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;864&quot; height=&quot;562&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성공!&lt;/figcaption&gt;
&lt;/figure&gt;
&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;b&gt;5. 참고문서&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/gettingstarted-limits.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/gettingstarted-limits.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://aws.amazon.com/ko/lambda/pricing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://aws.amazon.com/ko/lambda/pricing/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://github.com/aws/aws-lambda-base-images/blob/python3.12/Dockerfile.python3.12&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/aws/aws-lambda-base-images/blob/python3.12/Dockerfile.python3.12&lt;/a&gt;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>ai 모델 배포</category>
      <category>API Gateway</category>
      <category>AWS Lambda</category>
      <category>Docker</category>
      <category>docker lambda 배포</category>
      <category>lambda 에러</category>
      <category>lambda 파일 크기</category>
      <category>python lambda 배포</category>
      <category>컨테이너</category>
      <category>트러블슈팅</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/88</guid>
      <comments>https://pypystory.tistory.com/88#entry88comment</comments>
      <pubDate>Mon, 3 Jun 2024 18:21:28 +0900</pubDate>
    </item>
    <item>
      <title>[책 리뷰] CODE 2판 - 하드웨어와 소프트웨어에 숨어 있는 언어 (찰스 펫졸드 지음) 책 추천, 서평, 내용 정리</title>
      <link>https://pypystory.tistory.com/87</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그간 백엔드 개발에 포커스를 맞춰 공부를 해오던 중, 너무 표면적인 코드와 툴에만 매몰되어 있다는 생각이 들었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프레임워크의 사용 방법에는 익숙해져갔지만, 내가 이걸 정말 알고 사용하는 것인가에 대한 고민이 있었습니다.&amp;nbsp;그러던 중 소마에서 인연이 된 한 형님에게 이 고민을 털어놓을 기회가 있었고, 본질적인(fundamental) 분야를 다루는 책 몇권을 소개해주셨습니다. '컴퓨터를 만드는 방법을 알 수 있다'라는 말에 끌려, 제일 먼저 손이 갔던 이 책에 대해 정리해보고자 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;677&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y0dQd/btsHANw12Zr/5dK1QwppYZMzRqQOWW3DeK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y0dQd/btsHANw12Zr/5dK1QwppYZMzRqQOWW3DeK/img.jpg&quot; data-alt=&quot;CODE: The Hidden Language of Computer Hardware and Software&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y0dQd/btsHANw12Zr/5dK1QwppYZMzRqQOWW3DeK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY0dQd%2FbtsHANw12Zr%2F5dK1QwppYZMzRqQOWW3DeK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;217&quot; height=&quot;321&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;677&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CODE: The Hidden Language of Computer Hardware and Software&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Program Programming Programmer 시리즈로 'Charles Petzold'의 'CODE: The Hidden Language of Computer Hardware and Software'가 원작이다.&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;b&gt;2. 총평&lt;/b&gt;&lt;/h2&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;CS와 관련된 많은 책이 있지만, 이 책은 작성에 있어서 많은 노력이 들어갔다는 생각도 들었습니다. 책의 흐름이나 구성도 마음에 들었지만, 무엇보다 책에 포함된 정적인 예제 삽화를 직접 테스트해볼 수 있는 부분이 인상적이었습니다.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://codehiddenlanguage.com/&quot;&gt;Code by Charles Petzold (codehiddenlanguage.com)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인은 책을 1회독하고 나서야, 위 사이트에 접속해보았는데, 책을 읽으면서 같이 사이트를 사용해본다면 더욱 효과적인 독서가 될 수 있을 것 같으니 꼭 방문해보시길 바랍니다.&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;b&gt;3. 독서 기간&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;2회독하는데, &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;순수 읽은 날짜로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 한 달 정도 걸렸던 것 같습니다.&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;b&gt;4. 내용 정리&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter3&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 선행 precedence 부호 or shift 부호&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 뒤에오는 부호의 의미를 shift가 풀릴 때가지 반복&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- escape 부호 : 바로 뒤 한 글자에 대해서 새로운 해석&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 이전 부호를 알아야해서 복잡성이 증가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter4&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전자론 : 전기가 전자의 움직임으로 인해 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- charge, 전하 : 양성자, 전자가 가지는 특성 (음극 anode, 양극 cathode)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 원자의 전자궤도는 다양한 준위를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 최외곽 전자 1개면 전자를 쉽게 잃음 = 전도체(도체) conductors&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전도성 &amp;lt;-&amp;gt; 저항성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- voltage, 전압 : 뭔가 일을 할 수 있는 잠재력 potential&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- current 전류 : amp 앰프 -&amp;gt; 1amp = 6*10^18 전자가 흐름&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 저항.. ohm : 물질이 전자의 흐름을 얼마나 방해?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I = E / R&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P = E * I&amp;nbsp; &amp;nbsp; &amp;nbsp;(전력은 P, 전력은 W)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ground, 접지 : 지구를 전도체로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 6&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 논리학 George Boole -&amp;gt; 불 대수 (집합에 대해 적용)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 불 대수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - + 합집합 union&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - x 교집합 intersection&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 1 전체집합 universe&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 0 공집합 empty set&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ㄴ x 연산에 대한 + 연산의 결합 법칙도 성립&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모순의 법칙 : 그 자신과 그것에 반대되는 것에 모두 속할 순 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ F x (1 - F) = 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 7&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Relay (repeater, 중계기) : 입력되는 약한 전류를 증폭해서, 강한 전류로 만들어줄 수 있음&lt;/p&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; &amp;nbsp;ㄴ 입력되면 금속조각이 휘어 스위치 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 8&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- AND, OR Gate, Invertor&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- buffer : 신호의 딜레이나 증폭&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- fanout : 하나의 출력을 많은 입력에 연결할 때 출력 저하..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSKMyq/btsHz7QGXku/8FGDgphQsnMrtw06r8U0T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSKMyq/btsHz7QGXku/8FGDgphQsnMrtw06r8U0T1/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter08/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSKMyq/btsHz7QGXku/8FGDgphQsnMrtw06r8U0T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSKMyq%2FbtsHz7QGXku%2F8FGDgphQsnMrtw06r8U0T1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;407&quot; height=&quot;252&quot; data-origin-width=&quot;729&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter08/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- De Morgan's law&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 14&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Half Adder, Full Adder&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;461&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nLF5j/btsHAOJBFLt/oUnqUhFqj7s2kDT2KoCbKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nLF5j/btsHAOJBFLt/oUnqUhFqj7s2kDT2KoCbKk/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter14/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nLF5j/btsHAOJBFLt/oUnqUhFqj7s2kDT2KoCbKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnLF5j%2FbtsHAOJBFLt%2FoUnqUhFqj7s2kDT2KoCbKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;229&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;461&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter14/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&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;ㄴ HA는 입력값 2개에 대해서만, FA는 Carry In 까지 포함해서 3개의 입력값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 15&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1937년 벨 연구소 연구원 조지 스티비츠&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 릴레이로 1bit 덧셈기 (모델 K)를 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ proof of concept&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1940년 벨 연구소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 복소수 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1935년 콘라트 추제 Z1, Z2 릴레이 사용 컴퓨터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1937년 하버드&amp;amp;IBM 공동연구 하워드 에이킨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ ASCC -&amp;gt; 하버드 Mark1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1927~32년 MIT 교수 버니바 부시's 미분분석기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1947년 Mark2 컴퓨터 內 릴레이에 낀 나방 -&amp;gt; 최초의 Bug&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1940년대 릴레이 대체 -&amp;gt; 진공관(본래 라디오 신호 증폭 목적)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 릴레이 1ms 마다 값 변경, 진공관 1마이크로s 마다 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 펜실베니아 대학교 ENIAC, 18000개 진공관으로 만들어짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 폰 노인만 ENIAC 뒤를 잇는 EDVAC 설계&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;ㄴ 폰 노인만 아키텍처&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1948년 최초의 사용 컴퓨터 UNIVAC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1947년 트랜지스터 by 벨 연구소 소속 존 바틴, 윌터 브래튼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 저마늄(반도체) 판과 얇은 금박 조각&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 반도체(ex 저마늄, 실리콘) : 최외곽 전자 4개 &amp;lt;- 불순물 추가해서 N-형, P-형 반도체 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ NPN 트랜지스터 -&amp;gt; 컬렉터, 베이스, 이미터&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ㄴ 베이스에 걸리는 낮은 전압을 이용해서 컬렉터와 이미터 사이에 걸린 큰 전압 제어&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1958 칼비&amp;amp;노이스, 집적회로 IC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 얇은 실리콘 웨이퍼를 적층&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 무어의 법칙 : 칩에 집적되는 트랜지스터의 수가 18개월마다 2배로 늘어남&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- IC종류&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; - TTL : 속도우위, CMOS : 전력 덜 사용, 전압변화 덜 민감&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 17&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오실레이터(클럭) : 컴퓨터의 동기화를 위한..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 주기 : 한 사이클 동안 걸리는 시간&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwXP6e/btsHANDUZvL/kq1PLyRi1wNe84nKFqf8Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwXP6e/btsHANDUZvL/kq1PLyRi1wNe84nKFqf8Ik/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter17/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwXP6e/btsHANDUZvL/kq1PLyRi1wNe84nKFqf8Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwXP6e%2FbtsHANDUZvL%2Fkq1PLyRi1wNe84nKFqf8Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;459&quot; height=&quot;281&quot; data-origin-width=&quot;459&quot; data-origin-height=&quot;281&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter17/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- flip-flop -&amp;gt; D-type 래치&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yOeY1/btsHySmSGmX/Xy62lePPSWr8qv3JUNXCS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yOeY1/btsHySmSGmX/Xy62lePPSWr8qv3JUNXCS0/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter17/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yOeY1/btsHySmSGmX/Xy62lePPSWr8qv3JUNXCS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyOeY1%2FbtsHySmSGmX%2FXy62lePPSWr8qv3JUNXCS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;469&quot; height=&quot;229&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter17/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 누산기, accumulating adder를 만들 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 단,&amp;nbsp; 레벨 트리거 형태의 클럭입력으로 무한 루프가 발생...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ D-type 레벨 트리거 2개를 이어서 에지 트리거로 만들어야함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주파수 분할기 -&amp;gt; 이어 붙여서 ripple counter를 만들 수 있음 (각 플립플롭 출력이 다음 플립플롭으로)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사전설정과 초기화를 넣은 최종형태&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9oVzy/btsHzGFOLm7/kXdzHcVuW7H5T5V224Hkl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9oVzy/btsHzGFOLm7/kXdzHcVuW7H5T5V224Hkl0/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter17/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9oVzy/btsHzGFOLm7/kXdzHcVuW7H5T5V224Hkl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9oVzy%2FbtsHzGFOLm7%2FkXdzHcVuW7H5T5V224Hkl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;326&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter17/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 18&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BCD 이진화된 십진수 (0000~1001)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다이오드 : 전류가 한방향으로만 흐르게함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 19&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 1bit 플립플롭 -&amp;gt; latch -&amp;gt; memory&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Selector : 3 to 8 디코더&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 000~111까지 주소에 총 8개의 값 저장 가능(메모리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RAM(random access memory)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 아래는 8 x 1 RAM의 예시 8개 주소 당 각 1개의 데이터&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;883&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNHLTg/btsHztzZJFU/FKBFmgk2s4s3rJUJDskBi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNHLTg/btsHztzZJFU/FKBFmgk2s4s3rJUJDskBi1/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter19/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNHLTg/btsHztzZJFU/FKBFmgk2s4s3rJUJDskBi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNHLTg%2FbtsHztzZJFU%2FFKBFmgk2s4s3rJUJDskBi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;361&quot; data-origin-width=&quot;1853&quot; data-origin-height=&quot;883&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter19/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 삼상 버퍼, tri-state buffer&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 허용이 1이면 출력은 입력과 동일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 허용이 0이면 부동 상태&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 허용 bit 하나로 전체 바이트 처리시 유용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Chapter 20&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 오실레이터와 플립플롭으로 각 타이밍 조절&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;884&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZDnRM/btsHzcrH0zU/SHvaGKZgqcMAt4uQJUaZQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZDnRM/btsHzcrH0zU/SHvaGKZgqcMAt4uQJUaZQ0/img.png&quot; data-alt=&quot;https://codehiddenlanguage.com/Chapter20/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZDnRM/btsHzcrH0zU/SHvaGKZgqcMAt4uQJUaZQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZDnRM%2FbtsHzcrH0zU%2FSHvaGKZgqcMAt4uQJUaZQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;522&quot; data-origin-width=&quot;1108&quot; data-origin-height=&quot;884&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://codehiddenlanguage.com/Chapter20/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 21&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- opcode : CPU를 구성하는 회로에서 직접적으로 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ALU : arithmetic logic unit&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ add, add with carry, subtract, subtract with borrow 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ASCII : 대문자 -&amp;gt; 소문자 : 20h 더하기 대신 0010000과 or연산으로 해결가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ALU는 총 3개의 기능 bit 가짐 비트단위 AND XOR OR, COMPARE 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ COMPARE 연산 : 기본적으로 빼기와 동일. 단, 동일한 경우를 고려해 빼서 0인지 확인 -&amp;gt; Zero Flag 0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Sign Flag : 1이면 음수, 0이면 양수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Carry Flag : 자리올림 플레그&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 22&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 7개의 레지스터&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 누산 레지스터 : accumulator&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ&amp;nbsp; B C D E&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 메모리 접근 H, L&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ㄴ 간접주소 지정 방식에 활용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 즉치 이동 : 명령어 뒤에 나오는 바이트를 특정 레지스터나 메모리로 이동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 즉치 명령어 : ADI, ACI ... CPI&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- STA 누산 레지스터를 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- LDA 누산 레지스터로 로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- MOV (단, MOV M, M은 없음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- data bus : 모든 입력과 출력 사이 연결 (8bit)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- addr bus : 16bit 메모리 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메모리 주소 생성 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. PC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. STA, LDA 명령어 뒤 2byte&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. H, L을 묶은 16bit 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 23&lt;/h3&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;p data-ke-size=&quot;size16&quot;&gt;- RA, register array&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력 : 데이터버스, 주소버스&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 출력 : Acc, 데이터버스, 주소버스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력/출력 제어를 위해서 제어신호들 존재(SI, SO, RA, Acc, HL 클럭과 허용...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ALU&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력 : RA, 데이터버스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 출력 : 플래그(CY, Z, S),&amp;nbsp; 데이터버스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PC&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력 : 주소버스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 출력 : 주소버스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 명령어 래치&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력 : 데이터버스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 출력 : 래치1출력(opcode), 래치2출력(데이터버스), 래치2,3 출력(주소버스)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 증가/감소기, Inc-Dec&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 입력 : 주소버스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ 출력 : 주소버스&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Chapter 24&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- JMP adder : 분기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 무조건 분기 / 플래그 기준 조건 분기&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- Turing Machine&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 튜링 문제 : 어떤 문장을 넣었을 때, 이 문장이 수학적 논리에 의해서 결정가능한지 &amp;lt;- 불가능 증명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스크래치 패드 메모리 : 즉치값 저장을 위한 레지스터가 부족하면 임시보관소로 메모리를 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CALL, RET로 함수, 포로시저, 서브루틴을 만듬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ CALL 명령 실행시 서브루틴이 끝났을 때 재개를 위해서 주소를 stack에 보관(대부분 메모리 맨 끝)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;ㄴ stack pointer라는 16bit 레지스터를 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 25&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주변장치 -&amp;gt; IN port, OUT port 명령어 : 1byte를 입력장치로 부터 읽음, 1byte를 출력장치에 씀&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- polling : 프로그램에서 키보드를 자주 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- interrupt : I/O 장치에서 CPU로 신호 발생 RST 0~7&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 26&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- keyboard handler, command processor, file system 등 ROM에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- echoing : 키보드에서 입력한 글자를 화면에 전송하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 8bit OS ex) CP/M&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 장치독립성 가짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ 파일시스템 : 이름으로 식별, 디스크의 연속된 섹터 차지 X&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; ㄴ bootstrap loader 포함 for booting&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BIOS : 가장 낮은 수준에서 Basic I/O System&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Chapter 27&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- assembler : 코드-&amp;gt; 기계어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://link.coupang.com/a/bNF2PR&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://image14.coupangcdn.com/image/affiliate/banner/bbb034ba17ce2887be4d0756da104735@2x.jpg&quot; alt=&quot;CODE 코드 (화이트 에디션) + 쁘띠수첩 증정, 인사이트, 찰스 펫졸드&quot; width=&quot;120&quot; height=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&quot;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&quot;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/책 리뷰</category>
      <category>charles petzold</category>
      <category>code 2판 - 하드웨어와 소프트웨어에 숨어 있는 언어</category>
      <category>code 서평</category>
      <category>code 책</category>
      <category>code 후기</category>
      <category>code: the hidden language of computer hardware and software</category>
      <category>책 리뷰</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/87</guid>
      <comments>https://pypystory.tistory.com/87#entry87comment</comments>
      <pubDate>Thu, 23 May 2024 23:52:35 +0900</pubDate>
    </item>
    <item>
      <title>정보보안산업기사 필기 합격 후기 &amp;amp; 공부방법 + 공부기간 + 꿀팁 + 문제집추천 (Feat. 컴공 일주일 공부하고 합격하기, 정보보호병)</title>
      <link>https://pypystory.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;정보보안산업기사 필기에 합격했습니다~ 이래저래 일정이 겹쳐서, 공부기간이 너무 짧아서 취소할까도 고민했는데, 벼락치기로 공부했던 방법이 도움이 많이되었던 것 같아서 공유해보려합니다.&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;b&gt;공부기간&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자격증 공부는 일주일정도 하루에 3~4시간정도 투자해서 공부했던 것 같습니다.&lt;/p&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;b&gt;공부방법&lt;/b&gt;&lt;/h2&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 일단 문제집을 샀습니다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;구글링을 해봐도 '정보보안기사'에 대해서는 자료가 많이 나와도, 산업기사는 기사와 묶어서 설명하는 경우가 많았습니다. 그래서 기출과 해설을 모아서 보기위해서 문제집 구매를 결정했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wV3EA/btsGfxWM9xa/L7VXiNfk3shn7UbVw1bSEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wV3EA/btsGfxWM9xa/L7VXiNfk3shn7UbVw1bSEK/img.png&quot; data-alt=&quot;출처 : https://www.coupang.com/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wV3EA/btsGfxWM9xa/L7VXiNfk3shn7UbVw1bSEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwV3EA%2FbtsGfxWM9xa%2FL7VXiNfk3shn7UbVw1bSEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;240&quot; height=&quot;298&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://www.coupang.com/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 때 미리 문제집을 사뒀어서, 이걸로 공부했는데, 따로 기출 기준이 바뀐건 없어서 시험보는데 지장은 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론서 부분은 읽어보다가 시간 관계로 패스했고,&lt;b&gt; 기출 박치기로 3년치 기출&lt;/b&gt;을 밀었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 &lt;b&gt;답지를 보고 모르는 문제 풀이를 노트에 정리&lt;/b&gt;하면서 시작하다가 2년치 쯤 미니까 유형이 보이고, 익숙해져갔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;카페에서 꿀팁을 서칭했습니다.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 정보보안산업기사에 대한 유익한 글을 얻을 수 있는 유일한 경로였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카페 가입하고, 정보보안산업기사 관련해서 남겨진 후기 같은거 읽어보면서 느낌을 찾았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cafe.naver.com/algisa&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://cafe.naver.com/algisa&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.&lt;span&gt; 유튜브에서 정리된 내용을 2배속+스킵으로 재학습했습니다.&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;유튜브에 무료 강좌가 있길래 2배속으로 봤습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사실 크게 문제 위주로 다룬다기 보단 이론서의 개론을 다루고 있기에 머릿속에서 이론을 정리한다는 느낌으로 빠르게 보면 좋을 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=UDaTvhPPPgI&amp;amp;list=PLhBm8ObOpeEKP164L88l5al8ocvQVRBH3&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=UDaTvhPPPgI&amp;amp;list=PLhBm8ObOpeEKP164L88l5al8ocvQVRBH3&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시험 당일&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;강남 송파 CBT에서 응시하게 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금 일찍 도착하신분은 옆에 스벅이 넓고 쾌적해서 준비 중이신 분들이 많았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저도 1시간 정도 그동안 필기했던 내용을 보면서 대기했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mlNp0/btsGeeDTCOA/KbJItANRmAkAxdLgj2ka90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mlNp0/btsGeeDTCOA/KbJItANRmAkAxdLgj2ka90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mlNp0/btsGeeDTCOA/KbJItANRmAkAxdLgj2ka90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmlNp0%2FbtsGeeDTCOA%2FKbJItANRmAkAxdLgj2ka90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;384&quot; height=&quot;366&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어가니 수험번호와 신분증을 검사하고, 지정된 사물함에 짐을 넣고 대기할 수 있었는데, 시험자수에 비해서 대기실이 좁고, 책상도 없으니 애매하게 오셨다면 주변에 있다가 들어가는 걸 추천드립니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cskDuU/btsGeQCp0XB/OLAQRn5r4xmgQZNBFAm2wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cskDuU/btsGeQCp0XB/OLAQRn5r4xmgQZNBFAm2wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cskDuU/btsGeQCp0XB/OLAQRn5r4xmgQZNBFAm2wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcskDuU%2FbtsGeQCp0XB%2FOLAQRn5r4xmgQZNBFAm2wk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;586&quot; height=&quot;549&quot; data-origin-width=&quot;586&quot; data-origin-height=&quot;549&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시험을 보자마자 자동으로 가채점이 되어서, 합격 예정자라고 화면에 전시되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주쯤 뒤에 확정된 결과와 과목별 점수를 볼 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ls8Y8/btsGdr4XEtB/QbDbfkkud5BtyqpmaKsODk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ls8Y8/btsGdr4XEtB/QbDbfkkud5BtyqpmaKsODk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ls8Y8/btsGdr4XEtB/QbDbfkkud5BtyqpmaKsODk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fls8Y8%2FbtsGdr4XEtB%2FQbDbfkkud5BtyqpmaKsODk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;949&quot; height=&quot;197&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwWrB6/btsGet8GFP0/KxB4heW3qS4X9MYBuM4m8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwWrB6/btsGet8GFP0/KxB4heW3qS4X9MYBuM4m8k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwWrB6/btsGet8GFP0/KxB4heW3qS4X9MYBuM4m8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwWrB6%2FbtsGet8GFP0%2FKxB4heW3qS4X9MYBuM4m8k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;805&quot; height=&quot;98&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;평균 60점 이상 각 과목 40점 이상을 받으면 합격할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2024 정보보안산업기사 시험일정, 접수기간, 접수방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필기 원서 접수는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2회차 6월 3일 ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4회차 9월 9일 ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실기 원서 접수는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1회차 4월 1일 ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2회차 7월 15일 ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4회차 10월 28일 ~&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에 KCA 홈페이지에서 접수할 수 있습니다. &lt;a href=&quot;https://www.cq.or.kr/qh_quagm03_001.do&quot;&gt;https://www.cq.or.kr/qh_quagm03_001.do&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;854&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc3fEt/btsGfzf0ZWR/E1I1IQcQPjuWfynBTmbC5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc3fEt/btsGfzf0ZWR/E1I1IQcQPjuWfynBTmbC5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc3fEt/btsGfzf0ZWR/E1I1IQcQPjuWfynBTmbC5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc3fEt%2FbtsGfzf0ZWR%2FE1I1IQcQPjuWfynBTmbC5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;909&quot; height=&quot;854&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;854&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;보안기사/보안산업기사 문제집 추천&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기출에 대한 해설이 상세하게 잘 나와있고, 이론서도 있어서 딥하게 공부하실 분들께도 범용적으로 볼 수 있는 문제집 갔습니다. 괜히 따로 필기/실기 따로 사지말고, 올인원인점도 좋았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://link.coupang.com/a/buLbhI&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;img src=&quot;https://img4a.coupangcdn.com/image/affiliate/banner/2095771237facc64453e6dc9f8c8d6ee@2x.jpg&quot; alt=&quot;2024 이기적 정보보안기사 필기 + 실기 환상의 콤비 세트 전 3권, 영진닷컴&quot; width=&quot;120&quot; height=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&quot;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&quot;&lt;/span&gt;&lt;/p&gt;</description>
      <category>IT/자격증</category>
      <category>공군 정보보호병</category>
      <category>보안산업기사</category>
      <category>보안산업기사 기출</category>
      <category>정보보안산업기사</category>
      <category>정보보안산업기사 공부기간</category>
      <category>정보보안산업기사 접수</category>
      <category>정보보안산업기사 필기 합격</category>
      <category>정보보안산업기사 필기 후기</category>
      <category>정보보호병</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/86</guid>
      <comments>https://pypystory.tistory.com/86#entry86comment</comments>
      <pubDate>Sun, 31 Mar 2024 15:23:37 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] API Gateway + Lambda 사용하다가 생긴 502에러 'Internal server error' 트러블슈팅 with Terraform</title>
      <link>https://pypystory.tistory.com/85</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LP6wp/btsEV9xV0a3/Qt4QUKYn81VQmfW9tUush0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LP6wp/btsEV9xV0a3/Qt4QUKYn81VQmfW9tUush0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LP6wp/btsEV9xV0a3/Qt4QUKYn81VQmfW9tUush0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLP6wp%2FbtsEV9xV0a3%2FQt4QUKYn81VQmfW9tUush0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;236&quot; height=&quot;236&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;0. 개발환경&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform : 1.7.3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python : 3.12.x&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lambda로 크롤링 함수를 만들어서 서비스에 이용하고 있는데, 특정 parameter에 대해서 5XX에러를 띄우는 현상이 발생했습니다. 호출되는 과정은 NestJS Backend -&amp;gt; API Gateway -&amp;gt; Lambda(python) 순서로 호출됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Postman에서 API Gateway를 호출하였을 때, 502 Bad Gateway와 함께 다음과 같은 에러 메시지를 return 했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1708182783027&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;message&quot;: &quot;Internal server error&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 문제의 원인 및 &lt;/b&gt;&lt;b&gt;해결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 단순한 크롤링 과정의 문제인줄 알았습니다. 하지만 로컬에서 lambda에서 사용하는 python 함수를 돌려본 결과 문제없이 크롤링에 성공했습니다. AWS Console에서 lambda의 로그를 확인해보았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRtI3u/btsE2Dp1yu2/sBVNAqY5UAHqsdatVeb090/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRtI3u/btsE2Dp1yu2/sBVNAqY5UAHqsdatVeb090/img.png&quot; data-alt=&quot;AWS CloudWatch Lambda Log&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRtI3u/btsE2Dp1yu2/sBVNAqY5UAHqsdatVeb090/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRtI3u%2FbtsE2Dp1yu2%2FsBVNAqY5UAHqsdatVeb090%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;685&quot; height=&quot;175&quot; data-origin-width=&quot;685&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS CloudWatch Lambda Log&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적으로 statusCode 200을 뱉는 모습입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하자면 이 로그가 미궁으로 끌고갔는데, 실질적으로 lambda에서 문제가 있었지만 lambda를 CloudWatch로 봤을 땐 문제가 없었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;API Gateway의 '테스트' 기능을 이용해서 세부로그를 확인해보았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708183239142&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;Sat Feb 17 14:51:27 UTC 2024 : Sending request to https://lambda.ap-northeast-2.amazonaws.com/2015-03-31/functions/arn:aws:lambda:ap-northeast-2:489811481379:function:python-crawling-global/invocations
Sat Feb 17 14:51:31 UTC 2024 : Received response. Status: 200, Integration latency: 4411 ms
Sat Feb 17 14:51:31 UTC 2024 : Endpoint response headers: {Date=Sat, 17 Feb 2024 14:51:31 GMT, Content-Type=application/json, Content-Length=114, Connection=keep-alive, x-amzn-RequestId=13673bc9-c740-4ee2-ab30-24baad1c9f27, X-Amz-Function-Error=Unhandled, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-65d0c7ef-2404217f4088292e1c26f92b;parent=0539563ad3bd6674;sampled=0;lineage=44aac153:0}
Sat Feb 17 14:51:31 UTC 2024 : Endpoint response body before transformations: {&quot;errorMessage&quot;:&quot;2024-02-17T14:51:31.794Z 13673bc9-c740-4ee2-ab30-24baad1c9f27 Task timed out after 3.05 seconds&quot;}
Sat Feb 17 14:51:31 UTC 2024 : Lambda execution failed with status 200 due to customer function error: 2024-02-17T14:51:31.794Z 13673bc9-c740-4ee2-ab30-24baad1c9f27 Task timed out after 3.05 seconds. Lambda request id: 13673bc9-c740-4ee2-ab30-24baad1c9f27
Sat Feb 17 14:51:31 UTC 2024 : Method completed with status: 502&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 로그를 볼 수 있었는데 lambda에서 200 response를 받고도 timeout error가 나서 502를 던지는 모습입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리서치를 해본 결과 API Gateway와 Lambda 각각에 timeout 시간이 정해져있었습니다. Default값을 확인해보니 API Gateway는 29000ms, Lambda는 3s로 설정되어있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, Lambda가 크롤링과정에서 3초이상 돌아가면서 timeout으로 죽어버리는 상황이었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1708183722138&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_lambda_function&quot; &quot;lambda_function&quot; {
  count         = length(var.symbols)
  
  function_name = &quot;python-crawling-${var.symbols[count.index]}&quot;
  role          = aws_iam_role.iam_for_lambda.arn

  s3_bucket     = var.s3_bucket_name
  s3_key        = &quot;${var.symbols[count.index]}.zip&quot;

  handler       = &quot;lambda_function.lambda_handler&quot;
  runtime       = &quot;python3.12&quot;

  timeout       = 10 // Timeout 10초로 설정
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;terraform에서 lambda_function의 timeout 시간을 늘려줌으로서 해결할 수 있었습니다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;' Lambda execution failed with status 200 due to customer function ' 로그가 인상적입니다...&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 참고문서&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#timeout&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function#timeout&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://repost.aws/knowledge-center/malformed-502-api-gateway&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://repost.aws/knowledge-center/malformed-502-api-gateway&lt;/a&gt;&lt;/p&gt;</description>
      <category>인프라/AWS</category>
      <category>502</category>
      <category>API Gateway</category>
      <category>AWS</category>
      <category>internal server error</category>
      <category>lambda</category>
      <category>Lambda Timeout</category>
      <category>terraform</category>
      <category>Timeout</category>
      <category>트러블슈팅</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/85</guid>
      <comments>https://pypystory.tistory.com/85#entry85comment</comments>
      <pubDate>Sun, 18 Feb 2024 00:34:38 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] TypeORM으로 E2E test를 위한 Test DB 만들기, docker와 Github Action으로 CI 구현, 트러블슈팅</title>
      <link>https://pypystory.tistory.com/84</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uzzYa/btsDyCIgsuQ/xYWQRLkHGcuMPlOKQ0NUnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uzzYa/btsDyCIgsuQ/xYWQRLkHGcuMPlOKQ0NUnk/img.png&quot; data-alt=&quot;출처 : https://itilin.by/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uzzYa/btsDyCIgsuQ/xYWQRLkHGcuMPlOKQ0NUnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuzzYa%2FbtsDyCIgsuQ%2FxYWQRLkHGcuMPlOKQ0NUnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;393&quot; height=&quot;394&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;393&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : https://itilin.by/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 NestJS에서 E2E(End-to-End) 테스트를 구성하며 있었던 이야기를 소개해보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jest로 테스트를 구성하였고, 크게 3가지의 목표를 달성하고 싶었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.&lt;b&gt; Mocking을 최소화&lt;/b&gt;하여, 최대한 &lt;b&gt;실제 시나리오와 유사하게 동작&lt;/b&gt;하도록 하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;DB 특성&lt;/b&gt;을 가져갈 수 있도록, 테스트에서도 mysql DB를 사용할 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;b&gt;자동화된 자체 QA&lt;/b&gt;를 수행할 수 있도록, &lt;b&gt;Github Action과 연동되어 CI&lt;/b&gt;(지속적통합)를 지원할 수 있어야 할 것.&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;b&gt;0. 개발환경&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nest&amp;nbsp;:&amp;nbsp;10.3.0 &lt;br /&gt;typescript:&amp;nbsp;5.3.3 &lt;br /&gt;typeorm&amp;nbsp;:&amp;nbsp;0.3.19 &lt;br /&gt;jest&amp;nbsp;:&amp;nbsp;29.7.0 &lt;br /&gt;docker-compose&amp;nbsp;:&amp;nbsp;1.29.2&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;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 테스트용 DB(이하 Test_DB)를 AWS RDS로 구성했습니다. 실제 DB(Prod_DB)와 동일한 구성을 유지하면서 test용 DB 유저를 생성하고, 테스트할 때마다 완전히 Drop을 진행해도 되는, 빈 스키마를 구성했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬환경에서 테스트는 성공적이었습니다. 테스트 과정을 도식화해보면 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1331&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOtxGT/btsDCRYab13/iyoq2k2kKou2WdpGfrDm80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOtxGT/btsDCRYab13/iyoq2k2kKou2WdpGfrDm80/img.png&quot; data-alt=&quot;E2E 테스트 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOtxGT/btsDCRYab13/iyoq2k2kKou2WdpGfrDm80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOtxGT%2FbtsDCRYab13%2Fiyoq2k2kKou2WdpGfrDm80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1331&quot; height=&quot;456&quot; data-origin-width=&quot;1331&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;E2E 테스트 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ORM을 이용하고 있기에 TypeORM에서 제공하는 CLI를 이용하여 쉽게 '초기화', '동기화', '초기 데이터 추가' 과정을 구현할 수 있었습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705494143948&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bin/ormconfig.ts

const ormconfig = async (): Promise&amp;lt;DataSource&amp;gt; =&amp;gt; {
  const config = &amp;lt;{ db: DataSourceOptions }&amp;gt;await configuration();

  const dataSource = new DataSource({
    ...config.db,
    logging: false,
    logger: 'file',
    namingStrategy: new SnakeNamingStrategy(),
    entities: [`src/**/*.entity{.ts,.js}`],
    migrations: [`src/seeds/**/*.{js,ts}`],
  });

  return dataSource;
};

export default ormconfig();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json에 CLI를 저장해두고, npm run test:e2e:auto 라는 script를 만들어서 한 명령어로 일련의 과정을 직렬적으로 처리하였습니다. 로컬에서는 성공적인 테스트를 구현할 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 레퍼런스나 공식 docs에서 E2E 테스트 방법에 대해서는 상세히 다루고 있으니 따로 첨부하진 않겠습니다,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.nestjs.com/fundamentals/e2e-testing&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.nestjs.com/fundamentals/e2e-testing&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1705494181644&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;scripts&quot;: {
    &quot;test:e2e:auto&quot;: &quot;npm run test:entity:drop &amp;amp;&amp;amp; npm run test:entity:sync &amp;amp;&amp;amp; npm run test:seed:run &amp;amp;&amp;amp; jest --config ./test/jest.e2e.ts -i --verbose&quot;,
    &quot;test:entity:sync&quot;: &quot;NODE_ENV=test ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d bin/ormconfig.ts schema:sync&quot;,
    &quot;test:entity:drop&quot;: &quot;NODE_ENV=test ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d bin/ormconfig.ts schema:drop&quot;,
    &quot;test:seed:run&quot;: &quot;NODE_ENV=test ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d bin/ormconfig.ts migration:run&quot;,
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2b6Gj/btsDxUB7J3B/YAdwLkZPUjBvBX2Sjm7kx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2b6Gj/btsDxUB7J3B/YAdwLkZPUjBvBX2Sjm7kx1/img.png&quot; data-alt=&quot;Test 실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2b6Gj/btsDxUB7J3B/YAdwLkZPUjBvBX2Sjm7kx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2b6Gj%2FbtsDxUB7J3B%2FYAdwLkZPUjBvBX2Sjm7kx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;334&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Test 실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그대로 Github Action을 구성하였고, Pull Request를 trigger로 CI가 동작하게 함으로서, PR이 들어오면 merge를 위해서 Test를 의무적으로 통과하도록 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그런데...&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬에서도 잘 구현되고, PR을 날려서 확인했을 때에도 잘 돌아갔던 테스트가 이상하게 특정상황에서 에러를 뱉기 시작했습니다.&amp;nbsp;package의 버전관리를 위해 설정된 dependabot에서 특정 시간이 되면 패키지 갱신을 하도록 PR을 날리는데, 모든 Test가 실패하는 현상이 나타났습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;314&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cn9QbH/btsDBtccnUJ/HcDfQO53DHkVOWWxESqIw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cn9QbH/btsDBtccnUJ/HcDfQO53DHkVOWWxESqIw0/img.png&quot; data-alt=&quot;ㅇㅅㅇ...&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cn9QbH/btsDBtccnUJ/HcDfQO53DHkVOWWxESqIw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcn9QbH%2FbtsDBtccnUJ%2FHcDfQO53DHkVOWWxESqIw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1291&quot; height=&quot;314&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;314&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ㅇㅅㅇ...&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;2. 구조분석 및 &lt;/b&gt;&lt;/span&gt;&lt;b&gt;문제의 원인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;629&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wlbpF/btsDxUhPpZr/lHqDJbMvMCaJyaUFeRroi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wlbpF/btsDxUhPpZr/lHqDJbMvMCaJyaUFeRroi0/img.png&quot; data-alt=&quot;github action log 중 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wlbpF/btsDxUhPpZr/lHqDJbMvMCaJyaUFeRroi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwlbpF%2FbtsDxUhPpZr%2FlHqDJbMvMCaJyaUFeRroi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1087&quot; height=&quot;629&quot; data-origin-width=&quot;1087&quot; data-origin-height=&quot;629&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;github action log 중 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: start;&quot;&gt;에러가 난 부분을 확인해보았습니다. 분명 테스트 DB가 정상적으로 초기화되고, 동기화되었는데 Table을 찾을 수 없다는 에러가 났습니다... &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: start;&quot;&gt;생각해보면 당연한 일이었습니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: start;&quot;&gt;테스트는 PR마다 동시에 일어날 수 있는데, 하나의 테스트 DB를 공유하고 있으니 초기화와 동기화의 타이밍에 따라 다른 테스트 환경설정을 간섭할 수 있는 것이었습니다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. &lt;/b&gt;&lt;b&gt;문제의 해결&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 2가지 방법을 고민해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 테스트 trigger를 Queue 같은 FIFO 구조의 무엇인가에 넣어서, 각 테스트가 순차적으로 돌아갈 수 있도록 제어하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 테스트 환경 자체를 각 테스트마다 격리시켜서, 병렬적으로 처리될 수 있는 공간을 확보하는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글링을 해본 결과 (2)번 방법의 레퍼런스들을 찾을 수 있었습니다. docker를 활용하면 각 테스트에 격리된 공간을 사용하면서도, mysql 엔진의 특성까지 살려서 구현할 수 있다는 점입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705495722712&quot; class=&quot;haml&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// docker-compose.test.yml

services:
  db:
    image: mysql/mysql-server:latest
    ports:
      - ${TEST_DB_PORT}:3306
    environment:
      - MYSQL_ROOT_HOST=%
      - MYSQL_ROOT_PASSWORD=${TEST_DB_PASSWORD}
      - MYSQL_DATABASE=${TEST_DB_NAME}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, docker-compose로 환경 구성파일을 만들어줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705495756789&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// package.json

&quot;test:docker:up&quot;: &quot;docker-compose -f docker-compose.test.yml up -d&quot;,
&quot;test:docker:down&quot;: &quot;docker-compose -f docker-compose.test.yml down&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker를 up down 시킬 수 있는 script도 추가해줍니다. docker-compose 문법에 대해서는 다른 블로그들에서 자세히 설명하고 있으니 따로 다루진 않겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705495877740&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// .github/workflows/test.yml

name: NestJS-Test

on:
  pull_request:
    branches:
      - main
jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20.x]

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install Dependencies
        run: npm ci

      - name : Test DB up
        run: npm run test:docker:up

      - name: Run e2e Tests
        run: npm run test:e2e:auto

      - name : Test DB down
        run: npm run test:docker:down&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 test.yml 파일입니다. ubuntu에 node를 설치하고, 패키지들을 설치해준 뒤, 테스트 로직에 맞춰 명령어를 실행합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. &lt;/b&gt;&lt;b&gt;트러블슈팅&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 될 줄 알았지만... 새로운 문제가 발생했습니다. docker up을 한 직후, E2E 테스트를 위한 환경구성 코드를 돌렸더니 아래와 같은 에러가 발생했습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;425&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfk2R7/btsDDcgGaik/WHyZVV5JkGkqfxM1j7IzK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfk2R7/btsDDcgGaik/WHyZVV5JkGkqfxM1j7IzK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfk2R7/btsDDcgGaik/WHyZVV5JkGkqfxM1j7IzK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfk2R7%2FbtsDDcgGaik%2FWHyZVV5JkGkqfxM1j7IzK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;922&quot; height=&quot;425&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;425&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;Error:&amp;nbsp;Connection&amp;nbsp;lost:&amp;nbsp;The&amp;nbsp;server&amp;nbsp;closed&amp;nbsp;the&amp;nbsp;connection. &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;Socket.&amp;lt;anonymous&amp;gt;&amp;nbsp;(/workspaces/nestjs-rest-api-templete-v1/node_modules/mysql2/lib/connection.js:117:31) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;Socket.emit&amp;nbsp;(node:events:514:28) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;Socket.emit&amp;nbsp;(node:domain:488:12) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;at&amp;nbsp;TCP.&amp;lt;anonymous&amp;gt;&amp;nbsp;(node:net:337:12)&amp;nbsp;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;fatal:&amp;nbsp;true, &lt;br /&gt;&amp;nbsp;&amp;nbsp;code:&amp;nbsp;'PROTOCOL_CONNECTION_LOST' &lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에 연결을 실패했다는 말인 것 같습니다. 처음에는 docker로 DB 서버 생성에 실패했다고 생각했지만, mysql CLI로 접근해보니 서버 생성은 정상적으로 이루어졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다만, 서버 생성에 약간에 로딩 시간이 걸린다는 점이 문제였습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql이 올라오는 과정에서 연결을 시도하다보니, PROTOCOL_CONNECTION_LOST 에러가 난 것이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeORM에서는 딱히 자체적으로 내장함수가 없는 듯하여, 재귀적으로 t초마다 연결을 재시도하는 방식으로 구현해보았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705391446489&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// bin/ormconfig.ts

const wait = (timeToDelay: number) =&amp;gt; new Promise((resolve) =&amp;gt; setTimeout(resolve, timeToDelay));

const ormconfig = async (): Promise&amp;lt;DataSource&amp;gt; =&amp;gt; {
  const config = &amp;lt;{ db: DataSourceOptions }&amp;gt;await configuration();

  const dataSource = new DataSource({
    ...config.db,
    logging: false,
    logger: 'file',
    namingStrategy: new SnakeNamingStrategy(),
    entities: [`src/**/*.entity{.ts,.js}`],
    migrations: [`src/seeds/**/*.{js,ts}`],
  });

  async function connectionCheck() {
    await dataSource
      .initialize()
      .then(() =&amp;gt; {
        console.log('[SUCCESS] Data Source has been initialized!');
      })
      .catch(async (err: DatabaseConnectionException) =&amp;gt; {
        console.error('[FAILED] Error during Data Source initialization');
        if (err.code === 'PROTOCOL_CONNECTION_LOST') {
          console.log('[RECONNECT] Retrying connection');
          await wait(2000);
          await connectionCheck();
        } else {
          throw err;
        }
      });
    return dataSource;
  }
  await connectionCheck();
  await dataSource.destroy();
  return dataSource;
};

export default ormconfig();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;connect가 될 때까지 연결을 재시도하게 되었고, 정상적으로 독립된 환경에서 test를 구현할 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI9TBv/btsDBwtgFrE/GuygV0fvUsMMoZ1p1d146K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI9TBv/btsDBwtgFrE/GuygV0fvUsMMoZ1p1d146K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI9TBv/btsDBwtgFrE/GuygV0fvUsMMoZ1p1d146K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI9TBv%2FbtsDBwtgFrE%2FGuygV0fvUsMMoZ1p1d146K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;236&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 동시에 test가 trigger 되더라도, 성공적으로 테스트를 구현할 수 있었습니다.&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;b&gt;참고자료&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* &lt;a href=&quot;https://stackoverflow.com/questions/20210522/nodejs-mysql-error-connection-lost-the-server-closed-the-connection&quot;&gt;node.js - nodejs mysql Error: Connection lost The server closed the connection - Stack Overflow&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;* &lt;a href=&quot;https://github.com/sidorares/node-mysql2/issues/836&quot;&gt;Error: Connection lost: The server closed the connection. &amp;middot; Issue #836 &amp;middot; sidorares/node-mysql2 (github.com)&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://velog.io/@dramatic/NestJS-TypeORM-E2E-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0&quot;&gt;https://velog.io/@dramatic/NestJS-TypeORM-E2E-%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>Connection lost: The server closed the connection.</category>
      <category>docker mysql</category>
      <category>docker-compose</category>
      <category>e2e test</category>
      <category>e2e test docker</category>
      <category>e2e 테스트</category>
      <category>e2e 테스트 환경</category>
      <category>Jest e2e test</category>
      <category>NestJS e2e</category>
      <category>PROTOCOL_CONNECTION_LOST</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/84</guid>
      <comments>https://pypystory.tistory.com/84#entry84comment</comments>
      <pubDate>Wed, 17 Jan 2024 22:26:20 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] class-validator error message 처리 트러블슈팅, error format 바꿔서 exception filter로 처리하기</title>
      <link>https://pypystory.tistory.com/83</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dVP3Tm/btsDs5jdN1S/uxIkfN48kUIn0Ju77lTXo1/tfile.svg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dVP3Tm/btsDs5jdN1S/uxIkfN48kUIn0Ju77lTXo1/tfile.svg&quot; data-alt=&quot;https://nestjs.com/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dVP3Tm/btsDs5jdN1S/uxIkfN48kUIn0Ju77lTXo1/tfile.svg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdVP3Tm%2FbtsDs5jdN1S%2FuxIkfN48kUIn0Ju77lTXo1%2Ftfile.svg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;203&quot; height=&quot;196&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://nestjs.com/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;0&lt;/b&gt;&lt;b&gt;. 개발환경&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nest : 10.2.1&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class-validator: 0.14.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 :&amp;nbsp;&lt;a href=&quot;https://www.npmjs.com/package/class-validator&quot;&gt;class-validator - npm (npmjs.com)&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704638618910&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// user.entity.ts
@Entity('user')
export class User extends CoreEntity {

  ...
  
  @ApiProperty({ example: '홍길동' })
  @Column({ type: 'varchar', nullable: true })
  @Length(2, 10)
  @IsString()
  public username?: string;
  
  ...
  
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class-validator 라이브러리를 사용해서 'username' 필드의 Length를 제한하고, 예외의 경우를 넣어서 출력되는 메시지를 확인해보았습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1704638732567&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BadRequestException: Bad Request Exception
    at ValidationPipe.exceptionFactory (/workspaces/nestjs-personal-backend/node_modules/@nestjs/common/pipes/validation.pipe.js:101:20)
    at ValidationPipe.transform (/workspaces/nestjs-personal-backend/node_modules/@nestjs/common/pipes/validation.pipe.js:74:30)
    ...
    {
  response: {
    message: [ 'username must be longer than or equal to 2 characters' ],
    error: 'Bad Request',
    statusCode: 400
  },
  status: 400,
  options: {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 error message가 string으로 나오는 경우만 고려해서 filter를 짜뒀기에 상세 message인 'username must be longer than or equal to 2 characters' 가 error response 상에 출력되지 않는 문제가 발생했습니다.&lt;/p&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 구조분석 및 &lt;/b&gt;&lt;b&gt;원인 파악&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1704639016107&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export interface ValidatorPackage {
    validate(object: unknown, validatorOptions?: ValidatorOptions): ValidationError[] | Promise&amp;lt;ValidationError[]&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ValidationError의 경우 항상 array의 형태로 반환되고, class-validator 라이브러리 내에서는 Array[ Object ] 의 형태로 error를 throw하고 있습니다. 아무래도 한 request에 대해서 여러 validation error가 동시에 발생할 수 있기 때문인듯합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 문제의 해결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 error format의 변경이 필요하다. 이후 Validation Error를 위한 Exception을 만들어 줄 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 ValidationException 상황은 값이 잘못들어온 BadRequest 상황임으로 extends해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1704640193522&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;// common/exceptions/validation.exception.ts

import { BadRequestException, ValidationError } from '@nestjs/common';

export class ValidationException extends BadRequestException {
  constructor(public errors: ValidationError[]) {
    super();
  }
  override message: string = 'Validation Exception';
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 ValidationPipe를 추가할 때, exceptionFactory 옵션을 추가해주고, 만들어준 ValidationException을 throw하도록 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1704640164453&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// main.ts

app.useGlobalPipes(
    new ValidationPipe({
      exceptionFactory: (errors) =&amp;gt; {
        const result = errors.map((error) =&amp;gt; ({
          [error.property]: error.constraints,
        }));
        return new ValidationException(result);
      },
      transform: true,
    }),
  );&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 global하게 exception을 처리하는 filter에도 이를 반영해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 모든 exception을 처리해주는 filter인데, NestJS에서 기본적으로 제공하는 ExceptionFilter를 오버라이딩해서 사용하고 있습니다. 이에 관해서는 공식문서에서 자세히 언급하고 있으니 참고만 해주시면 될 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.nestjs.com/exception-filters&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://docs.nestjs.com/exception-filters&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1705389292109&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// /common/filters/all-exception.filter.ts

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  private readonly logger: Logger = new Logger();

  public catch(exception: unknown, host: ArgumentsHost): void {
    const ctx = host.switchToHttp();
    const res = ctx.getResponse&amp;lt;Response&amp;gt;();
    const req = ctx.getRequest&amp;lt;Request&amp;gt;();

    const statusCode = getHttpStatus(exception);
    const message = getMessage(exception);
    const detail = getDetail(exception);

    const exceptionResponse: ExceptionResponse = {
      statusCode,
      timestamp: new Date(),
      path: req.url,
      method: req.method,
      message,
      detail,
    };

    const args = req.body;
    this.exceptionLogging(exceptionResponse, args);

    res.status(statusCode).json(exceptionResponse);
  }

  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 다른 exception들과 format 통일을 위해서 instanceof로 타입 추론을 하면서 exception 분류를 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방금 추가한 ValidationException에 대해서도 각 errors의 value를 key: value로 하는 object를 만들어서, 발생하는 validation exception을 모아서 detail로 알려주게 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705389148933&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// /common/filters/utils

export function getDetail(exception: unknown): string | Array&amp;lt;object&amp;gt; | object {
  let detail: string | Array&amp;lt;object&amp;gt; | object = '';
  if (exception instanceof HttpException) {
    detail = exception.getResponse;
  }
  if (exception instanceof QueryFailedError) {
    detail = { query: exception.query, parameters: exception.parameters };
  }
  if (exception instanceof ValidationException) {
    detail = exception.errors.map((error) =&amp;gt; ({
      [error.property]: error.constraints,
    }));
  }

  return detail;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5. 참고문서&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/typestack/class-validator/issues/2055#issuecomment-1521392106&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/typestack/class-validator/issues/2055#issuecomment-1521392106&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/typestack/class-validator/issues/169&quot;&gt;How to customize validation messages globally? &amp;middot; Issue #169 &amp;middot; typestack/class-validator (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/typestack/class-validator/issues/707&quot;&gt;How to format error message response? &amp;middot; Issue #707 &amp;middot; typestack/class-validator (github.com)&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>class-validator</category>
      <category>class-validator 에러처리</category>
      <category>exception-filter</category>
      <category>nestjs class-validator</category>
      <category>NestJS validator</category>
      <category>ValidationException</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/83</guid>
      <comments>https://pypystory.tistory.com/83#entry83comment</comments>
      <pubDate>Tue, 16 Jan 2024 16:20:28 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] AWS S3에 파일 업로드, 저장하기, @aws-sdk/client-s3, multer 사용</title>
      <link>https://pypystory.tistory.com/82</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bezOa0/btsDrGa8kfg/E2wtbZZ3kLnV8APxNrMTbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bezOa0/btsDrGa8kfg/E2wtbZZ3kLnV8APxNrMTbk/img.png&quot; data-alt=&quot;https://nestjs.com/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bezOa0/btsDrGa8kfg/E2wtbZZ3kLnV8APxNrMTbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbezOa0%2FbtsDrGa8kfg%2FE2wtbZZ3kLnV8APxNrMTbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;173&quot; height=&quot;172&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://nestjs.com/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 NestJS에서 파일을 업로드 받고, AWS S3에까지 저장하는 REST API를 공유해보려합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws-sdk v2로 된 한국어 자료들은 많이 있는데, version3을 사용해서 만들어봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 필자도 처음에는 aws-sdk v2를 사용해서, 파일 업로드 기능을 만들었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 서버를 run 할 때 version3으로 migrate해달라는 굉장히 거슬리는 문구가 뜨는 걸 볼 수 있었습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;(node:2109)&amp;nbsp;NOTE:&amp;nbsp;We&amp;nbsp;are&amp;nbsp;formalizing&amp;nbsp;our&amp;nbsp;plans&amp;nbsp;to&amp;nbsp;enter&amp;nbsp;AWS&amp;nbsp;SDK&amp;nbsp;for&amp;nbsp;JavaScript&amp;nbsp;(v2)&amp;nbsp;into&amp;nbsp;maintenance&amp;nbsp;mode&amp;nbsp;in&amp;nbsp;2023. &lt;br /&gt;&lt;br /&gt;Please&amp;nbsp;migrate&amp;nbsp;your&amp;nbsp;code&amp;nbsp;to&amp;nbsp;use&amp;nbsp;AWS&amp;nbsp;SDK&amp;nbsp;for&amp;nbsp;JavaScript&amp;nbsp;(v3). &lt;br /&gt;For&amp;nbsp;more&amp;nbsp;information,&amp;nbsp;check&amp;nbsp;the&amp;nbsp;migration&amp;nbsp;guide&amp;nbsp;at&amp;nbsp;&lt;a href=&quot;https://a.co/7PzMCcy&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://a.co/7PzMCcy&lt;/a&gt;&lt;br /&gt;(Use&amp;nbsp;`node&amp;nbsp;--trace-warnings&amp;nbsp;...`&amp;nbsp;to&amp;nbsp;show&amp;nbsp;where&amp;nbsp;the&amp;nbsp;warning&amp;nbsp;was&amp;nbsp;created)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : aws-sdk v2 : &lt;a href=&quot;https://www.npmjs.com/package/aws-sdk&quot;&gt;aws-sdk - npm (npmjs.com)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 v3의 장점을 찾아보게 되었고, 후술할 장점들에 이끌려 version 3을 지원하는 패키지로 마이그레이션 해주고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 aws-sdk v3 : &lt;a href=&quot;https://www.npmjs.com/package/@aws-sdk/client-s3&quot;&gt;@aws-sdk/client-s3 - npm (npmjs.com)&lt;/a&gt;&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;b&gt;aws-sdk v3의 장점&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 과연 왜? Why? v3로 마이그레이션 해주어야하는가? 어떤 장점이 있는지 조사해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;* 출처 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;color: #0070d1; text-align: start;&quot; href=&quot;https://dev.to/dvddpl/aws-sdk-v2-or-v3-which-one-should-you-use-3kaj&quot;&gt;AWS SDK v2 or v3 - which one should you use? - DEV Community&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 글에서는 크게 3가지, Modular architecture, Middleware, Individual Configuration를 장점으로 꼽고있 습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 눈에 띄는건 ' Modular architecture'이다. 기존에 v2에서는 내가 S3 관련 매서드만 쓰고 싶더라도, aws-sdk를 통채로 import 했어야했습니다. 하지만 지금은 원하는 모듈만 import해서 사용할 수 있다는 점입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1705163332624&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// v2
import * as AWS from 'aws-sdk';
import AWS from 'aws-sdk/global';
// v3
import { ListBucketsCommand, S3Client } from &quot;@aws-sdk/client-s3&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 구조 개선으로 가독성, 디버깅 경험 확대 등 여러 장점이 있습니다.&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;b&gt;NestJS에서 적용&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1705163490349&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// file.controller.ts
import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiConsumes, ApiTags } from '@nestjs/swagger';

import { ApiFile } from './decorators';
import { FileService } from './providers/file.service';
import { UploadFile } from '#entities/file';

@ApiTags('file')
@Controller('file')
export class FileController {
  constructor(private readonly fileService: FileService) {}
  @ApiConsumes('multipart/form-data')
  @ApiFile()
  @Post('upload')
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(@UploadedFile() file: Express.Multer.File): Promise&amp;lt;UploadFile&amp;gt; {
    return await this.fileService.uploadSingleFile(file);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분에 관해서는 NestJS 공식문서를 포함한 다른 블로그에서 잘 설명해준글이 많으니 다른 글을 참고하길 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.nestjs.com/techniques/file-upload&quot;&gt;File upload | NestJS - A progressive Node.js framework&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1705163638014&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// file.service.ts

@Injectable()
export class FileService {
  
  ...

  public async uploadSingleFile(file: Express.Multer.File): Promise&amp;lt;UploadFile&amp;gt; {
    if (!file) throw new BadRequestException('File is not Exist');

    const awsRegion = this.config.get('aws.region');
    const bucketName = this.config.get('aws.s3.bucketName');
    const client = new S3Client({
      region: awsRegion,
      credentials: {
        accessKeyId: this.config.get('aws.accessKey'),
        secretAccessKey: this.config.get('aws.secretKey'),
      },
    });
    const key = `${Date.now().toString()}-${file.originalname}`;
    const params = {
      Key: key,
      Body: file.buffer,
      Bucket: bucketName,
      ACL: ObjectCannedACL.public_read,
    };
    const command = new PutObjectCommand(params);

    const uploadFileS3 = await client.send(command);
    if (uploadFileS3.$metadata.httpStatusCode !== 200)
      throw new BadRequestException('Failed upload File');
	
    ...
    
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 S3는 파일을 key-value 형태로 저장하기에 key는 파일명이 됩니다. 중복을 막기 위해서 Date.now를 사용하였으며, controller에서 받아온 파일의 buffer를 Body에 담아줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACL의 경우 Access Control List의 약자로 접근의 허용 유무를 보여줍니다. 본인은 global로 공개해도 상관없는 정책을 사용할 것이기에&amp;nbsp; public_read를 사용하였지만, 올리는 파일에 따라서 policy를 명확히 정해야할 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S3와 IAM 계정을 생성하는 방법에 대해서도 많은 블로그에서 다루고 있기에 따로 첨부하진 않겠지만, policy 설정을 aws에서 해줘야 SDK에서 에러를 뱉지 않습니다. 코드가 똑같은데 에러를 뱉는다면 AWS 내의 권한 설정을 의심해보면 좋을 것 같습니다!&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/javascript_s3_code_examples.html&quot;&gt;Amazon S3 examples using SDK for JavaScript (v3) - AWS SDK for JavaScript&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>@aws-sdk/client-s3</category>
      <category>AWS S3 file upload</category>
      <category>AWS S3 파일 올리기</category>
      <category>aws-sdk</category>
      <category>aws-sdk-v3</category>
      <category>express file upload</category>
      <category>multer</category>
      <category>NestJS file upload</category>
      <category>NestJS 파일 업로드</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/82</guid>
      <comments>https://pypystory.tistory.com/82#entry82comment</comments>
      <pubDate>Sun, 14 Jan 2024 01:45:08 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] Entity를 상속받아, 효율적으로 DTO 관리하기, @nestjs/swagger VS @nestjs/mapped-types 차이</title>
      <link>https://pypystory.tistory.com/81</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC48Cl/btsC9ziVxhL/WV8rlj1KbqofzzZpGUjsk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC48Cl/btsC9ziVxhL/WV8rlj1KbqofzzZpGUjsk0/img.png&quot; data-alt=&quot;출처 : stackjava.com&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC48Cl/btsC9ziVxhL/WV8rlj1KbqofzzZpGUjsk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC48Cl%2FbtsC9ziVxhL%2FWV8rlj1KbqofzzZpGUjsk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;250&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : stackjava.com&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로세스간 데이터 전달을 위해서 DTO(Data Transfer Object) 사용한다. NestJS에서도 MVC layer간의 데이터 전달이나 request 요청을 받을 때도 DTO를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 한 Domain에 대해서, 여러 layer별로 dto는 조금씩 사용되는데, 모든 dto를 각각의 객체로 관리하는 건 어려운 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 예시로 Register DTO와 Login DTO를 생각해보자.&lt;/p&gt;
&lt;pre id=&quot;code_1704519949713&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// register.dto.ts
export class RegisterDto {
  email!: string;
  password!: string;
  username!: string;
}

// login.dto.ts
export class LoginDto {
  email!: string;
  password!: string;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 User 도메인 내에 속하지만 로그인과 회원가입을 위해 필요한 dto는 다르다. 하지만 email과 password라는 공통적인 필드가 생기고, 필드와 DTO가 늘어가면 관리하기가 어려워진다.&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;b&gt;문제상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;swagger를 쓰면서 문제는 더 커졌다. NestJS에서는 REST API 문서화를 쉽게할 수 있도록 swagger 사용을 공식적으로 지원한다.&amp;nbsp;*github : &lt;a href=&quot;https://github.com/nestjs/swagger&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nestjs/swagger&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704520460505&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// login.dto.ts
export class LoginDto {
  @ApiProperty({ example: 'example@kakao.com' })
  email!: string;

  @ApiProperty({ example: 'querty1234' })
  password!: string;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;574&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RjC8v/btsC86nKcRR/zbuE1McF7G2WzKoDl9fcz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RjC8v/btsC86nKcRR/zbuE1McF7G2WzKoDl9fcz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RjC8v/btsC86nKcRR/zbuE1McF7G2WzKoDl9fcz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRjC8v%2FbtsC86nKcRR%2FzbuE1McF7G2WzKoDl9fcz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1429&quot; height=&quot;574&quot; data-origin-width=&quot;1429&quot; data-origin-height=&quot;574&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 DTO에 @ApiProperty 데코레이터를 추가해서 swagger docs에서, 내 API를 써볼 유저(다른 개발자)에게 보여줄 example이나 require여부 등을 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 모든 DTO에 각각 Property를 관리하기가 어렵다는 점이다. 그래서 DTO를 정의할 때 Entity 혹은 다른 DTO를 상속받도록하고, root에만 ApiProperty를 정의하여 재사용할 수 있도록 해야한다.&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;b&gt;해결방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS docs에는 Mapped Types라는 이름으로 방법을 소개하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.nestjs.com/openapi/mapped-types&quot;&gt;Mapped Types - OpenAPI | NestJS - A progressive Node.js framework&lt;/a&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704521012700&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// @nestjs/swagger 內
export * from './intersection-type.helper';
export * from './omit-type.helper';
export * from './partial-type.helper';
export * from './pick-type.helper';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Intersection-type, omit-type, partial-type, pick-type을 지원한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Partial : 부모의 모든 필드 optional로 상속&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Pick : 특정 필드만 상속&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Omit : 특정 필드만 빼고 상속&lt;/b&gt;&lt;br /&gt;&lt;b&gt;Intersection : 두 부모의 필드를 상속&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1704521070025&quot; class=&quot;typescript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;export class UpdateCatAgeDto extends PickType(CreateCatDto, ['age'] as const) {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방식으로 원하는 DTO에서 필요한 type만 받아와서 새로운 DTO를 구성할 수 있다.&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;b&gt;@nestjs/swagger VS @nestjs/mapped-types&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 짜다보니 '&lt;b&gt;대체 왜 이 PickType이라는 함수가 swagger 내장 함수일지'&lt;/b&gt; 궁금했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각해보면 일부 type만 pick해오는 단독 라이브러리가 있을법한데 말이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oCDnv/btsC8S4abPy/HiJZzKcx37ds5AIPPG73qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oCDnv/btsC8S4abPy/HiJZzKcx37ds5AIPPG73qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oCDnv/btsC8S4abPy/HiJZzKcx37ds5AIPPG73qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoCDnv%2FbtsC8S4abPy%2FHiJZzKcx37ds5AIPPG73qk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1180&quot; height=&quot;752&quot; data-origin-width=&quot;1180&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니나 다를까 @nestjs/mapped-types라는 라이브러리도 존재했다.&lt;/p&gt;
&lt;pre id=&quot;code_1704521222604&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// #1
import { PickType } from '@nestjs/mapped-types';

// #2
import { PickType } from '@nestjs/swagger';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 대체 두 라이브러리의 차이점은 무엇일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;본인은 mapped-types를 써서 한번 털려보고서야 깨달음을 얻었다... 미리 docs를 잘봤어야하는데&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 DTO를 상속받아올 때 ApiProperty 데커레이터까지 같이 상속받아올 수 있냐는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 import { PickType } from '@nestjs/mapped-types'; 를 사용한다면 아래와 같이 Property에 대한 description을 불러올 수 없는 문제가 발생해서 swagger를 원활하게 쓸 수 없게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bACafl/btsC4rmgOia/9euwBkx5QY9VCSM88U1cU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bACafl/btsC4rmgOia/9euwBkx5QY9VCSM88U1cU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bACafl/btsC4rmgOia/9euwBkx5QY9VCSM88U1cU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbACafl%2FbtsC4rmgOia%2F9euwBkx5QY9VCSM88U1cU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;181&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블로그를 쓰면서 추가로 조사해보니 반대로 @nestjs/swagger 썼을 때, 제한되는 부분이 있을 수도 있었는데, &lt;span style=&quot;background-color: #fdfdfd; color: #000000; text-align: start;&quot;&gt;PartialType을 쓸때는 모든 Field에 ApiProperty를 추가해야만 Optional로 불러올 수 있다는 점이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*참고 : &lt;a href=&quot;https://github.com/nestjs/swagger/issues/1043#issuecomment-727855261&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/nestjs/swagger/issues/1043#issuecomment-727855261&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704521893289&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;PartialType doesn't make property optional &amp;middot; Issue #1043 &amp;middot; nestjs/swagger&quot; data-og-description=&quot;I'm submitting a... [ ] Regression [x] Bug report [ ] Feature request [ ] Documentation issue or request [ ] Support request =&amp;gt; Please do not submit support request here, instead post your question...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/nestjs/swagger/issues/1043#issuecomment-727855261&quot; data-og-url=&quot;https://github.com/nestjs/swagger/issues/1043&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d0alS2/hyUXLURcyq/F5ahirAWxfDRp33JtteBGK/img.png?width=1200&amp;amp;height=600&amp;amp;face=975_138_1050_220&quot;&gt;&lt;a href=&quot;https://github.com/nestjs/swagger/issues/1043#issuecomment-727855261&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/nestjs/swagger/issues/1043#issuecomment-727855261&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d0alS2/hyUXLURcyq/F5ahirAWxfDRp33JtteBGK/img.png?width=1200&amp;amp;height=600&amp;amp;face=975_138_1050_220');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;PartialType doesn't make property optional &amp;middot; Issue #1043 &amp;middot; nestjs/swagger&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I'm submitting a... [ ] Regression [x] Bug report [ ] Feature request [ ] Documentation issue or request [ ] Support request =&amp;gt; Please do not submit support request here, instead post your question...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각 필요한 상황에 맞춰 라이브러리를 쓸 수 있어야겠다.&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>@nestjs/mapped-types</category>
      <category>@nestjs/swagger</category>
      <category>entends DTO</category>
      <category>NestJS DTO 상속</category>
      <category>NestJS swagger</category>
      <category>PartialType</category>
      <category>PickType</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/81</guid>
      <comments>https://pypystory.tistory.com/81#entry81comment</comments>
      <pubDate>Sat, 6 Jan 2024 15:24:00 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] winston을 사용해서 logger middleware, filter로 로깅하기. 로그 관심사 분리</title>
      <link>https://pypystory.tistory.com/80</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;왜 winston을 고르게 되었는가?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/os87k/btsCVFRpskq/AyitVm4MhIXQxVBCOiOX2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/os87k/btsCVFRpskq/AyitVm4MhIXQxVBCOiOX2k/img.png&quot; data-alt=&quot;https://github.com/winstonjs&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/os87k/btsCVFRpskq/AyitVm4MhIXQxVBCOiOX2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fos87k%2FbtsCVFRpskq%2FAyitVm4MhIXQxVBCOiOX2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;200&quot; data-origin-width=&quot;200&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://github.com/winstonjs&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS에서 logging을 구현하는 방법에는 여러가지가 있다. 기본적으로 @nestjs/common에 내장된 logger가 있긴하지만, package에는 편리한 기능들이 구현되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pino, morgan 등 JS 진영에서 쓸 수 있는 여러 package들이 있는데, 본인은 templete을 만들기 위해 가장 대중적인 패키지를 찾고 싶었고, 'popular node js logging'로 구글링을 해본 결과 아래와 같은 자료를 찾을 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;365&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mMwue/btsCOCIDl80/nqimwKUShXRzkKyb2K5DuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mMwue/btsCOCIDl80/nqimwKUShXRzkKyb2K5DuK/img.png&quot; data-alt=&quot;출처 :&amp;amp;nbsp;https://betterstack.com/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mMwue/btsCOCIDl80/nqimwKUShXRzkKyb2K5DuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmMwue%2FbtsCOCIDl80%2FnqimwKUShXRzkKyb2K5DuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;628&quot; height=&quot;365&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;365&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://betterstack.com/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 10월 기준으로 Winston이 많은 download를 기록하고 있었고, typescript를 지원하였기에 많은 레퍼런스를 기대하며 고르게 되었다.&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;b&gt;구현 방식&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Logger 불러오기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Logger를 불러오는 방법에는 여러가지가 있었다. 전역적으로 사용하기 위해서 NestApplicationContext 내의 option 중 logger를&amp;nbsp; 대체하는(Replacing the Nest logger) 방법도 있고, LoggerModule을 추가한 뒤 필요한 부분에 Inject해서(원한다면 Global로) 사용하는 방법도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://www.npmjs.com/package/nest-winston&quot;&gt;nest-winston - npm (npmjs.com)&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인은 Bootstrapping 단계부터 logging 되기를 원했기에 'Replacing the Nest logger ' 방법을 선택했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Logger로 Logging 하기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 불러온 Logger로 Logging은 어떻게 해야할까? Winston Docs에서는 아래와 같이 'Controller에 Logger를 Injection해서 필요한 부분을 로깅'하는 방법의 예시를 보여주고 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1704106443980&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import { Controller, Get, Logger } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    private readonly logger: Logger,
  ) {}

  @Get()
  getHello(): string {
    this.logger.log('Calling getHello()', AppController.name);
    this.logger.debug('Calling getHello()', AppController.name);
    this.logger.verbose('Calling getHello()', AppController.name);
    this.logger.warn('Calling getHello()', AppController.name);

    try {
      throw new Error()
    } catch (e) {
      this.logger.error('Calling getHello()', e.stack, AppController.name);
    }

    return this.appService.getHello();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 코드를 보면 logger를 상황마다 직접 사용하게 되는데, 이 경우 코드 가독성을 해칠 수 있고, controller의 역할이 커진다. log format을 일정하게 유지하거나, 바꾸기도 쉽지 않을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이유로 NestJS Docs에서는 middleware로 logger를 관리하는 예시를 보여주고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 참고 : &lt;a href=&quot;https://docs.nestjs.com/middleware&quot;&gt;Middleware | NestJS - A progressive Node.js framework&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS의 장점 중 하나는 LifeCycle을 활용해서 관심사를 분리할 수 있다는 점이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPpyPp/btsCP5DWRgv/Vixl5i8fJeWXKYSCak3xvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPpyPp/btsCP5DWRgv/Vixl5i8fJeWXKYSCak3xvK/img.png&quot; data-alt=&quot;출처 :&amp;amp;nbsp;https://slides.com/yariv-gilad&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPpyPp/btsCP5DWRgv/Vixl5i8fJeWXKYSCak3xvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPpyPp%2FbtsCP5DWRgv%2FVixl5i8fJeWXKYSCak3xvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;458&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;458&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;nbsp;https://slides.com/yariv-gilad&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 그림은 NestJS에서 Request의 LifeCycle을 보여주고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에서 Logger의 역할을 생각해보았을 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(1). 사용자가 요청한 기록을 Logging&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(2). 만약 Error가 발생했을 때 기록을 Logging&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정도를 생각해볼 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 (1)을 만족하기 위해서 logger.middleware를 만들어서 사용자 요청을 logging할 것이며, (2)를 만족하기 위해서 exception.filter를 만들어서 Error가 발생한 부분의 정보를 로깅할 것이다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Package 설치&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1704106054628&quot; class=&quot;stata&quot; style=&quot;background-color: #f8f8f8; color: #383a42;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npm install --save winston nest-winston winston-daily-rotate-file&lt;/code&gt;&lt;/pre&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;b&gt;Code&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. NestJS 내장 Logger를 replace해준다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704106842776&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// main.ts
...
import { winstonLogger } from './config';

async function bootstrap(): Promise&amp;lt;string&amp;gt; {
  const app = await NestFactory.create&amp;lt;NestExpressApplication&amp;gt;(AppModule, {
    bufferLogs: true,
    logger: winstonLogger, // replacing logger
  });

  await app.listen(process.env['PORT'] || 3000);

  return app.getUrl();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. logger.config 파일에 winstonLogger(WinstonModule)을 설정하고 export 해준다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704106930054&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// config/logger.config.ts

import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-winston';
import winstonDaily from 'winston-daily-rotate-file';
import * as winston from 'winston';

const isProduction = process.env['NODE_ENV'] === 'production';
const logDir = __dirname + '/../../logs';

const dailyOptions = (level: string) =&amp;gt; {
  return {
    level,
    datePattern: 'YYYY-MM-DD',
    dirname: logDir + `/${level}`,
    filename: `%DATE%.${level}.log`,
    zippedArchive: true,
    maxSize: '20m',
    maxFiles: '14d',
  };
};

export const winstonLogger = WinstonModule.createLogger({
  transports: [
    new winston.transports.Console({
      level: isProduction ? 'info' : 'silly',
      format: isProduction
        ? winston.format.simple()
        : winston.format.combine(
            winston.format.timestamp(),
            winston.format.ms(),
            nestWinstonModuleUtilities.format.nestLike('MyApp', {
              colors: true,
              prettyPrint: true,
            }),
          ),
    }),
    new winstonDaily(dailyOptions('info')),
    new winstonDaily(dailyOptions('warn')),
    new winstonDaily(dailyOptions('error')),
  ],
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Logger Moddleware를 구현해준다. NestMiddleware를 implement하고, 모든 request에 대해서, 동일한 logging format을 유지할 수 있도록 해준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;( 본인은 ip, method, originalURL, userAgent, user_id를 logging하기로 했다.)&lt;/p&gt;
&lt;pre id=&quot;code_1704107071503&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// common/middleware/logger-context.middleware.ts
import { Inject, Injectable, Logger, LoggerService, NestMiddleware } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { NextFunction, Request, Response } from 'express';
import { JwtPayload } from '../../../src/auth';

@Injectable()
export class LoggerContextMiddleware implements NestMiddleware {
  constructor(
    @Inject(Logger) private readonly logger: LoggerService,
    private readonly jwt: JwtService,
  ) {}

  use(req: Request, res: Response, next: NextFunction) {
    const { ip, method, originalUrl, headers } = req;
    const userAgent = req.get('user-agent');
    const payload = headers.authorization
      ? &amp;lt;JwtPayload&amp;gt;this.jwt.decode(headers.authorization)
      : null;
    const userId = payload ? payload.sub : 0;
    const datetime = new Date();
    res.on('finish', () =&amp;gt; {
      const { statusCode } = res;
      this.logger.log(
        `${datetime} USER-${userId} ${method} ${originalUrl} ${statusCode} ${ip} ${userAgent}`,
      );
    });

    next();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. Common Module을 Global 모듈로 설정하고, 모든 route '*'에 대해서 logger.middleware를 적용하도록 한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704107279196&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// common/common.module.ts
import { Global, Logger, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';

import { LoggerContextMiddleware } from './middleware';
import * as providers from './providers';
import { JwtModule } from '@nestjs/jwt';

const services = [Logger, ...Object.values(providers)];

@Global()
@Module({
  imports: [JwtModule.register({})],
  providers: services,
  exports: services,
})
export class CommonModule implements NestModule {
  public configure(consumer: MiddlewareConsumer): void {
    consumer.apply(LoggerContextMiddleware).forRoutes('*');
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. 추가적으로 모든 오류에 대해서 logging을 할 수 있도록 exception filter에 logger를 추가해준다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1704107343804&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// common/filters/exception.filter.ts
import { Catch, ArgumentsHost, HttpStatus, HttpException, Logger } from '@nestjs/common';
import { Request, Response } from 'express';
import { QueryFailedError } from 'typeorm';

enum MysqlErrorCode {
  ALREADY_EXIST = 'ER_DUP_ENTRY',
}

@Catch()
export class ExceptionsFilter {
  private readonly logger: Logger = new Logger();

  public catch(exception: unknown, host: ArgumentsHost): void {
    let args: unknown;
    let message: string = 'UNKNOWN ERROR';

    const ctx = host.switchToHttp();
    const res = ctx.getResponse&amp;lt;Response&amp;gt;();
    const req = ctx.getRequest&amp;lt;Request&amp;gt;();
    const statusCode = this.getHttpStatus(exception);
    const datetime = new Date();

    message = exception instanceof HttpException ? exception.message : message;
    message = exception instanceof QueryFailedError ? 'Already Exist' : message;

    const errorResponse = {
      code: statusCode,
      timestamp: datetime,
      path: req.url,
      method: req.method,
      message: message,
    };

    if (statusCode &amp;gt;= HttpStatus.INTERNAL_SERVER_ERROR) {
      this.logger.error({ err: errorResponse, args: { req, res } });
    } else {
      this.logger.warn({ err: errorResponse, args });
    }

    res.status(statusCode).json(errorResponse);
  }

  private getHttpStatus(exception: unknown): HttpStatus {
    if (
      exception instanceof QueryFailedError &amp;amp;&amp;amp;
      exception.driverError.code === MysqlErrorCode.ALREADY_EXIST
    ) {
      return HttpStatus.CONFLICT;
    } else if (exception instanceof HttpException) return exception.getStatus();
    else return HttpStatus.INTERNAL_SERVER_ERROR;
  }
}&lt;/code&gt;&lt;/pre&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;b&gt;결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;info, warn 등으로 나뉘어 지정한 format대로 로깅이 되고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1499&quot; data-origin-height=&quot;801&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUCFJi/btsCZjf8tj1/DwI75lnLE8DMkKLZXCdHBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUCFJi/btsCZjf8tj1/DwI75lnLE8DMkKLZXCdHBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUCFJi/btsCZjf8tj1/DwI75lnLE8DMkKLZXCdHBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUCFJi%2FbtsCZjf8tj1%2FDwI75lnLE8DMkKLZXCdHBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1499&quot; height=&quot;801&quot; data-origin-width=&quot;1499&quot; data-origin-height=&quot;801&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 로그는 local에 YYYY-MM-DD.log 파일로 저장되어 아카이빙된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;767&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzaSgI/btsCR9sjfPc/XoPpnTrQ85FqijzzalhDL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzaSgI/btsCR9sjfPc/XoPpnTrQ85FqijzzalhDL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzaSgI/btsCR9sjfPc/XoPpnTrQ85FqijzzalhDL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzaSgI%2FbtsCR9sjfPc%2FXoPpnTrQ85FqijzzalhDL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1812&quot; height=&quot;767&quot; data-origin-width=&quot;1812&quot; data-origin-height=&quot;767&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;전체코드&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/americano212/nestjs-rest-api-templete-v1&quot;&gt;americano212/nestjs-rest-api-templete-v1: [23.10.13 ~ ] NestJS REST API templete (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1704107397014&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - americano212/nestjs-rest-api-templete-v1: [23.10.13 ~ ] NestJS REST API templete&quot; data-og-description=&quot;[23.10.13 ~ ] NestJS REST API templete. Contribute to americano212/nestjs-rest-api-templete-v1 development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/americano212/nestjs-rest-api-templete-v1&quot; data-og-url=&quot;https://github.com/americano212/nestjs-rest-api-templete-v1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmdNu0/hyUXS6b3MH/4Go5RTGI59AlNI7wxPcy3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_118_1036_163&quot;&gt;&lt;a href=&quot;https://github.com/americano212/nestjs-rest-api-templete-v1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/americano212/nestjs-rest-api-templete-v1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmdNu0/hyUXS6b3MH/4Go5RTGI59AlNI7wxPcy3k/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_118_1036_163');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - americano212/nestjs-rest-api-templete-v1: [23.10.13 ~ ] NestJS REST API templete&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[23.10.13 ~ ] NestJS REST API templete. Contribute to americano212/nestjs-rest-api-templete-v1 development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>logger SOLID</category>
      <category>logger 분리</category>
      <category>nest-winston</category>
      <category>nestjs LifeCycle</category>
      <category>nestjs logger</category>
      <category>nestjs 로깅</category>
      <category>winston</category>
      <category>관심사 분리</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/80</guid>
      <comments>https://pypystory.tistory.com/80#entry80comment</comments>
      <pubDate>Mon, 1 Jan 2024 20:16:29 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] mysql 데이터베이스 이전하기, linux CLI, mysql dump, AWS RDS</title>
      <link>https://pypystory.tistory.com/79</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 상황&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS RDS를 사용하다가 프리티어 기간이 만료되어서 새로운 계정으로 DB를 옮겨야할 일이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 현재 개발 환경상 사지방 PC 자체에서 각종 포트들이 막혀있어서, mysql workbench와 같은 상용프로그램을 사용할 수 없는 상태이다. 그래서 외부 리눅스 서버에 웹콘솔로 접속을해서 해당 DB의 Mysql Dump를 뜨고, 옮겨서 load를 해야하는 상황이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOB0Xb/btsBKfMOFZE/7gkxkkSpJnyrWDa0d3JmJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOB0Xb/btsBKfMOFZE/7gkxkkSpJnyrWDa0d3JmJK/img.png&quot; data-alt=&quot;AWS RDS&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOB0Xb/btsBKfMOFZE/7gkxkkSpJnyrWDa0d3JmJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOB0Xb%2FbtsBKfMOFZE%2F7gkxkkSpJnyrWDa0d3JmJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;165&quot; height=&quot;165&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS RDS&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. AWS EC2를 생성 및 mysql-client 설치&lt;/h4&gt;
&lt;pre id=&quot;code_1699599574486&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo apt update
sudo apt install mysql-client&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. mysqldump 명령어로 덤프 파일 만들기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysqldump -u &amp;lt;유저명&amp;gt; -p -h &amp;lt;old 호스트주소&amp;gt; &amp;lt;스키마명&amp;gt; &amp;gt; &amp;lt;파일이름.sql&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 형태로 덤프 파일을 추출할 수 있다. 아래는 예시이다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1702195612916&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysqldump -u admin -p -h old.hostaddress.rds.amazonaws.com DB_NAME &amp;gt; db.sql&lt;/code&gt;&lt;/pre&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;h4 data-ke-size=&quot;size20&quot;&gt;3. RDS에서 허용하지 않는 옵션들 지우기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysqldump 명령어로 덤프파일을 생성할 때, AWS RDS에서 새로운 db.sql 파일을 load할 때 허용되지 않는 옵션들이 생성되게 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1702196333145&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi db.sql&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;vi 나 vim명령어로 추출한 sql 파일을 열어준다. 아래 3개의 옵션을 주석처리 혹은 지워주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1702196427766&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED=/*!80000 '+'*/ '';
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 vi 명령어모드(esc)에서 문자열 찾기를 하면 좀 더 수월하게 지울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;/검색어&lt;/b&gt; : '검색어'를 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;n&lt;/b&gt; : 다음 검색어 뒤로 이동.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;4. 덤프파일 옮기기(load)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Database를 생성해줘야한다. 새로운 RDS에 접속해서 DATABASE를 create한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CREATE DATABASE 데이터베이스명;&lt;/p&gt;
&lt;pre id=&quot;code_1702196900508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql -u username123 -p -h new.hostname.ap-northeast-2.rds.amazonaws.com // 접속
CREATE DATABASE new_db_name; // 새로운 DATABASE 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들어둔 덤프파일을 새로운 데이터베이스에 아래와 같은 형태로 불러올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql -u &amp;lt;유저명&amp;gt; -p -h &amp;lt;new&amp;nbsp;호스트주소 &amp;gt; &amp;lt;데이터베이스명&amp;gt; &amp;lt; &amp;lt;파일이름.sql&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 예시이다.&lt;/p&gt;
&lt;pre id=&quot;code_1702197191971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;mysql -u username123 -p -h new.hostname.ap-northeast-2.rds.amazonaws.com new_db_name &amp;lt; db.sql&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;성공적으로 DB이전이 완료되었다. dump파일을 만들고 load하는 과정에서 하드웨어, 네트워크 상태에 따라 렉이 걸리거나 버퍼링이 걸릴 수 있으나 dump파일 용량이 커서 그러니 잠깐 놔두면 정상적으로 명령이 수행된다.&lt;/p&gt;</description>
      <category>개발/Database</category>
      <category>AWS RDS</category>
      <category>AWS RDS 옮기기</category>
      <category>AWS RDS 이전</category>
      <category>DB 이전</category>
      <category>mysql CLI</category>
      <category>mysql dump</category>
      <category>mysqldump</category>
      <category>데이터베이스 옮기기</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/79</guid>
      <comments>https://pypystory.tistory.com/79#entry79comment</comments>
      <pubDate>Sun, 10 Dec 2023 17:37:15 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] AWS Elastic Beanstalk 'Unknown' 상태, terraform으로 aws elastic beanstalk를 관리할 때 유의할 점</title>
      <link>https://pypystory.tistory.com/78</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EpGzg/btsBj7IUqd5/QOKUpsk5RpdUDRdJlhZedk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EpGzg/btsBj7IUqd5/QOKUpsk5RpdUDRdJlhZedk/img.png&quot; data-alt=&quot;AWS IAM&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EpGzg/btsBj7IUqd5/QOKUpsk5RpdUDRdJlhZedk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEpGzg%2FbtsBj7IUqd5%2FQOKUpsk5RpdUDRdJlhZedk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;143&quot; height=&quot;144&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS IAM&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Elastic Beanstalk(이하 EB)에는 서비스를 관리하기 위한 역할(Role)을 최초 애플리케이션 생성시 만들게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Web Console로 EB를 생성하면 아래와 같은 화면을 볼 수 있다. 이때 '새 서비스 역할 생성 및 사용'을 선택하게 되면 자동으로 EB에 액세스하고 관리하는데 필요한 역할이 부여된 IAM을 생성하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;506&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUHr8b/btsBipcAvXm/u0bPdsFK2Rkt0ktfUJpTrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUHr8b/btsBipcAvXm/u0bPdsFK2Rkt0ktfUJpTrk/img.png&quot; data-alt=&quot;aws에서 EB 생성시 서비스 액세스를 위한 role을 요구한다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUHr8b/btsBipcAvXm/u0bPdsFK2Rkt0ktfUJpTrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUHr8b%2FbtsBipcAvXm%2Fu0bPdsFK2Rkt0ktfUJpTrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;639&quot; height=&quot;409&quot; data-origin-width=&quot;790&quot; data-origin-height=&quot;506&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;aws에서 EB 생성시 서비스 액세스를 위한 role을 요구한다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 테라폼을 사용해서 EB를 생성할 때 iam을 어떻게 설정해줄 수 있을까.&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;b&gt;문제 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IAM설정을 해주지 않고 terraform apply를 하면, 권한이 없어 EB가 생성되다말고 롤백을 하게 되는 모습을 볼 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진과 같이 상태가 'Unknown'으로 바뀌고 health check를 못하는 상태가 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6iWlX/btsz9ZLPW6x/PKh2F6ATYNbDDK6ENkPGS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6iWlX/btsz9ZLPW6x/PKh2F6ATYNbDDK6ENkPGS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6iWlX/btsz9ZLPW6x/PKh2F6ATYNbDDK6ENkPGS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6iWlX%2Fbtsz9ZLPW6x%2FPKh2F6ATYNbDDK6ENkPGS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;739&quot; height=&quot;269&quot; data-origin-width=&quot;883&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트 부분을 보면 health check가 안된 EB는 정상적으로 instance가 배포되지 않은 것으로 인식한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bey1hX/btsz9jKyKZz/PplAev9aiKFqWEVTcMblmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bey1hX/btsz9jKyKZz/PplAev9aiKFqWEVTcMblmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bey1hX/btsz9jKyKZz/PplAev9aiKFqWEVTcMblmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbey1hX%2Fbtsz9jKyKZz%2FPplAev9aiKFqWEVTcMblmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;782&quot; height=&quot;362&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/logs/daemon.log 에서 디테일한 오류를 확인해볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1701604731089&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# Logfile created on 2023-11-10 07:47:23 +0000 by logger.rb/v1.5.0


W, [2023-11-10T07:57:27.665909 #2144]  WARN -- : sending message(s) failed (attempt 10): (Aws::Healthd::Errors::AccessDeniedException) User: arn:aws:sts::158161732663:assumed-role/aws-elasticbeanstalk-ec2-role/i-0feca5ff1006ea9fa is not authorized to perform: elasticbeanstalk:PutInstanceStatistics on resource: arn:aws:elasticbeanstalk:ap-northeast-2:158161732663:application/ddakzip-eb-application. Backing off by 200 seconds in addition to delay interval
W, [2023-11-10T08:00:01.307654 #2144]  WARN -- : log file &quot;/var/log/nginx/healthd/application.log.2023-11-10-08&quot; does not exist
W, [2023-11-10T08:00:57.668536 #2144]  WARN -- : sending message(s) failed (attempt 11): (Aws::Healthd::Errors::AccessDeniedException) User: arn:aws:sts::158161732663:assumed-role/aws-elasticbeanstalk-ec2-role/i-0feca5ff1006ea9fa is not authorized to perform: elasticbeanstalk:PutInstanceStatistics on resource: arn:aws:elasticbeanstalk:ap-northeast-2:158161732663:application/ddakzip-eb-application. Backing off by 200 seconds in addition to delay interval
F, [2023-11-10T08:02:25.229480 #2144] FATAL -- : /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/puma-6.3.0/lib/puma/launcher.rb:434:in `block in setup_signals': SIGTERM (SignalException)
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/puma-6.3.0/lib/puma/single.rb:63:in `join'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/puma-6.3.0/lib/puma/single.rb:63:in `run'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/puma-6.3.0/lib/puma/launcher.rb:194:in `run'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/puma-6.3.0/lib/puma/cli.rb:75:in `run'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/healthd-1.0.6/bin/healthd:112:in `block in &amp;lt;top (required)&amp;gt;'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/healthd-1.0.6/bin/healthd:19:in `chdir'
	from /opt/elasticbeanstalk/lib/ruby/lib/ruby/gems/3.1.0/gems/healthd-1.0.6/bin/healthd:19:in `&amp;lt;top (required)&amp;gt;'
	from /opt/elasticbeanstalk/lib/ruby/bin/healthd:25:in `load'
	from /opt/elasticbeanstalk/lib/ruby/bin/healthd:25:in `&amp;lt;main&amp;gt;'
A, [2023-11-10T08:02:27.869107 #3601]   ANY -- : healthd daemon 1.0.6 initialized
W, [2023-11-10T08:02:38.021989 #3601]  WARN -- : sending message(s) failed (attempt 1): (Aws::Healthd::Errors::AccessDeniedException) User: arn:aws:sts::158161732663:assumed-role/aws-elasticbeanstalk-ec2-role/i-0feca5ff1006ea9fa is not authorized to perform: elasticbeanstalk:PutInstanceStatistics on resource: arn:aws:elasticbeanstalk:ap-northeast-2:158161732663:application/ddakzip-eb-application. Backing off by 2 seconds in addition to delay interval
W, [2023-11-10T08:02:49.911398 #3601]  WARN -- : sending message(s) failed (attempt 2): (Aws::Healthd::Errors::AccessDeniedException) User: arn:aws:sts::158161732663:assumed-role/aws-elasticbeanstalk-ec2-role/i-0feca5ff1006ea9fa is not authorized to perform: elasticbeanstalk:PutInstanceStatistics on resource: arn:aws:elasticbeanstalk:ap-northeast-2:158161732663:application/ddakzip-eb-application. Backing off by 3 seconds in addition to delay interval
W, [2023-11-10T08:03:02.885369 #3601]  WARN -- : sending message(s) failed (attempt 3): (Aws::Healthd::Errors::AccessDeniedException) User: arn:aws:sts::158161732663:assumed-role/aws-elasticbeanstalk-ec2-role/i-0feca5ff1006ea9fa is not authorized to perform: elasticbeanstalk:PutInstanceStatistics on resource: arn:aws:elasticbeanstalk:ap-northeast-2:158161732663:application/ddakzip-eb-application. Backing off by 4 seconds in addition to delay interval&lt;/code&gt;&lt;/pre&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;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 간단하다. 테라폼으로 EB를 생성할 때 부여하는 IAM을 직접 정의해주고, policy를 부여하는 방법으로 해결할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 EB를 직접적으로 생성하는 코드이다. EB에 세부적인 설정은 setting { }을 통해서 추가할 수 있다&lt;/p&gt;
&lt;pre id=&quot;code_1701604299417&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /main.tf
# Create elastic beanstalk application
resource &quot;aws_elastic_beanstalk_application&quot; &quot;eb_app&quot; {
  name = var.eb_application_name
}

# Create elastic beanstalk Environment
resource &quot;aws_elastic_beanstalk_environment&quot; &quot;eb_env&quot; {
  name                = var.eb_environment_name
  application         = aws_elastic_beanstalk_application.eb_app.name
  solution_stack_name = var.solution_stack_name
  tier                = &quot;WebServer&quot; 
  
  # IAM을 추가하는 setting
  setting {
    namespace = &quot;aws:autoscaling:launchconfiguration&quot;
    name      = &quot;IamInstanceProfile&quot;
    value     = aws_iam_instance_profile.eb_instance_profile.name
  }
  
  ...
  
}&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;이때 IAM은 다음과 같이 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼에서는 &amp;lt;&amp;lt;EOF EOF를 이용해서 여러줄의 단락을 처리하는 heredoc을 지원한다. 이를 이용하여 json format의 policy를 추가해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sts, s3 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;ec2 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;sqs &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;ecs &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;ecr &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;logs &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;,&lt;span&gt; &lt;/span&gt;&lt;/span&gt;elasticbeanstalk 권한들을 필요로한다. 실질적으로 오류를 해결하는데 필요한 권한은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sts:AssumeRole이지만, 기존의 EB 생성시 자동으로 부여되는 IAM을 새로 만드는 것이기에 EB에 필요한 모든 권한을 부여해줘야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1701606106187&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_iam_role&quot; &quot;eb_instance_profile&quot; {
  name = &quot;aws-elasticbeanstalk-ec2-role&quot;
  assume_role_policy = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Service&quot;: &quot;ec2.amazonaws.com&quot;
      },
      &quot;Action&quot;: &quot;sts:AssumeRole&quot;
    }
  ]
}
EOF
}

resource &quot;aws_iam_instance_profile&quot; &quot;eb_instance_profile&quot; {
  name = &quot;aws-elasticbeanstalk-ec2-role&quot;
  role = aws_iam_role.eb_instance_profile.name
}

# AWSElasticBeanstalkWebTier 정책 추가
resource &quot;aws_iam_role_policy&quot; &quot;web_tier_policy&quot; {
  name        = &quot;AWSElasticBeanstalkWebTierPolicy&quot;
  role        = aws_iam_role.eb_instance_profile.name
  policy      = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;s3:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    },
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;ec2:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
EOF
}

# AWSElasticBeanstalkWorkerTier 정책 추가
resource &quot;aws_iam_role_policy&quot; &quot;worker_tier_policy&quot; {
  name        = &quot;AWSElasticBeanstalkWorkerTierPolicy&quot;
  role        = aws_iam_role.eb_instance_profile.name
  policy      = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;sqs:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    },
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;ec2:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
EOF
}

# AWSElasticBeanstalkMulticontainerDocker 정책 추가
resource &quot;aws_iam_role_policy&quot; &quot;multicontainer_docker_policy&quot; {
  name        = &quot;AWSElasticBeanstalkMulticontainerDockerPolicy&quot;
  role        = aws_iam_role.eb_instance_profile.name
  policy      = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;ecs:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    },
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;ecr:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
EOF
}

# AWSElasticBeanstalkLogStream을 위한 정책 추가
resource &quot;aws_iam_role_policy&quot; &quot;attach_policy&quot; {
  name   = &quot;ElasticBeanstalkLoggingPolicy&quot;
  role   = aws_iam_role.eb_instance_profile.name
  policy = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: [
        &quot;logs:PutLogEvents&quot;,
        &quot;logs:CreateLogStream&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
EOF
}

# AWSElasticBeanstalkStatisticPolicy 정책 추가
resource &quot;aws_iam_role_policy&quot; &quot;eb_statistic_policy&quot; {
  name        = &quot;AWSElasticBeanstalkStatisticPolicy&quot;
  role        = aws_iam_role.eb_instance_profile.name
  policy      = &amp;lt;&amp;lt;EOF
{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: &quot;elasticbeanstalk:*&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}
EOF
}&lt;/code&gt;&lt;/pre&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;b&gt;참조문서&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-launchconfiguration.html&quot;&gt;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-launchconfiguration.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>인프라/Terraform</category>
      <category>aws iam</category>
      <category>elastic beanstalk</category>
      <category>health check</category>
      <category>terraform</category>
      <category>Unknown 에러</category>
      <category>엘라스틱빈스톡</category>
      <category>테라폼</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/78</guid>
      <comments>https://pypystory.tistory.com/78#entry78comment</comments>
      <pubDate>Sun, 3 Dec 2023 21:26:45 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] TypeORM으로 enum array를 사용한 entity 생성시 발생하는 오류 트러블슈팅 (feat. MySQL)</title>
      <link>https://pypystory.tistory.com/77</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;329&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwz0wk/btsyHoGM7Nk/U23K3k8FDOOptUXN0BS9OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwz0wk/btsyHoGM7Nk/U23K3k8FDOOptUXN0BS9OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwz0wk/btsyHoGM7Nk/U23K3k8FDOOptUXN0BS9OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcwz0wk%2FbtsyHoGM7Nk%2FU23K3k8FDOOptUXN0BS9OK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;220&quot; height=&quot;217&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;329&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;0. 개발환경&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@nestjs/typeorm : 10.0.0&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nest : 10.1.18&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mysql 8.0.xx&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typescript : 5.1.x&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 문제의 발생&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1697540203637&quot; class=&quot;scala&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;@Entity('user')
export class UserEntity extends CoreEntity {
  ...

  @Column({
    type: 'enum',
    enum: Role,
    array: true,
    default: [Role.User],
  })
  @IsString()
  public roles!: Role[];

  ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;user.entity를 설계하는 과정에서 Role을 Enum array로 관리하고자 하였고, 코드상으로는 syntax적 문제가 없었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;그런데 막상 npm run start:dev를 실행하여 mysql 서버상에 table 생성을 시도하자 아래와 같은 에러가 발생했다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;query&amp;nbsp;failed:&amp;nbsp;ALTER&amp;nbsp;TABLE&amp;nbsp;`user`&amp;nbsp;ADD&amp;nbsp;`roles`&amp;nbsp;enum&amp;nbsp;array&amp;nbsp;('User',&amp;nbsp;'Admin')&amp;nbsp;NOT&amp;nbsp;NULL&amp;nbsp;DEFAULT&amp;nbsp;'User' &lt;br /&gt;error:&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Error:&amp;nbsp;You&amp;nbsp;have&amp;nbsp;an&amp;nbsp;error&amp;nbsp;in&amp;nbsp;your&amp;nbsp;SQL&amp;nbsp;syntax;&amp;nbsp;check&amp;nbsp;the&amp;nbsp;manual&amp;nbsp;that&amp;nbsp;corresponds&amp;nbsp;to&amp;nbsp;your&amp;nbsp;MySQL&amp;nbsp;server&amp;nbsp;version&amp;nbsp;for&amp;nbsp;the&amp;nbsp;right&amp;nbsp;syntax&amp;nbsp;to&amp;nbsp;use&amp;nbsp;near&amp;nbsp;'array&amp;nbsp;('User',&amp;nbsp;'Admin')&amp;nbsp;NOT&amp;nbsp;NULL&amp;nbsp;DEFAULT&amp;nbsp;'User''&amp;nbsp;at&amp;nbsp;line&amp;nbsp;1&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKwYBA/btsyIKoL4bw/BVGCrGXmXspoYkUHUS39QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKwYBA/btsyIKoL4bw/BVGCrGXmXspoYkUHUS39QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKwYBA/btsyIKoL4bw/BVGCrGXmXspoYkUHUS39QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKwYBA%2FbtsyIKoL4bw%2FBVGCrGXmXspoYkUHUS39QK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1458&quot; height=&quot;36&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 문제의 원인&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼자 헤매다가 github에서 원인을 찾을 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oCpMY/btsyGq5T2Gq/PaetScg9QA1Lhyilfk49C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oCpMY/btsyGq5T2Gq/PaetScg9QA1Lhyilfk49C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oCpMY/btsyGq5T2Gq/PaetScg9QA1Lhyilfk49C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoCpMY%2FbtsyGq5T2Gq%2FPaetScg9QA1Lhyilfk49C1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;869&quot; height=&quot;145&quot; data-origin-width=&quot;869&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 MySQL에서는 array type을 쓸 수 없다는 점... Postgres에서는 지원하는데, MySQL에서는 지원하지 않는다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 Array를 쓸 상황이면 정규화를 해줘야하는 상황이 온거라고 보는 듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 링크에서 해당 이유를 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/17371639/how-to-store-arrays-in-mysql&quot;&gt;database schema - How to store arrays in MySQL? - Stack Overflow&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 문제의 해결&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나에게 남겨진 선택지는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. RDBMS 자체를 바꿔버린다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Role 테이블을 분리하고 User와 N:M으로 Join한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. user-role 테이블을 생성하고 User와 N:1으로 Join한다. 이때 Role의 enum 값들은 코드상에 하드코딩한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. string type으로 저장하고 불러올 때 split 해오는 Transform을 주입한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 아예 object화 시켜서 json 타입으로 저장해버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정도가 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기저기 물어보고 찾아보면서 고민해본 결과 Role을 확장성 있게 관리하고, 코딩 법칙들을 최대한 지키면서 구현하기 위해 2번( Role 테이블을 분리하고 User와 N:M으로 Join한다.)을 선택했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, N:M으로 생성되는 user-role 테이블에 관해서는 조회시 성능을 잘 생각해서 코딩해야할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;284&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bftpMo/btsyPCZ7A7c/goa1EEmTA5ZvYYKSNeP0kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bftpMo/btsyPCZ7A7c/goa1EEmTA5ZvYYKSNeP0kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bftpMo/btsyPCZ7A7c/goa1EEmTA5ZvYYKSNeP0kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbftpMo%2FbtsyPCZ7A7c%2Fgoa1EEmTA5ZvYYKSNeP0kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1014&quot; height=&quot;284&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;284&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 ERD와 같은 구조로 생성할 수 있었다.&lt;/p&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 참고문서&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://stackoverflow.com/questions/69278717/how-to-add-an-enum-array-in-a-typeorm-entity&quot;&gt;typescript - How to add an enum array in a TypeOrm entity? - Stack Overflow&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://github.com/typeorm/typeorm/issues/10363&quot;&gt;Nestjs typeorm mydsql enum types with array dont work &amp;middot; Issue #10363 &amp;middot; typeorm/typeorm (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://stackoverflow.com/questions/65553546/data-type-array-in-user-repositories-is-not-supported-by-mysql-database&quot;&gt;javascript - Data type &quot;Array&quot; in &quot;User.repositories&quot; is not supported by &quot;mysql&quot; database - Stack Overflow&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a style=&quot;background-color: #e6f5ff; color: #0070d1; text-align: start;&quot; href=&quot;https://stackoverflow.com/questions/17371639/how-to-store-arrays-in-mysql&quot;&gt;database schema - How to store arrays in MySQL? - Stack Overflow&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/NestJS</category>
      <category>mysql</category>
      <category>MySQL Array</category>
      <category>mysql enums</category>
      <category>RDBMS</category>
      <category>Roles database</category>
      <category>user role 구현</category>
      <category>user 권한 구현</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/77</guid>
      <comments>https://pypystory.tistory.com/77#entry77comment</comments>
      <pubDate>Fri, 20 Oct 2023 15:06:49 +0900</pubDate>
    </item>
    <item>
      <title>SQLD 합격 후기 &amp;amp; 공부방법 + 공부기간 + 꿀팁 (Feat. 군대에서 노랭이로 공부하고 합격하기)</title>
      <link>https://pypystory.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 SQLD 합격 기념으로 어떻게 공부했는지 &lt;b&gt;공부 방법과 꿀팁&lt;/b&gt;을 공유해보려고 합니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공부기간&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부는&lt;b&gt; 총 일주일 내외&lt;/b&gt;로 &lt;b&gt;하루에 3, 4시간 정도&lt;/b&gt; 공부한 것 같습니다.(풀 집중한 시간은 2시간?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자는 DB 전공수업을 듣지는 않았지만, 프로젝트를 하면서 SQL을 접해본 경험은 있었다는 점을 고려해서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; 생전 처음 SQL을 공부하시는분은 2, 3주 정도&lt;/b&gt;를 잡으면 넉넉하게 합격하실 수 있을 것 같습니다.&lt;/p&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공부방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필자도 공부하기 전에 여러 블로그를 해보고 직접 몸소 검증해봤기 때문에 &lt;b&gt;아래 ★순서대로★ 4가지 방법&lt;/b&gt;으로 공부하시면 충분히 합격하실 수 있을거에요~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; 구글링해서 SQLD 요약본으로 이론공부하기(2일 컷)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 SQLD를 위한 이론서를 하나 살까도 고민해봤지만, 뒤에 소개할 '노랭이책'과 이론서까지 사기엔 부담이 되실거에요ㅠㅠ 그렇기에 필자도 이론서보다는 다른분들이 정리해둔 SQLD 요약본 pdf들이 많았기에 그것만 보고 공부했고, 한 2개정도 인쇄해서 읽어보니 빠지는 내용없이 다 공부할 수 있었습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; 유튜브에서 SQLD 강의 보기(2시간 컷)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유튜브에 무료 강의가 많이 풀려있었습니다. 저는 아래의 강의를 보고 공부했어요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마음에 드는 강의를 찾아보셔도 되는데, 여러 영상을 보니까 아래 영상이 꽤나 적중률 높게 나왔던 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.youtube.com/watch?v=BQxAxMnHByU&quot;&gt;[SQLD 시험대비!!] 마무리 쪽집게 특강 - 44개의 핵심포인트!! - YouTube&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=BQxAxMnHByU&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/cIAuhV/hyT2CwXr3O/NOTIk3RvuxwHcwJkzeSbm1/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=990_170_1134_326&quot; data-video-width=&quot;600&quot; data-video-height=&quot;338&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/BQxAxMnHByU&quot; width=&quot;600&quot; height=&quot;338&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; 노랭이 책으로 문제 풀어보기(3일 소요)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 챕터별로 풀고, 답지로 채점해보고, 틀린 문제들만 따로 개념 정리를 하는 방식으로 공부했어요~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;틀린 개념만 따로 정리해뒀다가 마지막에 시험 직전에 봤더니 많이 도움되었던 것 같아요!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아셔야 할 것은 노랭이책은 이론서가 아니라 문제집입니다. 거의 이론은 없기 때문에 앞의 1,2번 방법으로 이론 공부를 하시고, 책을 사서 풀어보시는 걸 추천해요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시험을 제작하는 곳에서 만든 문제집이라, 시험문제의 반은 노랭이와 비슷한 문제가 나오니까 꼭 ☆ 꼭 ☆ 풀어보세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 전공자라도 SQLD를 위한 공부 없이 풀었다가는 반타작이 날 수 있기에 꼭 SQLD를 위한 공부를 하고 풀어보시는 걸 추천드립니다.&lt;/p&gt;
&lt;figure id=&quot;og_1695884228911&quot; style=&quot;color: #333333; text-align: start;&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fDSIx/hyTVRGFvSO/MoBVaF9erVHkkPKu99dBD1/img.jpg?width=230&amp;amp;height=230&amp;amp;face=0_0_230_230,https://scrap.kakaocdn.net/dn/bARVMB/hyTSzOqzDt/lD95Q2E4l1LaY4IUz5hEy0/img.jpg?width=230&amp;amp;height=230&amp;amp;face=0_0_230_230&quot; data-og-url=&quot;https://www.coupang.com/vp/products/73103197&quot; data-og-source-url=&quot;https://link.coupang.com/a/9oC0J&quot; data-og-host=&quot;www.coupang.com&quot; data-og-description=&quot;COUPANG&quot; data-og-title=&quot;SQL 자격검정 실전문제:국가공인 SQL전문가 국가공인 SQL개발자&quot; data-og-type=&quot;website&quot; data-ke-align=&quot;alignCenter&quot; data-ke-type=&quot;opengraph&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://link.coupang.com/a/9oC0J&quot; data-source-url=&quot;https://link.coupang.com/a/9oC0J&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fDSIx/hyTVRGFvSO/MoBVaF9erVHkkPKu99dBD1/img.jpg?width=230&amp;amp;height=230&amp;amp;face=0_0_230_230,https://scrap.kakaocdn.net/dn/bARVMB/hyTSzOqzDt/lD95Q2E4l1LaY4IUz5hEy0/img.jpg?width=230&amp;amp;height=230&amp;amp;face=0_0_230_230');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; style=&quot;color: #000000;&quot; data-ke-size=&quot;size16&quot;&gt;SQL 자격검정 실전문제:국가공인 SQL전문가 국가공인 SQL개발자&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;COUPANG&lt;/p&gt;
&lt;p class=&quot;og-host&quot; style=&quot;color: #909090;&quot; data-ke-size=&quot;size16&quot;&gt;www.coupang.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&quot;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&quot;&lt;/span&gt;&lt;/p&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;&lt;span style=&quot;background-color: #ffffff; color: #111111; text-align: left;&quot;&gt;★&lt;/span&gt; 최근 기출 구글링해서 풀어보기&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;마지막으로 SQLD 기출문제 라고 검색하면 많은 분들께서 복기해두신 문제들이 있어요!!&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;저는 마지막에 정리하는 차원에서 3회차 정도를 돌려봤는데, 정리도 되고 자신감도 얻었던 것 같아요~&lt;/span&gt;&lt;/span&gt;&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;결과&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bW6mZ1/btsv5m6Hyqb/B3A9pBbbKURcLBcW8nxuFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bW6mZ1/btsv5m6Hyqb/B3A9pBbbKURcLBcW8nxuFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bW6mZ1/btsv5m6Hyqb/B3A9pBbbKURcLBcW8nxuFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbW6mZ1%2Fbtsv5m6Hyqb%2FB3A9pBbbKURcLBcW8nxuFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;220&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pbK9U/btsv8QsfYhc/vr8YDKMESombpa8Ha9RKWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pbK9U/btsv8QsfYhc/vr8YDKMESombpa8Ha9RKWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pbK9U/btsv8QsfYhc/vr8YDKMESombpa8Ha9RKWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpbK9U%2Fbtsv8QsfYhc%2Fvr8YDKMESombpa8Ha9RKWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;975&quot; height=&quot;121&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;121&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;필자는 총점 82점으로 넉넉하게 합격할 수 있었습니다~&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #111111;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;시험 치고 3주정도 있다가 가결과(?)가 나왔고 &lt;b&gt;각 과목별 40점 이상, 총점 60점 이상&lt;/b&gt;이면 합격할 수 있습니다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2023 SQLD 시험일정, 접수기간&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coCsyV/btsv8g5OmD5/EtCmoK49NGVkqrWmgJe0t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coCsyV/btsv8g5OmD5/EtCmoK49NGVkqrWmgJe0t1/img.png&quot; data-alt=&quot;출처 :&amp;amp;amp;nbsp; 시험일정 : 데이터자격시험 (dataq.or.kr)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coCsyV/btsv8g5OmD5/EtCmoK49NGVkqrWmgJe0t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoCsyV%2Fbtsv8g5OmD5%2FEtCmoK49NGVkqrWmgJe0t1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;970&quot; height=&quot;196&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;196&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 :&amp;amp;nbsp; 시험일정 : 데이터자격시험 (dataq.or.kr)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터자격시험 홈페이지에서 접수할 수 있고 올해는 &lt;b&gt;51회 SQLD 접수가 10월 16일&lt;/b&gt;부터 진행됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때! &lt;b&gt;접수 사이트가 굉~~~장히 느리기 때문&lt;/b&gt;에 여유롭고도, 편안한 마음가짐으로 접수를 진행하시길 바랍니다 :)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;꿀팁을 드리자면&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 필자는 '신도림중학교'에 PBT로 신청했는데, &lt;b&gt;접수 시작일로 하루지났는데 CBT는 모두 마감&lt;/b&gt;된 상태였습니다.ㅠ.ㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주변 시험장이나 원하는 시험방식이 있다면 &lt;b&gt;빨리 신청&lt;/b&gt;하시는 걸 추천드립니다 ^^~&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;노랭이책 구매링크&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4yMM7/btswbGibXEN/sfDoK1HDmzQVMIWMixdewK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4yMM7/btswbGibXEN/sfDoK1HDmzQVMIWMixdewK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4yMM7/btswbGibXEN/sfDoK1HDmzQVMIWMixdewK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4yMM7%2FbtswbGibXEN%2FsfDoK1HDmzQVMIWMixdewK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;120&quot; height=&quot;240&quot; data-origin-width=&quot;240&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&quot;이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.&quot;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEiJyK/btswbeMSWmF/2t79Hjj4TzzxuFWBYK3msK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEiJyK/btswbeMSWmF/2t79Hjj4TzzxuFWBYK3msK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEiJyK/btswbeMSWmF/2t79Hjj4TzzxuFWBYK3msK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEiJyK%2FbtswbeMSWmF%2F2t79Hjj4TzzxuFWBYK3msK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;198&quot; height=&quot;254&quot; data-origin-width=&quot;335&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;궁금하신 부분 댓 달아주시면 알려드리겠습니다 ^^~&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>IT/자격증</category>
      <category>2023 SQLD</category>
      <category>SQLD</category>
      <category>SQLD 공부기간</category>
      <category>SQLD 공부방법</category>
      <category>SQLD 노랭이책</category>
      <category>SQLD합격후기</category>
      <category>sql자격검정실전문제</category>
      <author>파이랜스</author>
      <guid isPermaLink="true">https://pypystory.tistory.com/76</guid>
      <comments>https://pypystory.tistory.com/76#entry76comment</comments>
      <pubDate>Thu, 28 Sep 2023 16:21:33 +0900</pubDate>
    </item>
  </channel>
</rss>