[Kubernetes] 쿠버네티스에서 POD(파드)? 그리고 POD 생성하기

 

l  Kubernetes

 

파드(Pod) 쿠버네티스에서 생성하고 관리할 있는 배포 가능한 가장 작은 컴퓨팅 단위이다. 도커가 가장 일반적으로 알려진 컨테이너 런타임이지만, 쿠버네티스는 도커 외에도 다양한 컨테이너 런타임을 지원한다.

 

파드는 하나 이상의 컨테이너의 그룹이며 스토리지 네트워크를 공유하고, 해당 컨테이너를 구동하는 방식에 대한 명세를 갖는다. 파드의 컨텐츠는 항상 함께 배치되고, 스케줄되며, 공유 컨텍스트에서 실행된다. , 파드는 공유 네임스페이스와 공유 파일시스템 볼륨이 있는 컨테이너들의 집합과 비슷하다.

 

파드는 애플리케이션의 "논리 호스트" 모델링한다. 여기에는 상대적으로 밀접하게 결합된 하나 이상의 애플리케이션 컨테이너가 포함된다. 클라우드가 아닌 컨텍스트에서, 동일한 물리 또는 가상 머신에서 실행되는 애플리케이션은 동일한 논리 호스트에서 실행되는 클라우드 애플리케이션과 비슷하다.

 

애플리케이션 컨테이너와 마찬가지로, 파드에는 파드 시작 중에 실행되는 초기화 컨테이너가 포함될 있다. 클러스터가 제공하는 경우, 디버깅을 위해 임시 컨테이너를 삽입할 수도 있다. 쿠버네티스에서는 이러한 파드를 생성하기 위한 방법으로 kubectl run, kubectl create, kubectl apply 3가지가 있다. 각의 특징에 대해서 알아본다.

 

[kubectl run]

kubectl run kubernetes 클러스터에서 파드나 작업을 생성하는 명령어이다. 가장 간단하게 pod 만드는 방식이며, 실행 명령어 뒤에 각종 옵션 정보를 입력해서 생성한다. 가장 간편한 실행 방법인 반면 입력 정보가 남지 않기 때문에 재실행 문제가 발생했을 원인을 찾거나 해결 방법을 공유하는 등의 어려움이 있다. 일반적인 개발 단계에서 간편하게 pod 생성할 유용하지만 많은 옵션을 함께 사용해야 경우 모든 명령어를 입력해야하기 때문에, yaml 작성하여 사용하는 것이 일반적이다. 기본 구조는 아래와 같다.

Kubectl run [파드이름] –image=[이미지 이름]

 

아래 예시는 파드 생성시 실행할 이미지를 지정한다.

kubectl run nginx --image=nginx

 

아래 예시는 실행할 파드의 개수를 지정한다. Nginx 이미지를 사용하여 3개의 파드를 생성한다. 파드가 중간에 삭제되면 지정한 개수만큼 파드가 유지되도록 파드가 자동 생성된다.

kubectl run nginx --image=nginx --replicas=3

 

아래 예시는 파드를 생성할 포트 번호를 노출시킨다.

kubectl run nginx --image=nginx --port=80

 

아래 예시는 파드를 생성할 다양한 환경변수를 대입하여 파드를 실행한다.

kubectl run my-proxysql --image=my-proxysql --port=6033 --image-pull-policy=Never --restart=Never --env PROXY_ADMIN_PWD=pwd --env PROXY_ADMIN_ID=id

 

 

[kubectl create]

Kubectl create 명령은 kubernetes에서 새로운 리소스를 생성할 사용한다. 명령을 사용하면 yaml파일을 생성하지 않고도 명령어 자체에서 리소스를 생성할 있다. 기본구조는 아래와 같다.

kubectl create [리소스 종류] [리소스 이름]

 

아래 예시는 Nginx 이미지를 사용하는 my-nginx라는 pod 리소스를 생성한다.

kubectl create pod my-nginx --image=nginx

 

아래 예시는 Nginx 이미지를 사용하는 my-deployment 이름을 가진 Deployment 리소스를 생성한다.

Kubectl create deployment my-deployment --image=nginx

 

아래 예시는 80포트를 8080으로 매핑하는 my-service라는 이름의 ClusterIP 서비스 리소스를 생성한다.

Kubectl create service clusterip my-service --tcp=80:8080

 

아래 예시는 key1=value1, key2=value2 데이터를 가진 my-config 이름을 가진 ConfigMap 리소스를 생성한다.

kubectl create configmap my-config --from-literal=key1=value1 --from-literal=key2=value2

 

아래 예시는 password=1234데이터를 가진 my-secret 이름의 secret 리소스를 생성한다.

Kubectl create secret generic my-secret --from-literal=password=1234

 

아래 예시는 리소스를 생성하지 않고 생성 결과만 미리 확인한다.

kubectl create deployment my-deployment --image=nginx --dry-run

 

아래 예시는 파일(yaml 또는 json) 사용하여 리소스를 생성한다.

kubectl create -f test.yaml

 

아래 예시는 리소스가 생성될 네임스페이스를 지정한다.

Kubectl create deployment my-deployment --image=nginx -n my-namespace

 

아래 예시는 컨테이너의 재시작 정책을 지정한다. 상태는 Always, OnFailure, Never 하나를 사용한다.

Kubectl create pod my-pod --image=nginx --restart-policy=OnFailure

 

 

[kubectl apply]

kubectl apply kubectl create 동일하지만 가장 차이점은 기존에 동일한 pod 없다면 새로운 pod 생성하고, 이미 동일한 pod 존재하는 경우 기존 config 비교하여 수정된 부분만 업데이트 한다.

 

 

[kubectl delete]

파드나 리소스를 삭제하기 위해서는 kubectl delete 명령을 사용한다. 기본 구조는 아래와 같다.

Kubectl delete [리소스 유형] [리소스 이름]

 

아래 예시는 nginx라는 파드를 삭제한다.

kubectl delete pod nginx

 

삭제할 다양한 옵션을 함께 사용할 있다.

l  --all : 모든 리소스를 삭제

l  --force : 강제로 삭제

l  ---grace-period=<second> : 대기시간() 이후 삭제 설정

l  --timeout=<second> : 명령이 실행될 대기할 최대 시간() 설정

 

 

 

2023-09-08 / Sungwook Kang / https://sungwookkang.com

 

 

Kubernetes, 쿠버네티스, pod, 파드, kubectl, create, delete, apply, 파드생성, 리소스 생성

[kubernetes] minikube에서 로컬 docker image 사용하기

 

l  Kubernetes, Docker

 

일반적으로 로컬 컴퓨터에서 쿠버네티스(Kubernetes) 테스트할 minikube 환경을 많이 사용한다. 도커 데스크탑(docker desktop) 설치된 환경에서도 쿠버네티스를 활성화하면 minikube 활성화되어 동작한다. 이러한 환경에서 kubectl run 또는 yaml 파드를 생성할 , 로컬의 이미지를 사용할 경우 이미지를 가져올 없다는 오류와 함께 파드가 생성된 종료된다. 이번 포스트에서는 minikube 환경에서 로컬의 docker image 사용하여 파드를 생성하는 방법을 알아본다.

 

로컬의 docker images에서 커스텀 빌드된 이미지 proxysql 있다.

 

로컬의 도커 이미지를 사용하여 파드를 생성하면 오류가 발생한다.

kubectl run my-proxysql --image=proxysql

 

 

오류를 살펴보면 ErrImagePull이라는 상태 메시지를 있는데, 상태를 자세히 확인하기 위해 kubectl describe 명령을 사용하여 상세 메시지를 확인한다.

kubectl describe pods my-proxysql

 

 

마지막에 오류 메시지를 보면, 이미지를 가져올 없어 발생한 오류라는 것을 확인할 있다.

Failed to pull image "proxysql": rpc error: code = Unknown desc = Error response from daemon: pull access denied for proxysql, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

 

일반적으로 생각할 , 쿠버네티스를 사용하여 파드를 생성하면, 로컬의 이미지를 사용할 알았는데 그렇지 않다. 그래서 minikube에서 로컬의 이미지를 사용할 있도록 minikube 도커를 연결해야해는데, 다행히 쿠버네티스에서는 공식적으로 이러한 부분을 지원하고 있다.

 

아래 명령어를 사용하면, 현재 minikube에서 도커 host 연결할 있는 방법을 알려준다. 결과 정보를 바탕으로 일일이 등록해도 되지만, 마지막줄에서 도커 호스트와 한번에 연결할 있는 명령어를 제공하기 때문에 그대로 복사해서 사용할 있다.

minikube docker-env

 

 

마지막 줄의 명령어를 실행하여 minikube에서 docker host 연결한다.

eval $(minikube -p minikube docker-env)

 

명령어실행 도커에서 컨테이너를 조회해 보면 쿠버네티스의 컨테이너가 조회되는 것을 확인할 있다.

 

지금부터는 docker 이미지가 minikube에서 동작하는 driver(docker) 연결되었기 때문에 이제부터 생성되는 docker image minikube 위에 생성하게 된다.

 

다시 한번 이미지를 빌드 한다. 이번에는 이전과 차별을 두기 위해 my-proxysql 이라는 이름으로 이미지를 생성하였다.

docker build -t my-proxysql .

 

아래 명령을 사용하여 minikube 이미지 목록을 확인한다. 방금 빌드한 이미지 목록을 확인할 있다.

minikube image ls --format table

 

 

아래 명령을 사용하여 파드를 실행한다. 이때 로컬의 이미지를 사용하도록 --image-pull-policy=Never 옵션을 함께 사용한다. 정상적으로 파드가 실행중인 것을 확인할 있다.

kubectl run my-proxysql1 --image=my-proxysql --image-pull-policy=Never --restart=Never

 

 

 

[참고자료]

l  https://minikube.sigs.k8s.io/docs/handbook/pushing/#1-pushing-directly-to-the-in-cluster-docker-daemon-docker-env

l  https://www.baeldung.com/docker-local-images-minikube

l  https://egkatzioura.com/2020/03/08/use-local-docker-image-on-minikube/

 

 

 

2023-09-07 / Sungwook Kang / https://sungwookkang.com

 

 

도커파일, dockerfile, minikube, Kubernetes, 로컬이미지 사용, 파드생성, pod create, 도커이미지

[Docker] 컨테이너실행시 sh 스크립트 호출과 매개변수 사용

 

l  Docerk, Shell script

 

Dockerfil 제작하면서, 컨테이너 실행시 특정 스크립트를 실행할 , 스크립트 실행에 필요한 파라메터 값을 받아오지 못하는 문제가 있었다. (도커의 문제가 아닌 나의 코드 오류 문제) 단독으로 스크립트를 실행하면 정상적으로 실행되는데, 유독 컨테이너 실행시에만 값을 받지 못하였다. 해결 방법은 매우 간단하게 Dockerfile에서 사용한 ENV 환경변수를 그대로 스크립트에서 사용하면 되는거였다. (너무 어렵게 생각해서 문제를 해결하지 못한 것이었다.)

 

[잘못된 예시]

abc.sh에서 인풋 변수로 값을 사용할 있도록 read 명령어를 사용하였으며, 해당 변수로 받은 값을 출력하려고 작성.

abc.sh
#!/usr/bin/env bash
 
read var1
read var2
 
echo $var1
echo $var2

 

컨테이너 실행시 ENTRYPOINT에서 abc.sh 실행하면서 파라메터를 전달하려고 작성.

Dockerfile
FROM ~~~~
 
ENV sh_var1 var1_value
ENV sh_var2 var2_value
 
ENTRYPOINT [“abc.sh”, “$sh_var1”, “$sh_var2”]

 

 

[정상 예시]

abc.sh
#!/usr/bin/env bash
 
#read var1 <- 인풋 변수 삭제
#read var2 <- 인풋 변수 삭제
 
echo $sh_var1 #<- dockerfile ENV 변수를 그대로 가져다 사용
echo $sh_var2 #<- dockerfile ENV 변수를 그대로 가져다 사용

 

Dockerfile
FROM ~~~~
 
ENV sh_var1 var1_value
ENV sh_var2 var2_value
 
ENTRYPOINT [“abc.sh”] #<- ENTRYPOINT호출시 sh 파일만 실행

 

 

물론 방법 외에도 다양한 사용법이 있을텐데, 우선 나의 코드에서는 각각의 변수를 호출해서 사용하려고 해서 발생한 문제로, 도커파일과 스크립트간의 매개변수 전달에 대한 이해가 부족해서 발생한 문제였다.

 

 

 

 

2023-09-07 / Sungwook Kang / https://sungwookkang.com

 

 

도커파일, dockerfile, 쉘스크립트, shell script, 매개변수, 도커환경변수, docker env, shell read

[Kubernetes] 쿠버네티스에서 파드 생성시 프라이빗 레지스트리 이미지 사용하기

 

l  Kubernetes

 

Kubernetes 환경에서 pod 생성할 Private Registry에서 이미지를 다운받아 실행하는 방법에 대해서 알아본다.

 

현재 구성되어 있는 실습 환경은 MAC OS + PODMAN + MINIKUBE이다. 일반적으로 많이 사용하는 docker 환경은 아니지만 사용법이 거의 유사하기 때문에 따라하는데 크게 문제가 없으리라 생각한다. Minikube 설치 Podman 설치는 공식 문서에 쉽게 설명되어 있기 때문에 여기에서는 다루지 않는다.

 

l  Podman Installation Instructions : https://podman.io/docs/installation

l  minikube start : https://minikube.sigs.k8s.io/docs/start/

 

실습 시나리오는 아래와 같다.

1.       Dockerfile 작성

2.       컨테이너 이미지 빌드

3.       Docker Hub 개인 저장소에 이미지 푸시

4.       쿠버네티스에서 프라이빗 시크릿키 생성

5.       YAML 파일 작성

6.       Pod 생성

 

사용자 커스텀 이미지를 만들기 위해 Dockerfile 작성한다. Dockerfile 작성에 관한 방법은 다른 문서를 참고한다. 도커 허브의 공식 이미지 저장소에서는 Dockerfile 대한 샘플코드를 제공한다. 아래는 proxysql 공식 저장소이다.

l   https://hub.docker.com/r/proxysql/proxysql

 

 

 

 Dockerfile 작성이 완료되었으면, 이미지를 빌드 한다. Podman 명령어는 도커 명령어와 거의 유사하기 때문에 어려움 없이 사용할 있다. 아래 스크립트는 Dockerfile 빌드하여 컨테이너 이미지를 생성하고, 현재 생성되어 있는 이미지를 확인한다.

podman build -t proxysql-sw:1.0.0 .
 
podman images

 

 

 

podman에서는 도커 레지스트리에 push하기 위해 로그인 과정이 필요하다. 도커 허브의 로그인은 아래와 같은 명령어를 사용한다. 로그인은 ID, 패스워드로 인증한다.

podman login docker.io

 

 

 

이미지를 푸시 하기 위해서는 이미지 ID 필요하다. Podman images명령을 사용하여 확인한 이미지ID 사용하여 도커 허브의 프라이빗 레지스트리로 푸시 한다.

podman push 561f3e4999fddocker.io/<개인저장소 경로>

 

 

쿠버네티스에서 파드 생성시 사용할 프라이빗 레지스트리에 대한 시크릿 키를 생성한다. 시크릿 키에 대한 생성은 여러 방법이 있지만 여기에서는 커맨드 라인에서 자격증명을 통한 시크릿 키를 생성한다. 아래 예제에서는 시크릿 이름은 regcred 생성한다.

kubectl create secret docker-registry regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>

 

l   <your-registry-server> : 프라이빗 도커 저장소의 FQDN 주소로, 도커허브(DockerHub) https://index.docker.io/v1/ 사용

l   <your-name> : 도커 사용자의 계정

l   <your-pword> : 도커 사용자의 비밀번호

l   <your-email> : 도커 사용자의 이메일 주소

 

키가 정상적으로 생성되었는지는 아래 명령으로 확인 가능하다. 명령을 실행하면 키에 대한 자세한 정보를 확인할 있다.

kubectl get secret regcred --output=yaml

 

 

쿠버네티스에서 파드 생성시 사용할 YAML 파일을 작성한다. YAML에서 시크릿 키를 사용할 있도록 imagePullSecrets 항목에서 시크릿키 이름을 입력한다.

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: regcred

 

 

YAML파일을 사용하여 쿠버네티스 파드를 생성한다.

kubectl apply -f my-private-reg-pod.yaml

 

 

도커허브의 개인 저장소 이미지를 사용하여 파드가 정상적으로 생성된 것을 확인할 있다.

kubectl get pod 

 

 

 

지금까지 도커 허브의 프라이빗 레지스트리에서 이미지를 받아 파드를 생성하는 방법에 대해서 알아보았다. 원래 나의 목적은 로컬( 컴퓨터)에서 이미지를 빌드한 다음 로컬 저장소의 이미지를 사용하여 쿠버네티스 파드를 생성하려고 하였는데, podman에서 생성한 이미지를 minikube에서 찾지 못하여 (정확히는 내가 모르는 ) 도커 허브를 사용하는 방향으로 실습하였다. 이후 작업으로 로컬 저장소에서 파드를 생성하는 방법을 추가적으로 알아볼 예정이다.

 

 

[참고자료]

l  Podman Installation Instructions : https://podman.io/docs/installation

l  minikube start : https://minikube.sigs.k8s.io/docs/start/

l  docker hub : https://hub.docker.com/

l  프라이빗 레지스트리에서 이미지 받아오기 : https://kubernetes.io/ko/docs/tasks/configure-pod-container/pull-image-private-registry/

 

 

 

 

2023-08-09 / Sungwook Kang / https://sungwookkang.com

 

 

쿠버네티스, Kubernetes, 미니쿠베, minikube, 도커, 도커허브, 컨테이너, 도커파일, dockerfile, yaml, 도커 레지스트리, 프라이빗 레지스트리, podman, 파드맨, 도커빌드. 이미지빌드

[Kubernetes] vagrant 환경에서 Kubernetes 클러스터 구성하기

 

l  Kubernetes on vagrnat

 

vagrant에서 Kubernetes 클러스터를 구성하는 방법에 대해서 알아본다. 클러스터 구성환경은 virtualbox centos8 운영체제의 가상머신을 3 생성하고, 머신은 master, woker1, woker2 구성한다.

 

l  vagrant 활용한 개발 환경 구축하기 : https://sungwookkang.com/1523

l  vagrant 가상머신 생성하기 : https://sungwookkang.com/1524

 

호스트이름 IP 역할
k8s-master 192.168.10 Master node
k8s-worker1 192..168.11 Worker node
k8s-worker2 192.168.12 Worker node

 

l   Kubernetes Version : v1.27.3

l   Docker Version : 24.0.2, build cb74dfc

 

vagrnatfile 구성 Kubernetes 구성에 사용할 스크립트 파일은 아래 깃헙을 참고 한다.

l   https://github.com/sqlmvp/k8s-cluster-vagrant

 

 

vagrant up 완료되면 아래와 같이 클러스터가 생성되어 ready 상태로 동작되는 것을 확인할 있다.

 

 

2023-07-03 / Sungwook Kang / https://sungwookkang.com

 

 

vagrant, 베이그랜트, 쿠버네티스, Kubernetes,

[vagrant] vagrantfile 활용한 가상머신 N대를 한번에 생성하기

 

l  Vagrant

 

Vagrant(베이그랜트) Hashicorp(하시코프)에서 개발한 가상머신 관리를 자동화 도구로 루비 기반의 DSL 작성할 있으며, 가상머신 생성 관리, 환경 구축을 위한 프로비저닝까지 관리할 있다. 이번 포트스에서는 vagrant에서 가상머신을 생성할 참고하는 vagrantfile 대해서 알아본다.

 

l  vagrant 활용한 개발 환경 구축하기 : https://sungwookkang.com/1523

l  vagrant 가상머신 생성하기 : https://sungwookkang.com/1524

 

vagrantfile vagrant init 명령을 실행하면 생성되는 설정 파일이다. 물론 init 명령이 아닌 사용자가 수동으로 직접 파일을 생성하여 사용할 수도 있다. Vagrantfile 가상머신의 이미지 종류, IP할당, 공용 폴더 설정, NAT 설정 다양한 정보를 가지고 있다.  이렇게 생성된 파일은 vagrant up 명령을 실행할 로드되어 설정된 값으로 가상머신을 생성하게 된다.    

 

아래 코드는 vagrantfile 설정의 예시로 기초적인 명령어를 작성한 것이다. 예제에 포함된 설정 외에도 다양한 환경변수를 지원한다.

Vagrant.configure("2") do |config|
    config.vm.define "vm-name" do |cfg|
        cfg.vm.box = "generic/centos8"
        cfg.vm.hostname = "centos8"
        cfg.vm.network "private_network", ip: "192.168.1.10"
        cfg.vm.network "forwarded_port", guest: 22, host:19000, auto_correct: false, id "ssh"
        cfg.vm.synced_folder ".", "/vagrant", disabled: true
        cfg.vm.provider "virtualbox" do |vb|
            vb.name = "vm-name"
            vb.cpus = 2
            vb.memory = 2048
        end
    end
end

 

 

l  Vagrant.configure("2") do |config| : vagrant Version

l  config.vm.define "vm-name" do |cfg| : vagrant에서 정의한 가상머신 이름. Vagrant ssh에서 사용

l  cfg.vm.box = "generic/centos8" : vagrant box에서 다운로드 실행할 이미지 이름

l  cfg.vm.hostname = "centos8" : OS에서 설정될 호스트 서버 이름

l  cfg.vm.network "private_network", ip: "192.168.1.10" : 가상머신에 할당할 NAT 선택(public_network, private_netwrok), IP 입력하지 않을 경우 DHCP 동작.

l  cfg.vm.network "forwarded_port", guest: 22, host:19000, auto_correct: false, id "ssh" : 호스트의 19000 포트로 접속시 가상머신의 22 포트로 포워딩

l  cfg.vm.synced_folder ".", "/vagrant", disabled: true : 호스트와 가상머신의 공유 폴더 설정

l  cfg.vm.provider "virtualbox" do |vb| : virtualbox provider 지정

l  vb.name = "vm-name" : virtualbox에서 보여지는 가상머신 이름

l  vb.cpus = 2 : 가상머신에 할당될 CPU 코어

l  vb.memory = 2048 : 가상머신에 할당될 메모리 크기. 단위는 MB.

 

Vargrant up 명령으로 동시에 2 이상의 가상머신을 생성하려면 vagrantfile 파일에 생성하려는 서버 설정을 모두 입력하여 사용한다. 아래 예제는 동시에 3대의 가상머신을 생성한다.

Vagrant.configure("2") do |config|
    #vm1
    config.vm.define "vm-1" do |cfg|
        cfg.vm.box = "generic/centos8"
        cfg.vm.hostname = "vm1-centos8"
        cfg.vm.provider "virtualbox" do |vb|
            vb.name = "vm-1"
            vb.cpus = 2
            vb.memory = 2048
        end
    end
 
    #vm2
    config.vm.define "vm-2" do |cfg|
        cfg.vm.box = "generic/centos8"
        cfg.vm.hostname = "vm2-centos8"
        cfg.vm.provider "virtualbox" do |vb|
            vb.name = "vm-2"
            vb.cpus = 2
            vb.memory = 2048
        end
    end
 
    #vm3
    config.vm.define "vm-3" do |cfg|
        cfg.vm.box = "generic/centos8"
        cfg.vm.hostname = "vm3-centos8"
        cfg.vm.provider "virtualbox" do |vb|
            vb.name = "vm-3"
            vb.cpus = 2
            vb.memory = 2048
        end
    end
end
 

 

Vagrant up 명령으로 가상머신이 생성할 있으며, vagrantfile 설정대로 3대의 가상머신이 생성되는 것을 확인할 있다.

 

Virtualbox에서도 3대의 가상머신이 정상적으로 생성된 것을 확인할 있다.

 

 

개발환경을 구성할 이와 같이 스크립트로 생성할 있도록 구성하고 관리하면 매번 환경을 세팅할 때마다 투입되는 시간 리소스 절약할 있다. 그리고 가장 중요한 것은 동일한 환경을 다시 구성할 있기 때문에 매번 구성때마다 환경 바뀜으로 인한 여러가지 장애상황을 예방할 있다.

 

Vagrantfile 대한 자세한 옵션은 공식 문서를 참고 있도록 한다.

l   Vagrantfile : https://developer.hashicorp.com/vagrant/docs/vagrantfile

 

 

[참고자료]

l   Vagrantfile : https://developer.hashicorp.com/vagrant/docs/vagrantfile

 

 

 

2023-07-02 / Sungwook Kang / https://sungwookkang.com

 

 

Vagrant, 베이그랜트, 개발환경구성, 가상머신, vagrantfile, 베이그랜트 설정, 가상머신생성, virtualbox

[vagrant] vagrant 가상머신 생성하기

 

l  Vagrant

 

Vagrant(베이그랜트) Hashicorp(하시코프)에서 개발한 가상머신 관리를 자동화 도구로 루비 기반의 DSL 작성할 있으며, 가상머신 생성 관리, 환경 구축을 위한 프로비저닝까지 관리할 있다.

 

l  vagrant 활용한 개발 환경 구축하기 : https://sungwookkang.com/1523

 

이번 포트스에서는 vagrant 가상머신을 생성하는 방법을 설명한다. Vagrant 사용자가 수작업으로 진행하는 작업을 설정 파일을 통해서 자동으로 생성 관리를 도와주는 도구이지 vagrant 자체가 가상머신의 역할을 하는 것은 아니다. 따라서 Vagrant 사용하여 가상머신을 생성하기 위해서는 Virtualbox Hyper-V, parallels같은 가상머신 툴이 설치가 되어 있어야 한다. 가상머신 설치에 대한 내용은 이미 다른 정보가 많기 때문에 여기에서 다루지 않는다.

 

Vagrant 가상머신을 만들기 위해서는 사용할 box 추가해야 한다. Box 가상머신을 생성할 OS 대한 이미지와 OS 포함될 다양한 소프트웨어들을 포함한 패키지이다. 우선 box 추가하기 전에 어떤 이미지들이 제공되는지 box 사용할 주소를 확인하기 위해 아래 사이트에 접속하여 목록을 확인할 있다

l  HashiCorp 공식 box : https://app.vagrantup.com/boxes/search

 

 

 

이번 포스트에서는 Centos 설치하기 때문에 Centos 검색하여 Centos 8  정보를 확인한다. Box추가에 사용할 파라메터 이름을 확인할 있다.

 

Vagrant box 등록하는 방법은 box add 라는 명령을 사용한다. 위에서 확인한 경로를 사용하여 Centos8 box 등록한다. 등록과정에서 어떤 플랫폼의 box 사용할 것인지 선택하는 단계가 있으며 각자의 플랫폼에 맞는 박스 타입을 선택하면 된다. 이번 포스트에서는 virtualbox 사용하였다. 박스를 등록하면 가상머신 생성에 필요한 이미지를 다운로드 받는다.

vagrant box add generic/centos8

 

 

현재 등록되어 있는 박스의 목록을 확인하기 위해서는 box list 명령을 사용한다.

vagrant box list

 

 

등록된 박스 삭제는 box remove 명령을 사용한다.

vagrant box remove generic/centos8

 

 

가상머신을 생성할 디렉터리로 이동하여 가상머신 설정 파일을 생성한다, init 명령을 사용하며, 이때 파라메터 값으로 박스 이름을 입력한다. 이니셜 작업이 완성되면 Vagrantfile이라는 파일이 생성된 것을 확인할 있다.

vagrant init generic/centos8

 

 

설정파일을 살펴보면 현재 박스의 이미지 정보를 확인할 있다. 아래는 주석을 제외한 내용이다.

Vagrant.configure(“2”) do |config|
config.vm.box = “generic/centos8”

 

 

 

가상머신을 생성하기 위해서는 up 명령을 사용한다. 명령을 실행하면 다운로드 받은 이미지를 사용하여 가상머신이 생성된다.

vagrant up

 

 

 

Virtualbox에서도 가상머신이 생성되는 것을 확인할 있다.

 

생성한 가상머신에 접속하기 위해서는  ssh 명령을 사용하여 접속 한다.

vagrant ssh

 

 

Vagrant 생성한 가상머신을 중지하려면 halt 명령을 사용한다.

Vagrant halt

 

Vagrant 생성한 가상머신을 삭제하려면 destroy 명령을 사용한다. 가상머신을 삭제하려면 선행작업으로 가상머신을 중지해야 한다.

Vagrant destroy

 

 

지금까지 vagrant 활용하여 가상머신을 생성하는 방법에 대해서 알아보았다. 현재는 기본설정으로 가상머신을 생성하였지만, 각자 개발환경을 커스텀 환경으로 구성하기 위해서는 vagrantfile 수정하여 사용할 있다. 환경설정 파일에 대한 수정은 다른 포스트에서 다룰 예정이다.

 

2023-07-01 / Sungwook Kang / https://sungwookkang.com

 

 

Vagrant, 베이그랜트, 개발환경구성, 가상머신

[vagrant] vagrant 활용한 개발 환경 구축하기

 

l  Vagrant  with mac brew install

 

Vagrant(베이그랜트) Hashicorp(하시코프)에서 개발한 가상머신 관리를 자동화 도구로 루비 기반의 DSL 작성할 있으며, 가상머신 생성 관리, 환경 구축을 위한 프로비저닝까지 관리할 있다. 또한 가상 환경에 대한 설정을 관리할 있어 동일한 환경을 구성할 있다. 이번 포스트에서는 MAC 환경에서 vagrant 설치하는 방법에 대해서 알아본다.

 

[Homebrew 설치하기]

Homebrew vagrant 설치하는 방법은 매우 간단하다. Homebrew 명령어 하나로 쉽게 설치 삭제가 가능하다. 설치 과정에서 현재 사용자의 암호를 입력해야 한다.

brew install vagrant

 

 

정상적으로 설치가 왼료되었으면, --version 옵션을 사용하여 설치된 vagrant 버전을 확인할 있다. vagrant 설치된 디렉터리 위치를 확인하려면 whitch 명령을 사용한다.

vagrant –version
which vagrant

 

 

Homebrew 설치한 vagrant 삭제는 아래 명령어를 사용하면 된다.

brew uninstall vagrant

 

 

[Vagrant 공식사이트에서 다운로드]

Hashicorp 공식 사이트에서 vagrant 다운로드 받아 설치 있다.

l  https://www.vagrantup.com/

 

플랫폼에 맞는 버전을 다운로드 받아 설치하여 사용한다.

 

 

 

2023-06-30 / Sungwook Kang / https://sungwookkang.com

 

 

Vagrant, 베이그랜트, 개발환경구성, 가상머신

[Prometheus] Prometheus Thanos 아키텍처 살펴보기

 

l  Prometheous with Thanos

 

Thanos(타노스) CNCF(https://www.cncf.io/) 인큐베이팅 프로젝트로, 프로메테우스의 확장성과 내구성을 향상시키기 위한 오픈소스 프로젝트이다.

l  Prometheus 확장 내구성을 위한 다양한 구성 방법 : https://sqlmvp.tistory.com/1521

 

Thanos Prometheus 2.0 스토리지 형식을 활용하여 빠른 쿼리 대기 시간을 유지하면서 모든 개체 스토리지에 메트릭 데이터를 효율적으로 저장한다. 또한 운영중인 프로메테우스 서버의 데이터를 통합 저장 외부 저장소에 데이터를 저장할 있기 때문에 보관 기간에 제한이 없고, 단일 쿼리로 전체 프로메테우스 서버의 데이터를 쿼리 있다. 장점을 크게 정리하면 아래와 같이 정리할 있다.

l  Long-term Storage : 원격 스토리지에 데이터를 안정적으로 저장하여 장기적인 데이터 보존을 가능

l  Global Query : 여러 원격 스토리지에서 데이터를 통합하여 조회할 있는 Global Query 기능을 제공하여 분산된 데이터에 대해 단일 쿼리를 실행할 있어 데이터 분석과 모니터링에 유용

l  HA(고가용성) : 원격 스토리지에 데이터를 복제하여 프로메테우스 서버 하나가 장애가 발생하더라도 데이터의 고가용성을 보장

 

타노스는 Sidecar, Query Gateway, Store Gateway, Compactor, Ruler, Receiver라는 6개의 컴포넌트로 이루어져 있다.  

 

l   Thanos Sidecar

ü  Prometheus 함께 하나의 POD 배포되어 기존 프로메테우스 서버와 통합

ü  Prometheus 데이터를 Object Storage 버킷에 백업하고 다른 Thanos 구성 요소가 gRPC API 통해 Sidecar 연결된 Prometheus 인스턴스에 액세스

ü  2시간마다 프로메테우스 메트릭을 객체 스토리지로 보냄

ü  사이드카는 Prometheus 끝점을 사용. --web.enable-lifecycle 플래그로 활성화

l   Thanos Query Gateway

ü  PromQL 처리하는 부분으로 필요한 Prometheus sidecar 연결

ü  질의를 Store (Store API), Sidecar등으로 전달하고 수집

ü  타노스의 전역 쿼리 계층(Global query layer) 사용하여 모든 프로메테우스 인스턴스에 대해 PromQL 사용하여 한번에 조회가능

ü  쿼리 구성 요소는 상태 비저장이며 수평 확장이 가능하며 여러 복제본과 함께 배포 가능

ü  사이드카에 연결되면 주어진 PromQL 쿼리를 위해 어떤 프로메테우스 서버에 접속해야 하는지 자동으로 감지

ü  단일 Thanos 쿼리 엔드 포인트에서 여러 메트릭 백엔드를 집계하고 중복 제거하는 기능을 제공

l   Thanos Store Gateway

ü  Store 같은 개념이며, API Gateway 역할을 하며 오브젝트 스토리지에 접근하는 모든 작업은 Store API 사용

ü  Query, Receive, Ruler 등에 존재

ü  사이드카와 동일한 gRPC 데이터 API 구성되어 있지만 개체 저장소 버킷에서 찾을 있는 데이터로 백업

ü  스토어 게이트웨이는 오브젝트 스토리지 데이터에 대한 기본 정보를 캐싱 하기위해 소량의 디스크 공간을 차지 (타노스 쿼리 저장소 역할)

l   Thanos Compactor

ü  오브젝트 스토리지에 저장된 블록 데이터를 압축하여 저장공간 최적화 작업 진행

ü  개체 저장소를 간단히 스캔하고 필요한 경우 압축을 처리

ü  동시에 쿼리 속도를 높이기 위해 다운 샘플링된 데이터 복세본을 만드는 역할 수행

ü  주기적 배치 작업으로 실행하거나 데이터를 빨리 압축하기 위해 상시 실행 상태로 있음

ü  데이터 처리를 위해 100GB ~ 300GB 로컬 디스크 공간을 제공하는 것이 좋음  

ü  동시성이 보장되지 않으므로 전체 클러스터에서 싱글톤 형식으로 배포하고 버킷에서 데이터를 수동으로 수정할 실행하면 안됨

l   Thanos Ruler

ü  타노스 사이드카가 적용된 프로메테우스의 보존기간이 충분하지 않거나 전체 보기가 필요한 알림 또는 규칙 구성

ü  Thanos 쿼리 구성 요소에 연결하고 Prometheus Alert Record 규칙을 평가

ü  Prometheus Alert Manager 사용하여 Alert 트리거 있음

l   Thanos Receiver

ü  프로메테우스 서버에서 remote_write 통해 메트릭 데이터 수신할 사용

ü  기본 2시간 단위로 TSDB 블록을 만들어 오브젝트 스토리지에 저장

 

 

아키텍처를 살펴보고 요악하면 다음과 같은 활용을 구상해 있다.

l   다수의 프로메테우스 서버를 Global Query view기능을 통해 하나의 인터페이스로 조회 활용

l   Global Query view, 메트릭 duplication 기능으로 프로메테우스 서버가 장애나더라도 서비스 단절이나 데이터 손실 방지

l   외부 저장소를 활용할 있으므로 데이터 크기에 따른 스토리지 성능 하락에 대비할 있고, 메트릭 데이터를 영구 보관할 있으므로 다양하게 활용 가능



 

[참고자료]

l   Thanos공식 문서 : https://thanos.io/v0.6/thanos/getting-started.md/

l   Multi-Cluster Monitoring with Thanos : https://particule.io/en/blog/thanos-monitoring/

 

 

 

2023-06-29 / Sungwook Kang / https://sungwookkang.com

 

 

프로메테우스, Prometheus, 모니터링 시스템, Grafana, 그라파나, DevOps, 데브옵스, Kubernetes, 쿠버네티스, 타노스, Thanos, CNCF

[Prometheus] Prometheus 확장 내구성을 위한 다양한 구성 방법들

 

l  Prometheous with Thanos

 

Prometheus(프로메테우스) 모니터링 시스템은 오픈 소스 기반의 모니터링 시스템으로 Kubernetes(쿠버네티스) 활성화 함께 많이 사용되고 있다.  프로메테우스는 구조가 간단하며, 운영이 쉽고 강력한 쿼리 기능을 가지고 있다. 간단한 텍스트 형식으로 메트릭 데이터를 쉽게 익스포트 있으며, key-value 형식의 데이터 모델을 사용한다. 수집된 데이터는 Grafana(그라파나) 통해 시각화를 제공한다.

 

l  Prometheus 구조 개념 : https://sqlmvp.tistory.com/1520

 

프로메테우스의 가장 약점은 확장성과 가용성이다. 프로메테우스는 클러스터가 지원되지 않는 독립형 서비스로, 프로메테우스 서버 장애시 메트릭을 수집할 없다는 것이다. 프로메테우스 서버의 장애시간 또는 재설정 등으로 서버 또는 서비스가 재시작 동안 타켓에 대한 모니터링을 없다면 이는 서비스를 운영하는데 매우 리스크이다.  이러한 문제를 해결하기 위해 여러가지 프로메테우스 서버 구성에 대한 아키텍처를 생각해 있다.

 

[프로메테우스N 구성으로 타켓 서버 중복 모니터링]

대이상의 프로메테우스 서버를 구성하여, 프로메테우스 서버에서 타겟 서버를 교차해서 메트릭을 수집하는 방식이다.

 

이러한 방식으로 구성할 경우 관리 해야하는 프로메테우스 서버도 증가하지만, 모니터링 대상이 되는 타겟 서버 입장에서도 여러 프로메테우스 서버로부터 요청되는 메트릭 데이터를 수집 전달하기 위해 오버헤드가 발생한다. 또한 프로메테우스로 수집된 데이터를 분석할 때에도, 특정 시점에 장애가 번갈아 발생시, 데이터가 한쪽에만 있게 되므로 중앙에서 한번에 분석하기 불편한 단점이 있다.

 

 

[프로메테우스 Federation 구성]

프로메테우스 서버를 여러 구성하고, 프로메테우스 서버가 다른 프로메테우스 서버로 요청하여 데이터를 수집할 있다.

l  Hierarchical Federation 구성은 프로메테우스 서버 사이에 계층을 두고 Tree 형태로 Federation 구성하는 방법이다. 부모 프로메테우스는 자식 프로메테우스들의 통합 메트릭 제공 통합 메트릭을 기반으로 알람을 제공하는 용도로 사용할 있다.

l  Cross-service Federation 구성은 동일 레벨의 프로메테우스 서버사이를 Federation으로 구성하는 방법이다.

 

 

 

Federation으로 구성할 경우, 프로메테우스 서버는 타겟 서버로부터 일정 주기로 데이터를 수집하고 저장하고, 부모(중앙) 프로메테우스 서버는 프로메테우스 서버로부터 저장된 데이터를 별도의 주기로 수집할 있어, 데이터양이 많을 , 평균값이나 해상도 등을 조정할 있다. 예를들면 프로메테우스 서버는 10 단위로 수집하고, 중앙 프로메테우스는 1 단위로 하위 프로메테우스 서버로 요청하여 평균값 등을 이용할 있다. 하지만 프로메테우스 서버 장애 데이터 유실, 데이터 증가로 인한 중앙 프로메테우스 서버의 오버헤드 증가 문제가 있으므로 일정 규모 이상에서는 적용하기 힘든 부분이 있다.

 

 

[프로메테우스 Thanos 구성]

Thanos 프로메테우스의 확장성과 내구성을 향상 시키기 위한 오픈소스 프로젝트로, 프로메테우스의 메트릭 데이터를 분산된 원격 스토리지에 저장하고 조회할 있는 기능을 제공한다. 아래 그림에서 서드파티 스토리지로 데이터를 저장하기 위한 Adapter 역할이 Thanos 기능이다.

l   Thanos 사용하여 구성 경우 아래와 같은 장점이 있다.

l   Long-term Storage: 원격 스토리지에 데이터를 안정적으로 저장하여 장기적인 데이터 보존을 가능

l   Global Query: 여러 원격 스토리지에서 데이터를 통합하여 조회할 있는 Global Query 기능을 제공하여 분산된 데이터에 대해 단일 쿼리를 실행할 있어 데이터 분석과 모니터링에 유용

l   HA(고가용성): 원격 스토리지에 데이터를 복제하여 프로메테우스 서버 하나가 장애가 발생하더라도 데이터의 고가용성을 보장

 

프로메테우스 Thanos 구성으로 데이터를 수집하여 S3 저장하는 구성하는 구조를 만든다면 아래와 같은 형식으로 아키텍처를 디자인 있다.

1.          Prometheus Thanos 사이드카를 활성화

2.          Sidecar 대화할 있는 기능이 있는 Thanos Querier 배포

3.          Thanos Sidecar S3 버킷에 Prometheus 메트릭을 업로드할 있는지 확인

4.          Thanos Store 배포하여 장기 스토리지( 경우 S3 버킷) 저장된 메트릭 데이터를 검색

5.          데이터 압축 다운 샘플링을 위해 Thanos Compactor 설정

 

 

다양한 구성으로 프로메테우스의 단점인 확장 내구성을 보완하는 방법에 대해서 살펴보았다. 여러 방식이 있겠지만 현재 대규모 서비스에서는 Thanos 구성이 가장 많이 사용되는 하다. Thanos 아키텍처 자세한 내용은 다른 포스트에서 다뤄볼 예정이다. 모니터링을 구성하는데 있어서 정답은 없다. 항상 우리가 가진 리소스 환경에서 가장 최선의 방법을 찾는 것이 중요할 하다.

 

참고자료 :

l   https://wikitech.wikimedia.org/wiki/File:Prometheus_federation.png

l   https://prometheus.io/docs/prometheus/latest/federation/

l   https://www.robustperception.io/federation-what-is-it-good-for/

l   https://aws.amazon.com/blogs/opensource/improving-ha-and-long-term-storage-for-prometheus-using-thanos-on-eks-with-s3/

l   https://thanos.io/v0.6/thanos/getting-started.md/

l   https://particule.io/en/blog/thanos-monitoring/

 

 

 

2023-06-28 / Sungwook Kang / https://sungwookkang.com

 

 

프로메테우스, Prometheus, 모니터링 시스템, Grafana, 그라파나, DevOps, 데브옵스, Kubernetes, 쿠버네티스

[Prometheus] Prometheus 구조 개념

 

l  Prometheous

 

Prometheus(프로메테우스) 모니터링 시스템은 오픈 소스 기반의 모니터링 시스템으로 Kubernetes(쿠버네티스) 활성화 함께 많이 사용되고 있다. 물론 쿠버네티스 환경 외에도 일반적인 온프레미스 환경에서도 사용이 가능하여 많은 인기를 끌고 있다.  현재 CNCF(Cloud Native Computing Foundation) 소속되어 있다.

 

프로메테우스는 구조가 간단하며, 운영이 쉽고 강력한 쿼리 기능을 가지고 있다. 간단한 텍스트 형식으로 메트릭 데이터를 쉽게 익스포트 있으며, key-value 형식의 데이터 모델을 사용한다. 수집된 데이터는 Grafana(그라파나) 통해 시각화를 제공한다.

 

프로메테우스는 순전히 숫자로 시계열을 기록하는 적합하다. 기계 중심 모니터링과 고도로 동적인 서비스 지향 아키텍처 모니터링 모두에 적합하다. 프로메테우스는 중단 중에 신속하게 문제를 진단할 있도록 하는 시스템으로서 안정성을 위해 설계되어있으며, 프로메테우스 서버는 독립형으로 동작하며, 네트워크 스토리지 또는 기타 원격 서비스에 의존하지 않는다.

 

대부분의 모니터링 시스템은 타켓 서버(모니터링 대상 서버) 에이전트를 설치하여 중앙의 모니터링 수집 서버로 push(푸시) 하는 방식인데, 프로메테우스는 pull() 방식을 사용하여 데이터를 수집한다. 모니터링 대상 서버에 exporter(익스포터)라는 에이전트가 실행되어 있으면, 주기적으로 에이전트에 접속하여 데이터를 가져오는 방식이다.

 

l  Jobs / Exporter : 프로메테우스가 모니터링 데이터를 가져갈 있도록 타겟 서버에 설치되는 에이전트 이다. 서버 상태를 나타내는 Node exporter, DB 상태를 나타내는 SQL Exporter 다양한 커스텀 익스포터들이 개발되어 사용되고 있다. 익스포터 자체는 특별한 기능을 수행하지 않는다. 프로메테우스의 요청이 있을 시점에 메트릭을 수집하여 http get 방식으로 리턴한다. 히스토리를 저장하지 않기 때문에 시점의 값만 있다.

l  Pushgateway : Pushgateway는보안상의 이유로 프로메테우스가 직접 익스포터에 연결 없을 , Proxy Forwarding 사용하여 메트릭 데이터를 수집할 있도록 해주는 서비스이다. Application pushgateway 메트릭 데이터를 푸쉬하면, 프로메테우스 서버가 pushgateway 접근해 메트릭 데이터를 하는 방식으로 동작한다.

l  Alertmanager: Alertmanagr 메트릭에 대한 특정 룰을 설정하고 규칙을 위반하는 사항에 대해 알람을 전송하는 역할을 한다. 예를들면 “CPU 사용률이 50% 이상일때 알람을 보낸다.” 라고 룰을 설정하면, 수집된 CPU 메트릭의 값이 50 이상일때 알람을 발송한다.

l  Service discovery : 프로메테우스는 기본적으로 방식을 사용하여 모니터링을 하기 때문에 모니터링 대상 서버의 목록을 유지하고 있어야 한다. 쿠버네티스 환경처럼 오토스케일이 발생할 경우, 타겟 서버의 IP 가변적이어서 수집할 서버의 목록을 확인할 없는 경우가 많다. 이런 경우 모니터링 대상 목록을 관리하기 위해 서비스 디스커버리를 사용하여 유지한다.

l  Retrieval : 익스포터로 부터 주기적으로 메트릭을 수집하는 모듈이며, 서비스 디스커버리 시스템으로 부터 모니터링 대상 목록을 받아오는 역할도 수행하는 컴포넌트이다.

l  HDD/SDD : 수집된 데이터는 프로메테우스 서버의 로컬 메모리와 디스크에 저장된다. 단순하고 사용이 쉬운 방면, 별도의 데이터베이스가 없으므로 확장이 불가능하다.

l  Data visualization : 저장된 메트릭은 PromQL 쿼리 언어를 사용하여 조회가 가능하다. 또한 외부 API 프로메테우스 웹콘솔을 사용하여 visualization 구성할 있다.

 

프로메테우스 서버는 독립적인 구조로 운영되기 때문에, 많은 수의 모니터링 서버에서 대량의 메트릭을 수집할 프로메테우스 서버의 시스템 리소스가 부족할 경우 확장이 불가능한 구조로 되어 있다. 또한 프로메테우스 서버가 다운되거나 설정 변경으로 인한 재시작시 메트릭이 저장되지 않고 유실되는 문제가 있다. 이러한 문제를 수정하기 위해 프로메테우스 서버를 다양한 형태로 구성 운영하기 위한 노하우가 필요 하다. 부분은 다른 포스트에서 다루어 본다.

 

 

 

참고자료 :

https://prometheus.io/docs/introduction/overview/

 

 

2023-06-28 / Sungwook Kang / https://sungwookkang.com

 

 

프로메테우스, Prometheus, 모니터링 시스템, Grafana, 그라파나, DevOps, 데브옵스, Kubernetes, 쿠버네티스

Hive 데이터 입력시 노드당 처리 파티션 개수 초과 오류

 

·       Version : Hive

 

파티셔닝된Hive 테이블에 데이터 입력시 아래와 같은 오류가 발생하였다. 오류 메시지를 살펴보면 노드당 최대 동적 파티션 개수보다 많은 수의 동적 파티션이 생성되어 발생한 오류이다.

Error: java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {“col_1”:25513237,“col_2”:8104666,“col_3”:3808,“col_4”:6705,“col_4”:“2016-01-21 08:31:33",“col_6”:42,“col_7”:“471.00”,“col_8”:null} at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:157) at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54) at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:465) at org.apache.hadoop.mapred.MapTask.run(MapTask.java:349) at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:174) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:422) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1875) at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:168) Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {“col_1”:25513237,“col_2”:8104666,“col_3”:3808,“col_4”:6705,“col_5”:“2016-01-21 08:31:33",“col_6”:42,“col_7”:“471.00”,“col_8”:null} at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:494) at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.map(ExecMapper.java:148) ... 8 more Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Error 20004]: Fatal error occurred when node tried to create too many dynamic partitions. The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. Maximum was set to 100 partitions per node, number of dynamic partitions on this node: 101 at org.apache.hadoop.hive.ql.exec.FileSinkOperator.getDynOutPaths(FileSinkOperator.java:951) at org.apache.hadoop.hive.ql.exec.FileSinkOperator.process(FileSinkOperator.java:722) at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882) at org.apache.hadoop.hive.ql.exec.SelectOperator.process(SelectOperator.java:95) at org.apache.hadoop.hive.ql.exec.Operator.forward(Operator.java:882) at org.apache.hadoop.hive.ql.exec.TableScanOperator.process(TableScanOperator.java:130) at org.apache.hadoop.hive.ql.exec.MapOperator$MapOpCtx.forward(MapOperator.java:146) at org.apache.hadoop.hive.ql.exec.MapOperator.process(MapOperator.java:484) ... 9 more

 

Hive 노드당 최대 동적 파티션 기본값은 100으로 설정되어 있다. 문제를 해결하기 위해서는 아래와 같은 명령을 사용하여 노드당 최대 동적 파티션 갯수 설정을 변경할 있다.

set hive.exec.max.dynamic.partitions=100000;
set hive.exec.max.dynamic.partitions.pernode=100000;

 

노드당 파일 갯수 초과할 경우에도 비슷한 오류가 발생한다. 아래 같은 오류 구문이 발생 때에는 파일 갯수의 설정을 오류가 발생한 최대 값보다 크게 설정할 있도록 한다.

[Fatal Error] total number of created files now is 100028, which exceeds 100000. Killing the job.

 

set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode=100000;
set hive.exec.max.dynamic.partitions=100000;
set hive.exec.max.created.files=900000;

 

 

위와 같이 설정값을 변경하기에 앞서 Hive에서 이렇게 많은 파티션 또는 파일을 생성하는지 생각해보아야 한다. 대부분의 경우 사용자 설정값 범위 내에서 파티션이 이루어진다는 가정하에 사용하는데,  이렇게 한계를 벗어난 다는 것은 파티션 키를 잘못 배치했거나 파티션 처리에 적절하지 않는 데이터셋을 사용했을 가능성이 크다. 그럼에도 불구하고 파티션을 늘려야한다고 생각되면 옵션을 사용하여 적절할 임계치를 조절할 있도록 한다.

 

2021-09-13 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, 파티션 테이블, 동적 파티션 개수 초과,

Kubernetes 장점

 

·       Version :

 

 쿠버네티스(Kubernetes) 환경에서는 컨테이너에 애플리케이션에 필요한 모든 항목이 포함되어 있기 때문에 시스템 관리자가 애플리케이션을 실행하기 위해 아무것도 설치할 필요가 없다.

·       애플리케이션 배포 단순화 : 쿠버네티스는 모든 워커 노드를 단일 플랫폼으로 제공하므로 애플리케이션 개발자는 자체적으로 배포할 있으며 클러스터를 구성하는 서버에 대해서 필요가 없다. 특히 특정 컨테이너가  SSD에서만 실행되거나 또는 HDD에서만 실행되어야 하는  경우처럼 특정 리소스가 필요한 경우 쿠버네티스 노드에서 필요한 리소스가 있는 노드를 선택해서 배포할 있다.

·       효율적인 하드웨어 활용 : 쿠버네티스환경에서 애플리케이션을 배포,실행하면 애플리케이션 리소스 요구사항에 따라 사용 가능한 가장 적합한 노드가 선택되어 할당된다. 또한 특정 노드에 애플리케이션을 종속시키지 않는다면 클러스터를 자유럽게 이동할 있어 리소스 가용 상태에 따라 자동으로 이동하거나 매치하여 사용할 있다.

·       자동 복구 모니터링 : 특정 클러스터에 종속되지 않으면 자유롭게 클러스터를 이동할 있기 때문에 이러한 장점으로 인해 모니터링 중에 특정 노드에 장애가 발생하면 자동으로 다른 노드에 애플리케이션이 재배치 되어 실행되기 때문에 야간이나 장애 발생시 즉시 대응할 필요가 없다.

·     오토스케일링 : 쿠버네티스는 애플리케이션에서 사용하는 리소스를 모니터링 하고 애플리케이션에서 실행되는 인스턴스 수를 조정하도록 지시할 있다.

·       개발 환경 단순화 : 애플리케이션이 개발 운영 환경이 동일하기 때문에 개발자는 본인 컴퓨터에서 개발하고 버그를 수정하고, 테스트한 완성된 애플리케이션 환경 그대로 운영 환경에서 실행할수 있다.

 

 

2021-07-30 / Sungwook Kang / https://sungwookkang.com

 

 

Kubernetes, 쿠버네티스

Kubernetes 마스터 노드, 워커 노드

 

·       Version :

 

 쿠버네티스(Kubernetes) 클러스터에서 마스터 노드는 전체 쿠버네티스 시스템을 관리하고 통제하는 쿠버네티스 컨트롤 플레인을 관장한다. 워커 노드는 실제 배포하고자 하는 애플리케이션 실행을 담당한다.

마스터 노드(컨트롤 플레인)에서는 클러스터를 관리하고 클러스터의 기능을 실행한다. 단일 마스터 노드에서 실행하거나 여러 노드로 분할 복제되어 고가용성을 보장할 있는 여러 구성요소로 구성 있다.

·       API Server : 사용자와 컨트롤 플레인과 통신하는 쿠버네티스 API

·       Scheduler : 애플리케이션을 예약하는 스케줄러로, 배포 가능한 구성 요서에 워커 노드 할당을 담당

·       Control Manager : 구성 요소 복제, 워커 노드 추적, 노드 장애 처리 클러스터 기능을 실행

·       etcd : 클러스터 구성을 저장하는 분산 데이터 스토리지  

 

워커 노드는 컨테이너화된 애플리케이션을 실행하는 시스템으로 서비스 실행, 모니터링을 제공한다.

·       Kubelet : API 서버와 통신하고 노드에서 컨테이너를 관리

·       Kube-proxy : 애플리케이션 구성 요소 간에 네트워크 트래픽을 분산하는 쿠버네티스 서비스 프록시

 

 

2021-07-28 / Sungwook Kang / https://sungwookkang.com

 

 

Kubernetes, 쿠버네티스, 마스터 노드, 워커 노드, 컨트롤 플레인, Control Plane

'SW Engineering > DevOps, SRE' 카테고리의 다른 글

[Prometheus] Prometheus 구조 및 개념  (0) 2023.06.28
Kubernetes 장점  (0) 2021.07.31
SRE (Site Reliability Engineering) 역할  (0) 2020.05.14
SRE (Site Reliability Engineering)  (0) 2020.05.11
Docker Network  (0) 2019.03.27

Split Brain

 

스플릿 브레인 (Split Brain) 클러스터로 구성된 시스템간의 네트워크가 일시적으로 동시에 단절되거나 기타 시스템상의 이유로, 클러스터 상의 모든 노드들이 각자 자신이 Primary라고 인식하게 되는 상황을 뜻한다.  관제 시스템에 의해 하트비트(Heartbeat)등으로 Alive 유무가 체크되는 서비스가 있다고 가정했을때, 하트비트 통신이 단절되어 서비스 클러스터가 장애 상태라고 인식하고 서비스를 동시에 구동하는 경우, 또는 독립적인 개의 시스템이 비정상적으로 구성되어 서로가 Primary라고 믿게되는 현상을 모두 포함한다.

스플릿 브레인 현상이 발생하면, 노드가 동시에 Primary 되면서 이중 가동 현상이 발생한다. 이렇게 이중으로 가동되면서 노드들은 동시에 스토리지에 접근하기 때문에 데이터 동기화 복제에 비정상 적인 트랜잭션이 발생할 있으며, 예상하지 못한 다양한 문제로 전체 서비스가 불능 상태에 빠질 있다.

일반적으로 LB 중심으로 구성되어 특정 노드에 장애가 발생했을때 HA 제공하도록 구성된 토폴로지라면 스플릿 브레인 현상은 발생하지 않는다.  외에도 스플릿 브레인 현상을 방지하기 위해서는 노드에 구성된 쿼럼(Quorum) 홀수로 구성해 과반수 투표를 진행하거나 하트비트 네트워크를 서비스 네트워크와 통합하여 일관성을 유지할 있도록 한다.

 

Split Brain 대해서 설명된 글이 있으니 조금더 자세히 알고 싶으면 아래 링크를 참고 한다.

·       Split Brain - MariaDB Galera Cluster Case : https://bryan.wiki/290

 

 

2021-04-22 / Sungwook Kang / http://sungwookkang.com

 

Split Brain, 스플릿 브레인, 클러스터 단절, 클러스터 장애

B-tree vs Log-Structured Merge-Tree

 

데이터베이스에서 일반적으로 많이 사용되는 데이터 구조는 B-Tree LSM(Log-Structured Merged-Tree)이다.

B-Tree

B-Tree 데이터베이스에 널리사용되며, B-Tree 인덱싱 구조를 사용하면 데이터가 고정 크기 페이지 세그먼트로 디스크에 기록된다. 이러한 페이지 세그먼트의 크기느 4KB (DMBS마다 다를 있음) 이며 키별로 정렬된 Key-Value 가지고 있다. 단일 B-Tree노드는 페이지 범위에 대한 참조가 있는 배열과 같다. 배열의 최대 참조 수를 “branching factor” 한다. 페이지 범위는 다른 페이지 범위를 참조하는 다른 B-Tree 노드이다. 결국 리프수준에서 단일 페이지를 찾을 있다.

B-Tree 페이지 참조가 메모리가 아닌 디스크에 저장된다는 점을 제외하면 저수준 프로그래밍 언어의 포인터와 유사하다. B-Tree에서 삽입 삭제가 발생하면 branching factor 충족하기 위해(밸런스를 맞추기 위해) 노드를 개의 하위 트리로 분할 있다. 데이터베이스가 충돌하는 위험이 발생할 있다. 데이터베이스가 충돌하는 시나리오를 완화하기 위해 B-Tree 구현은 모든 단일 원자 데이터베이스 트랜잭션을 기록하는 WAL (Write-Ahead Log) 작성하여 기록을 추적한다.  WAL B-Tree 손상된 경우 B-Tree 상태를 복원 하는데 사용된다.

 

Algorithm

Average

Worst case

Space

O(n)

O(n)

Search

O(log n)

O(log n)

Insert

O(log n)

O(log n)

Delete

O(log n)

O(log n)

 

 

 

 

LSM Tree

LSM Tree Bitcask, MongoDB, Bigtable, Cassandra, InfluxDB SQLite4 같은 최신 관계형 비관계형 데이터베이스에서 사용하고 있는 인기있는 데이터 구조이다. LSM Tree 각각의 기본 저장 매체에 최적화된 개이상의 개별 구조로 데이터를 유지한다. 메모리에는 실제 디스크의 데이터 값을 포함하는 바이트 오프셋에 대한 참조 정보를 Key-Value  형태로 해시 테이블 (또는 해시 인덱스) 관리한다.

실제로 사용되는 대부분의  LSM Tree 여러 수준을 사용한다. 레벨 0 주로 메모리에 보관되며 트리를 사용하여 표시 있다. 디스크 데이터는 정렬된 상태로 실행될 있도록 구성되며 실행에는 인덱스 키별로 정렬된 데이터가 포함된다. 실행은 디스크에서 단일 파일로 표시되거나 범위가 겹치지 않는 파일 모음으로 표시 있다. 관련 값을 얻기 위해 특정 키에 대한 쿼리를 수행하려면 레벨0 트리에서 검색하고 실행을 수행해야한다.

 

Algorithm

Average

Worst case

Insert

O(1)

O(1)

Find-min

O(N)

O(N)

Delete-min

O(N)

O(N)

 

 

 

[참고자료]

·       B-Tree : https://en.wikipedia.org/wiki/B-tree

·       Log-structured merge-tree : https://en.wikipedia.org/wiki/Log-structured_merge-tree

 

 

 

2021-03-17 / Sungwook Kang / http://sungwookkang.com

 

B-Tree, LSM Tree, Data Structure, Log-Structured-Merged-Tree, Database Index, 자료구조, 데이터스트럭처, 데이터인덱스

Python Multiprocessing(Process) 사용한 데이터 처리 속도 개선

 

·       Version : MAC OS, Python 3.X, PIP3

 

대용량 데이터를 효율적으로 처리하기 위해서는 병렬 처리를 활용하는것이 좋다.  파이썬에서 병렬처리를 제공하는 대표적인 라이브러리는 Threading Multiprocessing 모듈이다. Threading 모들은 파이썬의 GIL(Global Interpreter Lock)라는불리우는 잠금 모델을 사용하기 때문에I/O 작업이 아닌 CPU 작업이 많을 경우 오히려 성능이 저하된다. 방식은 Lock 풀고 스레드를 교환하고 다시 Lock 거는 형태의 멀티스레드이기 떄문이다.

파이썬에서는 Multiprocessing 권장하고 있으며,   모듈에는 대표적으로 Pool Process 있지만 이번 글에서는 Process 대해서 다루기로 한다.

 

·       Pool 사용한 처리 속도 개선 : https://sungwookkang.com/1478

 

Process 하나의 프로세스에 하나의 함수를 할당하여 실행한다. Target= 파라메터에 작업을 할당하고, args=(agr1, ) 인수를 할당하여 프로세스 객체를 생성한다. start() 프로세스를 시작하여 join()으로 프로세스의 종료를 기다린다.

import os

import multiprocessing as mp

from multiprocessing import Pool, Process

import threading

import time

import datetime

 

def multiprocess():

    start = int(time.time())

 

    ojbect_list = []

    for i in range(1,12):

        task = Process(target=work_func, args=(i,))

        ojbect_list.append(task)

        task.start()

 

    for task in ojbect_list:

        task.join()

   

    end = int(time.time())

    print("***run time(sec) : ", end-start)   

   

    print("Number of Core : " + str(mp.cpu_count()))

   

 

def work_func(x):

    print("time : " + str(datetime.datetime.today()) +  " value :" + str(x)  + " PID : "  + str(os.getpid()))

 

if __name__ == '__main__':

# execute only if run as a script

   

    multiprocess()

 

 

코드를 실행한 결과를 살펴보면 실행마다 다른 프로세스(PID 각각 다름)에서 실행된것을 있다.

 

Pool Process 차이점은, Pool 경우 실행되어야 작업이 코어수 만큼 분할되고 코어수 만큼 프로세스가 생성되어 힐당받은 작업을 처리하는데, Process 경우 작업마다 새로운 프로세스가 할당되어 작업을 처리한다.

 

 

2021-03-02/ Sungwook Kang / http://sungwookkang.com

 

파이선파이썬, python, 병렬처리, Multiprocessing, Python Multiprocessing, 파이썬 병렬처리, 데이터 처리, Data Processing

 

Python Multiprocessing(Pool) 사용한 데이터 처리 속도 개선

 

·       Version : MAC OS, Python 3.X, PIP3

 

대용량 데이터를 효율적으로 처리하기 위해서는 병렬 처리를 활용하는것이 좋다. 대부분의 머신러닝/딥러닝에 사용되는 프레임워크들은 함수 내부에서 병렬처리가 가능하도록 설계되어 있기 때문에 시스템의 자원을 효율적으로 사용하지만, 일반적으로 많이 사용되는 데이터 가공 모듈인 pandas 같은 모듈은 병렬처리를 기본적으로 제공하지 않기 떄분에 별도의 병렬처리가 가능하도록 코딩을 해야한다.

 파이썬에서 병렬처리를 제공하는 대표적인 라이브러리는 Threading Multiprocessing 모듈이다. Threading 모들은 파이썬의 GIL(Global Interpreter Lock)라는불리우는 잠금 모델을 사용하기 때문에I/O 작업이 아닌 CPU 작업이 많을 경우 오히려 성능이 저하된다. 방식은 Lock 풀고 스레드를 교환하고 다시 Lock 거는 형태의 멀티스레드이기 떄문이다.

파이썬에서는 Multiprocessing 권장하고 있으며,   모듈에는 대표적으로 Pool Process 있지만 이번 글에서는 Pool 대해서 다루기로 한다.

 

아래 실습코드는 1에서 12까지 숫자를 1 간격으로 출력하는데, for 문을 사용한 싱글처리와 Pool 사용하여 병렬 처리를 하였을때의 처리 시간 할당된 프로세스를 확인한다.

import os

import multiprocessing as mp

from multiprocessing import Pool

import threading

import time

import datetime

 

def non_multiprocess():

    print("non multiprocess")

    start = int(time.time())

   

    for i in range(1,12):

        work_func(i)

 

    end = int(time.time())

 

    print("Number of Core : " + str(mp.cpu_count()))

    print("***run time(sec) : ", end-start)   

 

def multiprocess():

    print("non multiprocess")

 

     #멀티 프로세싱을 위한 CPU 숫자 확인 만들기

    num_cores = mp.cpu_count()

    pool = Pool(num_cores)

 

    start = int(time.time())

 

    ojbect_list = []

    for i in range(1,100):

        ojbect_list.append(i)

    #멀티 프로세싱 워커 호출

    pool.map(work_func, ojbect_list)

 

    end = int(time.time())

 

    #메모리 방지 위해 사용

    pool.close()

    pool.join()

 

    print("Number of Core : " + str(mp.cpu_count()))

    print("***run time(sec) : ", end-start)   

 

def work_func(x):

    print("time : " + str(datetime.datetime.today()) +  "value :" + str(x)  + " PID : "  + str(os.getpid()))

   

    time.sleep(1)

 

if __name__ == '__main__':

# execute only if run as a script

    #non_multiprocess()

    multiprocess()

   

 

 

코드를 실행하면 아래와 같은 결과를 확인할 있다. non multiprocess 라고 되어 있는 결과는 for문을 사용한 싱글 프로세스이며, 개의 프로세스(PID : 49650) 사용되었으며, 순차적으로 실행되어 12초의 시간이 소요된 것을 확인할 있다. Multiprocess 경우 동시에 6개의 프로세스(필자의 테스트 컴퓨터는 6core이다.) 할당되었으며 PID 다른것을 확인할 있다. 전체 실행시간은 2초가 소요된 것을 확인할 있다.

 

간단한 테스트에서는 Multiprocessing 대한 효과를 크게 느끼지 못할수도 있으나 데이터가 기하급수적으로 커질때에는 데이터 처리 속도에 따른 시간이 엄청나게 차이난다.

 

 

2021-03-01/ Sungwook Kang / http://sungwookkang.com

 

파이선파이썬, python, 병렬처리, Multiprocessing, Python Multiprocessing, 파이썬 병렬처리, 데이터 처리, Data Processing

 

Python에서 Yahoo 주식 데이터 가져오기

 

·       Version : MAC OS, Python 3.X, PIP3

 

Yahoo Finance(https://finance.yahoo.com/) 에서 제공하는 API 사용하여 Python에서 주식 데이터를 가져오는 방법에 대해서 알아본다.

 

Yahoo Finance API 종류가 다양하며 API에서 제공하는 데이터도 조금씩 다르다. 단순한 시계열 데이터 부터, 기업 재무제표를 제공하는 API 다양하게 제공한다. 다양한 파이썬 패키지로 제공되고 있으며 아래 링크에서 확인할 있다.

·       yahoo-finance-api : https://github.com/topics/yahoo-finance-api?l=python

이번 포스트에서는 일일 주가 데이터를 제공하는 yfinance라는 파이썬 패키지를 사용하였다.

pip3 install yfinance --user

 

패키지 설치가 완료 되었으면, yfinance import하고 원하는 종목명 날짜를 입력하면 데이터를 가져올 있다.아래 예시는 AAPL(APPLE inc) 주가 데이터를 2020 12 1일부터 데이터를 가져온다.

import yfinance as yf

yf.download('AAPL', start = '2020-12-01')

 

 

2 이상의 종목에 대한 데이터를 가져올 경우, list 형식으로 사용할 있다.

yf.download(['AAPL', 'F'],start = '2020-12-01')

 

 

배당이나, 분할, 애널리스트 평가 정보도 yfinance 패키지에서 확인할 있다.

aapl = yf.Ticker('AAPL')

 

배당 내역

aapl.dividends

분할 내역

aapl.splits

애널리스트 평가

aapl.recommendations

 

지금까지 파이썬으로 패키지를 사용하여 데이터를 가져오는것을 실습하였는데, 이렇게 수집된 데이터를 나만의 데이터베이스로 만들고, 각종 지표를 만들어서 비교해봄으로써, 의미있는 2, 3 데이터를 만들어내는것이 중요하다. 단순히 주가의 가격 변동이나 흐름이 아닌, 시장의 방향과 주가의 방향이 매칭되는 종목을 찾고, 다양한 변수를 대입하여 종목을 추천할 있는 알고리즘을 만든다면, 직감이나 일부 정보만을 가지고, 이른바 바라는 주식투자가 아닌 공학 관점에서 가까이 투자할 있지 않을까 생각해 본다.

 

 

 

2020-12-28/ Sungwook Kang / http://sungwookkang.com

 

파이선, 파이썬, python, 주식 데이터 가져오기, 파이썬 주식, 금융공학, 주식 분석, 미국 주식 

 

Python에서 Tesseract 사용하기

 

·       Version : MAC OS, Python 3.X, PIP3

 

이전 포스트에서 Tesseract 오픈소스 소프트웨어를 사용하여 이미지에 포함된 문자열을 추출하는 방법에 대해서 알아 보았다.

·       Tesseract 활용한 이미지 문자인식 : https://sungwookkang.com/1475

 

다른 포스트에도 언급한바 있지만, 이미지의 경우 배경 색상이나, 글꼴, 언어 타입에 따라 인식률에 차이가 크므로, 전처리 과정이 수반되어야 어느정도 정확도를 높일 있다. OpenCV 오픈소스로 공개된 다양한 이미지 처리 모듈을 사용하기 위해서는 파이썬을 활용할 있는데, 시작으로 파이썬에서 Tesseract 임포트하여 사용하는 방법을 설명한다. 이번 포스트의 내용을 따라하기 전에, Tesseract 프로그램이 설치되어 있어야 한다.

 

Python3.X PIP3 설치 한다. 그리고 아래 명령을 사용하여 Tesseract패키지를 설치 한다. 설치과정에서 Permission 문제가 발생하면 –user 명령을 함께 사용한다.

pip3 install pytesseract --user

pip3 install opencv-python --user

 

Python3 실행하여 아래 코드를 작성한다.

from PIL import Image

from pytesseract import *

import re

import cv2

 

img = Image.open('이미지파일명')

 

text = pytesseract.image_to_string(img,lang='euc') #한글은 'kor'

#간혹 lang 오류가 발생할경우, lang 파라메터 제거

#text = pytesseract.image_to_string(img)

 

print(text)

 

아래 결과는 인터넷에서 어느 식당에서 메뉴 사진을 찍은 이미지에서 메뉴와 가격을 추출한것이다. 아직 데이터가 정제되지 않은 상태이며 한글과 영어가 섞여 있는데, 한글은 판독하지 못한것을 확인할 있다.

 

실제 추출된 문자열에서 데이터로 활용하려면, 이미지 인식 개선, 다양한 문자열 인식, 데이터 가공을 통한 유요한 데이터 추출 등의 작업이 추가되어야 한다. 이러한 작업을 하나의 프로그램으로 만들기 위해서 오늘 실습한 코드에서 점진적으로 코드가 추가될 예정이다.

 

 

2020-12-18/ Sungwook Kang / http://sungwookkang.com

 

이미지 인식, OCR, Tesseract, 문자열 인식, OpenCV, 딥러닝, 머신러닝, 글자 인식, 이미지 분석, 파이선, 파이썬, python

 

Tesseract 활용한 이미지 문자인식

 

Tesseract 이미지로부터 텍스트를 인식하고 추출하는 소프트웨어이며 HP 연구에서에서 개발된 오픈소스 OCR 엔진이다. 현재까지도 LSTM(Long short-term memory) 같은 딥러닝 방식을 통해 텍스트 인식률을 지속적으로 개선하고 있다. Tesseract 사용하기 위해서는 관련 프로그램을 설치 해야한다. 프로그램은 아래 주소에서 다운로드 받을 있다.

·       https://github.com/tesseract-ocr/tesseract/wiki

 

필자의 경우 MAC OS에서 설치를 진행하였으며 home brew 사용하여 설치 하였다.

brew install tesseract

 

brew 설치한 경우 아래 명령으로 설치된 경로를 확인할 있다.

brew list tesseract

 

 

설치가 완료 되었으면, 이미지 파일을 읽어 문자열을 출력하도록 한다. 배경색상과 글자색상에 따른 이미지 인식률을 확인하기 위해 3가지 케이스를 테스트하였다. 실행명령은 아래와 같다.

tesseract /이미지경로/파일명 stdout

 

Image

Results

 

출력 결과를 살펴보면, 배경색과 글자색의 대비가 높을 수록 높은 인식률을 나타내고 있다. 또한 이미지속의 글자가 단순하고, 글꼴에 따라서도 인식률이 다르게 나타나는것을 확인할 있다. 글에는 포함되어 있지 않지만, 한글과 영어에 따른 인식률 차이도 발생함을 확인할 있었다.

이처럼 전체 텍스트 구조를 분석하고 인식하는 과정에 다양한 오차가 발생하기 때문에, 이미지의 인식률을 높이기 위한 전처리 과정이 필요하며, 대표적으로 OpenCV 사용하여 배경과 글자를 분리하여  작업을 진행할 있다.

 

 

 

2020-12-17/ Sungwook Kang / http://sungwookkang.com

 

이미지 인식, OCR, Tesseract, 문자열 인식, OpenCV, 딥러닝, 머신러닝, 글자 인식, 이미지 분석

 

Hive UDF (사용자 정의 함수)

 

·       Version : Hive

 

Hive UDF(User Define Function, 사용자 정의 함수) 사용자에게 HiveQL 확장할 있게 해주는 하이브의 강력한 기능이다. 자바를 이용해 구현하며 세션에 추가되면 마치 내장 함수처럼 동작하고 심지어 온라인 도움말도 제공할 있다. UDF 사용하면 하이브 쿼리가 동작하는 동일한 프로세스 안에서 마치 태스크처럼 돌아간다. 그러므로 효과적으로 동작하고 다른 시스템과의 통합 과정에서 발생하는 복잡함을 제거할 있다.

 

현재 하이브 세션에 로드된 내장함수는 SHOW FUNCTIONS 명령어를 사용하여 목록을 확인할 있다.

hive>show functions;

 

함수는 보통 자신을 설명하는 문서를 가지고 있으며 DESCRIBE FUNCTION 명령어를 사용하여 간략한 설명을 볼수 있다. EXTENDED 예약어로 확장 문서를 확인할 수도 있다.

hive>describe function concat;

 

hive>describe function extended concat;

 

함수를 사용할면 쿼리 안에서 필요한 인자를 넣고 간단히 이름으로 호출하면 된다. 어떤 함수는 지정된 개수의 인자를 받기도 하며, 어떤 함수는 인자와 데이터 형식을 받기도 하는등, 함수에 따라 필요 인수가 다를수 있다.

일반적으로 표준함수라 불리는, 하나의 로우 또는 하나 이상의 컬럼을 받아서 하나의 값을 반환하는 함수는 데이터형을 변환 (DOUBLE-> BIGINT)하거나 round(), floor(),  절대값을 계산하는 abs() 함수 같은 수학함수가 있으며, 대소문자 전환, 문자열 뒤집기, 문자열 연결등과 같은 문자열 조작 함수 등이 있다.

 

집계함수(aggregate function) 사용자 정의와 내장된 모든 집계 함수를 포함하여 0 이상의 로우 또는 하나 이상의 컬럼을 받아서 하나의 결과값을 반환한다. 대표적인 함수로 sum(), avg(), min(), max() 등이 있다.

 

테이블 생성함수(table generating function 0 또는 이상의 입력을 받아서 여러 컬럼 또는 로우를 결과값으로 생성한다. 대표적으로 array 함수가 있으며, explode() 함수는 배열을 입력받아서 배열의 요소를 ROW 반환한다.

 

2020-11-12 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, 하이브 사용자 함수, 하이브 UDF, Hive UDF, User Define Function, Hive Function

Hive Thrift Service (쓰리프트 서비스)

 

·       Version : Hive

 

Hive 하이브 서버(Hive Server) 또는 하이브 쓰리프트(Hive Thrift) 불리는 구성요소를 가지고 있다. 쓰리프트는 확장성과 서로 다른 언어간에 통신이 가능한 소프트웨어 프레임워크이다. 구성요소를 통해 클라이언트는 하나의 포트(Port) 하이브에 접근할 있다.

CLI 하이브를 접근하는 가능 일방적인 방식이다. CLI 모든 하이브 구성요소 설정이 로컬에 복사본으로 존재해야만 동작한다. 마찬가지로 하둡 클리아언트와 하둡 설정도 있어야 한다. 하이브 CLI HDFS 클라이언트, 맵리듀스 클라이언트, JDBC 클라이언트(메타스토어 접속용) 동작한다.

 

하이브 서비스는 쓰리프트를 이용한다. 쓰리프트는 인터페이스 언어를 제공한다. 쓰리프트 컴파일러는 인터페이스를 해석하여 다양한 언어로 네트워크 RPC 클라이언트 코드를 생성한다. 하이브는 자바로 작성되었고, 자바 바이트 코드(bytecode) 범용 플랫폼이므로 쓰리프트 서버를 위한 자바 클라이언트를 하이브 배포에 포함하고 있다. 클라이언트를 사용하는 방법중 하나는 자바 통합 개발 환경으로 프로젝트를 시작해 관련 라이브러리를 직접 포함시키거나 메이븐을 통해 가져오는 방법이 있다.

 

하이브 서비스는 쓰리프트를 통해 하이브 메타스토어에 접속한다. 일반적으로 사용자는 메타스토어를 직접 수정하는 메타스토어 메소드를 사용하지 말고 하이브를 통해 HiveQL 언어를 이용해야한다. 사용자는 테이블에 관한 메타 정보만 제공하는 읽기 전용 메소드를 사용하는것이 좋다.

 

하이브 CLI /tmp hadoop.tmp.dir 디렉터리에 .hivehistory 같은 산출물을 만들어 낸다. 하이브 서비스는 하둡 잡이 실행되는 시작점이기 때문에 하이브 서비스를 배치할 몇가지 고려할 점이 있다. 특히 클라이언트 장비에서하던 태스크 계획, 관리 작업이 서버에서 실행되기 때문에 여러 클라이언트의 동시 실행시 서비스 오버헤드를 줄이기 위하 부하 분산으로 TCP load balance 이용하거나 백엔스 서버의 pool 접속하는 프록시를 만들어 사용하는것이 좋다. 또한 하이브는 hive.start.cleanup.scratchdir 이라는 속성을 통해 재시작시 scratch 디렉터리를 비운다. 기본값은 false이며, true 변경하여 재시작시 디렉터리를 클린업 있다.

 

일반적으로 하이브 세션은 메타스토어로 이용하는 JDBC 데이터베이스에 직접 연결된다. 하이브는 쓰리프트 메타스토어(ThriftMetastore)라는 선택적 구성요소를 제공하는데, 이를 설치하면 하이브 클라이언트는 쓰리프트 메타스토어로 연결되고 쓰리프트 메타스토어가 JDBC 데이터베이스에 연결된다.

 

 

 

 

 

2020-11-08 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 쓰리프트, Hive Thrift, 하이브 관리, Hive Management

Hive 보안 인증, 권한 부여

 

·       Version : Hive

 

하둡은 보안강화를 위해 커버로스(Kerberos)인증을 지원한다. 커버로스 인증은 서버와 클라이언트 간의 상호 인증을 지원한다. 더이상 hadoop. job.ugi 속성을 설정하여 다른 사용자인척 없다. 하지만 이렇게 동작하려면 모든 하둡 구성요소는 커버로스 보안을 양쪽 끝에서 지원해야한다.  모든 하둡 에코 시스템이 커버로스 인증을 지원 못하듯이, 하이브 인증도 완전하지 않다. 하이브는 메타스토어에 접속하기 위해서 JDBC 데이터베이스 연결을 사용하거나 사용자를 대신해서 동작을 수행하는 쓰리프트를 사용한다. 쓰리프트 기반의 하이브 서비스 역시 다른 사용자인척 해야한다. 소유자와 그룹이 파일에 대한 소유권을 갖는 하둡의 파일 소유 모델은 테이블에서 로우나 컬럼 기반 방식으로 접근을 허용하고 금지하도록 구현된 많은 데이터베이스의 방식과 다르다.

앞에 설명한 파일 소유 모델 때문에 파일과 디렉터리의 소유가 서로 다른 사용자라면 파일에 퍼미션(permission) 부여하는 일이 중요하다.  HDFS 퍼미션 시스템은  user, group, others 요소가 있으며 read, write, execute라는 퍼미션이 있다. 하이브는 hive.files.umask.value 속성을 가지고 있는데 설정으로 새롭게 생성하는 파일의 기본 퍼미션을 비트 마스크를 통해서 설정한다. Hadoop Hive 사용자의 구성에 따라 664 권한인 0002 파일 권한 비트 마스크를 만들 있다.

<property> 

  <name>hive.files.umask.value</name> 

  <value>0002</value> 

  <description>The dfs.umask value for the hive created folders</description> 

</property>

 

hive.metastore.authorization.storage.checks 속성을 true 설정하면 테이블 내부에 사용자가 지울 있는 퍼미션을 갖지 못한 파일이 있을때 하이브는 해당 테이블을 드롭하는 것을 방지한다. 속성의 기본값은 false 이며 true 설정해야 한다.

<property> 

  <name>hive.metastore.authorization.storage.checks</name> 

  <value>true</value> 

  <description>Should the metastore do authorization checks against 

  the underlying storage for operations like drop-partition (disallow 

  the drop-partition if the user in question doesn't have permissions 

  to delete the corresponding directory on the storage).</description> 

</property>

 

동시에 Hive hive.metastore.execute.setugi 가능한 true 설정한다. 안전하지 않은 모드에서 속성을 true 설정하면 메타 스토어가 사용자 그룹의 권한을 정의하는 DFS 작업을 수행한다.

 

Hive 인증을 활성화 하는 방법은 hive.security.authorization.enabled true 설정한다. 기본값은 false이다.

<property> 

  <name>hive.security.authorization.enabled</name>  

  <value>true</value> 

  <description>Enable or disable the hive client authorization</description> 

</property>

 

hive.security.authorization.createtable.owner.grants 속성에서는 테이블 생성자가 접근할 있는 권한을 구성한다. 기본값은 null이며, ALL 설정하여 사용자가 자신이 만든 테이블에 액세스 있도록 한다.

<property> 

  <name>hive.security.authorization.createtable.owner.grants</name> 

  <value>ALL</value> 

  <description>The privileges automatically granted to the owner whenever 

  a table gets created.An example like "select,drop" will grant select 

  and drop privilege to the owner of the table</description> 

</property> 

 

아래 스크립트는 Hive명령으로 사용자 인증을 활성화 한다. 권한이 없을 경우 아래 예제 스크립트와 같이 테이블 생성시 오류가 발생한다.

hive> set hive.security.authorization.enabled=true;   

 

hive> CREATE TABLE auth_test (key int, value string);   

 

Authorization failed:No privilege 'Create' found for outputs { database:default}.   

Use show grant to get more details

 

권한을 부여하기 위해서는 아래 스크립트를 사용할수 있다. 사용자(USER), 그룹(GROUP), 역할(ROLES) 같은 다양한 주제에 권한을 부여할 있다.

hive> set system:user.name; 

 

system:user.name=hadoop 

 

hive> GRANT CREATE ON DATABASE default TO USER hadoop; 

 

hive> CREATE TABLE auth_test (key INT, value STRING); 

 

Confirm the permissions we have with the SHOW GRANT command:

hive> SHOW GRANT USER hadoop ON DATABASE default;   

database default   

principalName hadoop   

principalType USER   

privilege Create   

grantTime Sun May 06 17:18:10 EDT 2018   

grantor hadoop

 

사용자별로 퍼미션을 부여하는 작업은 사용자와 테이블이 많을수록 관리 부담이 증가한다. 이런경우 그룹 단위로 퍼미션을 부여할 있다. 하이브에서 그룹은 사용자의 번째 POSIX 그룹과 동일하다.

hive> CREATE TABLE auth_test_group(a int,b int); 

 

hive> SELECT * FROM auth_test_group;

 

Authorization failed:No privilege 'Select' found for inputs 

{ database:default, table:auth_test_group, columnName:a}. 

Use show grant to get more details. 

hive> GRANT SELECT on table auth_test_group to group hadoop; 

hive> SELECT * FROM auth_test_group; 

OK 

Time taken: 0.119 seconds

 

사용자와 그룹 퍼미션이 충분히 유연하지 않은경우 역할(role) 사용할 있다. 사용자에게 역할을 부여하고 특권이 역할에 부여될수 있다. 시스템 외부에서 제어하는 그룹과는 달리 역할은 하이브 내부에서 제어되므로 좀더 유연성을 제공한다.

hive> set system:user.name; 

 

system:user.name=hadoop 

 

hive> GRANT CREATE ON DATABASE default TO USER hadoop; 

 

hive> CREATE TABLE auth_test (key INT, value STRING); 

 

Confirm the permissions we have with the SHOW GRANT command:

hive> SHOW GRANT USER hadoop ON DATABASE default;   

database default    

principalName hadoop   

principalType USER   

privilege Create   

grantTime Sun May 06 17:18:10 EDT 2018   

grantor hadoop

 

기본적으로 파티션 테이블의 권한은 테이블의 권한을 따르거나  파티션에 대한 권한 메커니즘을 설정할 있다. 테이블 속성의 PARTITION_LEVEL_PRIVILEGE true 설정하여 사용할 있다.

hive> ALTER TABLE auth_part 

> SET TBLPROPERTIES ("PARTITION_LEVEL_PRIVILEGE"="TRUE"); 

Authorization failed:No privilege 'Alter' found for inputs 

{database:default, table:auth_part}. 

Use show grant to get more details.

 

일반 사용자는 쿼리를 수행하기 위해서 스스로 특권을 부여하는 번거로움 없이 테이블을 생성하고 싶을 것이다. 또는 기본 동작으로 모든 특권을 부여하여 사용하고 싶을 것이다. 아래 스크립트는 SELECT DROP 특권을 자신 소유의 테이블에 자동으로 권한을 부여한다.

<property> 

  <name>hive.security.authorization.createtable.owner.grants</name> 

  <value>select,drop</value> 

</property>

 

비슷하게 특정 사용자는 생성한 테이블에 대한 특권을 자동으로 부여받을수 있다. 아래 스크립트는 sungwook, sqlmvp 사용자가 모든 테이블을 읽을수 있는 권한을 부여한다. 그리고 tom 테이블 생성만 가능하다.

<property> 

  <name>hive.security.authorization.createtable.user.grants</name> 

  <value>sungwook,sqlmvp:select;tom:create</value> 

</property>

 

동일한 구성을 그룹 권한 역할 권한에도 적용할 있다.

hive.security.authorization.createtable.group.grants 

hive.security.authorization.createtable.role.grants

 

권한을 회수하는 방법은 아래 스크립트를 사용한다.

revoke create on database default from user sungwook;

revoke select on database default from group sungwook; 

 

 

 

[참고자료]

·       Hive - Authority Management (Authorization) : https://www.programmersought.com/article/1095315821/

 

 

2020-10-27 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, 하이브 보안, 하이브 인증, 하이브 권한, Hive Security, Hive Authorization, Hive Authority Management

Hive 잠금(lock)

 

·       Version : Hive

 

HiveQL SQL 유사하지만 잠금(locking) 대한 메커니즘은 완전히 다르다. SQL 비교한다면 매우 부족한 lock 모델을 가지고 있다. 하둡이 제한된 의미의 이어쓰기 (append) 지원하고 있지만 전통적으로는 write-once(한번쓰면 변경이 불가능하다는 의미) 특성을 가지고 있기 때문에 이러한 특성과 맵리듀스의 스트리밍 읽기 방식으로 인해 세밀한 잠금에 대한 접근은 불필요하기 때문이다.

그러나 하둡은 다중 사용자 시스템이기 때문에 잠금과 코디네이션이 필요할수도 있다. 예를들어 INSERT OVERWRITE 쿼리는 테이블의 모든 내용을 덮어쓰고 다른 사용자가 동시에 테이블에 쿼리를 시도하면 쿼리가 실패하거나 잘못된 결과를 반환할 있기 때문에 명시적으로 테이블에 잠금이 필요할 수도 있다.

하이브는 아파치 주키퍼(Apache Zookeeper) 이용하여 잠금을 제공한다. 주키퍼는 분산 코디네이션을 구현한 오픈소스로 Kafka 분산 코디네이션이 필요한 환경에서 많이 사용 한다. 하이브에서 주키퍼를 코디네이션으로 사용하려면 주피커 쿼럼 노드를 등록해야한다. hive-site.xml에서 설정할 있다.

#통신할 주키퍼 목록을 등록, 읽기/쓰기 잠금을 위해서만 필요

<property>

  <name>hive.zookeeper.quorum</name>

  <value>hadoopcluster01:2181,hadoopcluster02:2181</value>

</property>

 

#동시성을 제공할지 설정, 최소 하나의 주키퍼가 등록되어 있어야 한다.

<property>

  <name>hive.support.concurrency</name>

  <value>true</value>

</property>

 

설정으로 하이브는 쿼리를 실행할때 자동으로 잠금이 지원되며 현재 모든 잠금 목록을 확인하기 위해서는 아래 스크립트를 실행한다.

hive> show locks;

hive>show locks 테이블명 extended;

 

동시성 기능이 true 설정되어 있는 경우 하이브는 자동으로 가지 종류의 잠금 기능을 제공한다. 테이블을 읽을 때에는 공유 잠금(shared lock) 사용하고, 테이블을 수정할 때는 배타적 잠금(exclusive lock) 사용한다. 테이블이 파티션닝 되어 있을때 파티션에 대한 베타적 잠금을 얻게 되면 파티션이 수정되는 동안 테이블 삭제 시도와 같은 동시 변경이 발생되지 못하도록 테이블 자체에 공유 잠금을 건다. 베타적 잠금은 테이블의 모든 파티션에 영향을 미친다.

 

명시적으로 잠금을 관리할수도 있으며 아래 스크립트는 명시적으로 베타 잠금을 생성한다.

hive>lock table 테이블명 exclusive;

 

명시적 잠금 해제는 unlock 명령을 사용한다.

hive>unlock table 테이블명;

 

 

[참고자료]

https://cloudera.ericlin.me/2015/05/how-table-locking-works-in-hive/

 

 

 

 

2020-10-22 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, 하이브락, hive lock, 하이브 잠금

Hive 투기적 실행(Speculative execution)

 

·       Version : Hive

 

Hive에서 투기적 실행(Speculative execution)이라 불리는 기능은 하나의 잡을 중복된 태스크로 구성하여 동시에 수행 시키는 하둡의 기능이다. 같은 데이터를 중복하여 복사하기 때문에 많은 리소스를 사용하며, 대부분의 데이터는 버려진다. 기능의 목적은 느리게 동직하는 태스크 트래커를 제거함으로써 개별 태스크의 결과가 빨리 도출되고 결과적으로 전체 수행을 향상시키는데 있다.

, 동일한 태스크를 여러노드에서 실행함으로써, 특정 노드가 느리더라도 (장비 노후 또는 기타 문제로) 다른 노드에서 먼저 끝나면 해당 결과를 사용하고 나머지 노드는 중지 시킨다. 그래서 전체적으로는 수행시간이 단축된다.

Speculative execution 기능 활성화는 mapred-site.xml에서 아래 속성을 true 설정한다.

mapreduce.map.speculative

mapreduce.reduce.speculative

 

Speculative execution 기능은 실시간성이 중요한 잡의 경우 활성화 하여 사용하는 것이 전체적인 응답시간 향상에 이득이 있다. 하지만 입력 데이터 때문에 오래 걸리는 또는 리듀스 태스크에는 높은 오버헤드로 인해서 사용하지 않는것을 추천한다.

 

 

[참고자료]

·       https://community.cloudera.com/t5/Support-Questions/what-is-speculative-execution/td-p/241741

·       https://www.slideshare.net/Hadoop_Summit/t-325p210-cnoguchi

 

 

2020-10-19 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, MapReduce최적화, Map태스크, Reduce 태스크, 하이브 최적화, 투기적 실행, mapreduce.map.speculative, mapreduce.reduce.speculative, Speculative Execution

Hive 자바 가상 머신 재사용

 

·       Version : Hive

 

하둡에서 맵리듀스 태스크를 실행하면 기본적으로 자바 가상 머신이 실행되고 위에서 또는 리듀서 태스크를 실행한다. 하둡의 기본 설정은 일반적으로 포크(forked) 자바 가상 머신을 사용한다. 자바 가상 머신은 가동할 오버헤드가 있기 때문에, 가상 머신의 재사용은 하이브 성능과 매우 밀접한 관계가 있다. 특히 작은 파일을 처리해야하는 경우나 태스크 수행시간이 짧은 작업의 경우 자바 가상 머신을 재사용하면 매우 효율이 좋다. 만약 수십, 수백번의 태스크를 가진 잡을 수행할때 자바 가상 머신 인스턴스를 재사용한다면 동일한 잡에 N 재사용된다. 가상 머신의 재사용 설정은 하둡의 mapred-site.xml에서 설정할 있다.

mapred.job.reuse.jvm.num.tasks= 10

자바 가상 머신 하나당 번의 태스크를 수행할지 설정 -1 설정할 경우 제한이 없음.

 

자바 가상 머신을 재사용할 경우, 잡을 실행할때마다  가상 머신이 새로 가동되는 오버헤드를 줄일 있지만, 예약된 태스크 슬롯을 잡이 완료할 때까지 점유하고 있는 단점이 있다. 예를들어 잡이  병렬로 실행될때, 먼저 끝난 가상 머신은 유휴 상태로 대기하게 되고 마지막 작업이 완료되기 전까지다른 잡이 사용하지 못하는 상태가 된다. 물론 다른 잡은 다른 자바 가상 머신을 생성해서 사용하지만, 이러한 불균형이 지속적으로 발생한다면 리소스 병목이 발생할 있다.  

 

 

 

2020-10-14 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, MapReduce최적화, Map태스크, Reduce 태스크, 하이브 최적화, 자바 가상 머신, JVM

Hive Mapper, Reduce 개수 최적화

 

·       Version : Hive

 

하이브는 쿼리를 이상의 맵리듀스 잡으로 나누어 병렬로 처리한다. 맵리듀스는 다수의 맵퍼와 리듀서 태스크로 실행되는데 맵퍼와 리듀서의 수는 입력하는 데이터 크기, 데이터 수행 연산 종류 다양한 변수에 의존적이다. 너무 많은 맵퍼와 리듀서 태스크는 잡을 초기화 하고, 스케줄링하고 실행하기 위해 많은 오버헤드를 유발한다. 반대로 너무 적은 태스크는 클러스터가 가진 병렬처리의 장점을 활용하지 못하게 된다.

 

리듀스 단계가 있는 하이브 쿼리를 실행하면 리듀서 수를 출력한다. GROUP BY 항상 리듀서 단계가 필요하기 때문에 해당 구문이 포함한스크립트를 실행하면 사용된 맵퍼와 리듀서의 개수를 확인할 있다.

INFO  : Hadoop job information for Stage-1: number of mappers: 5; number of reducers: 1

INFO  : 2020-09-29 22:31:55,395 Stage-1 map = 0%,  reduce = 0%

INFO  : 2020-09-29 22:32:04,712 Stage-1 map = 20%,  reduce = 0%, Cumulative CPU 5.03 sec

INFO  : 2020-09-29 22:32:05,749 Stage-1 map = 60%,  reduce = 0%, Cumulative CPU 12.13 sec

INFO  : 2020-09-29 22:32:09,885 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 19.8 sec

INFO  : 2020-09-29 22:32:16,080 Stage-1 map = 100%,  reduce = 100%, Cumulative CPU 25.89 sec

INFO  : MapReduce Total cumulative CPU time: 25 seconds 890 msec

INFO  : Ended Job = job_1591911716086_1525

INFO  : MapReduce Jobs Launched:

INFO  : Stage-Stage-1: Map: 5  Reduce: 1   Cumulative CPU: 25.89 sec   HDFS Read: 610485 HDFS Write: 775295 HDFS EC Read: 0 SUCCESS

INFO  : Total MapReduce CPU Time Spent: 25 seconds 890 msec

INFO  : Completed executing command(queryId=hive_20200929223144_877a1f4b-329b-4418-831d-89bcdc466f30); Time taken: 33.485 seconds

INFO  : OK

 

하이브는 입력 크기에 따라 리듀서 개수를 정한다. fs -count 명령을 사용하여 하둡에서 사용하려는 파일을 지정하여 예상 리듀서의 개수를 확인할 있다.

hadoop fs -count /user/data/nclick/file.txt

 

결과

0            1           12469765 /user/data/nclick/file.txt

 

리듀서의 개수는 하이브 속성중  hive.exec.reducers.bytes.per.reducer 설정된 수자를 파일 크기와 나눈값으로 계산할 있다. 설정 값은 사용자마다 다를 있다. 아래 스크립트는 hive.exec.reducers.bytes.per.reducer 속성값을 수정하는 명령이다. 단위가 바이트임을 주의한다.

set hive.exec.reducers.bytes.per.reducer=75000000

 

쿼리의 단계에서 입력 데이터 크기보다 훨씬 많은 데이터를 만들어내는 경우가 있다. 단계에서 과도한 데이터를 만들어내면 입력 데이터로 추정한 기본 리듀서의 수는 부족할 있으며 비슷하게 함수가 입력 데이터의 많은 부분을 필터링 수도 있다. 그러면 기본값보다 적은 리듀서만 있어도 된다.리듀서의 태스크 수는 mapred.reduce.tasks 설정값으로 조절할 있다.

 

하둡 클러스터에는 태스크를 할당하는 고정된 크기의 슬롯이 있다. 개의큰 잡이 하둡의 모든 슬롯을 점유하면 다른 잡이 시작되지 못할 있다. hive.exec.reducers.max 설정 값을 조절하여 쿼리가 너무 많은 리듀서 자원을 사용하는 것을 예방할 있다.

 

하둡은 맵과 리듀스 태스크를 기동하고 스케줄링하는데 정도 오버헤드가 발생한다. 성능 테스트를 수행할때 이러한 요인을 염두해 두어야 하며 특히 잡의 크기가 작을수록 이러한 부분을 염두해서 테스트를 진행해야한다.

 

 

 

2020-09-29 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, MapReduce최적화, Map태스크, Reduce 태스크, 하이브 최적화

HDFS Cluster Balancing(데이터 블록 분포의 불균형 해소)

 

·       Version : HDFS

 

HDFS 시스템은 여러대의 노드가 클러스터로 동작하기 때문에 시간이 지날수록 데이터 노드의 블록 분포에 대한 불균형이 발생할 있다. 불균형 상태의 클러스터는 맵리듀스의 로컬리티에 영향을 주기 때문에 자주 사용되는 데이터노드에 많은 부하를 주게 된다. 따라서 이러한 블록의 불균형 분포를 해결하기 위해 밸런서 작업으로 블록을 재분배 하여 전체적으로 블록을 고르게 유지할 있도록 다른 노드로 블록을 이동한다. 이때 데이터 유실을 방지하기 위해 데이터 블록 복제본의 배치전략은 유지된다. 밸런서를 실행하는 명령은 아래와 같다.

sudo -u hdfs hdfs balancer

 

 

노드의 균형은 노드들의 이용률(노드에서 사용중인 공간 비율과 저장공간의 비율), 클러스터의 이용률(클러스터에서 사용중인 공간과 저장공간의 비율) 비교하여 임계치 보다 적을때 까지 실행된다. 임계치는 기본 10% 이며 클러스터에는 오직 하나의 밸런서만이 실행될 있다. 임계치 변경은 아래 명령으로 변경할 있다.

sudo -u hdfs hdfs balancer -threshold 5

 

밸런서 작업중 노드 이동에 대한 기본 대역폭은 1MB/s 이지만 hdfs-site.xml에서 dfs.balance.bandwidthPerSec 속성에서 대역폭을 설정 있으며 단위는 byte이다. 아래 명령으로도 설정이 가능하다.

dfsadmin -setBalancerBandwidth  newbandwidth

 

 

 

[참고자료]

·       How-to: Use the New HDFS Intra-DataNode Disk Balancer in Apache Hadoop : https://blog.cloudera.com/how-to-use-the-new-hdfs-intra-datanode-disk-balancer-in-apache-hadoop/

·       HDFS Balancers : https://docs.cloudera.com/documentation/enterprise/5-12-x/topics/admin_hdfs_balancer.html

 

 

 

 

2020-09-25 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, HDFS, 하둡 파일 시스템, 데이터 블록 불균형, 노드 밸런서, 하둡 밸런서, Hadoop Balancer, Cluster Balancing, 하둡 튜닝, 하둡 관리, HDFS 관리

Hive LIMIT 튜닝 (데이터 샘플링으로 빠르게 응답하기)

 

·       Version : Hive

 

하이브에서 현재 저장되어 있는 데이터의 일부분을 확인하려고 LIMIT 절을 자주 사용한다. RDB 경우 데이터를 ROW단위로 읽기때문에(정확히는 페이지 단위) ROW단위로 처리하면서LIMIT 결과를 (Sort, Group 연산을 하지 않았을 경우) 빠르게 응답할 있다.  하지만 하이브의 경우 데이터 전체에 대해 쿼리를 수행하고 일부 결과만을 반환하기 때문에 불필요한 리소스 낭비가 크다. 그래서 최대한 LIMIT 명령을 피하는 것이 좋다.

만약 limit 자주 사용할 경우 hive-site.xml 파일에서 hive.limit.optimize.enable설정을 통해서  LIMIT 사용할 경우 원본 데이터를 샘플링 있다.

<property>

       <name>hive.limit.optimize.enable</name>

       <value>false</value>

       <description>Whether to enable to optimization to trying a smaller subset of data for simple LIMIT first.</description>

</property>

 

hive.limit.optimize.enable 옵션을 True 설정하면 hive.limit.row.max.size hive.limit.optimize.limit.file 제어할 있다.

<property>

       <name>hive.limit.row.max.size</name>

       <value>100000</value>

       <description>When trying a smaller subset of data for simple LIMIT, how much size we need to guarantee each row to have at least.</description>

</property>

 

<property>

       <name>hive.limit.optimize.limit.file</name>

       <value>10</value>

       <description>When trying a smaller subset of data for simple LIMIT, maximum number of files we can sample.</description>

</property>

 

하지만 기능은 JOIN이나 GRPUP BY 같이 리듀스 과정이 필요한 모든 쿼리에서는 결과 값이 달라지기 때문에 주의해야 한다.

 

 

 

2020-09-22 / Sungwook Kang / http://sungwookkang.com

 

 

Hadoop, Big Data, 하둡, 빅데이터, 데이터분석, Hive, Hive tunning, 하이브 튜닝, limit tunning, Limit Optimize, limit sampling

+ Recent posts