<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발자로 살아남기</title>
    <link>https://118k.tistory.com/</link>
    <description>Hello World!</description>
    <language>ko</language>
    <pubDate>Thu, 7 May 2026 23:59:20 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>hs_seo</managingEditor>
    <image>
      <title>개발자로 살아남기</title>
      <url>https://t1.daumcdn.net/cfile/tistory/264DE04A59165E9A08</url>
      <link>https://118k.tistory.com</link>
    </image>
    <item>
      <title>[k8s] kopf 라이브러리 - 파이썬 오퍼레이터 라이브러리</title>
      <link>https://118k.tistory.com/1249</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kopf(Kubernetes Operator Pythonic Framework)&lt;/b&gt;는 Python을 사용하여 &lt;b&gt;Kubernetes Operator(오퍼레이터)&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;일반적으로 쿠버네티스 오퍼레이터 개발에는 Go 언어와 &lt;code&gt;kubebuilder&lt;/code&gt;가 표준처럼 쓰이지만, Kopf는 Python 특유의 간결함을 살려 복잡한 인프라 로직 없이 &lt;b&gt;비즈니스 도메인 로직&lt;/b&gt;에만 집중할 수 있게 해줍니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 언제 사용하면 좋은가요?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kopf는 다음과 같은 상황에서 최고의 효율을 발휘합니다.&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;Python 생태계 활용이 필요할 때:&lt;/b&gt; 이미 머신러닝(ML), 데이터 분석, 혹은 자동화 스크립트가 Python으로 작성되어 있어 이를 쿠버네티스 자원과 연동해야 할 때 매우 유용합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빠른 프로토타이핑:&lt;/b&gt; 복잡한 Go 언어 설정이나 보일러플레이트 코드 없이, 단 몇 줄의 Python 데코레이터(&lt;code&gt;@kopf.on.create&lt;/code&gt; 등)만으로 오퍼레이터를 만들 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단순한 자동화 도구 개발:&lt;/b&gt; 특정 Custom Resource(CR)가 생성될 때 알림을 보내거나, 보조적인 리소스(ConfigMap, Secret 등)를 자동으로 생성하는 정도의 가벼운 오퍼레이터가 필요할 때 적합합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Go 언어 숙련도가 낮을 때:&lt;/b&gt; 쿠버네티스 내부 구조는 깊이 몰라도 Python만 안다면 바로 개발에 뛰어들 수 있어 진입장벽이 낮습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Kopf의 주요 장점 (이용하면 좋은 이유)&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;① 직관적인 Pythonic API&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kopf는 핸들러를 정의할 때 Python 데코레이터를 사용합니다. 이벤트 발생 시 실행될 함수를 직관적으로 연결할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot;&gt;&lt;code&gt;import kopf

@kopf.on.create('my-custom-resource')
def create_fn(spec, **kwargs):
    print(f&quot;리소스 생성됨! 스펙: {spec}&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;② 복잡한 제어 루프(Reconciliation Loop)의 추상화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 오퍼레이터의 핵심은 &quot;현재 상태를 원하는 상태로 맞추는 것&quot;입니다. Kopf는 리소스의 변화를 감시하고, 에러 시 재시도(Retry)하거나, 상태를 업데이트하는 복잡한 과정을 내부적으로 처리해 줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;③ 풍부한 기능 지원&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Timer &amp;amp; Daemon:&lt;/b&gt; 특정 주기마다 실행되는 작업(&lt;code&gt;@kopf.timer&lt;/code&gt;)이나, 리소스가 존재하는 동안 계속 실행되는 백그라운드 작업(&lt;code&gt;@kopf.daemon&lt;/code&gt;)을 쉽게 구현할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Events &amp;amp; Logging:&lt;/b&gt; Python의 기본 &lt;code&gt;logging&lt;/code&gt;을 사용하면 자동으로 쿠버네티스 Event로 기록되어 &lt;code&gt;kubectl describe&lt;/code&gt;로 확인할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Diff handling:&lt;/b&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;3. 요약 및 비교&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;특징&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Kopf (Python)&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Kubebuilder / Operator SDK (Go)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;난이도&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;매우 낮음 (초보자 권장)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;보통 ~ 높음 (학습 곡선 있음)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;개발 속도&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;매우 빠름&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;초기 설정에 시간이 걸림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;성능&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;보통 (대규모 클러스터에선 부담일 수 있음)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;매우 높음 (고성능, 저지연)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;b&gt;생태계&lt;/b&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Python 라이브러리 활용 용이&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;쿠버네티스 표준 도구들과의 통합 우수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;Go 언어에 익숙하지 않거나, Python의 강력한 라이브러리(Pandas, Boto3, Requests 등)를 활용해 쿠버네티스 리소스를 제어하는 관리 도구를 빠르게 만들고 싶을 때&quot;&lt;/b&gt; Kopf를 사용하는 것이 가장 좋습니다. 반면, 수천 개의 노드를 관리하는 초고성능 엔터프라이즈급 오퍼레이터를 만든다면 Go 기반의 도구를 고려하는 것이 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1249</guid>
      <comments>https://118k.tistory.com/1249#entry1249comment</comments>
      <pubDate>Fri, 10 Apr 2026 00:02:35 +0900</pubDate>
    </item>
    <item>
      <title>[Tools] Event Catalog 란?</title>
      <link>https://118k.tistory.com/1248</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현대적인 마이크로서비스 아키텍처(MSA)나 이벤트 기반 아키텍처(EDA)를 구축하다 보면, 어떤 서비스가 어떤 이벤트를 발행하고 구독하는지 파악하기가 매우 힘들어집니다. 이때 필요한 것이 바로 &lt;b&gt;EventCatalog&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;a href=&quot;https://www.eventcatalog.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.eventcatalog.dev/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1775746029503&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;EventCatalog - Know how your systems connect  -  EventCatalog&quot; data-og-description=&quot;Turn your distributed architecture into a searchable, visual, AI-queryable source of truth. Self-hosted, open source.&quot; data-og-host=&quot;www.eventcatalog.dev&quot; data-og-source-url=&quot;https://www.eventcatalog.dev/&quot; data-og-url=&quot;https://eventcatalog.dev/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.eventcatalog.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.eventcatalog.dev/&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;EventCatalog - Know how your systems connect - EventCatalog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Turn your distributed architecture into a searchable, visual, AI-queryable source of truth. Self-hosted, open source.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.eventcatalog.dev&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. EventCatalog란 무엇인가?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;EventCatalog&lt;/b&gt;는 오픈소스 도구로, 프로젝트의 &lt;b&gt;이벤트, 스키마, 그리고 서비스 간의 관계를 시각화하고 문서화해 주는 정적 사이트 생성기&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말해, &quot;우리 시스템에 어떤 이벤트가 돌아다니는지&quot;를 보여주는 &lt;b&gt;전사적 이벤트 사전&lt;/b&gt;이라고 이해하시면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;주요 특징&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Markdown 기반:&lt;/b&gt; 개발자에게 친숙한 마도다운 파일로 이벤트 정보를 관리합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시각화:&lt;/b&gt; 서비스 간의 흐름(Producer와 Consumer 관계)을 다이어그램으로 보여줍니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;버전 관리:&lt;/b&gt; 이벤트 스키마의 변경 이력을 추적할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동화:&lt;/b&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;2. 왜 사용하는가? (해결하는 문제)&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;파편화된 정보 통합:&lt;/b&gt; 코드 여기저기에 흩어진 이벤트 정의를 한곳에서 볼 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;커뮤니케이션 비용 감소:&lt;/b&gt; 기획자나 새로 합류한 개발자가 &quot;주문이 완료되면 어떤 데이터가 넘어가나요?&quot;라고 물을 때 이 카탈로그 링크 하나로 답변이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;영향도 분석:&lt;/b&gt; 특정 이벤트를 수정했을 때 영향을 받는 서비스가 무엇인지 즉각 파악할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 어떻게 사용하는가? (기본 흐름)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용법은 매우 직관적이며, 일반적인 문서화 도구와 유사합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 1: 프로젝트 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js 환경에서 아래 명령어로 프로젝트를 생성합니다.&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;npx @eventcatalog/create-eventcatalog@latest my-catalog&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 2: 이벤트와 서비스 정의&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더 내의 &lt;code&gt;events&lt;/code&gt; 폴더와 &lt;code&gt;services&lt;/code&gt; 폴더에 각각 Markdown 파일을 작성합니다.&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;이벤트 정의 예시 (&lt;code&gt;events/OrderCreated/index.md&lt;/code&gt;):&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-markdown&quot;&gt;  ---
  name: OrderCreated
  version: 1.0.0
  summary: 고객이 주문을 완료했을 때 발생하는 이벤트
  producers:
      - Order Service
  consumers:
      - Inventory Service
      - Shipping Service
  ---

  ### 이벤트 페이로드 (Schema)
  이곳에 JSON 스키마나 설명을 작성합니다.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Step 3: 시각화 확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성된 파일들을 기반으로 EventCatalog가 자동으로 관계도를 생성합니다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;npm run dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 실행하면 웹 브라우저에서 서비스 간의 화살표 흐름도(Node Graph)를 확인할 수 있습니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 실무 활용 팁&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;자동 생성 도구 활용:&lt;/b&gt; AsyncAPI 파일이나 AWS EventBridge, SNS/SQS 설정을 기반으로 Markdown 파일을 자동으로 생성해 주는 플러그인을 사용하면 관리가 훨씬 편해집니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CI/CD 통합:&lt;/b&gt; 코드가 메인 브랜치에 머지될 때마다 EventCatalog를 빌드하고 정적 호스팅(GitHub Pages, Vercel 등)에 배포하여 항상 최신 상태를 유지하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.eventcatalog.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.eventcatalog.dev/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1775745982573&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;EventCatalog - Know how your systems connect  -  EventCatalog&quot; data-og-description=&quot;Turn your distributed architecture into a searchable, visual, AI-queryable source of truth. Self-hosted, open source.&quot; data-og-host=&quot;www.eventcatalog.dev&quot; data-og-source-url=&quot;https://www.eventcatalog.dev/&quot; data-og-url=&quot;https://eventcatalog.dev/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.eventcatalog.dev/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.eventcatalog.dev/&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;EventCatalog - Know how your systems connect - EventCatalog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Turn your distributed architecture into a searchable, visual, AI-queryable source of truth. Self-hosted, open source.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.eventcatalog.dev&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>Tools</category>
      <category>eventcatalog</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1248</guid>
      <comments>https://118k.tistory.com/1248#entry1248comment</comments>
      <pubDate>Thu, 9 Apr 2026 23:47:23 +0900</pubDate>
    </item>
    <item>
      <title>[Airflow] Apache Airflow Helm Chart (1.18.0) PostgreSQL 이미지 오류 해결 방법</title>
      <link>https://118k.tistory.com/1247</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Apache Airflow Helm Chart 1.18.0&lt;/b&gt; 버전을 배포하거나 업데이트하는 과정에서 PostgreSQL 이미지를 불러오지 못하는 오류가 빈번하게 발생하고 있습니다.&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. 문제의 원인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Bitnami는 Docker Hub의 이미지 관리 방식을 변경하면서, 기존 &lt;code&gt;bitnami/postgresql&lt;/code&gt; 레포지토리의 구버전 태그들을 대거 삭제하거나 &lt;code&gt;bitnamilegacy&lt;/code&gt;로 이동시켰습니다. 이로 인해 Airflow Helm Chart 내부에서 기본값으로 설정된 PostgreSQL 이미지 태그를 찾지 못해 &lt;b&gt;ImagePullBackOff&lt;/b&gt; 에러가 발생하게 됩니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 즉각적인 해결 방법: values.yaml 수정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 운영 중이거나 당장 PostgreSQL을 사용해야 한다면, &lt;code&gt;values.yaml&lt;/code&gt; 파일에서 이미지 레포지토리를 &lt;b&gt;bitnamilegacy&lt;/b&gt;로 명시적으로 변경해 주어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;수정 전:&lt;/b&gt; (기본 설정 사용 시 에러 발생 가능)&lt;br /&gt;&lt;b&gt;수정 후 (values.yaml):&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;postgresql:
  image:
    registry: docker.io
    repository: bitnamilegacy/postgresql
    tag: 16.1.0-debian-11-r15
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고:&lt;/b&gt; 위 설정은 삭제된 이미지가 아닌, 레거시 보관소에 남아있는 이미지를 직접 지정하여 배포를 정상화하는 방법입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 향후 권장 사항: DB 엔진 변경 고려&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Airflow 공식 커뮤니티와 차트 관리자들은 이러한 외부 종속성 문제를 해결하기 위해 기본 DB 설정을 &lt;b&gt;SQLite&lt;/b&gt;로 변경하거나 다른 대안을 모색하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;b&gt;MySQL 또는 외부 PostgreSQL 사용:&lt;/b&gt; * Bitnami Helm 차트에 의존하는 내장 PostgreSQL 대신, 직접 관리하는 외부 DB(RDS, Cloud SQL 등)로 연결 설정을 변경하는 것이 프로덕션 환경에서는 가장 안전합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 환경이라면 SQLite 활용:&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 테스트나 로컬 개발 용도라면 향후 공식 업데이트에 맞춰 SQLite로 전환하는 것도 방법입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Helm Chart 버전 업데이트 모니터링:&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;차기 버전에서는 이 이미지 주소 이슈가 해결되어 배포될 예정이므로, 지속적으로 차트 업데이트를 확인하시기 바랍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;갑작스러운 이미지 오류로 당황하셨겠지만, &lt;code&gt;repository&lt;/code&gt; 경로를 &lt;code&gt;bitnamilegacy/postgresql&lt;/code&gt;로 변경하는 것만으로도 당장의 문제는 해결할 수 있습니다. 하지만 Bitnami의 이미지 관리 정책이 계속 변하고 있는 만큼, 중장기적으로는 DB 인프라 운영 전략을 점검해 보시는 것을 권장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/apache/airflow/issues/56498&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/apache/airflow/issues/56498&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1767625505608&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Missing postgres docker images &amp;middot; Issue #56498 &amp;middot; apache/airflow&quot; data-og-description=&quot;Official Helm Chart version 1.15.0 Apache Airflow version 2.9.3 Kubernetes Version 1.32.4 Helm Chart configuration No response Docker Image customizations No response What happened After restart I ...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/apache/airflow/issues/56498&quot; data-og-url=&quot;https://github.com/apache/airflow/issues/56498&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cxTiZO/dJMb8Z3jWse/LPfLYZss0SuDzMdpx8bPhK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/mznWl/dJMb8XRYeLR/PB2Khz5kLUodNQ4rVKjCpk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/apache/airflow/issues/56498&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/apache/airflow/issues/56498&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cxTiZO/dJMb8Z3jWse/LPfLYZss0SuDzMdpx8bPhK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/mznWl/dJMb8XRYeLR/PB2Khz5kLUodNQ4rVKjCpk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;Missing postgres docker images &amp;middot; Issue #56498 &amp;middot; apache/airflow&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Official Helm Chart version 1.15.0 Apache Airflow version 2.9.3 Kubernetes Version 1.32.4 Helm Chart configuration No response Docker Image customizations No response What happened After restart I ...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>빅데이터/airflow</category>
      <category>airflow</category>
      <category>chart</category>
      <category>helm</category>
      <category>PostgreSQL</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1247</guid>
      <comments>https://118k.tistory.com/1247#entry1247comment</comments>
      <pubDate>Tue, 6 Jan 2026 00:05:22 +0900</pubDate>
    </item>
    <item>
      <title>[superset] Superset 최신 버전(5.0.0) 설치 중 오류 (Field.__init__() got an unexpected keyword argument 'minLength')</title>
      <link>https://118k.tistory.com/1246</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Ubuntu 22 에 Superset 최신 버전을 설치하는 중에 다음과 같은 오류가 발생하였습니다.&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;원인은 최신버전에 설치된 객체를 직렬화, 역직렬화할 때 사용하는 marshmarrow가 문제가 되어서 발생하였습니다. 이 컴포넌트를 4.x 버전이 아니라 3.x 버전으로 설치하면 오류가 해결됩니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753834014655&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 수정 버전 설치
pip3 install marshmallow==3.26.1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-07-30 오전 9.07.22.png&quot; data-origin-width=&quot;2174&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIYUaX/btsPC5cYiyG/SEtHWDTGnE1r2VOhG9lG21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIYUaX/btsPC5cYiyG/SEtHWDTGnE1r2VOhG9lG21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIYUaX/btsPC5cYiyG/SEtHWDTGnE1r2VOhG9lG21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIYUaX%2FbtsPC5cYiyG%2FSEtHWDTGnE1r2VOhG9lG21%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;2174&quot; height=&quot;612&quot; data-filename=&quot;스크린샷 2025-07-30 오전 9.07.22.png&quot; data-origin-width=&quot;2174&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1753833327693&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;  File &quot;/opt/superset/lib/python3.10/site-packages/superset/initialization/__init__.py&quot;, line 130, in init_views
    from superset.cachekeys.api import CacheRestApi
  File &quot;/opt/superset/lib/python3.10/site-packages/superset/cachekeys/api.py&quot;, line 27, in &amp;lt;module&amp;gt;
    from superset.cachekeys.schemas import CacheInvalidationRequestSchema
  File &quot;/opt/superset/lib/python3.10/site-packages/superset/cachekeys/schemas.py&quot;, line 20, in &amp;lt;module&amp;gt;
    from superset.charts.schemas import (
  File &quot;/opt/superset/lib/python3.10/site-packages/superset/charts/schemas.py&quot;, line 427, in &amp;lt;module&amp;gt;
    class ChartDataAggregateOptionsSchema(ChartDataPostProcessingOperationOptionsSchema):
  File &quot;/opt/superset/lib/python3.10/site-packages/superset/charts/schemas.py&quot;, line 433, in ChartDataAggregateOptionsSchema
    fields.List(
  File &quot;/opt/superset/lib/python3.10/site-packages/marshmallow/fields.py&quot;, line 709, in __init__
    super().__init__(**kwargs)
TypeError: Field.__init__() got an unexpected keyword argument 'minLength'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/apache/superset/issues/33162&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/apache/superset/issues/33162&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1753833795036&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Make Superset compatible with &amp;#96;marshmallow&amp;gt;=4.0.0&amp;#96; &amp;middot; Issue #33162 &amp;middot; apache/superset&quot; data-og-description=&quot;Bug description On a fresh install of superset, since marshmallow 4.0.0 released https://pypi.org/project/marshmallow/, superset fails to init due to an error validating parameters It is possible t...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/apache/superset/issues/33162&quot; data-og-url=&quot;https://github.com/apache/superset/issues/33162&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/blPuqo/hyZrqqQmYs/VeWNaxdhtBKCcsM5CpMNh1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bq9osP/hyZrvMrWiJ/i53Gdv43ClfTIAShoApk1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/apache/superset/issues/33162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/apache/superset/issues/33162&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/blPuqo/hyZrqqQmYs/VeWNaxdhtBKCcsM5CpMNh1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bq9osP/hyZrvMrWiJ/i53Gdv43ClfTIAShoApk1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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;Make Superset compatible with `marshmallow&amp;gt;=4.0.0` &amp;middot; Issue #33162 &amp;middot; apache/superset&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Bug description On a fresh install of superset, since marshmallow 4.0.0 released https://pypi.org/project/marshmallow/, superset fails to init due to an error validating parameters It is possible t...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>superset</category>
      <category>설치</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1246</guid>
      <comments>https://118k.tistory.com/1246#entry1246comment</comments>
      <pubDate>Wed, 30 Jul 2025 09:07:39 +0900</pubDate>
    </item>
    <item>
      <title>[k8s] ingress contains invalid paths: path /xxx(/I$)(.*) cannot be used with pathType Prefix 오류 수정</title>
      <link>https://118k.tistory.com/1245</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;K8s 인그레스를 등록할 때 다음과 같은 오류가 발생하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;one or more objects failed to apply, reason: admission webhook &quot;validate.nginx.ingress.kubernetes.io&quot; denied the request: ingress contains invalid paths: path /server-scheduler(/1$)(*) cannot be used with pathType Prefix,admission webhook &quot;validate.nginx.ingress.kubernetes.io&quot; denied the request: ingress contains invalid paths: path /reader(/I$)(.*) cannot be used with pathType Prefix&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;k8s 의 버전이 업그레이드 되면서 체크가 변경된 것으로 보이며, annotaion 의 use-regex를 추가 하고, pathType을 Prefix에서 ImplementationSpecific 으로변경합니다.&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1750592261449&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ingress:
    ingressClass: nginx
    annotations:
        nginx.ingress.kubernetes.io/use-regex: &quot;true&quot;
    hosts:
        - host: abc.com
          paths:
              - path: /server-scheduler(/|$)(.*)
                pathType: ImplementationSpecific
    tls:
        - host: abc.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>ingress</category>
      <category>k8s</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1245</guid>
      <comments>https://118k.tistory.com/1245#entry1245comment</comments>
      <pubDate>Sun, 22 Jun 2025 20:41:02 +0900</pubDate>
    </item>
    <item>
      <title>[github action] 코멘트를 이용하여 작업을 실행하는 방법</title>
      <link>https://118k.tistory.com/1244</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;github aciton 에 맞는 yaml 파일을 .github/workflows 아래에 생성합니다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 pr 을 생성하고, comment 에 /build 를 입력하면 실행됩니다. &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;스크린샷 2025-05-26 오후 11.21.24.png&quot; data-origin-width=&quot;576&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9Smct/btsOd82YYNS/p2P94ofkiezlyu7AH2qhuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9Smct/btsOd82YYNS/p2P94ofkiezlyu7AH2qhuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9Smct/btsOd82YYNS/p2P94ofkiezlyu7AH2qhuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9Smct%2FbtsOd82YYNS%2Fp2P94ofkiezlyu7AH2qhuK%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;576&quot; height=&quot;208&quot; data-filename=&quot;스크린샷 2025-05-26 오후 11.21.24.png&quot; data-origin-width=&quot;576&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-26 오후 11.24.00.png&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXjdtC/btsOclCuMdg/B0ON26jkoLlK2OsffRSy30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXjdtC/btsOclCuMdg/B0ON26jkoLlK2OsffRSy30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXjdtC/btsOclCuMdg/B0ON26jkoLlK2OsffRSy30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXjdtC%2FbtsOclCuMdg%2FB0ON26jkoLlK2OsffRSy30%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;858&quot; height=&quot;412&quot; data-filename=&quot;스크린샷 2025-05-26 오후 11.24.00.png&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1748269366696&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Build on Comment

on:
  issue_comment:
    types: [created]

jobs:
  build_image:
    # 코멘트가 '/build'이고, PR에 작성된 코멘트인 경우에만 실행
    if: github.event.issue.pull_request &amp;amp;&amp;amp; contains(github.event.comment.body, '/build')
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub (Optional)
        # Docker Hub에 이미지를 푸시하려면 주석을 해제하고 사용자 이름과 토큰을 설정하세요.
        # Docker Hub 이외의 레지스트리를 사용하는 경우 해당 레지스트리에 맞게 수정하세요.
        # uses: docker/login-action@v3
        # with:
        #   username: ${{ secrets.DOCKERHUB_USERNAME }}
        #   password: ${{ secrets.DOCKERHUB_TOKEN }}
        run: echo &quot;Docker login step skipped for now. Uncomment and configure if needed.&quot;

      - name: Build Docker image
        # 'DOCKERHUB_USERNAME/IMAGE_NAME:TAG' 부분을 실제 이미지 이름과 태그로 변경하세요.
        # Dockerfile의 위치가 루트 디렉토리가 아니라면 context와 file 옵션을 수정하세요.
        run: |
          docker build -t my-image:latest .
          echo &quot;Docker image built: my-image:latest&quot;

      # - name: Push Docker image (Optional)
      #   # 이미지를 푸시하려면 주Kk석을 해제하고 이미지 이름을 수정하세요.
      #   # run: docker push my-image:latest
      #   run: echo &quot;Docker push step skipped for now. Uncomment if needed.&quot;

      - name: Add reaction to comment
        uses: peter-evans/create-or-update-comment@v4
        with:
          comment-id: ${{ github.event.comment.id }}
          reaction-type: '+1' # 빌드 시작을 알리는 반응 (예:  )

      - name: Comment on build completion (Optional)
        # 빌드 완료 후 코멘트를 남기려면 주석을 해제하세요.
        # uses: peter-evans/create-or-update-comment@v4
        # with:
        #   issue-number: ${{ github.event.issue.number }}
        #   body: |
        #     Image build triggered by @${{ github.event.comment.user.login }} has completed.
        #     Image: my-image:latest
        run: echo &quot;Build completion comment step skipped for now. Uncomment if needed.&quot;&lt;/code&gt;&lt;/pre&gt;</description>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1244</guid>
      <comments>https://118k.tistory.com/1244#entry1244comment</comments>
      <pubDate>Mon, 26 May 2025 23:24:18 +0900</pubDate>
    </item>
    <item>
      <title>[iceberg] 2025년 아이스버그의 한계 요약 (Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025)</title>
      <link>https://118k.tistory.com/1243</link>
      <description>&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://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748175767265&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;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025 | Apache Iceberg Practical Limitations in 2025&quot; data-og-description=&quot;At Quesma we help customers to innovate faster by re-shaping the way applications are built and connected to their DBs. Quesma database gateway enables development teams to modernise and evolve application architecture.&quot; data-og-host=&quot;quesma.com&quot; data-og-source-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; data-og-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e1UHH/hyYYtvAHUP/h8wyGOdTFZVMKjVcKmJwR1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/bzF7ub/hyYYtvAHOY/8Exf1vUgbwIAXLGHrthji1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/PnfAJ/hyY0ozHIyG/rrHoRvbtlIyp3ToVRZe7RK/img.png?width=2240&amp;amp;height=692&amp;amp;face=0_0_2240_692&quot;&gt;&lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e1UHH/hyYYtvAHUP/h8wyGOdTFZVMKjVcKmJwR1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/bzF7ub/hyYYtvAHOY/8Exf1vUgbwIAXLGHrthji1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/PnfAJ/hyY0ozHIyG/rrHoRvbtlIyp3ToVRZe7RK/img.png?width=2240&amp;amp;height=692&amp;amp;face=0_0_2240_692');&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;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025 | Apache Iceberg Practical Limitations in 2025&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;At Quesma we help customers to innovate faster by re-shaping the way applications are built and connected to their DBs. Quesma database gateway enables development teams to modernise and evolve application architecture.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;quesma.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;chatgpt 요약&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;Quesma의 블로그 글 &quot;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025&quot;에서는 Apache Iceberg의 실용적인 한계점들을 다루고 있습니다. 주요 내용을 요약하면 다음과 같습니다:(&lt;a href=&quot;https://quesma.com/blog?utm_source=chatgpt.com&quot;&gt;quesma.com&lt;/a&gt;)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. &lt;b&gt;소규모 데이터 환경에서의 비효율성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apache Iceberg는 Netflix에서 페타바이트 규모의 대규모 데이터를 처리하기 위해 설계되었습니다. 그러나 현재 많은 조직들은 100GB 미만의 데이터 웨어하우스를 운영하고 있으며, 핵심 데이터셋은 수 기가바이트에 불과한 경우가 많습니다. 이러한 소규모 환경에서는 Iceberg의 복잡한 메타데이터 구조와 간접 계층이 오히려 비효율을 초래할 수 있습니다.(&lt;a href=&quot;https://en.wikipedia.org/wiki/Apache_Iceberg?utm_source=chatgpt.com&quot;&gt;위키백과&lt;/a&gt;)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. &lt;b&gt;쓰기 작업 시 메타데이터 오버헤드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Iceberg에서 단일 행을 업데이트할 때도 새로운 Parquet 파일, 매니페스트 파일, 매니페스트 리스트 파일, 테이블 메타데이터 JSON 등 네 개의 블롭 저장소 쓰기 작업이 필요합니다. 이러한 작업은 각각 수백 밀리초가 소요되어, PostgreSQL과 같은 전통적인 데이터베이스에서는 수 밀리초 내에 완료되는 작업이 Iceberg에서는 수 초가 걸릴 수 있습니다.(&lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025?utm_source=chatgpt.com&quot;&gt;quesma.com&lt;/a&gt;)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. &lt;b&gt;정기적인 컴팩션 필요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓰기 작업이 누적되면 &quot;파일 폭발(file explosion)&quot; 현상이 발생하여 쿼리 성능이 저하됩니다. 이를 방지하기 위해서는 데이터 및 메타데이터 파일을 정기적으로 컴팩션해야 합니다. 그러나 현재 Iceberg 구현체는 자동 컴팩션 기능이 부족하여, 사용자가 직접 Spark나 Athena를 통해 OPTIMIZE 작업을 수행해야 하며, 이는 추가적인 비용과 복잡성을 초래합니다.(&lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025?utm_source=chatgpt.com&quot;&gt;quesma.com&lt;/a&gt;)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. &lt;b&gt;생태계의 단편화&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Iceberg는 언어에 구애받지 않는 사양을 지향하지만, 실제로는 대부분의 프로덕션 코드가 Java 기반으로 실행됩니다. Python(PyIceberg), Rust, Go 등의 포트는 아직 Java 구현체에 비해 여러 릴리스를 뒤처져 있으며, 컴팩션 서비스와 같은 부가 도구도 부족한 상황입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. &lt;b&gt;향후 개선 사항&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Iceberg의 공동 창립자인 Ryan Blue는 단일 파일 커밋(single-file commit)을 Iceberg Spec V4의 목표로 언급했지만, 2025년 5월 현재 이는 아직 개념적인 단계에 머물러 있습니다.(&lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025?utm_source=chatgpt.com&quot;&gt;quesma.com&lt;/a&gt;)&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 블로그 글은 Apache Iceberg의 강력한 기능에도 불구하고, 소규모 데이터 환경에서는 오히려 복잡성과 비효율을 초래할 수 있음을 강조합니다. 따라서 조직의 데이터 규모와 요구 사항에 따라 Iceberg의 도입을 신중히 고려해야 하며, 특히 소규모 데이터셋을 다루는 경우에는 기존의 간단한 형식을 유지하는 것이 더 효율적일 수 있습니다.(&lt;a href=&quot;https://medium.com/%40rames1000/apache-iceberg-the-ultimate-table-format-for-big-data-f63f9b727878?utm_source=chatgpt.com&quot;&gt;Medium&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 글은 아래 링크에서 확인하실 수 있습니다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot;&gt;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748175986892&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;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025 | Apache Iceberg Practical Limitations in 2025&quot; data-og-description=&quot;At Quesma we help customers to innovate faster by re-shaping the way applications are built and connected to their DBs. Quesma database gateway enables development teams to modernise and evolve application architecture.&quot; data-og-host=&quot;quesma.com&quot; data-og-source-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; data-og-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e1UHH/hyYYtvAHUP/h8wyGOdTFZVMKjVcKmJwR1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/bzF7ub/hyYYtvAHOY/8Exf1vUgbwIAXLGHrthji1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/PnfAJ/hyY0ozHIyG/rrHoRvbtlIyp3ToVRZe7RK/img.png?width=2240&amp;amp;height=692&amp;amp;face=0_0_2240_692&quot;&gt;&lt;a href=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://quesma.com/blog-detail/apache-iceberg-practical-limitations-2025&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e1UHH/hyYYtvAHUP/h8wyGOdTFZVMKjVcKmJwR1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/bzF7ub/hyYYtvAHOY/8Exf1vUgbwIAXLGHrthji1/img.png?width=2746&amp;amp;height=1318&amp;amp;face=0_0_2746_1318,https://scrap.kakaocdn.net/dn/PnfAJ/hyY0ozHIyG/rrHoRvbtlIyp3ToVRZe7RK/img.png?width=2240&amp;amp;height=692&amp;amp;face=0_0_2240_692');&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;Don&amp;rsquo;t Let Apache Iceberg Sink Your Analytics: Practical Limitations in 2025 | Apache Iceberg Practical Limitations in 2025&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;At Quesma we help customers to innovate faster by re-shaping the way applications are built and connected to their DBs. Quesma database gateway enables development teams to modernise and evolve application architecture.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;quesma.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Gemini 요약&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;제공해주신 웹페이지는 2025년 아파치 아이스버그(Apache Iceberg)의 실제적인 한계점들에 대해 설명하고 있습니다. 주요 내용은 다음과 같습니다:&lt;/li&gt;
&lt;li&gt;빅데이터 우선 설계, 스몰데이터 사용성 개선 필요: 아이스버그는 본래 페타바이트 규모의 느리게 변화하는 데이터셋을 위해 설계되었기 때문에, 더 작은 규모의 데이터셋을 다루는 조직에게는 불편함이 있을 수 있습니다.&lt;br /&gt;쓰기&amp;nbsp;증폭&amp;nbsp;후&amp;nbsp;메타데이터&amp;nbsp;오버헤드:&amp;nbsp;아이스버그에서&amp;nbsp;업데이트는&amp;nbsp;여러&amp;nbsp;번의&amp;nbsp;쓰기&amp;nbsp;작업을&amp;nbsp;포함하며,&amp;nbsp;이는&amp;nbsp;포스트그레스(Postgres)와&amp;nbsp;같은&amp;nbsp;시스템에&amp;nbsp;비해&amp;nbsp;느릴&amp;nbsp;수&amp;nbsp;있습니다.&amp;nbsp;이&amp;nbsp;문제는&amp;nbsp;업데이트가&amp;nbsp;많을수록&amp;nbsp;악화되어&amp;nbsp;성능&amp;nbsp;유지를&amp;nbsp;위해&amp;nbsp;압축(compaction)&amp;nbsp;작업이&amp;nbsp;필요합니다.&lt;/li&gt;
&lt;li&gt;압축&amp;nbsp;및&amp;nbsp;유지보수&amp;nbsp;비용:&amp;nbsp;데이터&amp;nbsp;및&amp;nbsp;메타데이터&amp;nbsp;파일의&amp;nbsp;정기적인&amp;nbsp;압축은&amp;nbsp;성능을&amp;nbsp;회복하는&amp;nbsp;데&amp;nbsp;필수적이지만,&amp;nbsp;복잡성,&amp;nbsp;지연,&amp;nbsp;비용을&amp;nbsp;추가합니다.&lt;/li&gt;
&lt;li&gt;단편화되고&amp;nbsp;불완전한&amp;nbsp;생태계:&amp;nbsp;아이스버그&amp;nbsp;명세는&amp;nbsp;특정&amp;nbsp;언어에&amp;nbsp;구애받지&amp;nbsp;않지만,&amp;nbsp;대부분의&amp;nbsp;프로덕션&amp;nbsp;코드는&amp;nbsp;여전히&amp;nbsp;자바&amp;nbsp;스택에&amp;nbsp;의존하고&amp;nbsp;있습니다.&amp;nbsp;다른&amp;nbsp;언어로의&amp;nbsp;새로운&amp;nbsp;포팅은&amp;nbsp;JVM&amp;nbsp;참조&amp;nbsp;구현에&amp;nbsp;비해&amp;nbsp;뒤쳐져&amp;nbsp;있습니다.&amp;nbsp;또한&amp;nbsp;일부&amp;nbsp;쿼리&amp;nbsp;엔진은&amp;nbsp;쓰기&amp;nbsp;지원이&amp;nbsp;부족하거나&amp;nbsp;아이스버그&amp;nbsp;사용&amp;nbsp;시&amp;nbsp;성능&amp;nbsp;격차가&amp;nbsp;발생할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/li&gt;
&lt;li&gt;비정형&amp;nbsp;데이터,&amp;nbsp;넓은&amp;nbsp;테이블:&amp;nbsp;아이스버그는&amp;nbsp;잘&amp;nbsp;정의된&amp;nbsp;스키마에&amp;nbsp;가장&amp;nbsp;적합하며,&amp;nbsp;비정형&amp;nbsp;데이터와&amp;nbsp;넓은&amp;nbsp;테이블(컬럼이&amp;nbsp;매우&amp;nbsp;많은&amp;nbsp;테이블)에는&amp;nbsp;한계가&amp;nbsp;있습니다.&lt;/li&gt;
&lt;li&gt;거버넌스&amp;nbsp;및&amp;nbsp;보안은&amp;nbsp;대부분&amp;nbsp;범위&amp;nbsp;밖:&amp;nbsp;아이스버그는&amp;nbsp;데이터&amp;nbsp;거버넌스나&amp;nbsp;보안&amp;nbsp;정책을&amp;nbsp;직접&amp;nbsp;처리하지&amp;nbsp;않으므로,&amp;nbsp;상위&amp;nbsp;계층에서&amp;nbsp;구현해야&amp;nbsp;합니다.&lt;/li&gt;
&lt;li&gt;제한된&amp;nbsp;쓰기&amp;nbsp;동시성:&amp;nbsp;아이스버그의&amp;nbsp;동시성&amp;nbsp;모델은&amp;nbsp;분당&amp;nbsp;커밋&amp;nbsp;수를&amp;nbsp;제한하므로&amp;nbsp;OLTP(온라인&amp;nbsp;트랜잭션&amp;nbsp;처리)&amp;nbsp;스타일의&amp;nbsp;워크로드에는&amp;nbsp;적합하지&amp;nbsp;않습니다.&lt;/li&gt;
&lt;li&gt;제한된&amp;nbsp;실시간&amp;nbsp;기능:&amp;nbsp;아이스버그는&amp;nbsp;즉각적인&amp;nbsp;가시성보다&amp;nbsp;원자적&amp;nbsp;배치&amp;nbsp;트랜잭션을&amp;nbsp;우선시하므로&amp;nbsp;실시간&amp;nbsp;또는&amp;nbsp;거의&amp;nbsp;실시간&amp;nbsp;데이터가&amp;nbsp;필요한&amp;nbsp;사용&amp;nbsp;사례에는&amp;nbsp;덜&amp;nbsp;적합합니다.&lt;/li&gt;
&lt;li&gt;데이터&amp;nbsp;반출&amp;nbsp;비용:&amp;nbsp;클라우드에서&amp;nbsp;데이터를&amp;nbsp;옮기는&amp;nbsp;데&amp;nbsp;드는&amp;nbsp;높은&amp;nbsp;비용은&amp;nbsp;특정&amp;nbsp;공급업체에&amp;nbsp;머무르게&amp;nbsp;하는&amp;nbsp;유인이&amp;nbsp;될&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;이는&amp;nbsp;아이스버그의&amp;nbsp;이식성이라는&amp;nbsp;장점을&amp;nbsp;제한할&amp;nbsp;수&amp;nbsp;있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1243</guid>
      <comments>https://118k.tistory.com/1243#entry1243comment</comments>
      <pubDate>Sun, 25 May 2025 21:30:33 +0900</pubDate>
    </item>
    <item>
      <title>[ubuntu] crontab 정보가 설정된 파일을 이용한 크론잡 실행</title>
      <link>https://118k.tistory.com/1242</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;서버 초기화시 crontab -e 명령을 이용하지 않고, 정보가 설정된 파일을 이용하여 크론잡을 실행할 수 있습니다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/etc/cron.d/ 아래에 파일을 생성합니다. &lt;/li&gt;
&lt;li&gt;이 파일은 crontab -e 로 작성하는 내용과 동일하게 생성하면 되는데, 꼭 실행하는 사용자를 입력해야 합니다. &lt;/li&gt;
&lt;li&gt;다음과 같이 실행하고자 하는 사용자 root 를 꼭 입력해야 합니다. 다른 유저로 실행하려면 해당 유저의 이름을 입력하면 됩니다. &lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1748175439036&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# /etc/cron.d/metastore
* * * * * root /usr/local/bin/metastore-script.sh &amp;gt;&amp;gt; /var/log/metastore.log 2&amp;gt;&amp;amp;1&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;/p&gt;</description>
      <category>리눅스</category>
      <category>crontab</category>
      <category>ubuntu</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1242</guid>
      <comments>https://118k.tistory.com/1242#entry1242comment</comments>
      <pubDate>Sun, 25 May 2025 21:18:58 +0900</pubDate>
    </item>
    <item>
      <title>[hbase] phoenix 연계 및 실행 방법</title>
      <link>https://118k.tistory.com/1241</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Apache Phoenix는 &lt;b&gt;HBase 위에서 SQL 쿼리를 사용할 수 있게 해주는 오픈소스 프로젝트&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;HBase라는 NoSQL 데이터베이스 위에 RDBMS 스타일의 SQL 인터페이스를 제공&lt;/b&gt;하는 레이어입니다. &lt;/p&gt;
&lt;p data-start=&quot;211&quot; data-end=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;원래 HBase는 Key-Value 기반의 비정형 테이블이어서 SQL 같은 쿼리 언어가 없는데, Phoenix는 HBase의 데이터를 &lt;b&gt;JDBC를 통해 SQL로 조회하거나 수정&lt;/b&gt;할 수 있게 해주는 도구입니다.&lt;/p&gt;
&lt;p data-start=&quot;211&quot; data-end=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-start=&quot;211&quot; data-end=&quot;329&quot; data-ke-size=&quot;size26&quot;&gt;설치&lt;/h2&gt;
&lt;p data-start=&quot;211&quot; data-end=&quot;329&quot; data-ke-size=&quot;size16&quot;&gt;HBase 2.6에 Phoenix 5.2.1 을 설치 하는 방법은 ${HBASE_HOME}/lib 아래에 Phoenix 라이브러리를 추가 하면 됩니다. ${PHOENIX_HOME}/phoenix-server-hbase-2.6-5.2.1.jar 의 라이브러리를 ${HBASE_HOME}/lib 아래로 추가합니다. &lt;/p&gt;
&lt;p data-start=&quot;211&quot; data-end=&quot;329&quot; 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;스크린샷 2025-05-17 오후 6.55.20.png&quot; data-origin-width=&quot;2288&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0GGDZ/btsN2mtihuD/Gj8qD6WTIKMBOIDJ7S29n0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0GGDZ/btsN2mtihuD/Gj8qD6WTIKMBOIDJ7S29n0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0GGDZ/btsN2mtihuD/Gj8qD6WTIKMBOIDJ7S29n0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0GGDZ%2FbtsN2mtihuD%2FGj8qD6WTIKMBOIDJ7S29n0%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;2288&quot; height=&quot;360&quot; data-filename=&quot;스크린샷 2025-05-17 오후 6.55.20.png&quot; data-origin-width=&quot;2288&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실행 &lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리를 추가 하고 나면 HBase 를 재시작해야 합니다. HMaster와 RegionServer 를 재시작하여 실행합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;${PHOENIX_HOME}/bin/sqlline.py localhost:2181 와 같이 실행하여 피닉스가 실행되는 것을 확인할 수 있습니다. 피닉스가 실행되면 메타 정보가 자동으로 추가 되고, SELECT 1 명령을 이용해서 동작을 확인할 수 있습니다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1747476129854&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sqlline.py $(hostname -f):2181

CREATE TABLE example_phoenix (
    id INTEGER PRIMARY KEY,
    name VARCHAR,
    age INTEGER
);

UPSERT INTO example_phoenix (id, name, age) VALUES (1, 'Alice', 30);

SELECT * FROM example_phoenix;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;오류 상황 &lt;/h2&gt;
&lt;pre id=&quot;code_1747476225651&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;2025-05-16 13:32:35,228 INFO  [task-truncated-0] client.RpcRetryingCallerImpl: Call exception, tries=12, retries=46, started=68455 ms ago, cancelled=false, msg=no meta location available, details=row 'SYSTEM.CATALOG' on table 'hbase:meta' at null, see https://s.apache.org/timeout
2025-05-16 13:32:39,621 ERROR [RpcServer.priority.RWQ.Fifo.read.handler=10,queue=4,port=16020] coprocessor.MetaDataEndpointImpl: createTable failed
org.apache.hadoop.hbase.client.RetriesExhaustedException: Cannot get the location for replica0 of region for \x00\x00EXAMPLE_PHOENIX in SYSTEM.CHILD_LINK&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;피닉스를 실행하면서 이런 오류가 발생하면서 sqlline.py 가 행이 걸리는 오류가 있었습니다. 오류상으로는 통신이 되지 않는 상황 같았지만 리전서버를 재시작하면 다시 동작하였습니다. 라이브러리 추가후 재시작하고, 동작이 이상하면 다시 한번 재시작하면 동작할 수 있습니다. &lt;/p&gt;</description>
      <category>빅데이터/hbase</category>
      <category>hbase</category>
      <category>Phoenix</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1241</guid>
      <comments>https://118k.tistory.com/1241#entry1241comment</comments>
      <pubDate>Sat, 17 May 2025 19:06:44 +0900</pubDate>
    </item>
    <item>
      <title>[java] 객체 생성의 form, of, builder 비교</title>
      <link>https://118k.tistory.com/1240</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 객체를 생성할 때 사용하는 from, of, builder 패턴을 비교해 보겠습니다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;of: 엔티티의 필수 데이터를 이용하여 객체를 생성할 때 사용 &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;객체&amp;nbsp;생성에&amp;nbsp;필요한&amp;nbsp;필수&amp;nbsp;인자가&amp;nbsp;명확하고,&amp;nbsp;불변&amp;nbsp;객체를&amp;nbsp;만들거나&amp;nbsp;간단한&amp;nbsp;유효성&amp;nbsp;검사를&amp;nbsp;수행하고&amp;nbsp;싶을&amp;nbsp;때&amp;nbsp;유용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1745156623450&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static User of(String username, String email) { // 필수 필드
    return new User(null, username, email);
}

public static Color of(int red, int green, int blue) {
    return new Color(red, green, blue);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;from: 다른 객체로부터 객체를 생성할 때 주로 사용 &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른&amp;nbsp;객체나&amp;nbsp;데이터&amp;nbsp;구조로부터&amp;nbsp;엔티티&amp;nbsp;객체를&amp;nbsp;생성하거나&amp;nbsp;매핑하는&amp;nbsp;로직을&amp;nbsp;명확하게&amp;nbsp;분리하고&amp;nbsp;싶을&amp;nbsp;때&amp;nbsp;사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1745156642212&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static User from(UserDto userDto) {
    return new User(null, userDto.getUsername(), userDto.getEmail());
}

public static Order from(ResultSet rs) throws SQLException {
    return new Order(rs.getLong(&quot;id&quot;), rs.getString(&quot;orderNumber&quot;), ...);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;builder: 속성이 많은 객체를 단계별로 생성할 때 사용 &lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성해야&amp;nbsp;할&amp;nbsp;객체의&amp;nbsp;속성이&amp;nbsp;많거나&amp;nbsp;선택적인&amp;nbsp;속성이&amp;nbsp;많아&amp;nbsp;생성자의&amp;nbsp;파라미터가&amp;nbsp;늘어나는&amp;nbsp;것을&amp;nbsp;방지하고,&amp;nbsp;객체&amp;nbsp;생성&amp;nbsp;과정을&amp;nbsp;더&amp;nbsp;명확하고&amp;nbsp;유연하게&amp;nbsp;관리하고&amp;nbsp;싶을&amp;nbsp;때&amp;nbsp;사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1745156679679&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Computer {
    private String cpu;
    private String ram;
    private String storage;
    private String graphicsCard; // 선택적

    private Computer(Builder builder) {
        this.cpu = builder.cpu;
        this.ram = builder.ram;
        this.storage = builder.storage;
        this.graphicsCard = builder.graphicsCard;
    }

    public static class Builder {
        private String cpu;
        private String ram;
        private String storage;
        private String graphicsCard;

        public Builder(String cpu, String ram, String storage) { // 필수 필드
            this.cpu = cpu;
            this.ram = ram;
            this.storage = storage;
        }

        public Builder graphicsCard(String graphicsCard) { // 선택적 필드
            this.graphicsCard = graphicsCard;
            return this;
        }

        public Computer build() {
            return new Computer(this);
        }
    }

    // Getter 생략

    public static void main(String[] args) {
        Computer myComputer = new Computer.Builder(&quot;Intel i7&quot;, &quot;16GB&quot;, &quot;512GB SSD&quot;)
                .graphicsCard(&quot;NVIDIA RTX 3060&quot;)
                .build();

        Computer basicComputer = new Computer.Builder(&quot;Intel i5&quot;, &quot;8GB&quot;, &quot;256GB HDD&quot;)
                .build();
    }
}&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;</description>
      <category>java/디자인패턴</category>
      <category>java</category>
      <author>hs_seo</author>
      <guid isPermaLink="true">https://118k.tistory.com/1240</guid>
      <comments>https://118k.tistory.com/1240#entry1240comment</comments>
      <pubDate>Sun, 20 Apr 2025 22:44:48 +0900</pubDate>
    </item>
  </channel>
</rss>