<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발산발</title>
    <link>https://sanhee.tistory.com/</link>
    <description>Backend Developer</description>
    <language>ko</language>
    <pubDate>Tue, 7 Apr 2026 22:10:49 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>산희</managingEditor>
    <image>
      <title>개발산발</title>
      <url>https://tistory1.daumcdn.net/tistory/4825589/attach/c03f7e0fd59f452d8f542776ec28bc08</url>
      <link>https://sanhee.tistory.com</link>
    </image>
    <item>
      <title>&amp;ldquo;같은 검색어인데 왜 결과가 다르지?&amp;rdquo; - 한글 검색 정규화 문제 해결기</title>
      <link>https://sanhee.tistory.com/63</link>
      <description>&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;  문제의 시작: &amp;ldquo;왜 검색 결과가 다르지?&amp;rdquo;&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;&lt;b&gt;&amp;ldquo;힛&lt;span style=&quot;color: #006dd7;&quot;&gt;탠&lt;/span&gt;다드&amp;rdquo;&lt;/b&gt;와 같은 &lt;b&gt;검색어&lt;/b&gt;를 직접 입력했을 때는 문제가 없었어요. 하지만 &lt;b&gt;&quot;힛&lt;span style=&quot;color: #ee2323;&quot;&gt;텐&lt;/span&gt;다드&quot;&lt;/b&gt;와 같이 &lt;b&gt;잘못된 검색어&lt;/b&gt;를 입력했을 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색 서비스에서 제공하는 &lt;b&gt;검색어 제안 기능으로 &lt;/b&gt;&quot;&lt;b&gt;힛&lt;span style=&quot;color: #006dd7;&quot;&gt;탠&lt;/span&gt;다드&lt;/b&gt;&quot;가&lt;b&gt;&amp;nbsp; 검색이 되면&lt;/b&gt;&amp;nbsp; NR(검색 결과 없음)으로 표시되는 이슈가 발생했습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;1266&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q3Qe0/btsKIEjKroP/39omkyOMZcBfkENnghXcmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q3Qe0/btsKIEjKroP/39omkyOMZcBfkENnghXcmK/img.png&quot; data-alt=&quot;힛탠다드에 대한 정상적인 검색 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q3Qe0/btsKIEjKroP/39omkyOMZcBfkENnghXcmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq3Qe0%2FbtsKIEjKroP%2F39omkyOMZcBfkENnghXcmK%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;498&quot; height=&quot;527&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;1266&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQulgU/btsKHv2tU7O/EeoaUGkwD0aTJEK4WbkIC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQulgU/btsKHv2tU7O/EeoaUGkwD0aTJEK4WbkIC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQulgU/btsKHv2tU7O/EeoaUGkwD0aTJEK4WbkIC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQulgU%2FbtsKHv2tU7O%2FEeoaUGkwD0aTJEK4WbkIC1%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;1196&quot; height=&quot;236&quot; data-origin-width=&quot;1196&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;&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;1206&quot; data-origin-height=&quot;428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3KVdp/btsKIFJIMdX/YmjAiKbrKvafIyre7sXJ01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3KVdp/btsKIFJIMdX/YmjAiKbrKvafIyre7sXJ01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3KVdp/btsKIFJIMdX/YmjAiKbrKvafIyre7sXJ01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3KVdp%2FbtsKIFJIMdX%2FYmjAiKbrKvafIyre7sXJ01%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;640&quot; height=&quot;227&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;428&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;첫 번째 단서: encodeURIComponent로 인한 문자열 길이 차이 발견&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;size16&quot;&gt;검색어가 제안되었을 때만 &lt;b&gt;NR(검색 결과 없음)&lt;/b&gt;이 발생하는 것을 발견하고, &lt;b&gt;검색어&amp;nbsp;&amp;nbsp;제안 과정&lt;/b&gt;에 문제가 있을 가능성을 의심했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 &lt;b&gt;프론트엔드 개발자&lt;/b&gt;분이 &lt;b&gt;&lt;span&gt;encodeURIComponent(&quot;힛탠다드&quot;)&lt;/span&gt;&lt;/b&gt;로 인코딩한 결과, &lt;b&gt;문자열의 길이 차이&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0SVEv/btsKHH2TOfJ/qayf9rt0lTkzAsnzKh81V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0SVEv/btsKHH2TOfJ/qayf9rt0lTkzAsnzKh81V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0SVEv/btsKHH2TOfJ/qayf9rt0lTkzAsnzKh81V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0SVEv%2FbtsKHH2TOfJ%2Fqayf9rt0lTkzAsnzKh81V0%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;609&quot; height=&quot;311&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;478&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;두 번째 단서: 유니코드 분석으로 확인한 NFD와 NFC 차이&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;size16&quot;&gt;문자열 길이 차이의 원인을 더 자세히 파악하기 위해, &lt;b&gt;유니코드 코드 포인트&lt;/b&gt;로 두 검색어를 분해하여 비교했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그&amp;nbsp;결과,&amp;nbsp;자동&amp;nbsp;제안된&amp;nbsp;키워드가&amp;nbsp;&lt;b&gt;NFD &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;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;NFC(정상적인 검색어)&lt;/b&gt;: &lt;u&gt;힛탠다드&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 포인트: &lt;i&gt;U+D79B U+D0E0 U+B2E4 U+B4DC&lt;/i&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;NFD(자동 제안된 검색어)&lt;/b&gt;: &lt;u&gt;힛탠다드&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 포인트: &lt;i&gt;U+1112 U+1175 U+11BA U+1110 U+1162 U+11AB U+1103 U+1161 U+1103 U+1173&lt;/i&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;NFD 방식으로 분리된 형태&lt;/b&gt;로 제공되어, 검색 엔진에 &lt;b&gt;NFC 방식&lt;/b&gt;으로 저장된 데이터와 일치하지 않아 검색 결과가 나오지 않았던 것이 원인이었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 이해하기 위해 &lt;b&gt;문자셋&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문자셋(Character Set)&lt;/b&gt;&lt;b&gt;&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;size16&quot;&gt;문자셋은 컴퓨터가 문자들을 다루기 위해 각 &lt;i&gt;&lt;b&gt;문자에 부여한 고유한 코드의 집합&lt;/b&gt;&lt;/i&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;ASCII 코드&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;: 영어 알파벳, 숫자, 특수 문자 등을 포함하는 &lt;b&gt;7비트&lt;/b&gt; 문자셋으로 구성되며 &lt;b&gt;총 128개의 문자&lt;/b&gt;를 표현&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: &lt;b&gt;A&lt;/b&gt;는 ASCII 코드로 &lt;b&gt;65&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;에 해당.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;유니코드(Unicode)&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;: 전 세계의 모든 문자를 통합적으로 표현하기 위한 문자셋&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&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;인코딩(Encoding)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;인코딩&lt;/b&gt;은 문자셋에 정의된 문자 코드를 컴퓨터 시스템에서&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;실제로 저장하고 전달하는 방식&lt;/b&gt;입니다.&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;대표적인 인코딩 방식:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;UTF-8&lt;/b&gt;: 가변 길이 인코딩으로, ASCII 문자는 1바이트, 한글 등은 2~4바이트로 표현&lt;/li&gt;
&lt;li&gt;&lt;b&gt;UTF-16&lt;/b&gt;&lt;span&gt;: 대부분의 문자를 2바이트로 표현&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  문제 원인: NFD와 NFC   정규화 방식의 차이&lt;/b&gt;&lt;/h2&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;유니코드와 한글&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;유니코드는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;완성형 문자&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;조합형 문자&lt;/b&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;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;&lt;b&gt;조합형 문자&lt;/b&gt;&lt;span&gt;: 자음과 모음을 개별적인 코드 포인트로 분리하여 표현합니다.&lt;/span&gt;&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 유니코드에서는 동일한 문자를 여러 가지 방법으로 표현할 수 있기 때문에, 이를 표준화하기 위한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;정규화(Normalization)&lt;/b&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;size16&quot;&gt;&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이 정규화 방식&lt;/b&gt;에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;NFC&lt;/b&gt;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;NFD&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;등이 있습니다.&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;NFC (Normalization Form Composed)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자를&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;size16&quot;&gt;&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시&lt;/b&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;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;U+D79B&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'&lt;/b&gt;&lt;span&gt;&lt;b&gt;탠'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;i&gt;&lt;b&gt;U+D0E0&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'다'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;U+B2E4&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'드'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;U+B4DC&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p 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;&lt;b&gt;NFD (Normalization Form Decomposed)&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자를&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;size16&quot;&gt;&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;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;예시&lt;/b&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;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&amp;lsquo;ᄒ&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;(U+1112)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ &amp;lsquo;ᅵ&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;(U+1175)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ &amp;lsquo;ᆺ&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;(U+11BA)&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'탠'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;&amp;lsquo;ᄐ&amp;rsquo;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;(U+1110)&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&amp;lsquo;ᅢ&amp;rsquo; (U+1162)&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&amp;lsquo;ᆫ&amp;rsquo; (U+11AB)&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'다'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;&amp;lsquo;ᄃ&amp;rsquo; (U+1103)&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&amp;lsquo;ᅡ&amp;rsquo; (U+1161)&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;'드'&lt;/b&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;i&gt;&lt;b&gt;&amp;lsquo;ᄃ&amp;rsquo; (U+1103)&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;&amp;lsquo;ᅳ&amp;rsquo; (U+1173)&lt;/b&gt;&lt;/i&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 &lt;b&gt;최근 검색어 제안 시스템을 이관하는 과정에서&lt;/b&gt; 제안된 응답을 &lt;b&gt;NFC 방식으로 정규화하는 과정이 누락&lt;/b&gt;되면서 발생했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안된 키워드가 &lt;i&gt;&lt;b&gt;NFD 방식으로 응답되었지만, 브라우저 상에서는 완성형처럼 보여&lt;/b&gt;&lt;/i&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;NFD로 정규화된 키워드가 그대로 검색 요청에 사용&lt;/b&gt;되었고, &lt;b&gt;NFC 방식으로 저장된 검색 엔진 데이터&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;&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;div style=&quot;background-color: #fffffe; color: #000000;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2561&quot; data-origin-height=&quot;1913&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clemMG/btsKIcnFNF2/Xr7KfeOYeS6GnROaEEXE1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clemMG/btsKIcnFNF2/Xr7KfeOYeS6GnROaEEXE1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clemMG/btsKIcnFNF2/Xr7KfeOYeS6GnROaEEXE1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclemMG%2FbtsKIcnFNF2%2FXr7KfeOYeS6GnROaEEXE1k%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;2561&quot; height=&quot;1913&quot; data-origin-width=&quot;2561&quot; data-origin-height=&quot;1913&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &amp;nbsp; &lt;/b&gt;&lt;b&gt;검색어 제안 시스템에서는 왜 NFD를 사용했을까?&lt;/b&gt;&lt;/h2&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;b&gt;&lt;/b&gt;&lt;/h3&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;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;예시: &quot;사&lt;span style=&quot;color: #006dd7;&quot;&gt;랑&quot;&lt;/span&gt;, &quot;사&lt;span style=&quot;color: #006dd7;&quot;&gt;물&quot;&lt;/span&gt;, &quot;사&lt;span style=&quot;color: #006dd7;&quot;&gt;장&quot;&lt;/span&gt;, &quot;사&lt;span style=&quot;color: #006dd7;&quot;&gt;돈&quot;&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;size16&quot;&gt;위 네 단어는 한 글자 차이지만, &lt;u&gt;의미는 완전히 다릅니다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자소 분리를 하지 않고 단어 전체를 비교하면 &lt;b&gt;편집 거리&lt;/b&gt;가 동일하게 계산되어 &lt;i&gt;의도하지 않은 제안&lt;/i&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;초성, 중성, 종성&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;예시: 힛&lt;span style=&quot;color: #006dd7;&quot;&gt;탠&lt;/span&gt;다드와 힛&lt;span style=&quot;color: #ee2323;&quot;&gt;텐&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;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;자소 분리 후 편집거리를 비교하면 &lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;ㅐ&lt;/span&gt;&lt;b&gt;와 &lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;ㅔ&lt;/span&gt;&lt;b&gt;의 차이&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;만 인식&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;b&gt;  유니코드 정규화 일관성 유지하기&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;검색어 제안 API에서 응답을 제공할 때, &lt;b&gt;유니코드 정규화(NFC 방식)&lt;/b&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;이를 통해 NFC 방식으로 저장된 &lt;b&gt;검색 엔진 데이터와 정규화 규약이 일치&lt;/b&gt;하게 되었고, &lt;b&gt;제안된 키워드로도 정상적인 검색이 가능&lt;/b&gt;해져 문제가 해결되었습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;⌨️ 번외.&amp;nbsp; &lt;/b&gt;&lt;b&gt;플랫폼별 NFD와 NFC 렌더링 방식 차이&lt;/b&gt;&lt;/h2&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;크롬 브라우저에서의 NFD와 NFC 처리&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;size16&quot;&gt;크롬 브라우저에서는 &lt;b&gt;NFD&lt;/b&gt;와 &lt;b&gt;NFC&lt;/b&gt;&lt;i&gt; 정규화 여부와 상관없이&lt;/i&gt; 한글을 &lt;b&gt;일관된 완성형 문자인 것처럼&lt;/b&gt;&amp;nbsp;렌더링합니다. 이로 인해 NFD와 NFC의 차이가 시각적으로 드러나지 않아 &lt;u&gt;&lt;b&gt;처음 문제를 파악하는 데 어려움&lt;/b&gt;&lt;/u&gt;이 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NFD면 당연히 쪼개져서 표현될 거라 생각했거든요. &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;2344&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DIP9n/btsKIQ5oXnv/0or4g30sUiBBLmUUz1KC60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DIP9n/btsKIQ5oXnv/0or4g30sUiBBLmUUz1KC60/img.png&quot; data-alt=&quot;크롬 브라우저상 NFC, NFD 글자 표현되어 구분이 되지 않는다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DIP9n/btsKIQ5oXnv/0or4g30sUiBBLmUUz1KC60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDIP9n%2FbtsKIQ5oXnv%2F0or4g30sUiBBLmUUz1KC60%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;2344&quot; height=&quot;414&quot; data-origin-width=&quot;2344&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크롬 브라우저상 NFC, NFD 글자 표현되어 구분이 되지 않는다.&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;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;macOS에서의 NFD와 NFC 처리&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;size16&quot;&gt;&lt;b&gt;macOS&lt;/b&gt;는 기본적으로 &lt;b&gt;NFD &lt;/b&gt;방식을 사용하며, &lt;b&gt;NFC&lt;/b&gt;와 &lt;b&gt;NFD&lt;/b&gt;를 모두 지원합니다. 이 때문에 &lt;b&gt;힛탠다드(NFC)&lt;/b&gt;라는 이름의 폴더를 생성한 후, &lt;b&gt;힛탠다드(NFD)&lt;/b&gt;&amp;nbsp;라는 이름의 폴더를 생성하려고 하면 &lt;b&gt;같은 이름으로 인식되어 충돌&lt;/b&gt;이 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 macOS 파일 시스템이 &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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-14 오전 1.28.16.png&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beacRp/btsKIuPfMPq/byUQ97eK5zqdhcXN5PWwd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beacRp/btsKIuPfMPq/byUQ97eK5zqdhcXN5PWwd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beacRp/btsKIuPfMPq/byUQ97eK5zqdhcXN5PWwd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeacRp%2FbtsKIuPfMPq%2FbyUQ97eK5zqdhcXN5PWwd0%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;596&quot; height=&quot;312&quot; data-filename=&quot;스크린샷 2024-11-14 오전 1.28.16.png&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;458&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Windows에서의 NFD와 NFC 처리&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;size16&quot;&gt;Windows에서는 기본적으로 &lt;b&gt;NFC &lt;/b&gt;방식만을 사용하여 한글을 처리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 이유로 &lt;b&gt;NFD&lt;/b&gt;로 인코딩된 한글은 Windows 환경에서 &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;NFD&lt;/b&gt; 방식의 &lt;b&gt;힛탠다드&lt;/b&gt;를 폴더 이름으로 지정하려고 하면&amp;nbsp; &quot;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;ㅎ ㅣ ㅅ ㅌ ㅐ ㄴ ㄷ ㅏ ㄷ ㅡ&lt;/span&gt;&quot;&lt;/b&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-filename=&quot;111402.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;132&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p0KYr/btsKI5VyMBx/n1Q4D0tYg5KYTBZsxX76Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p0KYr/btsKI5VyMBx/n1Q4D0tYg5KYTBZsxX76Q1/img.png&quot; data-alt=&quot;Windows11 에서의 NFD, NFC&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p0KYr/btsKI5VyMBx/n1Q4D0tYg5KYTBZsxX76Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp0KYr%2FbtsKI5VyMBx%2Fn1Q4D0tYg5KYTBZsxX76Q1%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;768&quot; height=&quot;132&quot; data-filename=&quot;111402.png&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;132&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Windows11 에서의 NFD, NFC&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;&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;안드로이드에서의 NFD와 NFC 처리&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;size16&quot;&gt;흥미롭게도 &lt;b&gt;안드로이드 14&lt;/b&gt;에서는 &lt;b&gt;NFC&lt;/b&gt;와 &lt;b&gt;NFD&lt;/b&gt; 간에 &lt;b&gt;폰트 렌더링 차이&lt;/b&gt;가 있어 구분이 가능했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NFD로 인코딩된 한글은 글자 모양이 미세하게 다르게 표시되는 것이 확인되었습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1000012049.jpg&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;401&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vQH5N/btsKHrF0rVX/kLMcUgFj5Skm0E1Qh5QIg0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vQH5N/btsKHrF0rVX/kLMcUgFj5Skm0E1Qh5QIg0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vQH5N/btsKHrF0rVX/kLMcUgFj5Skm0E1Qh5QIg0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvQH5N%2FbtsKHrF0rVX%2FkLMcUgFj5Skm0E1Qh5QIg0%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;1080&quot; height=&quot;401&quot; data-filename=&quot;1000012049.jpg&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;401&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 문제는 겉보기에는 작은 해프닝처럼 보일 수 있지만, 이를 해결하는 과정에서 &lt;b&gt;데이터 처리 일관성의 중요성&lt;/b&gt;과 &lt;b&gt;한글 검색어 처리의 중요성을&lt;/b&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배운 점 1: &lt;/b&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;b&gt;빅 엔디안과 리틀 엔디안 간의 차이로 발생한 NUXI 문제&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배운 점 2: 협업의 가치&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>Backend</category>
      <category>nfc</category>
      <category>Nfd</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/63</guid>
      <comments>https://sanhee.tistory.com/63#entry63comment</comments>
      <pubDate>Wed, 13 Nov 2024 23:40:14 +0900</pubDate>
    </item>
    <item>
      <title>Elasticsearch Enrich를 활용한 데이터 통합</title>
      <link>https://sanhee.tistory.com/62</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Elasticsearch Enrich 프로세서란?&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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;Elasticsearch Enrich 프로세서는 데이터에 추가적인 정보를 자동으로 결합해주는 기능입니다. 이 기능은 Elasticsearch 7.5 버전부터 제공되며, 특정 데이터를 사전에 정의된 정책(policy)에 따라 색인화 과정에서 다른 인덱스의 데이터와 결합할 수 있게 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Enrich 프로세서를 사용하기 위해서는 &lt;b&gt;Elasticsearch 클러스터 내&lt;/b&gt;에 &lt;b&gt;인제스트(Ingest) 노드&lt;/b&gt;가 필요합니다. Ingest 노드는 Ingest Pipeline을 통해 문서가 처리될 때 필수적인 역할을 하며, 데이터를 통합하거나 변환하는 과정을 처리합니다.&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;451&quot; data-origin-height=&quot;337&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1qv5Z/btsJihi99bB/oKNjl2BK8TAv3ejXpVh7Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1qv5Z/btsJihi99bB/oKNjl2BK8TAv3ejXpVh7Mk/img.png&quot; data-alt=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1qv5Z/btsJihi99bB/oKNjl2BK8TAv3ejXpVh7Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1qv5Z%2FbtsJihi99bB%2FoKNjl2BK8TAv3ejXpVh7Mk%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;451&quot; height=&quot;337&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;337&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&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;Enrich Index의 특성&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Enrich Index는 Elasticsearch에 의해 내부적으로 관리되는 &lt;b&gt;시스템 인덱스&lt;/b&gt;입니다. 이 인덱스는 일반 사용자가 직접 접근하여 변경하는 것은 불가능합니다.&lt;/li&gt;
&lt;li&gt;모든 Enrich Index는 &lt;b&gt;.enrich-*&lt;/b&gt; 형식으로 시작하는 이름을 가집니다.&lt;/li&gt;
&lt;li&gt;Enrich Index는 &lt;b&gt;읽기 전용&lt;/b&gt;으로 설정되어 있어, 직접적인 데이터 변경이 불가능합니다. 데이터 수정이 필요한 경우 원본 인덱스 데이터를 수정하고 Enrich Policy를 다시 실행하여 Enrich Index를 갱신해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Policy를 통해 생성된 Enrich 데이터는 시스템 인덱스에 저장된 후 &lt;u&gt;자동으로 업데이트되지 않습니다&lt;/u&gt;&lt;/b&gt;. 즉, 소스 데이터(예: 카테고리 정보)가 변경될 경우, 변경된 데이터를 인덱싱에 반영하기 위해서는 &lt;u&gt;Policy를 &lt;b&gt;수동으로 다시 실행&lt;/b&gt;&lt;/u&gt;해주어야 합니다. 이를 통해 Enrich 인덱스가 갱신됩니다.&lt;/li&gt;
&lt;li&gt;검색 속도를 최적화하기 위해, Enrich Index는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;force merge&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&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;Enrich를 활용해 다중 문서 통합해보기&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 제가 구성한 시나리오를 기반으로, Enrich 프로세서를 활용해 &lt;b&gt;상품 정보에 카테고리 정보를 통합하는 실습&lt;/b&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;h3 data-ke-size=&quot;size23&quot;&gt;1.&amp;nbsp; 카테고리 인덱스 생성 및 데이터 입력&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;먼저, 다양한 카테고리 정보를 담고 있는 category_index를 생성하고 데이터를 추가합니다.&amp;nbsp; &lt;b&gt;이 데이터는&lt;/b&gt; &lt;b&gt;나중에 상품 정보와 통합될&lt;/b&gt; &lt;b&gt;소스 데이터&lt;/b&gt;로 사용됩니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1724771250539&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PUT /category_index/_doc/1
{
  &quot;category_code1&quot;: &quot;001&quot;,
  &quot;category_name1&quot;: &quot;패션&quot;,
  &quot;category_title1&quot;: &quot;패션&quot;,
  &quot;category_code2&quot;: &quot;001001&quot;,
  &quot;category_name2&quot;: &quot;남성패션&quot;,
  &quot;category_title2&quot;: &quot;남성패션&quot;,
  &quot;category_code3&quot;: &quot;001001001&quot;,
  &quot;category_name3&quot;: &quot;상의&quot;,
  &quot;category_title3&quot;: &quot;상의&quot;,
  &quot;category_code4&quot;: &quot;001001001001&quot;,
  &quot;category_name4&quot;: &quot;티셔츠&quot;,
  &quot;category_title4&quot;: &quot;티셔츠&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;001001001001@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/2
{
  &quot;category_code1&quot;: &quot;002&quot;,
  &quot;category_name1&quot;: &quot;스포츠&quot;,
  &quot;category_title1&quot;: &quot;스포츠&quot;,
  &quot;category_code2&quot;: &quot;002002&quot;,
  &quot;category_name2&quot;: &quot;축구&quot;,
  &quot;category_title2&quot;: &quot;축구&quot;,
  &quot;category_code3&quot;: &quot;002002002&quot;,
  &quot;category_name3&quot;: &quot;용품&quot;,
  &quot;category_title3&quot;: &quot;용품&quot;,
  &quot;category_code4&quot;: &quot;002002002002&quot;,
  &quot;category_name4&quot;: &quot;축구공&quot;,
  &quot;category_title4&quot;: &quot;축구공&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;002002002002@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/3
{
  &quot;category_code1&quot;: &quot;003&quot;,
  &quot;category_name1&quot;: &quot;생활용품&quot;,
  &quot;category_title1&quot;: &quot;생활용품&quot;,
  &quot;category_code2&quot;: &quot;003003&quot;,
  &quot;category_name2&quot;: &quot;주방용품&quot;,
  &quot;category_title2&quot;: &quot;주방용품&quot;,
  &quot;category_code3&quot;: &quot;003003003&quot;,
  &quot;category_name3&quot;: &quot;그릇&quot;,
  &quot;category_title3&quot;: &quot;그릇&quot;,
  &quot;category_code4&quot;: &quot;003003003003&quot;,
  &quot;category_name4&quot;: &quot;접시&quot;,
  &quot;category_title4&quot;: &quot;접시&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;003003003003@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/4
{
  &quot;category_code1&quot;: &quot;004&quot;,
  &quot;category_name1&quot;: &quot;전자제품&quot;,
  &quot;category_title1&quot;: &quot;전자제품&quot;,
  &quot;category_code2&quot;: &quot;004004&quot;,
  &quot;category_name2&quot;: &quot;컴퓨터&quot;,
  &quot;category_title2&quot;: &quot;컴퓨터&quot;,
  &quot;category_code3&quot;: &quot;004004004&quot;,
  &quot;category_name3&quot;: &quot;노트북&quot;,
  &quot;category_title3&quot;: &quot;노트북&quot;,
  &quot;category_code4&quot;: &quot;004004004004&quot;,
  &quot;category_name4&quot;: &quot;게이밍노트북&quot;,
  &quot;category_title4&quot;: &quot;게이밍노트북&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;004004004004@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/5
{
  &quot;category_code1&quot;: &quot;005&quot;,
  &quot;category_name1&quot;: &quot;가전제품&quot;,
  &quot;category_title1&quot;: &quot;가전제품&quot;,
  &quot;category_code2&quot;: &quot;005005&quot;,
  &quot;category_name2&quot;: &quot;청소기&quot;,
  &quot;category_title2&quot;: &quot;청소기&quot;,
  &quot;category_code3&quot;: &quot;005005005&quot;,
  &quot;category_name3&quot;: &quot;무선청소기&quot;,
  &quot;category_title3&quot;: &quot;무선청소기&quot;,
  &quot;category_code4&quot;: &quot;005005005005&quot;,
  &quot;category_name4&quot;: &quot;로봇청소기&quot;,
  &quot;category_title4&quot;: &quot;로봇청소기&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;005005005005@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/6
{
  &quot;category_code1&quot;: &quot;006&quot;,
  &quot;category_name1&quot;: &quot;자동차용품&quot;,
  &quot;category_title1&quot;: &quot;자동차용품&quot;,
  &quot;category_code2&quot;: &quot;006006&quot;,
  &quot;category_name2&quot;: &quot;타이어&quot;,
  &quot;category_title2&quot;: &quot;타이어&quot;,
  &quot;category_code3&quot;: &quot;006006006&quot;,
  &quot;category_name3&quot;: &quot;자동차타이어&quot;,
  &quot;category_title3&quot;: &quot;자동차타이어&quot;,
  &quot;category_code4&quot;: &quot;006006006006&quot;,
  &quot;category_name4&quot;: &quot;겨울용타이어&quot;,
  &quot;category_title4&quot;: &quot;겨울용타이어&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;006006006006@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/7
{
  &quot;category_code1&quot;: &quot;007&quot;,
  &quot;category_name1&quot;: &quot;취미&quot;,
  &quot;category_title1&quot;: &quot;취미&quot;,
  &quot;category_code2&quot;: &quot;007007&quot;,
  &quot;category_name2&quot;: &quot;사진촬영&quot;,
  &quot;category_title2&quot;: &quot;사진촬영&quot;,
  &quot;category_code3&quot;: &quot;007007007&quot;,
  &quot;category_name3&quot;: &quot;카메라&quot;,
  &quot;category_title3&quot;: &quot;카메라&quot;,
  &quot;category_code4&quot;: &quot;007007007007&quot;,
  &quot;category_name4&quot;: &quot;DSLR&quot;,
  &quot;category_title4&quot;: &quot;DSLR&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;007007007007@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/8
{
  &quot;category_code1&quot;: &quot;008&quot;,
  &quot;category_name1&quot;: &quot;도서&quot;,
  &quot;category_title1&quot;: &quot;도서&quot;,
  &quot;category_code2&quot;: &quot;008008&quot;,
  &quot;category_name2&quot;: &quot;소설&quot;,
  &quot;category_title2&quot;: &quot;소설&quot;,
  &quot;category_code3&quot;: &quot;008008008&quot;,
  &quot;category_name3&quot;: &quot;판타지&quot;,
  &quot;category_title3&quot;: &quot;판타지&quot;,
  &quot;category_code4&quot;: &quot;008008008008&quot;,
  &quot;category_name4&quot;: &quot;하이판타지&quot;,
  &quot;category_title4&quot;: &quot;하이판타지&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;008008008008@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/9
{
  &quot;category_code1&quot;: &quot;009&quot;,
  &quot;category_name1&quot;: &quot;게임&quot;,
  &quot;category_title1&quot;: &quot;게임&quot;,
  &quot;category_code2&quot;: &quot;009009&quot;,
  &quot;category_name2&quot;: &quot;비디오게임&quot;,
  &quot;category_title2&quot;: &quot;비디오게임&quot;,
  &quot;category_code3&quot;: &quot;009009009&quot;,
  &quot;category_name3&quot;: &quot;콘솔게임&quot;,
  &quot;category_title3&quot;: &quot;콘솔게임&quot;,
  &quot;category_code4&quot;: &quot;009009009009&quot;,
  &quot;category_name4&quot;: &quot;플레이스테이션&quot;,
  &quot;category_title4&quot;: &quot;플레이스테이션&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;009009009009@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}

PUT /category_index/_doc/10
{
  &quot;category_code1&quot;: &quot;010&quot;,
  &quot;category_name1&quot;: &quot;음악&quot;,
  &quot;category_title1&quot;: &quot;음악&quot;,
  &quot;category_code2&quot;: &quot;010010&quot;,
  &quot;category_name2&quot;: &quot;악기&quot;,
  &quot;category_title2&quot;: &quot;악기&quot;,
  &quot;category_code3&quot;: &quot;010010010&quot;,
  &quot;category_name3&quot;: &quot;피아노&quot;,
  &quot;category_title3&quot;: &quot;피아노&quot;,
  &quot;category_code4&quot;: &quot;010010010010&quot;,
  &quot;category_name4&quot;: &quot;그랜드 피아노&quot;,
  &quot;category_title4&quot;: &quot;그랜드 피아노&quot;,
  &quot;category_type&quot;: &quot;ITEM&quot;,
  &quot;find_code&quot;: &quot;010010010010@#ITEM&quot;,
  &quot;use_yn&quot;: &quot;Y&quot;,
  &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
  &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;2.&amp;nbsp; 상품 인덱스 맵핑 구조 정의&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;공식 문서에서는 동적인 문서 맵핑으로 데이터 통합 예제를 제공하지만, 이번 실습을 통해 &lt;b&gt;정적인 맵핑 구조로도 유연하게 데이터 통합이 가능하다는 점&lt;/b&gt;을 확인하기 위해 타겟 인덱스인 상품 인덱스(test-product)를 정적 구조로 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1724771535558&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PUT /test-product
{
  &quot;settings&quot;: {
    &quot;analysis&quot;: {
      &quot;analyzer&quot;: {
        &quot;ngram_analyzer&quot;: {
          &quot;type&quot;: &quot;custom&quot;,
          &quot;tokenizer&quot;: &quot;ngram_tokenizer&quot;
        }
      },
      &quot;tokenizer&quot;: {
        &quot;ngram_tokenizer&quot;: {
          &quot;type&quot;: &quot;ngram&quot;,
          &quot;min_gram&quot;: 1,
          &quot;max_gram&quot;: 3,
          &quot;token_chars&quot;: [
            &quot;letter&quot;,
            &quot;digit&quot;
          ]
        }
      }
    },
    &quot;index&quot;: {
      &quot;max_ngram_diff&quot;: 2
    }
  },
  &quot;mappings&quot;: {
    &quot;dynamic&quot;: &quot;strict&quot;,  // strict 맵핑 구조 설정
    &quot;properties&quot;: {
      &quot;goods_no&quot;: {
        &quot;type&quot;: &quot;keyword&quot;
      },
      &quot;goods_name&quot;: {
        &quot;type&quot;: &quot;keyword&quot;
      },
      &quot;brand_name&quot;: {
        &quot;type&quot;: &quot;keyword&quot;
      },
      &quot;category_code&quot;: {
        &quot;type&quot;: &quot;keyword&quot;
      },
      &quot;enriched_category&quot;: {  // 통합된 카테고리 정보 저장
        &quot;properties&quot;: {
          &quot;find_code&quot;: {
            &quot;type&quot;: &quot;keyword&quot;,
            &quot;fields&quot;: {
              &quot;analyzed&quot;: {
                &quot;type&quot;: &quot;text&quot;,
                &quot;analyzer&quot;: &quot;ngram_analyzer&quot;
              }
            }
          },
          &quot;category_code1&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_name1&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_title1&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_code2&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_name2&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_title2&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_code3&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_name3&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_title3&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_code4&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_name4&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_title4&quot;: { &quot;type&quot;: &quot;keyword&quot; },
          &quot;category_type&quot;: {
            &quot;type&quot;: &quot;keyword&quot;,
            &quot;fields&quot;: {
              &quot;analyzed&quot;: {
                &quot;type&quot;: &quot;text&quot;,
                &quot;analyzer&quot;: &quot;ngram_analyzer&quot;
              }
            }
          },
          &quot;display_start_date&quot;: {
            &quot;type&quot;: &quot;date&quot;,
            &quot;format&quot;: &quot;yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second&quot;
          },
          &quot;display_end_date&quot;: {
            &quot;type&quot;: &quot;date&quot;,
            &quot;format&quot;: &quot;yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_second&quot;
          },
          &quot;use_yn&quot;: {
            &quot;type&quot;: &quot;keyword&quot;
          }
        }
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;3.&amp;nbsp; Enrich Policy 설정&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로, Enrich Policy를 설정하여 카테고리 정보를 상품 정보에 통합할 수 있도록 준비합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1724771401225&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PUT /_enrich/policy/category_hierarchy_policy
{
  &quot;match&quot;: {
    &quot;indices&quot;: &quot;category_index&quot;,
    &quot;match_field&quot;: &quot;find_code&quot;,
    &quot;enrich_fields&quot;: [
      &quot;category_code1&quot;,
      &quot;category_name1&quot;,
      &quot;category_title1&quot;,
      &quot;category_code2&quot;,
      &quot;category_name2&quot;,
      &quot;category_title2&quot;,
      &quot;category_code3&quot;,
      &quot;category_name3&quot;,
      &quot;category_title3&quot;,
      &quot;category_code4&quot;,
      &quot;category_name4&quot;,
      &quot;category_title4&quot;,
      &quot;category_type&quot;,
      &quot;display_start_date&quot;,
      &quot;display_end_date&quot;,
      &quot;use_yn&quot;
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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;4.&amp;nbsp; Enrich  Policy 실행&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;pre id=&quot;code_1724772401082&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /_enrich/policy/category_hierarchy_policy/_execute&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp;앞서 언급했듯이,&lt;span&gt;&amp;nbsp;소스 데이터(예: 카테고리 정보)가 변경되면 변경된 내용을 반영하기 위해 &lt;b&gt;Enrich Policy를 수동으로 다시 실행&lt;/b&gt;해야 합니다. 이 작업을 통해 Enrich 인덱스가 갱신되어, 최신 데이터를 인덱싱할 수 있습니다.&lt;/span&gt;&lt;/span&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;5.&amp;nbsp;  Ingest Pipeline 설정&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Enrich Policy가 설정된 후, 이를 실제 문서에 적용하기 위한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Ingest Pipeline&lt;/b&gt;을 구성해야 합니다. 이 Pipeline은 데이터를 인덱싱할 때 카테고리 정보를 상품 문서에 통합하는 역할을 합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1724771450871&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;PUT _ingest/pipeline/enrich_category_pipeline
{
  &quot;processors&quot;: [
    {
      &quot;enrich&quot;: {
        &quot;policy_name&quot;: &quot;category_hierarchy_policy&quot;,
        &quot;field&quot;: &quot;category_code&quot;,
        &quot;target_field&quot;: &quot;enriched_category&quot;,
        &quot;max_matches&quot;: &quot;100&quot;
      }
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max_matches는 Enrich 프로세서에서 매우 중요한 설정으로, 매칭되는 데이터의 최대 개수를 정의합니다.이 설정은 Enrich Policy에서 지정한 match_field와 일치하는 여러 문서가 있을 때, 몇 개의 문서를 통합할지 결정합니다.&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://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 문서에 따르면&lt;/a&gt; &lt;b&gt;최대값은 128&lt;/b&gt;이며, 그 이유는 문서의 크기가 지나치게 커지는 것을 방지하기 위함이라고 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;max_matches: 1로 설정할 경우&lt;/span&gt;&lt;b&gt;&lt;/b&gt;, 매칭되는 데이터 중 하나만 통합되며,target_field는 &lt;b&gt;JSON 객체&lt;/b&gt; 형태가 됩니다.&lt;/li&gt;
&lt;li data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;max_matches: 2 이상으로 설정할 경우&lt;/span&gt;&lt;/span&gt;, 여러 매칭된 데이터를 통합할 수 있으며, 이때 target_field는 &lt;b&gt;JSON 배열&lt;/b&gt;로 변환됩니다. 예를 들어, 여러 개의 카테고리 정보가 상품에 연결될 경우, 각각의 카테고리가 배열에 담기게 됩니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;6.&amp;nbsp;  상품 데이터 인덱싱&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이제 상품 데이터를 인덱싱할 때, Enrich Pipeline을 사용하여 카테고리 정보를 통합합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적인 ES 문서 색인과 동일하지만 URL 파라미터를 보면 &lt;u&gt;&lt;b&gt;pipeline=enrich_category_pipeline&lt;/b&gt;&lt;/u&gt;가 추가 된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1724772627376&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;POST /test-product/_doc?pipeline=enrich_category_pipeline
{
  &quot;goods_no&quot;: &quot;123456&quot;,
  &quot;goods_name&quot;: &quot;멀티 카테고리 상품&quot;,
  &quot;brand_name&quot;: &quot;브랜드명&quot;,
  &quot;category_code&quot;: [
    &quot;001001001001@#ITEM&quot;,
    &quot;002002002002@#ITEM&quot;,
    &quot;003003003003@#ITEM&quot;,
    &quot;004004004004@#ITEM&quot;,
    &quot;005005005005@#ITEM&quot;,
    &quot;006006006006@#ITEM&quot;,
    &quot;007007007007@#ITEM&quot;,
    &quot;008008008008@#ITEM&quot;,
    &quot;009009009009@#ITEM&quot;,
    &quot;010010010010@#ITEM&quot;
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;7.&amp;nbsp; 통합된 데이터 확인&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style5&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱싱된 데이터를 조회하여 카테고리 정보가 통합된 상태를 확인할 수 있습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1724772666379&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GET /test-product/_search
{
  &quot;query&quot;: {
    &quot;match_all&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;&lt;b&gt;응답&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1724772801349&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;took&quot;: 1,
  &quot;timed_out&quot;: false,
  &quot;_shards&quot;: {
    &quot;total&quot;: 1,
    &quot;successful&quot;: 1,
    &quot;skipped&quot;: 0,
    &quot;failed&quot;: 0
  },
  &quot;hits&quot;: {
    &quot;total&quot;: {
      &quot;value&quot;: 2,
      &quot;relation&quot;: &quot;eq&quot;
    },
    &quot;max_score&quot;: 1,
    &quot;hits&quot;: [
      {
        &quot;_index&quot;: &quot;test-product&quot;,
        &quot;_id&quot;: &quot;bxMTb5EBZ_Pa7rwW3zqv&quot;,
        &quot;_score&quot;: 1,
        &quot;_source&quot;: {
          &quot;goods_name&quot;: &quot;멀티 카테고리 상품&quot;,
          &quot;enriched_category&quot;: [
            {
              &quot;category_title3&quot;: &quot;콘솔게임&quot;,
              &quot;category_title4&quot;: &quot;플레이스테이션&quot;,
              &quot;category_name4&quot;: &quot;플레이스테이션&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;게임&quot;,
              &quot;category_title2&quot;: &quot;비디오게임&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;009009009009@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;게임&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;비디오게임&quot;,
              &quot;category_name3&quot;: &quot;콘솔게임&quot;,
              &quot;category_code4&quot;: &quot;009009009009&quot;,
              &quot;category_code3&quot;: &quot;009009009&quot;,
              &quot;category_code2&quot;: &quot;009009&quot;,
              &quot;category_code1&quot;: &quot;009&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;무선청소기&quot;,
              &quot;category_title4&quot;: &quot;로봇청소기&quot;,
              &quot;category_name4&quot;: &quot;로봇청소기&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;가전제품&quot;,
              &quot;category_title2&quot;: &quot;청소기&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;005005005005@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;가전제품&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;청소기&quot;,
              &quot;category_name3&quot;: &quot;무선청소기&quot;,
              &quot;category_code4&quot;: &quot;005005005005&quot;,
              &quot;category_code3&quot;: &quot;005005005&quot;,
              &quot;category_code2&quot;: &quot;005005&quot;,
              &quot;category_code1&quot;: &quot;005&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;노트북&quot;,
              &quot;category_title4&quot;: &quot;게이밍노트북&quot;,
              &quot;category_name4&quot;: &quot;게이밍노트북&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;전자제품&quot;,
              &quot;category_title2&quot;: &quot;컴퓨터&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;004004004004@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;전자제품&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;컴퓨터&quot;,
              &quot;category_name3&quot;: &quot;노트북&quot;,
              &quot;category_code4&quot;: &quot;004004004004&quot;,
              &quot;category_code3&quot;: &quot;004004004&quot;,
              &quot;category_code2&quot;: &quot;004004&quot;,
              &quot;category_code1&quot;: &quot;004&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;피아노&quot;,
              &quot;category_title4&quot;: &quot;그랜드 피아노&quot;,
              &quot;category_name4&quot;: &quot;그랜드 피아노&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;음악&quot;,
              &quot;category_title2&quot;: &quot;악기&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;010010010010@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;음악&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;악기&quot;,
              &quot;category_name3&quot;: &quot;피아노&quot;,
              &quot;category_code4&quot;: &quot;010010010010&quot;,
              &quot;category_code3&quot;: &quot;010010010&quot;,
              &quot;category_code2&quot;: &quot;010010&quot;,
              &quot;category_code1&quot;: &quot;010&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;백팩&quot;,
              &quot;category_title4&quot;: &quot;노트북백팩&quot;,
              &quot;category_name4&quot;: &quot;노트북백팩&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;패션잡화&quot;,
              &quot;category_title2&quot;: &quot;가방&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;011011011011@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;패션잡화&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;가방&quot;,
              &quot;category_name3&quot;: &quot;백팩&quot;,
              &quot;category_code4&quot;: &quot;011011011011&quot;,
              &quot;category_code3&quot;: &quot;011011011&quot;,
              &quot;category_code2&quot;: &quot;011011&quot;,
              &quot;category_code1&quot;: &quot;011&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;그릇&quot;,
              &quot;category_title4&quot;: &quot;접시&quot;,
              &quot;category_name4&quot;: &quot;접시&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;생활용품&quot;,
              &quot;category_title2&quot;: &quot;주방용품&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;003003003003@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;생활용품&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;주방용품&quot;,
              &quot;category_name3&quot;: &quot;그릇&quot;,
              &quot;category_code4&quot;: &quot;003003003003&quot;,
              &quot;category_code3&quot;: &quot;003003003&quot;,
              &quot;category_code2&quot;: &quot;003003&quot;,
              &quot;category_code1&quot;: &quot;003&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;판타지&quot;,
              &quot;category_title4&quot;: &quot;하이판타지&quot;,
              &quot;category_name4&quot;: &quot;하이판타지&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;도서&quot;,
              &quot;category_title2&quot;: &quot;소설&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;008008008008@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;도서&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;소설&quot;,
              &quot;category_name3&quot;: &quot;판타지&quot;,
              &quot;category_code4&quot;: &quot;008008008008&quot;,
              &quot;category_code3&quot;: &quot;008008008&quot;,
              &quot;category_code2&quot;: &quot;008008&quot;,
              &quot;category_code1&quot;: &quot;008&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;상의&quot;,
              &quot;category_title4&quot;: &quot;티셔츠&quot;,
              &quot;category_name4&quot;: &quot;티셔츠&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;패션&quot;,
              &quot;category_title2&quot;: &quot;남성패션&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;001001001001@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;패션&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;남성패션&quot;,
              &quot;category_name3&quot;: &quot;상의&quot;,
              &quot;category_code4&quot;: &quot;001001001001&quot;,
              &quot;category_code3&quot;: &quot;001001001&quot;,
              &quot;category_code2&quot;: &quot;001001&quot;,
              &quot;category_code1&quot;: &quot;001&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;카메라&quot;,
              &quot;category_title4&quot;: &quot;DSLR&quot;,
              &quot;category_name4&quot;: &quot;DSLR&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;취미&quot;,
              &quot;category_title2&quot;: &quot;사진촬영&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;007007007007@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;취미&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;사진촬영&quot;,
              &quot;category_name3&quot;: &quot;카메라&quot;,
              &quot;category_code4&quot;: &quot;007007007007&quot;,
              &quot;category_code3&quot;: &quot;007007007&quot;,
              &quot;category_code2&quot;: &quot;007007&quot;,
              &quot;category_code1&quot;: &quot;007&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;용품&quot;,
              &quot;category_title4&quot;: &quot;축구공&quot;,
              &quot;category_name4&quot;: &quot;축구공&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;스포츠&quot;,
              &quot;category_title2&quot;: &quot;축구&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;002002002002@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;스포츠&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;축구&quot;,
              &quot;category_name3&quot;: &quot;용품&quot;,
              &quot;category_code4&quot;: &quot;002002002002&quot;,
              &quot;category_code3&quot;: &quot;002002002&quot;,
              &quot;category_code2&quot;: &quot;002002&quot;,
              &quot;category_code1&quot;: &quot;002&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            },
            {
              &quot;category_title3&quot;: &quot;자동차타이어&quot;,
              &quot;category_title4&quot;: &quot;겨울용타이어&quot;,
              &quot;category_name4&quot;: &quot;겨울용타이어&quot;,
              &quot;display_start_date&quot;: &quot;2022-01-01 00:00:00&quot;,
              &quot;category_title1&quot;: &quot;자동차용품&quot;,
              &quot;category_title2&quot;: &quot;타이어&quot;,
              &quot;use_yn&quot;: &quot;Y&quot;,
              &quot;find_code&quot;: &quot;006006006006@#ITEM&quot;,
              &quot;category_name1&quot;: &quot;자동차용품&quot;,
              &quot;category_type&quot;: &quot;ITEM&quot;,
              &quot;category_name2&quot;: &quot;타이어&quot;,
              &quot;category_name3&quot;: &quot;자동차타이어&quot;,
              &quot;category_code4&quot;: &quot;006006006006&quot;,
              &quot;category_code3&quot;: &quot;006006006&quot;,
              &quot;category_code2&quot;: &quot;006006&quot;,
              &quot;category_code1&quot;: &quot;006&quot;,
              &quot;display_end_date&quot;: &quot;2030-12-31 23:59:59&quot;
            }
          ],
          &quot;brand_name&quot;: &quot;브랜드명&quot;,
          &quot;category_code&quot;: [
            &quot;001001001001@#ITEM&quot;,
            &quot;002002002002@#ITEM&quot;,
            &quot;003003003003@#ITEM&quot;,
            &quot;004004004004@#ITEM&quot;,
            &quot;005005005005@#ITEM&quot;,
            &quot;006006006006@#ITEM&quot;,
            &quot;007007007007@#ITEM&quot;,
            &quot;008008008008@#ITEM&quot;,
            &quot;009009009009@#ITEM&quot;,
            &quot;010010010010@#ITEM&quot;,
            &quot;011011011011@#ITEM&quot;
          ],
          &quot;goods_no&quot;: &quot;123456&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;번외.&amp;nbsp; Enrich 인덱스의 문서 내용 확인하는 법?&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kibana에서 Enrich 인덱스 문서를 확인하려면 다음 단계를 따릅니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Kibana&lt;/b&gt;에서 &lt;b&gt;Index Management&lt;/b&gt;로 이동합니다.&lt;/li&gt;
&lt;li&gt;상단에서 &lt;b&gt;Include hidden indices&lt;/b&gt; 옵션을 클릭한 후, 검색창에 enrich를 입력하여 생성된 Enrich 인덱스를 검색합니다.&lt;/li&gt;
&lt;li&gt;우리가 생성한 &lt;b&gt;.enrich-category_hierarchy_policy&lt;/b&gt; 인덱스를 클릭합니다.&lt;/li&gt;
&lt;li&gt;우측 상단에 있는 &lt;b&gt;나침반 아이콘&lt;/b&gt;을 클릭하면, 해당 Enrich 인덱스에 색인된 문서들을 확인할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법을 통해 Enrich 인덱스의 내용을 쉽게 확인할 수 있습니다.&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-filename=&quot;스크린샷 2024-08-28 오전 12.35.53.png&quot; data-origin-width=&quot;3420&quot; data-origin-height=&quot;996&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPYfFE/btsJhPU0fTo/Fb4v6m0P2gm6kR7yazHlL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPYfFE/btsJhPU0fTo/Fb4v6m0P2gm6kR7yazHlL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPYfFE/btsJhPU0fTo/Fb4v6m0P2gm6kR7yazHlL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPYfFE%2FbtsJhPU0fTo%2FFb4v6m0P2gm6kR7yazHlL0%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;3420&quot; height=&quot;996&quot; data-filename=&quot;스크린샷 2024-08-28 오전 12.35.53.png&quot; data-origin-width=&quot;3420&quot; data-origin-height=&quot;996&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-08-28 오전 12.38.10.png&quot; data-origin-width=&quot;1488&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUUkc6/btsJg7BTVen/va3xBRiPfEUl2cezbdBoi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUUkc6/btsJg7BTVen/va3xBRiPfEUl2cezbdBoi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUUkc6/btsJg7BTVen/va3xBRiPfEUl2cezbdBoi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUUkc6%2FbtsJg7BTVen%2Fva3xBRiPfEUl2cezbdBoi1%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;1488&quot; height=&quot;828&quot; data-filename=&quot;스크린샷 2024-08-28 오전 12.38.10.png&quot; data-origin-width=&quot;1488&quot; data-origin-height=&quot;828&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;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2844&quot; data-origin-height=&quot;1606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ds8nTF/btsJg4STSPT/5aTJwYZ0NxcMQ9qHADCu01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ds8nTF/btsJg4STSPT/5aTJwYZ0NxcMQ9qHADCu01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ds8nTF/btsJg4STSPT/5aTJwYZ0NxcMQ9qHADCu01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fds8nTF%2FbtsJg4STSPT%2F5aTJwYZ0NxcMQ9qHADCu01%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;2844&quot; height=&quot;1606&quot; data-origin-width=&quot;2844&quot; data-origin-height=&quot;1606&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-08-28 오전 12.39.50.png&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;1652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kZHeS/btsJgDH9feg/MSlZFZgLBO826KjmBYR0Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kZHeS/btsJgDH9feg/MSlZFZgLBO826KjmBYR0Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kZHeS/btsJgDH9feg/MSlZFZgLBO826KjmBYR0Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkZHeS%2FbtsJgDH9feg%2FMSlZFZgLBO826KjmBYR0Z0%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;1450&quot; height=&quot;1652&quot; data-filename=&quot;스크린샷 2024-08-28 오전 12.39.50.png&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;1652&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;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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이번 리서치와 실습을 통해 Elasticsearch의 Enrich 프로세서를 활용하여 데이터를 효과적으로 통합하는 방법을 익혔습니다. 특히, 공식 문서에서 주로 소개되는 &lt;b&gt;동적 맵핑&lt;/b&gt;뿐만 아니라, &lt;b&gt;정적 맵핑 구조&lt;/b&gt;를 사용하여 데이터를 더 엄격하고 명확하게 관리할 수 있다는 점도 확인했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Enrich 프로세서를 활용할 때 몇 가지 유의사항만 잘 숙지한다면, 다양한 데이터 소스를 결합하고 복합적인 작업을 효율적으로 처리할 수 있을 것으로 보입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1724773765563&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;Enrich your data | Elasticsearch Guide [8.15] | Elastic&quot; data-og-description=&quot;You can use the enrich processor to add data from your existing indices to incoming documents during ingest. For example, you can use the enrich processor to: Identify web services or vendors based on known IP addresses Add product information to retail or&quot; data-og-host=&quot;www.elastic.co&quot; data-og-source-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&quot; data-og-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/ingest-enriching-data.html&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;Enrich your data | Elasticsearch Guide [8.15] | Elastic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;You can use the enrich processor to add data from your existing indices to incoming documents during ingest. For example, you can use the enrich processor to: Identify web services or vendors based on known IP addresses Add product information to retail or&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.elastic.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;
&lt;figure id=&quot;og_1724773733531&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;Enrich processor | Elasticsearch Guide [8.15] | Elastic&quot; data-og-description=&quot;The enrich processor can enrich documents with data from another index. See enrich data section for more information about how to set this up. Table 17. Enrich Options Name Required Default Description policy_name yes - The name of the enrich policy to use&quot; data-og-host=&quot;www.elastic.co&quot; data-og-source-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html&quot; data-og-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/enrich-processor.html&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;Enrich processor | Elasticsearch Guide [8.15] | Elastic&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The enrich processor can enrich documents with data from another index. See enrich data section for more information about how to set this up. Table 17. Enrich Options Name Required Default Description policy_name yes - The name of the enrich policy to use&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.elastic.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>Backend</category>
      <category>elasticsearch</category>
      <category>enrich</category>
      <category>ingest</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/62</guid>
      <comments>https://sanhee.tistory.com/62#entry62comment</comments>
      <pubDate>Wed, 28 Aug 2024 00:42:21 +0900</pubDate>
    </item>
    <item>
      <title>왜 Elasticsearch 검색이 실패할까? 인덱스 Close와 Alias의  관계</title>
      <link>https://sanhee.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 Elasticsearch를&amp;nbsp;사용하면서 index_closed_exception 오류를 경험한 적이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 에러는 ES에서 &lt;b&gt;4XX&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;485&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wYnVj/btsIoNQHIoZ/LFvX4bIZd7jkohNc8NuqI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wYnVj/btsIoNQHIoZ/LFvX4bIZd7jkohNc8NuqI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wYnVj/btsIoNQHIoZ/LFvX4bIZd7jkohNc8NuqI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwYnVj%2FbtsIoNQHIoZ%2FLFvX4bIZd7jkohNc8NuqI0%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;485&quot; height=&quot;208&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;208&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;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;복수 개의 인덱스가 존재하고 공통 alias로 인덱스가 연결 되어있는 상태일 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; alias 연관 인덱스를 close 하고 alias 검색 시 close 인덱스에도 접근을 시도 하게 되어 index_closed_exception 예외가 발생하며 검색 요청이 실패합니다.&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;/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;원인은 close된 인덱스가 여전히 alias에 의해 참조되고 있어서 발생한 에러 입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A closed index is blocked for read/write operations and does not allow all operations that opened indices allow. It is not possible to index documents or to search for documents in a closed index&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-close.html&quot;&gt;https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-close.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스를 close하기 전에 해당 인덱스를 공통 alias에서 제거하거나 인덱스를 삭제하는 것입니다.&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;</description>
      <category>Backend</category>
      <category>elasticsearch</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/60</guid>
      <comments>https://sanhee.tistory.com/60#entry60comment</comments>
      <pubDate>Thu, 4 Jul 2024 20:33:28 +0900</pubDate>
    </item>
    <item>
      <title>GitHub Actions를 이용하여 GitOps의 YAML 파일 동적 업데이트</title>
      <link>https://sanhee.tistory.com/59</link>
      <description>&lt;h1 data-pm-slice=&quot;1 3 []&quot;&gt;배경&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Jenkins &amp;amp; Spinnaker 기반의 CI/CD 환경에서 GitHub Action &amp;amp; Argo CD로 전환하게 되었습니다.&lt;/li&gt;
&lt;li&gt;Spinnaker에서는 배포 시 동적 파라미터를 제공하여 yaml 을 수정하는 기능이 있었으나, Argo CD는 이러한 기능을 지원하지  않는걸로 파악했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;구현&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Argo CD가 GitOps 방식을 따르므로, 애플리케이션 배포 시 GitHub Actions를 활용하여 Deploy Repository의 yaml 파일을 워크플로우 디스패치 이벤트로부터 받은 파라미터로 동적으로 수정합니다. 이를 통해 최종 배포 단계에서 yaml 파일을 업데이트하여 파라미터를 주입합니다. (* yq 활용)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exZ7oA/btsIoZQTjHC/gxFrONxyz8MkdbTgkkSHxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exZ7oA/btsIoZQTjHC/gxFrONxyz8MkdbTgkkSHxK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exZ7oA/btsIoZQTjHC/gxFrONxyz8MkdbTgkkSHxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexZ7oA%2FbtsIoZQTjHC%2FgxFrONxyz8MkdbTgkkSHxK%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;496&quot; height=&quot;301&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1&gt;구현 샘플.&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Application Repository 설정&lt;/h2&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# GitHub Workflow

name: Update WORKER_COUNT in sample.yaml

on:
  workflow_dispatch:
    inputs:
      workerCount:
        description: 'New WORKER_COUNT value'
        required: true
        default: '99' 
      userName:
        description: 'New userName value'
        required: true
        default: 'root'
      versionName:
        description: 'New Version Value'
        required: true
        default: '2'

jobs:
  update-yaml:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout B Repository
      uses: actions/checkout@v2
      with:
        repository: 'author/repository'
        token: ${{ secrets.TEST_B_REPO_TOKEN }}
        ref: 'main'

    - name: Install yq (YAML Processor)
      run: sudo snap install yq

    - name: Update WORKER_COUNT in sample.yaml
      run: |
        yq eval '.version = ${{ github.event.inputs.versionName }}' -i sample.yaml
        yq eval '.services.worker.environment.WORKER_COUNT = &quot;${{ github.event.inputs.workerCount }}&quot;' -i sample.yaml
        yq eval '.databases.postgres.environment.POSTGRES_USER = &quot;${{ github.event.inputs.userName }}&quot;' -i sample.yaml

    - name: Commit and Push changes
      uses: EndBug/add-and-commit@v7
      with:
        author_name: authorName
        author_email: authorEmail
        message: 'Update WORKER_COUNT in sample.yaml to ${{ github.event.inputs.workerCount }}'
        add: 'sample.yaml'
        push: true
        token: ${{ secrets.B_REPO_TOKEN }}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Deploy Repository의 sample.yaml 예시&lt;/h2&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;version: 1
services:
  web:
    image: &quot;example/webapp:latest&quot;
    ports:
      - &quot;80:80&quot;
    environment:
      DEBUG: &quot;false&quot;
      DATABASE_URL: &quot;postgres://user:password@postgres:5432/dbname&quot;
  worker:
    image: &quot;example/worker:latest&quot;
    environment:
      QUEUE: &quot;tasks&quot;
      WORKER_COUNT: &quot;2&quot;
databases:
  postgres:
    image: &quot;postgres:13&quot;
    ports:
      - &quot;5432:5432&quot;
    environment:
      POSTGRES_USER: &quot;sampe&quot;
      POSTGRES_PASSWORD: &quot;password&quot;
      POSTGRES_DB: &quot;dbname&quot;
networks:
  default:
    external:
      name: &quot;my-custom-network&quot;&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;&amp;nbsp;&lt;/h2&gt;</description>
      <category>Backend</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/59</guid>
      <comments>https://sanhee.tistory.com/59#entry59comment</comments>
      <pubDate>Thu, 4 Jul 2024 20:32:19 +0900</pubDate>
    </item>
    <item>
      <title>[Datadog] Anomaly Detection 리서치</title>
      <link>https://sanhee.tistory.com/58</link>
      <description>&lt;h2 data-pm-slice=&quot;1 3 []&quot; data-ke-size=&quot;size26&quot;&gt;Anomaly Detection&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메트릭의 과거 트렌드, 계절별 패턴을 비교 분석하여 메트릭이 정상적인 범위를 벗어 났는지 탐지하는 데이터독 기능&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;그래서 언제 사용?&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pceSj/btsInmUsrak/LSMNs5D6S2vglKWcPhe7l0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pceSj/btsInmUsrak/LSMNs5D6S2vglKWcPhe7l0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pceSj/btsInmUsrak/LSMNs5D6S2vglKWcPhe7l0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpceSj%2FbtsInmUsrak%2FLSMNs5D6S2vglKWcPhe7l0%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;1070&quot; height=&quot;296&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&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;a href=&quot;https://docs.datadoghq.com/ko/monitors/guide/anomaly-monitor/&quot;&gt;https://docs.datadoghq.com/ko/monitors/guide/anomaly-monitor/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모니터링 하고자 하는 Elasticsearch 클러스터의 검색 성능과 관련된 지표에서 규칙적인 패턴이 발견됨.&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1679&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9nvCl/btsIopbw3Ol/XZ9gnWnLdnqkKoFF1ADZdk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9nvCl/btsIopbw3Ol/XZ9gnWnLdnqkKoFF1ADZdk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9nvCl/btsIopbw3Ol/XZ9gnWnLdnqkKoFF1ADZdk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9nvCl%2FbtsIopbw3Ol%2FXZ9gnWnLdnqkKoFF1ADZdk%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;1679&quot; height=&quot;458&quot; data-origin-width=&quot;1679&quot; data-origin-height=&quot;458&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;1682&quot; data-origin-height=&quot;455&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/72zKx/btsIoBJANeX/5l5HCTELwoGDAujjyB6pC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/72zKx/btsIoBJANeX/5l5HCTELwoGDAujjyB6pC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/72zKx/btsIoBJANeX/5l5HCTELwoGDAujjyB6pC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F72zKx%2FbtsIoBJANeX%2F5l5HCTELwoGDAujjyB6pC1%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;1682&quot; height=&quot;455&quot; data-origin-width=&quot;1682&quot; data-origin-height=&quot;455&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이상 징후 모니터를 통해 기대 하는 것 (가설)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Datadog의 Anomaly Monitor를 통해 검색 지표를 모니터링 하여 비정상적인 부하를 조기에 감지하여 알람을 받을 수 있다.&lt;/li&gt;
&lt;li&gt;이상 징후 알람으로 조기 조치가 가능 해진다면 시스템 다운타임을 방지하고, 사용자 경험을 개선하는 데 도움을 줄 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설정 방법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Datadog - Monitors&lt;/li&gt;
&lt;li&gt;Choose the detection method &amp;gt; Anomaly Detection 선택&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pcTfm/btsIm5SUabA/LVNp1Q207WqIXLCAqqE8oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pcTfm/btsIm5SUabA/LVNp1Q207WqIXLCAqqE8oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pcTfm/btsIm5SUabA/LVNp1Q207WqIXLCAqqE8oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpcTfm%2FbtsIm5SUabA%2FLVNp1Q207WqIXLCAqqE8oK%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;1672&quot; height=&quot;306&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Define the metric&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Anomaly Detection은 모니터링 쿼리에 대해 &lt;b&gt;Historical View,Evaluation Preview&lt;/b&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;2492&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G8xlu/btsIoqIhQzW/zkLnrl3HMXRII1KIqhgF70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G8xlu/btsIoqIhQzW/zkLnrl3HMXRII1KIqhgF70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G8xlu/btsIoqIhQzW/zkLnrl3HMXRII1KIqhgF70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG8xlu%2FbtsIoqIhQzW%2FzkLnrl3HMXRII1KIqhgF70%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;2492&quot; height=&quot;586&quot; data-origin-width=&quot;2492&quot; data-origin-height=&quot;586&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 colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;b&gt;Historical View&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Evaluation Preview 보다 넓은 시간 범위에서 지표를 확인 할 수 있어 트렌드 파악에 용이&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;b&gt;Evaluation Preview&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Alerting Window 보다 큰 범위가 제공되며, Anomaly Algorithm이 계산한 경계를 회색 영역으로 제공함.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt; Set alert conditions&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdL7PP/btsImHdJA5b/gVJNut7s2aSdAWvfqra070/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdL7PP/btsImHdJA5b/gVJNut7s2aSdAWvfqra070/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdL7PP/btsImHdJA5b/gVJNut7s2aSdAWvfqra070/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdL7PP%2FbtsImHdJA5b%2FgVJNut7s2aSdAWvfqra070%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;2274&quot; height=&quot;1556&quot; data-origin-width=&quot;2274&quot; data-origin-height=&quot;1556&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 colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Anomaly Detection&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;메트릭이 Anomaly Algorithm에 의해 생성된 회색 영역을 벗어나는 경우를 감지할 때 사용 되는 조건&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;above&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Trigger Window (= Alert Window)&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Anomaly detection에서 알림을 트리거하기 위해 고려되는 특정 시간 범위&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Evaluate the bounds for the last 1 hour&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Recovery Window&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;메트릭이 정상지표로 탐지 되는 데 걸리는 시간 범위&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Recover if the values are within the bounds for at least 1 hour&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Alert Threshold&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Datadog의 Anomaly detection에서 알림을 발생시키는 데 사용되는 기준이며, 일정 시간 동안 Deviations로 정해진 안정 범위(회색 영역)를 벗어난 메트릭의 비율을 말합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt; 70%&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Threshold가 높으면 많은 수의 데이터 포인트가 비정상 범위에 있어야 알림이 발생하고, 낮으면 적은 수의 데이터 포인트만으로도 알림이 트리거 됩니다.&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Recovery Threshold&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Recovery Window 동안 메트릭 비율이 정상으로 간주되는 비율&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;30%&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Recovery Threshold가 30%로 설정된 경우, Recovery Window 동안의 메트릭 중 30%만 비정상이어도 나머지 70%가 정상 범위에 있으면 알람이 해제&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Recovery Window 크기&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/types/anomaly/#anomaly-detection-algorithms:~:text=Note%3A%20The%20range%20of%20accepted%20values%20for%20the%20Recovery%20Window%20depends%20on%20the%20Trigger%20Window%20and%20the%20Alert%20Threshold%20to%20ensure%20the%20monitor%20can%E2%80%99t%20both%20satisfy%20the%20recovery%20and%20the%20alert%20condition%20at%20the%20same%20time.%20Example%3A&quot;&gt;문서&lt;/a&gt;에 따르면, Recovery Window는 Trigger Window의 사이즈와 동일하게 가져가는 것이 일반적입니다.&lt;/li&gt;
&lt;li&gt;하지만, Trigger와 Recovery 조건을 모두 충족시키는 상황을 피하기 위해 Trigger Window와 Alert Threshold에 따라 Recovery Window의 사이즈는 달라질 수 있습니다.&lt;/li&gt;
&lt;/ul&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;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diBdYM/btsIm3U5tGQ/YRJbZurjDwQbQuB5rPaPDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diBdYM/btsIm3U5tGQ/YRJbZurjDwQbQuB5rPaPDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diBdYM/btsIm3U5tGQ/YRJbZurjDwQbQuB5rPaPDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiBdYM%2FbtsIm3U5tGQ%2FYRJbZurjDwQbQuB5rPaPDK%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;814&quot; height=&quot;442&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Recovery Window 크기 계산&lt;/h2&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;- (최소 길이) Trigger Window * (1 - Threshold/100) + 1 min
- (최대 길이) Trigger Window 이상&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Recovery Window 크기 계산 예시&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;- Threshold: 50%
- Trigger Window: 4h
- Recovery Window:
  - (최소 길이) 121 min (= 4h * (1-0.5) + 1min)
  - (최대 길이) 4h 이상&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Recovery Window는 Trigger 시간 보다 조금 더 길어야만, Recovery 조건과 Trigger 조건을 동시에 만족하지 않게 됩니다.&lt;/li&gt;
&lt;li&gt;따라서 Recovery Window의 최소 길이는 Trigger Window와 동시 충족되는 상황을 피하기 위해 2시간(120분)보다 1분 더 긴 121분이 되어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Advanced option&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;671&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bA6M3K/btsIm5yz04K/wqEDTWEt8qxcK69YJWDaXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bA6M3K/btsIm5yz04K/wqEDTWEt8qxcK69YJWDaXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bA6M3K/btsIm5yz04K/wqEDTWEt8qxcK69YJWDaXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbA6M3K%2FbtsIm5yz04K%2FwqEDTWEt8qxcK69YJWDaXk%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;887&quot; height=&quot;671&quot; data-origin-width=&quot;887&quot; data-origin-height=&quot;671&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
Advanced options설명예시&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 colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Deviations&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;비정상 감지의 민감도를 설정하는 표준편차의 배수로, 정상 범위에서 얼마나 많은 표준 편차를 벗어난 것을 비정상으로 간주할지 정의&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Evaluation View의 &lt;b&gt;회색 영역&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Algorithm&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;이상 감지 알고리즘의 종류&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;basic,&amp;nbsp;agile, robust&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;b&gt;Seasonality&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;b&gt;agile, robust 알고리즘에서 사용되는 메트릭의 패턴&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;hourly, daily, weekly&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Daylight savings&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;agile, robust 알고리즘의 daily, weekly 패턴에서 사용 되는 썸머타임(타임존) 옵션&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/guide/anomaly-monitor/#%EC%84%9C%EB%A8%B8%ED%83%80%EC%9E%84%EC%9D%80-%EC%9D%B4%EC%83%81-%EC%A7%95%ED%9B%84-%ED%83%90%EC%A7%80-%EB%AA%A8%EB%8B%88%ED%84%B0%EC%97%90-%EC%96%B4%EB%96%A4-%EC%98%81%ED%96%A5%EC%9D%84-%EB%AF%B8%EC%B9%98%EB%82%98%EC%9A%94&quot;&gt;&lt;b&gt;서머타임은 이상 징후 탐지 모니터에 어떤 영향을 미치나요?&lt;/b&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Anomaly detection algorithms&lt;/h2&gt;
&lt;p&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 colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Basic&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Basic 알고리즘은 Seasonality를 보지 않고, 롤링 &lt;a href=&quot;https://bioinformaticsandme.tistory.com/246&quot;&gt;퀀타일&lt;/a&gt;이라는 통계적 기법으로 정상 범위를 계산합니다.&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;데이터가 비교적 안정적이고 예측 가능할 때 사용, 변동성이 크지 않고 일관된 패턴을 보이는 메트릭에 적합&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Basic 알고리즘은 Alert Window 크기 만큼의 최근 데이터에서 계산된 퀀타일에서 구한 표준편차에 Deviations 값을 곱하여 정상 범위의 상한과 하한을 결정&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Agile&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;메트릭의 최근 트렌드와 패턴 변화에 빠르게 적응 가능하여&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;b&gt;웹 트래픽 모니터링&lt;/b&gt;, &lt;b&gt;IT 인프라 모니터링&lt;/b&gt; 등..&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;알고리즘은 변동성이 더 높고, 빠르게 변하는 데이터에 적합&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Robust&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;메트릭 최근 트렌드의 큰 변화나 중요한 이상 현상을 감지하는 데 초점을 맞춘 방법&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;장기적인 변화 또는 추세를 감지하는 데 이상적&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;장기적인 매출 감소나 증가 추세를 감지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Seasonality&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 Seasonality는 최소 3배 이상 많은 데이터를 가지고 있어야함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(데이터를 집계해서 표준편차를 구하는 것 같음)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&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 colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Hourly&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;한 시간전과 같이 동작하도록 예상&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;오후 5시15분이라면 오후 4시 15분, 오후 3시 15분 등과 같이 동작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Daily&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;오늘 시간이 지난 날의 시간처럼 동작할 것을 예상&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;오늘 오후 5시가 어제 오후 5시처럼 동작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;Weekly&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt;특정 요일이 지난 요일 처럼 동작하도록 예상함.&lt;/span&gt;&lt;/td&gt;
&lt;td colspan=&quot;1&quot; rowspan=&quot;1&quot;&gt;&lt;span&gt; 이번 화요일은 지난 화요일처럼 동작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Alert Conditions 사례 (by GPT)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;장기적 이상 감지, 빠른 회복 확인&lt;/b&gt;:&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;* 장기적인 데이터 패턴이 중요한 시스템 *

- Trigger Window: 4시간
- Alert Threshold: 70%
- Recovery Window: 1시간 13분 -&amp;gt; 2시간
- Recovery Threshold: 30%&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;민감한 알람 설정, 완화된 회복 조건&lt;/b&gt;:&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;* 빠른 이상 감지가 중요한 민감한 시스템 *

- Trigger Window: 30분
- Alert Threshold: 50%
- Recovery Window: 30분
- Recovery Threshold: 20%&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직은 Anomaly Detection을 적용하면서 처음 기대한 조기 예측에 따른 효과를 보지 못했다. 차차 서비스에 맞게 Threshold, Deviations, Algorithm 커스텀을 하면서 상황을 지켜봐야할 것 같다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deviations (표준편차) 1배수 / agile 알고리즘&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1514&quot; data-origin-height=&quot;215&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ekoxog/btsIni5HKH7/C8S8EjAImWnJ8ebHxNYlMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ekoxog/btsIni5HKH7/C8S8EjAImWnJ8ebHxNYlMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ekoxog/btsIni5HKH7/C8S8EjAImWnJ8ebHxNYlMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fekoxog%2FbtsIni5HKH7%2FC8S8EjAImWnJ8ebHxNYlMK%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;1514&quot; height=&quot;215&quot; data-origin-width=&quot;1514&quot; data-origin-height=&quot;215&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Deviations (표준편차) 4배수, agile 알고리즘&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1461&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6FV8T/btsInPWgJyR/xHFbAtcZl5VAFjM7b0VUA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6FV8T/btsInPWgJyR/xHFbAtcZl5VAFjM7b0VUA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6FV8T/btsInPWgJyR/xHFbAtcZl5VAFjM7b0VUA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6FV8T%2FbtsInPWgJyR%2FxHFbAtcZl5VAFjM7b0VUA1%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;1461&quot; height=&quot;233&quot; data-origin-width=&quot;1461&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Reference.&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/types/anomaly/#anomaly-detection-algorithms&quot;&gt;https://docs.datadoghq.com/ko/monitors/types/anomaly/#anomaly-detection-algorithms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/guide/how-to-update-anomaly-monitor-timezone/&quot;&gt;https://docs.datadoghq.com/ko/monitors/guide/how-to-update-anomaly-monitor-timezone/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/guide/anomaly-monitor/&quot;&gt;https://docs.datadoghq.com/ko/monitors/guide/anomaly-monitor/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Backend</category>
      <category>datadog</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/58</guid>
      <comments>https://sanhee.tistory.com/58#entry58comment</comments>
      <pubDate>Thu, 4 Jul 2024 20:28:33 +0900</pubDate>
    </item>
    <item>
      <title>[Datadog] Detection Method 정리</title>
      <link>https://sanhee.tistory.com/57</link>
      <description>&lt;blockquote data-pm-slice=&quot;2 3 []&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터독에 전송된 메트릭은 사전에 정의한 임계값에 도달하면 알람을 받을 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC0pVR/btsInx2DKPR/kka7Vgkva3Iongo2dgEdsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC0pVR/btsInx2DKPR/kka7Vgkva3Iongo2dgEdsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC0pVR/btsInx2DKPR/kka7Vgkva3Iongo2dgEdsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC0pVR%2FbtsInx2DKPR%2Fkka7Vgkva3Iongo2dgEdsk%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;851&quot; height=&quot;144&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Threshold Alert&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 메트릭이 설정된 임계값을 초과하거나 미달할 때 경고를 발생시키는 방법&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 상황&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;잘 알려진 성능 기준이나 목표가 있을 때 유용&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용 케이스&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CPU 사용량 (`elasticsearch.node.cpu.utilization`)이 설정된 임계치 도달&lt;/li&gt;
&lt;li&gt;클러스터 상태 (`&lt;a href=&quot;http://elasticsearch.cluster.health&quot;&gt;elasticsearch.cluster.health&lt;/a&gt;_status`)가 &quot;yellow&quot; 또는 &quot;red&quot;로 변경.&lt;/li&gt;
&lt;li&gt;단위 샤드 크기 50GB 초과&lt;/li&gt;
&lt;li&gt;ES JVM 힙 메모리 85% 이상 사용&lt;/li&gt;
&lt;li&gt;LB 응답시간 p95가 200ms 이상&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Change Alert&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;메트릭 값의 변화율을 감지하고, 이 변화율이 설정한 임계치를 초과할 때 알림을 발생시킵니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 상황&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;평소와 다른 사용량 증가나 급격한 변화가 예상될 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예상 사용 케이스&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노드 수의 증가 또는 감소&lt;/li&gt;
&lt;li&gt;샤드 수 변화&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://docs.datadoghq.com/monitors/types/forecasts/?tab=linear&quot;&gt;Forecast Alert&lt;/a&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장기적인 과거 데이터를 바탕으로 미래의 데이터 트렌드를 예측하고, 예측된 범위를 벗어나는 경우&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 상황&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 추세나 패턴을 따르는 메트릭에 유용하며, 예측 가능한 트래픽 증가나 이벤트가 예정되어 있을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예상 사용 케이스&lt;/b&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;JVM 메모리 사용 추세 예측&lt;/li&gt;
&lt;li&gt;CPU 부하의 미래 추세 예측&lt;/li&gt;
&lt;li&gt;색인화 속도의 미래 추세 예측&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://docs.datadoghq.com/monitors/types/outlier/?tab=dbscan&quot;&gt;Outliers Alert&lt;/a&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 그룹이 동료 그룹과 다르게 행동하는 경우를 감지&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예상 사용 케이스&lt;/b&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;특정 파드의 일반적이지 않은 JVM 메모리 사용량&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://docs.datadoghq.com/ko/monitors/types/anomaly/&quot;&gt;Anomaly Alert&lt;/a&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;과거 데이터를 기반으로 정상 범위를 학습하고, 현재 데이터가 이 범위를 벗어날 때 경고를 발생시키는 메소드&lt;/li&gt;
&lt;li&gt;&lt;b&gt;적합한 상황&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트래픽 변동성이 크거나, 평소와 다른 사용 패턴이 예상될 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;사용 케이스&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비정상적인게 query_current 증가&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Reference.&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datadoghq.com/monitors/&quot;&gt;https://docs.datadoghq.com/monitors/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Backend</category>
      <category>datadog</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/57</guid>
      <comments>https://sanhee.tistory.com/57#entry57comment</comments>
      <pubDate>Thu, 4 Jul 2024 20:27:50 +0900</pubDate>
    </item>
    <item>
      <title>[Elasticsearch] maximum normal shards open - 클러스터 샤드 수 제한</title>
      <link>https://sanhee.tistory.com/56</link>
      <description>&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;상황&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래 ES 에러 메시지가 발생하면서 신규 인덱스 생성 불가&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;{&quot;type&quot;:&quot;illegal_argument_exception&quot;,
&quot;reason&quot;:&quot;Validation Failed: 1: this action would add [10] shards, 
but this cluster currently has [993]/[1000] 
maximum normal shards open;&quot;}&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;분석&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/current/misc-cluster-settings.html&quot;&gt;ES 공식문서&lt;/a&gt;에 따르면,&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클러스터의 샤드 수는 노드 수에 기반한 소프트 제한이 있으며, 이것은 클러스터를 불안정하게 할 수 있는 작업을 방지하기 위함입니다.&lt;/li&gt;
&lt;li&gt;클러스터 샤드 제한은 하드웨어 구성과 부하량에 따라 안정적인 샤드 수가 다릅니다.&lt;/li&gt;
&lt;li&gt;closed index는 위 max_shards_per_node 에 포함되지 않습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;새 인덱스 생성, 인덱스 스냅샷 복원, closed index 열기와&lt;/b&gt; 같은 작업으로 샤드 수가 초과하게 되면 위와 같은 maximum normal shards open 에러가 발생합니다.&lt;/li&gt;
&lt;li&gt;클러스터가 이미 샤드 제한을 초과한 경우, 일부 인덱스가 closed 되거나 삭제될 때까지 새로운 인덱스 생성이나 closed index 열기 작업이 실패합니다.&lt;/li&gt;
&lt;li&gt;cluster.max_shards_per_node 설정으로 클러스터 샤드 제한을 동적으로 조정할 수 있으며, 이는 노드당 최대 수를 제한합니다.&lt;/li&gt;
&lt;li&gt;cluster.max_shards_per_node 기본값은 1000입니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eAfR0Y/btsIm5STHpE/ridpy2GgAX7Lener9BjRO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eAfR0Y/btsIm5STHpE/ridpy2GgAX7Lener9BjRO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eAfR0Y/btsIm5STHpE/ridpy2GgAX7Lener9BjRO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeAfR0Y%2FbtsIm5STHpE%2Fridpy2GgAX7Lener9BjRO0%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;947&quot; height=&quot;234&quot; data-origin-width=&quot;947&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;해결방법&lt;/h1&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;1. 샤드 수 조정
  - 인덱스당 샤드 수 조정
  - 샤드 병합(포스 머지)
  -  Open Index 중 사용하지 않는 인덱스를 Closed 혹은 Delete 처리

2. 클러스터 설정 변경 (cluster.max_shards_per_node)

3. 데이터 노드 증설&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;클러스터 설정 변경 (cluster.max_shards_per_node)&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 옵션은 각 노드가 보유할 수 있는 최대 샤드(Shard) 수로 상황에 따라 성능 저하가 동반될 수 있어 장기적으로는 샤드 크기와 구조를 최적화 하는게 바람직함.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cluster.max_shards_per_node 설정 확인&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;    
GET _cluster/settings?include_defaults&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9Gxkc/btsInOQBiRg/kYRAtcGNreBeQCKF0EsDu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9Gxkc/btsInOQBiRg/kYRAtcGNreBeQCKF0EsDu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9Gxkc/btsInOQBiRg/kYRAtcGNreBeQCKF0EsDu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9Gxkc%2FbtsInOQBiRg%2FkYRAtcGNreBeQCKF0EsDu1%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;319&quot; height=&quot;71&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max_shards_per_node 옵션 조정&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;PUT _cluster/settings
{
  &quot;persistent&quot;: {
    &quot;cluster.max_shards_per_node&quot;: &quot;원하는 샤드 수&quot;
  }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Backend</category>
      <category>elasticsearch</category>
      <author>산희</author>
      <guid isPermaLink="true">https://sanhee.tistory.com/56</guid>
      <comments>https://sanhee.tistory.com/56#entry56comment</comments>
      <pubDate>Thu, 4 Jul 2024 20:18:03 +0900</pubDate>
    </item>
  </channel>
</rss>