2장 카프카 환경 구성

2-1. 책의 실습 환경 구성

책에서는 aws 내에서 실습환경을 구성하였으나,

GCP의 무료크레딧을 사용하여 환경을 구성하기로 했다...(금전 이슈ㅠ)

1) 인스턴스 생성

GCP의 인스턴스 그룹을 사용해서 7개의 인스턴스를 통합적으로 생성, 관리하기로 했다.

(아 테라폼 안쓴다 오예)

내가 만든 인스턴스들

2) hosts 파일 수정하기 & ansible을 위한 ssh 키 복사

DNS를 사용하기에는 실습환경에서는 굳이라는 생각이 들어 사용하지 않았다.

차라리 그돈으로 일주일 더 학습하는 것이..

그래서 hosts파일을 수정해서 사용하기로 했다.

ansible용으로 하나, 주키퍼 3대, 카프카 3대로 구성했다.

sudo nano /etc/hosts
<내부ip> peter-ansible01.foo.bar
<내부ip> peter-zk01.foo.bar
<내부ip> peter-zk02.foo.bar
<내부ip> peter-zk03.foo.bar
<내부ip> peter-kafka01.foo.bar
<내부ip> peter-kafka02.foo.bar
<내부ip> peter-kafka03.foo.bar

 

자 이제 ansible으로 카프카를 설치할 것이므로 ssh로 각 인스턴스들을 연결할 수 있도록 해야 한다.

ssh키를 scp 명령을 이용해 ansible 인스턴스에 전송한다.

scp -i keypair.pem keypair.pem key@<ansible01-ip>

 

키를 보냈다면 사용을 위해서 키의 권한을 조정하고

등록하는 과정이 필요하다. 

# 키 권한 조정
chmod 600 keypair.pem
# 키 등록
ssh-agent bash
ssh-add keypair.pem

 

마지막으로 모든 작업이 끝나면 git을 이용해서 예제 파일을 다운로드 한다.

(실습 환경설정 완료?)

git clone https://github.com/onlybooks/kafka2

 

 

2-2. 카프카 클러스터 구성

1) common role 편집 (yum → apt)

책에서는 amazon-linux 또는 centOS를 추천하나 GCE에서 해당 환경이 이용 불가하므로 Ubuntu에서 진행....

이에 yum 코드를 apt를 사용하는 코드로 변경해 주는 작업이 필요했다.

 

따라서 roles/common/tasks/main.yml 파일을 수정할 필요가 있다.

# 변경 코드
---
- name: Set timezone to Asia/Seoul
  timezone:
    name: Asia/Seoul

- name: Install Java and tools
  apt:
    name:
      - dstat
      - openjdk-8-jdk
      - openjdk-8-jdk-headless
      - krb5-user
      - git
    state: latest
    update_cache: yes

- name: Copy krb5.conf
  template:
    src: krb5.conf.j2
    dest: /etc/krb5.conf
    owner: root
    group: root
    mode: '0644'
    backup: no

코드를 변경하고 정상적으로 설치가 진행되었다!

 

2) 주키퍼 & 카프카 설치

책의 설명대로 주키퍼와 카프카를 설치한다.

실습 파일을 뜯어보면 간단한 코드니까

저자를 위해서 해당 코드는 공개하지 않는다!

 

주키퍼 설치완료!
카프카 설치 완료!

2-3. 카프카 맛보기

2장의 마지막에는 카프카 토픽을 생성하고

컨슈머와 프로듀서를 실행해 간단한 실습을 수행하는 부분이 나와있다.

정말 간단하니까 실습을 해보는 것을 추천하고

마지막은 내가 실습했던 사진을 첨부한다.

 

마지막으로 내가 참고했던 글들을 가져왔다.

 

실시간 처리에 대해서 관심이 있었던지라 카프카 스터디에 참여해 실시간 데이터 수집에 대해 공부하기 시작했다.

작성할 내용들은 카프카 스터디를 통해서 알게 된 내용들을 적고 실습한 내용을 같이 채우고자 한다.

1장 카프카 개요

카프카의 도입 사례, 주요 특징, 성장에 대해서 가볍게 짚고 넘어간다.

조금씩 뜯어보면서 어떤 부분이 중요한지 살펴보자

 

1-1. 카프카 도입 사례 및 이용 현황

책에서는 잘란도라는 기업(처음 들어봤다..)과 트위터의 도입 사례를 설명한다.

잘란도는 독일의 무신사(?) 같은 느낌의 기업이라고 한다. 궁금해서 웹 페이지를 들어가 봤는데..

그린 고블린 형님께서..!

(여튼 트위터는 X로 바뀌고.. 다들 많이 아니까 패스!)

 

잘란도의 도입배경은 이러하다.

 

'데이터 변화가 스트림으로 컨슈머에 전달되는 이벤트 드리븐 시스템으로의 전환'

 

이를 목적으로 여러 시도들을 진행했는데..!

바운드 아웃바운드 데이터의 일치성 검증, 통신 방법에 대한 선택과 같은 다각적 고민 
->

동기화 방식의 CRUD를 채택했으나, 한계점에 봉착했다. 이유는 다양한 클라이언트들의 요구사항을 효율적으로 지원하기 어렵다는 것.

빠른 전송을 위한 클라이언트 또는 대량의 배치 전송을 위한 클라이언트를 지원하기 어려움

 

위와 같은 문제들에 봉착하고 말았다. 그래서 꺼내든 것은 바로 카프카! 

그 이유들은 카프카의 주요 특징들에 담겨있으니 아래에서 한 번에 설명하고자 한다.

1-2. 카프카 주요 특징

높은 처리량과 낮은 지연시간

카프카는 매우 높은 처리량과 낮은 지연시간을 자랑한다고 한다.

 

다른 MQ들과 비교했는데..

래빗 MQ의 경우 응답속도가 가장 빠르나, 처리량이 늘어나면 카프카가 독보적이라고 한다.

펄사의 경우는 서버 간의 메시징을 위한 멀티테넌트 고성능 솔루션이라고..(?)

(GPT:티 테넌트(Multi-tenant)는 소프트웨어 아키텍처 모델로,
여러 고객(테넌트)이 단일 소프트웨어 인스턴스를 공유하는 방식을 말합니다. )

 

추가로 관련 자료를 가져왔다.

카프카, 펄사, 래빗 MQ 비교: https://www.confluent.io/blog/kafka-fastest-messaging-system/

 

Benchmarking RabbitMQ vs Kafka vs Pulsar Performance

A complete benchmark of RabbitMQ, Kafka, and Pulsar to determine performance, throughput, and latency at scale. View the comparison results!

www.confluent.io

Apache Pulsar 소개: https://devocean.sk.com/blog/techBoardDetail.do?ID=164597&boardType=techBlog

 

Open Source 기반 Messaging Platform - Apache Pulsar 소개

 

devocean.sk.com

 

높은 확장성

카프카는 손쉬운 확장이 가능하도록 설계되었다고 한다.

프로듀서와 컨슈머를 생성해서 넣으면 되니까..?라고 생각한다.

여튼 링크드인에서는 확장이 필요서 해당 부분을 고려해 설계했다고 한다.

 

고가용성

클러스터 내 리플리케이션 기능을 통해서 고가용성을 확보했다.

 

내구성

acks옵션을 이용해서 메시지 내구성을 강화했다.

 

개발편의성, 운영 및 관리의 편의성

프로듀서와 컨슈머가 완벽하게 분리되어 동작해 원하는 부분만 개발해 사용가능하다.

또한 개발 편의성을 위해 카프카 커넥트와 스키마 레지스트리를 지원한다.

 

 

자..

마지막으로 카프카는 Apache Kafka와 Confluent 카프카가 있는데 이를 비교한 글이 컨플루언트에 있어서 가져와보았다.

https://www.confluent.io/ko-kr/apache-kafka-vs-confluent/

 

Apache Kafka vs. Confluent: 특징 및 기능 비교 | KR

Kafka and Confluent have numerous differences. Here's a side-by-side comparison of Confluent vs Kafka: features, connectors, clients, performance, scalability, and more.

www.confluent.io

 


책을 읽으면서 제로카피, 이벤트 버스 패턴, 람다 아키텍처와 같이 기존에 알지 못했던 지식들이 나와
CS공부를 함에 있어서도 많은 도움이 되리라 생각한다.

 

이번 기회로 카프카를 공부해 보고 실제 환경에서 데이터를 가져오는 방법으로 카프카를 고려할 수 있는 역량을 길러보고자 한다.

'Data Engineering > kafka' 카테고리의 다른 글

kafka > 실전 카프카 개발부터 운영까지 2장  (3) 2024.10.15

SIGTERM이란?

  • 유닉스 기반의 프로세스 종료 신호
  • SIG_KILL과 반대
  1. 정의와 목적:
    • SIGTERM은 프로세스에게 정상적으로 종료할 것을 요청하는 신호.
    • 프로세스가 자원을 정리하고 안전하게 종료할 수 있도록 하는 "부드러운" 종료 방식이다.
  2. 신호 번호:
    • SIGTERM의 표준 신호 번호는 15이다.
  3. 동작 방식:
    • 프로세스는 SIGTERM을 받으면 정리 작업을 수행한 후 종료
    • 프로세스는 이 신호를 무시하거나 다르게 처리하도록 프로그래밍될 수 있다.
  4. 사용 사례:
    • 시스템 종료 시: 운영 체제가 종료될 때 실행 중인 프로세스들에게 SIGTERM을 보냅니다.
    • 프로세스 관리: 관리자나 사용자가 프로세스를 정상적으로 종료하고자 할 때 사용합니다.
    • 컨테이너 환경: Docker나 Kubernetes에서 컨테이너를 정상 종료할 때 SIGTERM을 사용합니다.
  5. SIGKILL과의 차이:
    • SIGTERM은 프로세스가 정리 작업을 수행할 기회를 제공하지만, SIGKILL(신호 번호 9)은 즉시 강제 종료한다.
    • SIGTERM은 프로세스가 무시할 수 있지만, SIGKILL은 무시할 수 없다.
  6. 프로그래밍에서의 처리:
    • 프로그래머는 SIGTERM 핸들러를 구현하여 프로세스가 이 신호를 받았을 때의 동작을 정의할 수 있습니다.
    • 일반적으로 열린 파일을 닫고, 네트워크 연결을 정리하고, 임시 파일을 삭제하는 등의 작업을 수행합니다.
  7. 시스템 동작:
    • 프로세스가 SIGTERM을 받고 일정 시간 내에 종료되지 않으면, 시스템은 SIGKILL을 보내 강제 종료할 수 있습니다.
  8. 명령어 사용:
    • Unix/Linux 시스템에서 'kill' 명령어를 사용하여 SIGTERM을 보낼 수 있습니다. (예: kill -15 [PID] 또는 단순히 kill [PID])
  9. 그레이스풀 셧다운(Graceful Shutdown):
    • SIGTERM은 그레이스풀 셧다운을 구현하는 데 주로 사용됩니다. 이는 프로세스가 진행 중인 작업을 완료하고 리소스를 정리한 후 종료되도록 합니다.

SIGTERM은 프로세스를 안전하게 종료하기 위한 표준적인 방법으로, 시스템 관리와 애플리케이션 개발에서 중요한 역할을 합니다.

간단한 코드로 수행해 보기

코드

import signal
import time
import sys

def signal_handler(signum, frame):
    print("Received SIGTERM. Cleaning up...")
    # 여기에 정리 작업을 수행하는 코드를 작성합니다.
    # 예: 파일 닫기, 네트워크 연결 종료 등
    print("Cleanup finished. Exiting.")
    sys.exit(0)

def main():
    # SIGTERM 신호에 대한 핸들러 등록
    signal.signal(signal.SIGTERM, signal_handler)

    print("Process started. PID:", os.getpid())
    print("Press Ctrl+C to exit")

    try:
        # 무한 루프로 프로세스 실행 상태 유지
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Received KeyboardInterrupt. Exiting.")

if __name__ == "__main__":
    main()

결과

  • kill -TERM <PID>를 수행한 경우 (-15도 가능하다.)

  • kill -9 <PID> 를 수행한 경우

SIGTERM 무시 및 다른 대안으로 교체

SIGTERM을 무시하거나 다른 작업을 수행하도록 만들어보는 경우에 다음 명령을 사용할 수 있다.

import signal

# SIGTERM 신호를 무시하도록 설정
signal.signal(signal.SIGTERM, signal.SIG_IGN)
import signal
import sys

def sigterm_handler(signum, frame):
    print("SIGTERM 신호를 받았지만, 프로그램을 계속 실행합니다.")

signal.signal(signal.SIGTERM, sigterm_handler)

참고

SIGKILL vs SIGTERM 리눅스 종료 신호

 

SIGKILL vs SIGTERM 리눅스 종료 신호

우리가 만든 서버 프로그램은 리눅스 서버의 한 프로세스로 동작 합니다.고로, 프로세스로 구동하는 모든 프로그램들, 예) 도커, nginx, node.js, Mysql 등의 종료에 관한 메커니즘을 이해 한다면, 장

velog.io

문제 상황

Windows에서 정상적으로 실행되던 셀레니움을 linux환경으로 이식하면서 headless옵션으로 변경 시 다음과 같은 에러가 발생했다.

no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[1]/link[2]"}

 

 

Youtube 페이지의 정보를 정상적으로 읽어오지 못한 문제가 발생했다.

해결 시도

참고) 요소가 뜰 때까지 기다린다거나 time.sleep을 한다거나 하는 이슈는 모두 실패로 돌아갔습니다.

Change window size

linux에서 모바일 사이즈의 창으로 변경되면서 Window size에 영향을 받는 요소들이 나타났다.

따라서 윈도우 사이즈를 조정해서 해결을 시도하였다.

chrome_options.add_argument("--window-size=1920,1080")

→ 결과는 실패.. 다른 원인이 있는 것 같다.

참고로 linux에서는 chrome_options.add_argument("--start-maximized") 옵션이 적용되지 않는다고 한다.

Blocks ‘headless’ mode

headless모드로 크롤링을 수행하면 user_agent가 자동으로 HeadlessChrome으로 변경되어 수행된다고 한다.

그런데 특정사이트에서는 이를 막아두는 경우가 발생한다고 하니.. 다음 블로그를 참고하여 user_agent를 하드코딩 해주었다.

user_agent = Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36
chrome_options.add_argument(f'user-agent={user_agent}')

[Debuging] Selenium을 이용한 자동 로그인 모듈에서 Headless 모드에서만 No Such Element 에러 날 때

 

[Debuging] Selenium 을 이용한 자동 로그인 모듈에서 Headless 모드에서만 No Such Element 에러 날때

Selenium을 이용해서 구글에 자동로그인을 하는 프로그램을 만들던 도중 그냥 할때는 잘되는데, Headless 설정만 해주면 Element들을 못 찾는 문제가 발생했다 . 왜 그런지 검색을하다가 알게된 사실은

devkingdom.tistory.com

→ 이것도 실패했다..

SSL 인증서 무시

잘못된 ssl 인증서가 원인이 될 수 있다는 글을 보았다. 따라서 다음 옵션으로 인증서를 무시하고 진행하도록 했다.

chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--allow-running-insecure-content')

→ 실패

Proxy 적용(추가)

Azure에서 크롤링이 안되면 프록시를 사용해서 우회해보자 라는 생각으로 도전했습니다.

무료 프록시를 넣어서 수행해 보았으나..
https 접속을 막은 프록시들도 많았으며, 구글에서도 대부분의 프록시 접속을 제한해 둔 상태였습니다.

chrome_options.add_argument("--proxy-server='proxy_ip:port'")

→ 실패!

추가적으로 적용 가능한 옵션들

연이은 실패에 힘입어..(?) extension을 사용하지 않는다던가 프록시서버 옵션을 넣어준다던가 추가적으로 다른 사람들이 진행했다는 옵션들을 모두 가져와 넣어주었다..

chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--proxy-bypass-list=*")
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--no-sandbox')

→ 실패..

결과적으로 시도한 모든 방법들이 실패했다…

 

결과

로컬에서 진행 시 무리없이 작동하였으나, ec2나 azure VM에서 에러가 발생했다.

IP주소가 원인이라 생각하는데 프록시까지 사용해서 크롤링을 수행하기에는 무료 프록시의 경우 대다수가 막혀있어 의미가 없다.

youtube의 경우 API를 지원하니 이를 이용해서 데이터를 수집하면 될것같다.

 

셀레니움에서 적용가능한 옵션들을 나열해두어 나중에 사용할 기회가 있다면 위 옵션들을 참고하면 좋을 듯 하다.

 

 

참고 문헌

[Debuging] Selenium 을 이용한 자동 로그인 모듈에서 Headless 모드에서만 No Such Element 에러 날때

 

[Debuging] Selenium 을 이용한 자동 로그인 모듈에서 Headless 모드에서만 No Such Element 에러 날때

Selenium을 이용해서 구글에 자동로그인을 하는 프로그램을 만들던 도중 그냥 할때는 잘되는데, Headless 설정만 해주면 Element들을 못 찾는 문제가 발생했다 . 왜 그런지 검색을하다가 알게된 사실은

devkingdom.tistory.com

Making Chrome Headless Undetectable

 

Making Chrome Headless Undetectable

Using MitmProxy and injected JavaScript feature mocks to bypass Headless Chrome detection tests.

intoli.com

Headless is Going Away!

 

Headless is Going Away!

Now that we got your attention, headless is not actually going away, just the convenience method to set it in Selenium

www.selenium.dev

Unable to locate elements on webpage with headless chrome

 

Unable to locate elements on webpage with headless chrome

I have a script that's accessing printers, and my code works totally fine when chrome is run normally, but when it's run headless, selenium can't seem to find elements on the webpage. Here's the

stackoverflow.com

 

'Python' 카테고리의 다른 글

Web Scraping - python  (1) 2024.03.15

+ Recent posts