Kubernetes CLI 

K8s의 기본 구성 요소 보기 >>  K8s 1) 쿠버네티스 기본 


Cluster

  • 여기에서는 EKS(Elastic Kubernetes Service)을 이용하여 클러스터를 생성 (AKS, GKE 등 대체 가능)
  • 사전 구성으로 IAM User 생성 및 AWS CLI에 Credential은 프로그래밍 방식 액세스 설정 필요

 

설치 및 사용법

 

eksctl 설치

# 이하 '$' 생략
curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin

 

kubectl 설치

#AWS CLI 버전 확인
#kubectl 접근을 위해 AWS CLI 버전 1.21 이상 유효. 1.21 이하면 업데이트 핋요
aws --version 
pip install awscli --upgrade --user

#kubectl 설치
curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
kubectl version --client

 

참조용 Cluster 생성 Flag 매트릭

eksctl create cluster \
		--name eks-an2-cnl-dev \
		--version 1.21 \
		--vpc-private-subnets SUBNET-ID-1,SUBNET-ID-2
		--without-nodegroup
eksctl create nodegroup \
		--cluster eks-an2-cnl-dev \
		--name nodegroup-an2-cnl-dev \
		--node-type t3.micro \
		--nodes 2 \
		--nodes-min 1 \
		--nodes-max 3 \
		#node-private-networking 옵션은 private-subnet 통신 과정에서 유리하게 작용
		--node-private-networking \ 
		--managed=false
        
#그 외 Flag 매트릭
General flags:
  -n, --name string               EKS cluster name (generated if unspecified, e.g. "scrumptious-sculpture-1648975311")
      --tags stringToString       A list of KV pairs used to tag the AWS resources (e.g. "Owner=John Doe,Team=Some Team") (default [])
  -r, --region string             AWS region
      --zones strings             (auto-select if unspecified)
      --version string            Kubernetes version (valid options: 1.12, 1.13, 1.14, 1.15) (default "1.14")
  -f, --config-file string        load configuration from a file (or stdin if set to '-')
      --timeout duration          maximum waiting time for any long-running operation (default 25m0s)
      --install-vpc-controllers   Install VPC controller that's required for Windows workloads
      --managed                   Create EKS-managed nodegroup
      --fargate                   Create a Fargate profile scheduling pods in the default and kube-system namespaces onto Fargate

Initial nodegroup flags:
      --nodegroup-name string          name of the nodegroup (generated if unspecified, e.g. "ng-46273157")
      --without-nodegroup              if set, initial nodegroup will not be created
  -t, --node-type string               node instance type (default "m5.large")
  -N, --nodes int                      total number of nodes (for a static ASG) (default 2)
  -m, --nodes-min int                  minimum nodes in ASG (default 2)
  -M, --nodes-max int                  maximum nodes in ASG (default 2)
      --node-volume-size int           node volume size in GB
      --node-volume-type string        node volume type (valid options: gp2, io1, sc1, st1) (default "gp2")
      --max-pods-per-node int          maximum number of pods per node (set automatically if unspecified)
      --ssh-access                     control SSH access for nodes. Uses ~/.ssh/id_rsa.pub as default key path if enabled
      --ssh-public-key string          SSH public key to use for nodes (import from local path, or use existing EC2 key pair)
      --node-ami string                Advanced use cases only. If 'ssm' is supplied (default) then eksctl will use SSM Parameter; if 'auto' is supplied then eksctl will automatically set the AMI based on version/region/instance type; if static is supplied (deprecated), then static AMIs will be used; if any other value is supplied it will override the AMI to use for the nodes. Use with extreme care.
      --node-ami-family string         Advanced use cases only. If 'AmazonLinux2' is supplied (default), then eksctl will use the official AWS EKS AMIs (Amazon Linux 2); if 'Ubuntu1804' is supplied, then eksctl will use the official Canonical EKS AMIs (Ubuntu 18.04). (default "AmazonLinux2")
  -P, --node-private-networking        whether to make nodegroup networking private
      --node-security-groups strings   Attach additional security groups to nodes, so that it can be used to allow extra ingress/egress access from/to pods
      --node-labels stringToString     Extra labels to add when registering the nodes in the nodegroup, e.g. "partition=backend,nodeclass=hugememory" (default [])
      --node-zones strings             (inherited from the cluster if unspecified)

Cluster and nodegroup add-ons flags:
      --asg-access            enable IAM policy for cluster-autoscaler
      --external-dns-access   enable IAM policy for external-dns
      --full-ecr-access       enable full access to ECR
      --appmesh-access        enable full access to AppMesh
      --alb-ingress-access    enable full access for alb-ingress-controller

VPC networking flags:
      --vpc-cidr ipNet                 global CIDR to use for VPC (default 192.168.0.0/16)
      --vpc-private-subnets strings    re-use private subnets of an existing VPC
      --vpc-public-subnets strings     re-use public subnets of an existing VPC
      --vpc-from-kops-cluster string   re-use VPC from a given kops cluster

 

Cluster 생성

#yaml 기반
eksctl create cluster -f cluster.yaml

 

Cluster 삭제

#eksctl로 생성된 클러스터만 eksctl로 삭제 가능
#삭제전 Cluster에서 실행 중인 서비스 조회
kubectl get svc --all -namespaces

#EXTERNAL-IP(LB) 삭제
kubectl delete svc <서비스 이름>

#Cluster 삭제
eksctl delete cluster --name <클러스터 이름>

#수행 LOG 마지막 줄
#2024-05-17 14:43:37 [✔]  all cluster resources were deleted

 


Pod

  • Pod는 대체적으로 container와 1:1 관계 (1:n 관계도 가능)
  • container는 Pod로 캡슐화가 되어있다.
  • k8s는 container에 직접 배포하지 않기에 캡슐화된 Pod를 배포한다.

 

Pod생성

 

kubectl run

kubectl run nginx --image nginx # nginx pod 기본 생성 명령어

#Namespace를 지정한 Pod 생성
kubectl run nginx --image nginx --namespace=<파드 이름>

#yaml 예시
apiVersion:
kind:
metadata:
	namespace:<파드 이름>
spec:

 

kubectl create

- yaml을 통해서 만드는 방식 (동일 Pod 존재할 경우 에러 발생)

kubectl ceate -f create-nginx.ymal

 

kubectl apply

- Pod가 없으면 new Pod를 생성, Pod가 존재하면 Update 한다.

kubectl apply -f apply-nginx.yaml

 

Pod 조회

kubectl get pods

#상세 조회
kubectl decribe pod nginx <오브젝트> <이름>

#nginx 파드의 상세 조회
kubectl describe pod nginx

#yaml 형식 조회
kubectl get pod nginx -o yaml

#조회 결과 output 저장
kubectl get pod nginx -o > output.yaml

#생성하지 않은 채로 output 저장
kubectl run nginx --image nginx --dry-run=client -o > yaml output.yaml

#output 조회
cat output.yaml

 

Pod 로그 조회

kubectl logs <파드 이름>

#tail -f 조회
kubectl logs -f <파드 이름>

 

Pod 삭제

kubectl delete <오브젝트> <이름>

#실행중인 nginx Pod 삭제
kubectl delete pod nginx

 

 

리소스 확인

 

Pod requests, limits 값 확인

kubectl get po -o yaml <파드 이름>

 


Deployment

  • 뒤이어 나올 ReplicaSet의 상위개념이라고 볼 수 있다.
  • ReplicaSet을 생성하는 Deployment를 정의할 수 있으며, 롤링 업데이트 등 세분화 조작할 수 있는 기능이다.

 

사용법

 

Deployment 생성

#create
kubectl create deployment <디플로이먼트 이름> --image=<이미지 이름>

#yaml
kubectl apply -f <YAML 파일>

 

Deployment 수정

kubectl edit deployment <디플로이먼트 이름>

#Deployment를 추가한 ReplicaSet Pod 설정
kubectl scale --replicas=N deployment <디플로이먼트 이름>

 

Deployment 업데이트(Roll Out)

- Pod가 실행 중인 상태에서 이미지 버전 변경 배포

- 이전 배포 정보는 스케일 다운, 새 배포는 ReplicaSet을 새로 생성하여 스케일 업

- 스케일 다운과 스케일 업은 부분적으로 동시에 발생

kubectl set image deployment/<디플로이먼트 이름> <컨테이너 이름>=<새 배포 태그>

#예시
kubectl set image deployment/sojuking-deployment nginx=nginx:1.23.4

 

Deployment Roll Out 조회

#상태 확인
kubectl rollout status deployment <디플로이먼트 이름>

#이력 확인
kubectl rollout history deployment <디플로이먼트 이름>

#리비전별 상세조회 Flag
# --revision=N

 

Deployment Roll Back

kubectl rollout undo deployment/<디플로이먼트 이름>

#특정 리비전 번호 N으로 롤백
kubectl rollout undo deployment/<디플로이먼트 이름> --to-revision=N

 

Deployment Scaling

#N개의 복제 파드 조정
kubectl scale deployment/<디플로이먼트 이름> --replicas=N

 

Deployment 조회

kubectl get deployment

#namespace
kubectl get deployment -n <네임스페이스>

 

Deployment 삭제

kubectl delete deployment <디플로이먼트 이름>

Set

ReplicaSet

  • Pod 개수를 유지하게 하는 가용성을 보증하는 장치
  • 예를 들어 Pod의 개수를 5개로 설정하였으면, Node가 다운되어 Pod가 사라져도 자동생성으로 Pod 수를 5개로 유지

 

사용법

 

ReplicaSet 생성

#create
kubectl create -f nginx-rs.yaml

#apply
kubectl apply -f nginx-rs.yaml

 

ReplicaSet 확인

#Cluster에 실행중인 ReplicaSet 조회
kubectl get rs

#ReplicaSet 상세 조회
kubectl describd rs

#yaml 형식 조회
kubectl get rs <레플리카셋 이름> -o=yaml

#Pod의 ReplicaSet 조회
kubectl get pod <파드> -o yaml

#실행 예시
kubectl get pod new-replica-set-a10jr -o yaml

#yaml 예시
apiVersion: app/v1
kind: ReplicaSet
metadata:
    name:
spec:
    template:
        metadata:
            name: <파드 이름>
            labels:
                app:
                type:
        spec:
            containers:
            - name: nginx-controller
              image: nginx
    seletor:
        matchLabels:
            type: <파드 라벨>

 

ReplicaSet Scaling

#N개의 복제 파드 조정
kubectl scale rs <레플리카셋 이름> --replicas=N

#예시
kubectl scale rs sojuking --replicas=5

 

ReplicaSet 편집

kubectl edit rs <레플리카셋 이름>

 

ReplacaSet 리소스 삭제

#리소스만 삭제
kubectl delete rs --cascade=orphan <레플리카셋 이름>

#Pod까지 삭제
kubectl delete rs <레플리카셋 이름>

 

DaemonSet

  • Cluster 내 새로운 Node가 하나 생길 때마다, Pod 복제본이 자동으로 Node에 생성 (자동 배포 기능)
  • Cluster 내 모든 Node에는 항상 1개 이상의 Pod 복사본이 존재하도록 보장

 

ReplacaSet과 마찬가지로 DaemonSet도 kind만 제외하고 정의 내용이 같다.

#yaml 예시
apiVersion: app/v1
kind: DaemonSet
metadata:
    name:
spec:
    template:
        metadata:
            name: <파드 이름>
            labels:
                app:
                type:
        spec:
            containers:
            - name: nginx-controller
              image: nginx
    seletor:
        matchLabels:
            type: <파드 라벨>

 

StatefulSet

  • StatefulSet은 각 파드의 독자성을 유지
  • Pod 집합의 Deployment와 Scailing을 관리하며, Pod의 순서 및 고유성을 보장
  • 상태가 없는 앱/웹은 Deployment로 배포, 상태가 있는 DB 같은 경우는 StatefulSet으로 배포한다.

 

 StatefulSet은 Cluster IP가 없는 헤드리스 서비스를 사용해야 한다.

vi soju-sts.yaml

#yaml 예시
apiVersion: app/v1
kind: StatefulSet
metadata:
    name: soju-sts
spec:
  selector:
    matchLabels:
      app: soju-sts
  serviceName: soju-svc-headless #추가된 헤드리스 서비스 이름
  replicas: 2
  template:
    metadata:
      labels:
        app: soju-sts
    spec:
      containers:
      - name: myapp
        image: ghcr.io/fn1vkd2/go-myweb:lupine
        ports:
        - containerPort: 8080

 

Cluster IP가 없는 Service

vi soju-svc-headless.yaml #StatefulSet에 정의한 헤드리스 서비스의 본체

apiVersion: v1
kind: Service
metadata:
  name: soju-svc-headless
  labels:
    app: soju-svc-headless
spec:
  ports:
  - name: http
    port: 80
  clusterIP: None #헤드리스 서비스 정의( Cluster IP: None)
  selector:
    app: soju-sts #soju-sts.yaml의 label 조회

 

StatefulSet 생성

kubectl -f soju-sts.yaml -f soju-svc-headless.yaml

 

StatefulSet 조회

kubectl get sts, svc, ep #sts: statefulSet, svc: service, ep: endpoint

#Controller 뒤의 번호 생성 조회 (고유성)
kubectl get pod -o wide

#network-multitool 이미지 실행
kubectl run nettool --image ghcr.io/fn1vkd2/network-multitool -it --rm

#nettool < Pod 이름 생성
#--image 이미지 지정
#-it Pod를 인터랙티브 모드 실행, 터미널 할당 및 실시간 상호작용 상태
#--rm Pod 종료시 자동 Pod 삭제

#호스트 질의 - 서비스 이름 지정
host soju-svc headless

# StatefulSet + headless >> Pod의 이름으로 통신하여 Pod의 IP 변환
host soju-sts-0.soju-svc-headless
host soju-sts-1.soju-svc-headless

 


Job

Job

  • 프로세스가 종료되면 Container가 다시는 시작되지 않는 배치라 보면 된다.
  • 노드에 장애가 발생하면 ReplicaSet의 파드와 같은 방식으로 다른 노드로 재스케줄 기능이 있다.
  • 프로세스 오류일 경우 Container를 재실행하도록 할 수 있다.

YAML 리소스 구성

apiVersion: batch/v1 # API 그룹은 batch 버전 v1
kind: Job
metadata:
  name: soju-job
spec:    
  template:
    spec:
      containers:
      - name: soju-job
        image: 2.mi.g
        command: ["Job 끝내고 쐐애주나 마시자!"]
      restartPolicy: Never #Pod의 재시작 정책 설정
      completions: 2 #실행 종료되어야 하는 파드 수 설정 (기본값 1)
      parallelism: 2 #잡 병렬성 관리(기본값 1)
  backoffLimit: 2 #재시도 횟수 설정
  activeDeadlineSeconds: 100 #Pod의 실행시간 설정(넘으면 Pod 종료 시도 및 Job은 Fail)

 

Job 삭제

#Job을 삭제하면 관련 Pod도 같이 삭제가 된다.
kubectl delete job <잡 이름>

 

Cronjob

  • 반복 작업을 실행하는 데 사용하는 리소스 중 하나, 지정된 시간 또는 간격으로 작업 생성한다.
  • Linux의 crontab 기능을 떠올리면 된다.

 

YAML  리소스 구성

apiVersion: batch/v1 # API 그룹은 batch
kind: CronJob
metadata:
  name: soju-cronjob
spec:
  schedule: "*/1 * * * *"   #매 1분마다 실행
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: soju-cronjob
            image: busybox
            command: ["퇴근하고 쐐애주나 마시자!"]
          restartPolicy: OnFailure
  concurrencyPolicy: Forbid

 

CronJob 조회

kubectl get cronjobs

 

CronJob 삭제

kube delete cronjobs <크론잡 이름>

Resource 

  • 다수의 컨테이너가 Pod에 있으면 Request와 Limit은 각각의 컨테이너에 개별적으로 할당
  • Resource 중 CPU는 Resource Limit 보다 초과로 사용 불가, Memory는 사용 가능하나 Pod 다운 및 OOM 발생

 

Resource 감시

 

kubectl top 설치

-top을 사용하기 위하여 명령어로 설치

git clone https://github.com/kodekloudhub/kubernetes-metrics-server.git
cd kubernetes-metrics-server/
kubectl create -f

 

CPU, Memory 사용율 확인

#node 확인
kubectl top node

#pod 확인
kubectl top pod

 

 

Resource 제한

 

Resource Limit 

-Pod 내 리소스 사용량을 제한

apiVersion: v1
kind: Pod
metadata:
    name:
spec:
    containers:
    - name: sojuking
      image: nginx
      ports:
        - containerPort: 8080
      resources:
        requests: #요구되는 리소스 양
          memory: "2Gi"
          cpu: 2
        limit: #리소스 사용 제한
          memory: "4Gi"
          cpu: 4

 

 

Resource Quotas

- K8s 내 배포된 전체 애플리케이션이 소모하는 전체 리소스의 양을 제한

- namespace 레벨에서 적용

apiVersion: v1
kind: ResourceQuota
metadata:
  name: sojuking-quota
spec:
  hard:
    requests.cpu: 2
    requests.memory: 2Gi
    limits.cpu: 10
    limits.memory: 10Gi

krew

  • kubectl을 보다 편리하게 사용할 수 있게 해주는 Plugin 관리 도구이다.
  • kubectl v1.12 이상의 버전에서 사용 가능하다.
  • git 설치가 되어 있어야 한다.

 

설치법

 

설치 명령어

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

 

Path 추가

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

 

설치 확인

kubectl krew

 

 

사용법

 

Plugin 설치

kubectl krew install NAME <플러그인 이름>

#예시
kubectl krew install sojuking

 

Plugim 사용

kubectl <플러그인 이름>

 

Plugin 업데이트

kubectl krew upgrade <플러그인 이름>

#모든 플러그인 업그레이드
kubectl krew upgrade

 

Plugin 검색

kubectl krew search KEYWORD

#모든 플러그인 목록 확인 (키워드 제거)
kubectl krew search

#설치 플러그인 목록 확인
kubectl krew list

 

 

Plugin 삭제

kubectl krew uninstall <플러그인 이름>

 


 

 

 

'Architecture' 카테고리의 다른 글

K8s 1) 쿠버네티스 기본  (0) 2024.05.17
Kafka 3) MSK Cluster 모니터링 메트릭  (2) 2024.01.11
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

Kubernetes

※ Docker 등 Container에 대한 기본 설명은 제외하였습니다.


K8s의 구조

  • Master에 API 서버와 상태 저장소를 두고, 각 Node(서버)의 에이전트(Kublet)와 통신하는 구조

K8s의 구조 : Master

  • K8s 클러스터 관리하는 역할
  • 노드의 상황을 파악
  • 컨테이너를 어떤 노드에서 가동할지 선택
  • etcd 분산 저장소를 사용하여 클러스터의 정보를 저장

K8s 구조 (By.Lukša)

Master

 API Server

  • API 서버는 모든 요청을 처리하는 마스터의 핵심
  • 모든 컴포넌트들은 API 서버를 통해서 커뮤니케이션함
  • 인증 및 인가 기능 보유

Scheduler

  • 컨테이너를 어떤 노드에서 가동할지 결정하는 컴포넌트
  • 노드들의 정보를 파악하고 컨테이너를 가동할 적합한 노드 선택

Controller Manager

  • K8s 클러스터의 상태를 감시
  • 시스템의 상태 감시 및 유지
  • 요청된 상태와 현재 시스템의 상태의 차이 감시

etcd 

  • 분산 key-value 저장소
  • 클러스터의 모든 설정, 상태 데이터 저장
  • 스케줄러와 컨트롤러 매니저 등이 API 서버를 통해 etcd의 데이터 조회 및 갱신
  • 마스터에서 분리하여 독자적으로 분리 가능

K8s의 구조 : Node

  • 컨테이너가 가동되는 서버
  • 다수의 노드로 클러스터를 구성
  • 클라우드의 경우 가상머신이 노드가 됨 ex.) ec2...

K8s 구조 (By.Rancher Admin)

Node

Kubelet

  • 실제로 컨테이너를 생성하는 주체
  • 마스터로부터 생성 요청을 받으면 컨테이너를 생성
  • 컨테이너의 상태를 감시하는 역할 수행
  • 컨테이너의 상태를 API 서버로 전송

Kube proxy

  • 각 노드에서 실행되는 네트워크 프록시
  • 노드의 네트워크 규칙을 유지 및 관리
  • 내부 네트워크 세션, 클러스터 외부에서 내부로 네트워크 통신

Pod

  • 한 개 또는 여러 개의 컨테이너의 묶음

 


K8s Object

  • Container, Network 등 분산에 필요한 필요 요소의 추상화

K8s Object

Object

Replica Set

  • Pod를 한 개 이상 복제하여 관리
  • Pod를 생성하고 개수 유지를 위해서 ReplicaSet을 사용해야 함

Daemon Set

  • 클러스터 전체에 Pod를 띄울 때 사용하는 Controller
  • 항상 모든 Node에 특정 Pod가 실행됨
  • 새로운 Node가 추가되면 자동으로 Pod 실행됨
  • 로그 수집기, 모니터링 에이전트 등 실행하는 용도

Stateful Set

  • K8s 대부분의 Object는 Stateless
  • StatefulSet은 상태를 유지하는 Pod를 위한 Object
  • Volume을 사용해서 데이터 저장, Pod 재기동 시에도 유지 가능
  • DB 등을 컨테이너화 할 때 사용 가능

Pod

  • K8s에서 배포할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
  • Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근 가능

Service

  • 네트워크와 관련된 Object
  • Pod 간 연결 및 Pod와 외부 네트워크를 연결
  • 여러 개의 Pod에 대한 내부 로드밸런서
  • 내부 DNS에 서비스 등록하여 서비스 디스커버리 역할도 함
  • Pod에 대한 L4 로드밸런싱 수행
  • Cluster IP, Node Port, Load Balancer 등 옵션 지정 가능

Deployment

  • K8s에서 실제 배포를 진행하는 기본 단위
  • 배포 Revision 관리 및 Roll Back 등 다양한 옵션 제공

Ingress

  • 외부 트래픽을 받는 Object
  • Http/ Https 등 L7 레벨로 라우팅 규칙, 로드벨런싱 규칙 등도 포함
  • Service도 외부로 노출 가능하지만 L4 레벨만 가능

Others

  • ConfifMap, Secret : 설정정보 저장 등 Pod 참조
  • Job, CronJab : 배치 관리
  • Label, Selector : 자원 관리 위해 Labeling

 


K8s Manifest File

  • 선언적 설정을 위한 YAML/JSON 형태의 파일

Manifest File

YAML or JSON

YAML

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.1
    ports:
    - containerPort: 80

Json

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "nginx"
  },
  "spec": {
    "containers": [
      {
        "name": "nginx",
        "image": "nginx:1.20.1",
        "ports": [
          {
            "containerPort": "80"
          }
        ]
      }
    ]
  }
}

apiVersion

  • K8s API 버전 정보 기술

kind

  • Object의 종류 기술 (Pod, Service...)

metadata.name

  • Object 이름을 기술

spec

  • Object 상세 정보 기술
  • 포트 등 환경 정보 기술

 


K8s 사용


K8s 사용

유/무료 설치형 배포판

  • Red Hat OpenShift
  • Pivotal PKS
  • Rancher
  • Kubeadm

Cloud Managed Kubernetes

  • EKS
  • GKE
  • AKS
  • NCloud K8s Service


 

'Architecture' 카테고리의 다른 글

K8s 2) 쿠버네티스 구축  (0) 2024.05.18
Kafka 3) MSK Cluster 모니터링 메트릭  (2) 2024.01.11
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

Catch - Multi thread (feat. ORA-00060)  


서론

 

위의 사진을 잘 관람한다면 현재의 무한경쟁시대에 돌입하듯 동그란 자원을 서로 못 가져가서 안달이다.

이렇게 서로 잡고 안 놔주니 자원이 교착상태가 일어나게 된다.

 

그렇담, 치열하게 전투를 할 수밖에 없어진 명백한 사유에 대하여 알아보자.


Reason

 

위의 그림은 하드웨어 아키텍처를 단순화한 다이어그램이다.

CPU는 두 개의 코어를 나타낸 것이고, 각 CPU는 주어진 시간 내로 하나의 스레드를 실행할 수 있다.

즉, 스레드의 경우 CPU당 스레드가 애플리케이션 내에서 동시에 실행될 수 있음을 의미한다.

 

그리고 변수를 사용할 때 Main Memory에 도달하기 전 CPU Cache에 우선적으로 들락거려야 한다.

즉, 캐시에 존재하는 데이터를 읽는다는 Sound인데, 아래와 같이 개체와 변수가 컴퓨터의 다양한 메모리 영역에 저장되어 사용하는 경우, 위에서 보았던 피 튀기는 자원무한경쟁의 시대가 개막을 하게 되는 것이다.


Solution

synchronized

 

하나의 스레드만 이용이 가능한 '임계 영역'을 코드단에서 synchronized를 이용하여 설정을 할 수 있다.

하나의 스레드가 해당 임계 영역에 당도하면 그 스레드는 'Lock'을 수여받는데, 무언가를 수행 중인 스레드가 Lock을 반납해야만 다른 스레드가 임계 영역을 사용할 수 있다. 이를 동기화라고 한다.

 

메서드 단위, 코드 블록 단위 등 원하는 단위로 나누어 사용이 가능하다.

사용법 외에 스레드 처리에 대한 예시는 굳~이 하지 않겠다.

 

아래의 예시와 같이 사용법은 간단하다.

    // 1. 메소드 전체를 임계영역화
    public synchronized void batchDosa() {

    }

    // 2. 특정영역만 임계영역화
    public void moDosa() {
        synchronized (){ 
        
        }
    }

 

Key Point: 임계 영역, Lock


volatile

 

앞서 데이터 교환이 일어나려면 CPU 메모리의 캐싱된 값을 가져온다고 하였다. 

반면 volatile는 synchronized 와는 다르게 캐싱된 값이 아닌,

항상 최신의 값을 가지도록 메인 메모리의 값을 참조하고 'Lock free'인 관계로 성능면에서 유리한 장점이 있다.

그러나 단지 최신의 값을 가질 뿐이지 모든 동기화를 해결할 수는 없다.

단, 단순한 스레드 간의 통신이나 원자적 연산은 동기화가 잘 될 것이다.

 

아래의 예시와 같이 사용법은 간단하다.

 // Before
 boolean catchThread = false;
 
 // After
 volatile boolean catchThread = false;

Atomic

 

이름만 들어도 원자성은 기필코 확보할 것만 같은 이름이다.

앞서 두 개의 경우는 예약어지만, Atomic은 java.util.concurrent.atomic 패키지에 정의된 클래스이다.

synchronized와 유사하지만 Lock이 아닌, 저수준 CPU 연산 기술인 Compare-And-Swap(CAS) 알고리즘을 사용한다.

이는 메인 메모리에 저장된 값 CPU 캐시에 저장된 값 비교하고, 두 값이 같은 경우에만 데이터를 수정한다. 

synchronized의 장점인 가시성과 원자성을 챙기면서도 Lock도 없어 성능까지 챙길 수 있는 아주 영특한 녀석이다.

 

아래의 예시와 같이 사용법은 간단하다.

 // Before
 private boolean soJuNaMaSyo = false;
 
 // After
 private AtomicBoolean soJuNaMaSyo = new AtomicBoolean();

 

 

아래의 URL에 Atomic 패키지의 다양한 사용법 및 예제가 있으니, 더 많은 사용법을 원한다면 URL을 참조하면 될 것이다.

 

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/package-summary.html

 

java.util.concurrent.atomic (Java Platform SE 8 )

Class Summary  Class Description AtomicBoolean A boolean value that may be updated atomically. AtomicInteger An int value that may be updated atomically. AtomicIntegerArray An int array in which elements may be updated atomically. AtomicIntegerFieldUpdate

docs.oracle.com


결론: 배치도사 무도사

 

필자는 이렇게 생각한다. 

배치 수행 시 Read시간이 경과되는 Where절이 존재하는 배치는 싱글 스레드로 돌리는 것이 보다 안전하다.

본 바와 같이 동기화를 사용하여 자원동행을 하는 것은 기본. DML별로 디렉터리 or URL로 쪼개서 관리하는 법도 있다.

실시간 배치, 특히 DML에서 C, D가 동시에 존재하는 경우 경합이 될 소지가 높으니 이의 경우에는 D를 제거하고, DB 파티션을 데이터에 맞게 분할을 하여 삭제를 도모하는 것도 있으니 여러 방면으로 골똘히 아이디어를 창출해 보면 좋을 것이다.

 

 

 

 

 

 

 


 

[AWS] CloudWatch를 사용한 MSK 모니터링 참조 메트릭


DEFAULT 수준 모니터링

 

다음 표에 설명된 지표는 DEFAULT 모니터링 수준에서 사용할 수 있습니다. 

이름표시되는 경우 Dimensions설명

ActiveControllerCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름 클러스터당 하나의 컨트롤러만 지정된 시간에 활성화되어야 합니다.
BurstBalance 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 클러스터의 EBS 볼륨에 대한 입력-출력 버스트 크레딧의 남은 잔액. 지연 시간 또는 처리량 감소를 조사하는 데 사용합니다.
볼륨의 기준 성능이 최대 버스트 성능보다 높은 경우 EBS 볼륨에 대해 BurstBalance가 보고되지 않습니다. 자세한 내용은 I/O 크레딧 및 버스트 성능을 참조하세요.
BytesInPerSec 주제를 생성한 후. 클러스터 이름, 브로커 ID, 주제 클라이언트로부터 받은 초당 바이트 수입니다. 이 지표는 브로커별 및 주제별로 제공됩니다.
BytesOutPerSec 주제를 생성한 후. 클러스터 이름, 브로커 ID, 주제 클라이언트에 전송된 초당 바이트 수입니다. 이 지표는 브로커별 및 주제별로 제공됩니다.
ClientConnectionCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID, 클라이언트 인증 인증된 활성 클라이언트 연결 수입니다.
ConnectionCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 활성 인증, 미인증 및 브로커 간 연결 수입니다.
CPUCreditBalance 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 이 지표는 브로커의 CPU 크레딧 잔액을 모니터링하는 데 도움이 될 수 있습니다. CPU 사용량이 기준 수준인 20% 사용률 이상으로 지속되면 CPU 크레딧 잔액이 부족해져 클러스터 성능에 부정적인 영향을 미칠 수 있습니다. CPU 부하를 줄이기 위한 조치를 취할 수 있습니다. 예를 들어 클라이언트 요청 수를 줄이거나 브로커 유형을 M5 브로커 유형으로 업데이트할 수 있습니다.
CpuIdle 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID CPU 유휴 시간의 백분율입니다.
CpuIoWait 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 보류 중인 디스크 작업 중 CPU 유휴 시간의 백분율입니다.
CpuSystem 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 커널 공간에 있는 CPU의 백분율입니다.
CpuUser 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 사용자 공간에 있는 CPU의 백분율입니다.
GlobalPartitionCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름 클러스터의 모든 주제에서 복제본을 제외한 파티션 수입니다. GlobalPartitionCount에는 복제본이 포함되지 않으므로 주제의 복제 인수가 1보다 큰 경우 PartitionCount 값의 합계가 GlobalPartitionCount보다 클 수 있습니다.
GlobalTopicCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름 클러스터의 모든 브로커에 있는 총 주제 수입니다.
EstimatedMaxTimeLag 소비자 그룹이 주제에서 소비한 후. 소비자 그룹, 주제 MaxOffsetLag를 배출하는 데 걸리는 예상 시간(초)입니다.
KafkaAppLogsDiskUsed 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 애플리케이션 로그에 사용된 디스크 공간의 백분율입니다.
KafkaDataLogsDiskUsed(Cluster Name, Broker ID 차원) 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 데이터 로그에 사용된 디스크 공간의 백분율입니다.
KafkaDataLogsDiskUsed(Cluster Name 차원) 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름 데이터 로그에 사용된 디스크 공간의 백분율입니다.
LeaderCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커당 총 파티션 리더 수(복제본 제외)입니다.
MaxOffsetLag 소비자 그룹이 주제에서 소비한 후. 소비자 그룹, 주제 주제의 모든 파티션에 대한 최대 오프셋 지연입니다.
MemoryBuffered 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 대한 버퍼링된 메모리의 크기(바이트)입니다.
MemoryCached 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 대한 캐시 메모리의 크기(바이트)입니다.
MemoryFree 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 사용할 수 있는 메모리의 크기(바이트)입니다.
HeapMemoryAfterGC 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 가비지 수집 이후 사용된 총 힙 메모리의 백분율입니다.
MemoryUsed 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에서 사용 중인 메모리의 크기(바이트)입니다.
MessagesInPerSec 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커의 초당 수신 메시지 수입니다.
NetworkRxDropped 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 삭제된 수신 패키지의 수입니다.
NetworkRxErrors 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 대한 네트워크 수신 오류 수입니다.
NetworkRxPackets 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에서 수신된 패킷 수입니다.
NetworkTxDropped 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 삭제된 전송 패키지의 수입니다.
NetworkTxErrors 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커의 네트워크 전송 오류 수입니다.
NetworkTxPackets 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커가 전송한 패킷 수입니다.
OfflinePartitionsCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름 클러스터에서 오프라인 상태인 총 파티션 수입니다.
PartitionCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 복제본을 포함하여 브로커당 주제 파티션의 총 개수입니다.
ProduceTotalTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 밀리초 단위의 평균 생산 시간.
RequestBytesMean 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 대한 요청 바이트의 평균 수입니다.
RequestTime 요청 조절이 적용된 후. 클러스터 이름, 브로커 ID 브로커 네트워크 및 I/O 스레드가 요청을 처리하는 데 소비한 평균 시간(밀리초)입니다.
RootDiskUsed 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커가 사용하는 루트 디스크의 백분율입니다.
SumOffsetLag 소비자 그룹이 주제에서 소비한 후. 소비자 그룹, 주제 주제의 모든 파티션에 대한 집계된 오프셋 지연입니다.
SwapFree 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에서 사용할 수 있는 스왑 메모리의 크기(바이트)입니다.
SwapUsed 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에서 사용 중인 스왑 메모리의 크기(바이트)입니다.
TrafficShaping 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 네트워크 할당 초과로 인해 형성(삭제 또는 대기열에 추가)된 패킷 수를 나타내는 상위 수준 지표입니다. PER_BROKER 지표를 사용하면 더 자세한 내용을 확인할 수 있습니다.
UnderMinIsrPartitionCount 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커의 minIsr 파티션 수입니다.
UnderReplicatedPartitions 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에 대해 복제가 덜 진행된 파티션 수입니다.
ZooKeeperRequestLatencyMsMean 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 브로커에서 Apache ZooKeeper 요청에 대한 평균 대기 시간(밀리초)입니다.
ZooKeeperSessionState 클러스터가 ACTIVE 상태에 도달한 후. 클러스터 이름, 브로커 ID 다음 중 하나일 수 있는 브로커의 ZooKeeper 세션의 연결 상태: NOT_CONNECTED: '0.0', ASSOCIATING: '0.1', CONNECTING: '0.5', CONNECTEDREADONLY: '0.8', CONNECTED: '1.0', CLOSED: '5.0', AUTH_FAILED: '10.0'.

 


PER_BROKER 수준 모니터링

 

모니터링 수준을 PER_BROKER로 설정하면 모든 DEFAULT 수준 지표 외에 다음 표에 설명된 지표가 표시됩니다. 다음 표의 지표에 해당하는 비용을 지불하지만 DEFAULT 수준 지표는 계속 무료로 제공됩니다. 이 표에 있는 지표의 차원은 클러스터 이름, 브로커 ID입니다.

 

PER_BROKER 모니터링 수준부터 사용할 수 있는 추가 지표이름표시되는 경우설명

BwInAllowanceExceeded 클러스터가 ACTIVE 상태에 도달한 후. 인바운드 집계 대역폭이 브로커의 최대치를 초과하여 형성된 패킷 수입니다.
BwOutAllowanceExceeded 클러스터가 ACTIVE 상태에 도달한 후. 아웃바운드 집계 대역폭이 브로커의 최대치를 초과하여 형성된 패킷 수입니다.
ConnTrackAllowanceExceeded 클러스터가 ACTIVE 상태에 도달한 후. 연결 추적이 브로커의 최대치를 초과하여 형성된 패킷 수입니다. 연결 추적은 설정된 각 연결을 추적하여 반환 패킷이 예상대로 전달되도록 하는 보안 그룹과 관련이 있습니다.
ConnectionCloseRate 클러스터가 ACTIVE 상태에 도달한 후. 리스너당 초당 닫힌 연결 수입니다. 이 숫자는 리스너별로 집계되며 클라이언트 리스너에 대해 필터링됩니다.
ConnectionCreationRate 클러스터가 ACTIVE 상태에 도달한 후. 리스너당 초당 설정된 새 연결 수입니다. 이 숫자는 리스너별로 집계되며 클라이언트 리스너에 대해 필터링됩니다.
CpuCreditUsage 클러스터가 ACTIVE 상태에 도달한 후. 이 지표는 인스턴스의 CPU 크레딧 사용량을 모니터링하는 데 도움이 될 수 있습니다. CPU 사용량이 기준 수준인 20% 이상으로 지속되면 CPU 크레딧 잔액이 부족해져 클러스터 성능에 부정적인 영향을 미칠 수 있습니다. 이 지표를 모니터링하고 경보를 보내 수정 조치를 취할 수 있습니다.
FetchConsumerLocalTimeMsMean 생산자/소비자가 만들어진 이후. 소비자 요청이 리더에서 처리되는 평균 시간(밀리초)입니다.
FetchConsumerRequestQueueTimeMsMean 생산자/소비자가 만들어진 이후. 소비자 요청이 요청 대기열에서 대기하는 평균 시간(밀리초)입니다.
FetchConsumerResponseQueueTimeMsMean 생산자/소비자가 만들어진 이후. 소비자 요청이 응답 대기열에서 대기하는 평균 시간(밀리초)입니다.
FetchConsumerResponseSendTimeMsMean 생산자/소비자가 만들어진 이후. 소비자가 응답을 보내는 평균 시간(밀리초)입니다.
FetchConsumerTotalTimeMsMean 생산자/소비자가 만들어진 이후. 소비자가 브로커에서 데이터를 가져오는 데 소요하는 평균 총 시간(밀리초)입니다.
FetchFollowerLocalTimeMsMean 생산자/소비자가 만들어진 이후. 팔로어 요청이 리더에서 처리되는 평균 시간(밀리초)입니다.
FetchFollowerRequestQueueTimeMsMean 생산자/소비자가 만들어진 이후. 팔로어 요청이 요청 대기열에서 대기하는 평균 시간(밀리초)입니다.
FetchFollowerResponseQueueTimeMsMean 생산자/소비자가 만들어진 이후. 팔로어 요청이 응답 대기열에서 대기하는 평균 시간(밀리초)입니다.
FetchFollowerResponseSendTimeMsMean 생산자/소비자가 만들어진 이후. 팔로어가 응답을 보내는 평균 시간(밀리초)입니다.
FetchFollowerTotalTimeMsMean 생산자/소비자가 만들어진 이후. 팔로어가 브로커에서 데이터를 가져오는 데 소비하는 평균 총 시간(밀리초)입니다.
FetchMessageConversionsPerSec 주제를 생성한 후. 브로커의 초당 가져오기 메시지 변환 횟수입니다.
FetchThrottleByteRate 대역폭 조절이 적용된 후. 초당 병목 현상 바이트 수입니다.
FetchThrottleQueueSize 대역폭 조절이 적용된 후. 조절 대기열에 있는 메시지 수입니다.
FetchThrottleTime 대역폭 조절이 적용된 후. 평균 가져오기 조절 시간(밀리초)입니다.
NetworkProcessorAvgIdlePercent 클러스터가 ACTIVE 상태에 도달한 후. 네트워크 프로세서가 유휴 상태인 시간의 평균 백분율입니다.
PpsAllowanceExceeded 클러스터가 ACTIVE 상태에 도달한 후. 양방향 PPS가 브로커의 최대치를 초과하여 형성된 패킷 수입니다.
ProduceLocalTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 리더에서 요청이 처리되는 평균 시간(밀리초)입니다.
ProduceMessageConversionsPerSec 주제를 생성한 후. 브로커의 초당 생산 메시지 변환 수입니다.
ProduceMessageConversionsTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 메시지 형식 변환에 소요된 평균 시간(밀리초)입니다.
ProduceRequestQueueTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 요청 메시지가 대기열에 소비하는 평균 시간(밀리초)입니다.
ProduceResponseQueueTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 응답 메시지가 대기열에서 소비하는 평균 시간(밀리초)입니다.
ProduceResponseSendTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 응답 메시지를 보내는 데 소비한 평균 시간(밀리초)입니다.
ProduceThrottleByteRate 대역폭 조절이 적용된 후. 초당 병목 현상 바이트 수입니다.
ProduceThrottleQueueSize 대역폭 조절이 적용된 후. 조절 대기열에 있는 메시지 수입니다.
ProduceThrottleTime 대역폭 조절이 적용된 후. 평균 생산 조절 시간(밀리초)입니다.
ProduceTotalTimeMsMean 클러스터가 ACTIVE 상태에 도달한 후. 밀리초 단위의 평균 생산 시간.
RemoteBytesInPerSec 생산자/소비자가 생성된 후. 소비자 가져오기에 대한 응답으로 계층형 스토리지에서 전송된 총 바이트 수입니다. 이 지표에는 다운스트림 데이터 전송 트래픽에 기여하는 모든 주제 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteBytesOutPerSec 생산자/소비자가 생성된 후. 로그 세그먼트, 인덱스, 기타 보조 파일의 데이터를 포함하여 계층화된 스토리지로 전송된 총 바이트 수입니다. 이 지표에는 업스트림 데이터 전송 트래픽에 기여하는 모든 토픽 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteLogManagerTasksAvgIdlePercent 클러스터가 ACTIVE 상태에 도달한 후. 원격 로그 관리자가 유휴 상태로 보낸 평균 시간 비율입니다. 원격 로그 관리자는 브로커에서 계층화된 스토리지로 데이터를 전송합니다. 범주는 내부 활동입니다. 이것은 KIP-405 지표입니다.
RemoteLogReaderAvgIdlePercent 클러스터가 ACTIVE 상태에 도달한 후. 원격 로그 리더가 유휴 상태로 보낸 평균 시간 비율입니다. 원격 로그 리더는 소비자의 가져오기에 대한 응답으로 원격 스토리지에서 브로커로 데이터를 전송합니다. 범주는 내부 활동입니다. 이것은 KIP-405 지표입니다.
RemoteLogReaderTaskQueueSize 클러스터가 ACTIVE 상태에 도달한 후. 예약 대기 중인 계층형 스토리지에서 읽기를 담당하는 작업의 수입니다. 범주는 내부 활동입니다. 이것은 KIP-405 지표입니다.
RemoteReadErrorPerSec 클러스터가 ACTIVE 상태에 도달한 후. 지정된 브로커가 소비자 가져오기에 대한 응답으로 데이터를 검색하기 위해 계층화된 스토리지로 전송한 읽기 요청에 대한 총 오류 발생율입니다. 이 지표에는 다운스트림 데이터 전송 트래픽에 영향을 미치는 모든 주제 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteReadRequestsPerSec 클러스터가 ACTIVE 상태에 도달한 후. 지정한 브로커가 소비자 가져오기에 대한 응답으로 데이터를 검색하기 위해 계층화된 스토리지로 전송한 총 읽기 요청 수입니다. 이 지표에는 다운스트림 데이터 전송 트래픽에 영향을 미치는 모든 주제 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteWriteErrorPerSec 클러스터가 ACTIVE 상태에 도달한 후. 지정된 브로커가 데이터를 업스트림으로 전송하기 위해 계층화된 스토리지로 전송한 쓰기 요청에 대한 응답으로 발생한 총 오류 발생율입니다. 이 지표에는 업스트림 데이터 전송 트래픽에 영향을 미치는 모든 주제 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
ReplicationBytesInPerSec 주제를 생성한 후. 다른 브로커로부터 수신하는 초당 바이트 수입니다.
ReplicationBytesOutPerSec 주제를 생성한 후. 다른 브로커로 전송되는 초당 바이트 수입니다.
RequestExemptFromThrottleTime 요청 조절이 적용된 후. 브로커 네트워크 및 I/O 스레드가 조절에서 제외된 요청을 처리하는 데 소비한 평균 시간(밀리초)입니다.
RequestHandlerAvgIdlePercent 클러스터가 ACTIVE 상태에 도달한 후. 요청 핸들러 스레드가 유휴 상태인 시간의 평균 백분율입니다.
RequestThrottleQueueSize 요청 조절이 적용된 후. 조절 대기열에 있는 메시지 수입니다.
RequestThrottleTime 요청 조절이 적용된 후. 평균 요청 조절 시간(밀리초)입니다.
TcpConnections 클러스터가 ACTIVE 상태에 도달한 후. SYN 플래그가 설정된 수신 및 발신 TCP 세그먼트 수를 표시합니다.
TotalTierBytesLag 주제를 생성한 후. 브로커에서 계층화할 수 있지만 아직 계층화된 스토리지로 전송되지 않은 데이터의 총 바이트 수입니다. 이 지표는 업스트림 데이터 전송의 효율성을 보여줍니다. 지연이 증가하면 계층형 스토리지에 유지되지 않는 데이터의 양이 증가합니다. 범주는 아카이브 지연입니다. 이것은 KIP-405 지표가 아닙니다.
TrafficBytes 클러스터가 ACTIVE 상태에 도달한 후. 클라이언트(생산자 및 소비자)와 브로커 간의 네트워크 트래픽을 전체 바이트 단위로 표시합니다. 브로커 사이의 트래픽은 보고되지 않습니다.
VolumeQueueLength 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간 동안 완료되기를 기다리는 읽기 및 쓰기 작업 요청의 수입니다.
VolumeReadBytes 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간 동안 읽은 바이트 수입니다.
VolumeReadOps 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간 동안의 읽기 작업 횟수입니다.
VolumeTotalReadTime 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간에 완료된 모든 읽기 작업에 소요된 총 시간(초)입니다.
VolumeTotalWriteTime 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간에 완료된 모든 쓰기 작업에 소요된 총 시간(초)입니다.
VolumeWriteBytes 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간 동안 기록된 바이트 수입니다.
VolumeWriteOps 클러스터가 ACTIVE 상태에 도달한 후. 지정된 기간 동안의 쓰기 작업 횟수입니다.

 


PER_TOPIC_PER_BROKER 수준 모니터링

 

모니터링 수준을 PER_TOPIC_PER_BROKER로 설정하면 모든 PER_BROKER 및 기본 수준 지표 외에 다음 표에 설명된 지표가 표시됩니다. DEFAULT 수준 지표만 무료입니다. 이 표에 있는 지표의 차원은 클러스터 이름, 브로커 ID, 주제입니다.

*중요*

Apache Kafka 2.4.1 이상 버전을 사용하는 Amazon MSK 클러스터의 경우 다음 표의 지표는 해당 값이 처음으로 0이 아닌 값이 된 후에만 나타납니다. 예를 들어, BytesInPerSec를 보려면 하나 이상의 생산자가 먼저 클러스터로 데이터를 전송해야 합니다.

 

PER_TOPIC_PER_BROKER 모니터링 수준부터 사용할 수 있는 추가 지표이름표시되는 경우설명

FetchMessageConversionsPerSec 주제를 생성한 후. 초당 가져와서 변환한 메시지 수입니다.
MessagesInPerSec 주제를 생성한 후. 초당 수신된 메시지 수입니다.
ProduceMessageConversionsPerSec 주제를 생성한 후. 생산된 메시지의 초당 변환 수입니다.
RemoteBytesInPerSec 주제 생성 후 해당 주제가 생산/소비되고 있는 경우. 지정된 주제 및 브로커에 대한 소비자 가져오기에 대한 응답으로 계층형 스토리지에서 전송된 바이트 수입니다. 이 지표에는 지정된 브로커의 다운스트림 데이터 전송 트래픽에 기여하는 주제의 모든 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteBytesOutPerSec 주제 생성 후 해당 주제가 생산/소비되고 있는 경우. 지정된 주제 및 브로커에 대해 계층형 스토리지로 전송된 바이트 수입니다. 이 지표에는 지정된 브로커의 업스트림 데이터 전송 트래픽에 기여하는 주제의 모든 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteReadErrorPerSec 주제 생성 후 해당 주제가 생산/소비되고 있는 경우. 지정된 주제에 대한 소비자 가져오기에 대한 응답으로 데이터를 검색하기 위해 지정된 브로커가 계층화된 스토리지로 보내는 읽기 요청에 대한 응답으로 발생하는 오류의 비율입니다. 이 지표에는 지정된 브로커의 다운스트림 데이터 전송 트래픽에 기여하는 주제의 모든 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteReadRequestsPerSec 주제 생성 후 해당 주제가 생산/소비되고 있는 경우. 지정된 주제에 대한 소비자 가져오기에 대한 응답으로 데이터를 검색하기 위해 지정한 브로커가 계층화된 스토리지로 보내는 읽기 요청의 수입니다. 이 지표에는 지정된 브로커의 다운스트림 데이터 전송 트래픽에 기여하는 주제의 모든 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.
RemoteWriteErrorPerSec 주제 생성 후 해당 주제가 생산/소비되고 있는 경우. 지정된 브로커가 데이터를 업스트림으로 전송하기 위해 계층형 스토리지로 보내는 쓰기 요청에 대한 응답으로 발생하는 오류의 비율입니다. 이 지표에는 지정된 브로커의 업스트림 데이터 전송 트래픽에 기여하는 주제의 모든 파티션이 포함되어 있습니다. 범주는 트래픽 및 오류 발생율입니다. 이것은 KIP-405 지표입니다.

 


PER_TOPIC_PER_PARTITION 수준 모니터링

 

모니터링 수준을 PER_TOPIC_PER_PARTITION로 설정하면 모든 PER_TOPIC_PER_BROKER, PER_BROKER, 기본 수준 지표 외에 다음 표에 설명된 지표가 표시됩니다. DEFAULT 수준 지표만 무료입니다. 이 표의 지표에는 소비자 그룹, 주제, 파티션 등의 차원이 있습니다.

 

PER_TOPIC_PER_PARTITION 모니터링 수준부터 사용할 수 있는 추가 지표이름표시되는 경우설명

EstimatedTimeLag 소비자 그룹이 주제에서 소비한 후. 파티션 오프셋 지연을 배출하는 데 걸리는 예상 시간(초)입니다.
OffsetLag 소비자 그룹이 주제에서 소비한 후. 파티션 수준 소비자 지연의 오프셋 수입니다.

 

 


 

'Architecture' 카테고리의 다른 글

K8s 2) 쿠버네티스 구축  (0) 2024.05.18
K8s 1) 쿠버네티스 기본  (0) 2024.05.17
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

지원되는 버전

Instancea가 수집하는 모든 Kafka 지표는 이용자 그룹 시차  소비자/프로듀서 바이트 비율/조절 지표와 별도로 Apache Kafka, Cloudera Kafka및 Confluent Kafka의 모든 버전에 사용할 수 있습니다. 오픈 소스 Apache Kafka에 빌드된 IBM® Event Streams 는 IBM Event Streams 11.0.4 (IBM Event Streams Operator 3.0.5) 이상 버전에서 지원됩니다.

이용자 그룹 지연 지표는 다음 버전에서 사용 가능합니다.

  • 0.11.x.x 에서 3.x.x 까지의 Apache Kafka 버전
  • 3.x.x 에서 4.1.x 로의 Cloudera Kafka 버전
  • 3.3.x 에서 7.x.x까지의 Confluent Kafka 버전.
  • 11.0.4 (IBM Event Streams Operator 3.0.5) 이상 버전의 IBM Event Streams 버전

소비자/생성자 바이트 비율/조절 메트릭은 Java Kafka 클라이언트에서만 사용 가능하며 다음과 같습니다.

  • 1.1.x 에서 3.x.x 로의 Apache Kafka 버전
  • 4.0.x 에서 4.1.x 까지의 Cloudera Kafka 버전
  • 4.1.x 에서 7.x.x까지의 Confluent Kafka 버전.
  • 11.0.4 (IBM Event Streams Operator v3.0.5) 이상 버전의 IBM Event Streams 버전

 구성

Instancea 에이전트는 실행 중인 Kafka 에이전트를 자동으로 발견하므로 구성이 필요하지 않습니다.

Instana는 주제 이름별로 정렬된 첫 번째 400 주제를 수집합니다.

주제를 필터링하기 위한 요구사항이 있는 경우 에이전트 구성 파일 <agent_install_dir>/etc/instana/configuration.yaml에서 이를 구성할 수 있습니다.

com.instana.plugin.kafka:
  topicsRegex: '<OPTIONAL_REGEX_HERE>'
  brokerPropertiesFilePath: '/path/to/server.properties'
  collectLagData: '' # true or false. The default value is true
  • topicsRegex: 이름별로 최대 400개의 주제를 선택하는 선택적 정규식입니다. 값이 비어 있거나 존재하지 않는 경우 Instana는 이름별로 정렬된 처음 400개의 주제를 수집합니다.
  • brokerPropertiesFilePath: 에이전트가 브로커 네트워크 및 보안 프로토콜 설정에 대한 정보를 가져오는 데 사용하는 브로커 server.properties 파일의 경로입니다.
  • collectLagData: 지연 데이터 콜렉션을 명시적으로 사용/사용 안함으로 설정하는 데 사용되는 플래그입니다 (기본적으로 사용으로 설정됨).

브로커 특성에 대한 경로가 지정되지 않은 경우 에이전트는 다음 위치에서 server.properties 를 찾으려고 시도합니다.

  • Kafka 브로커 프로세스 인수
  • KAFKA_SERVER_PROPERTIES 환경 변수
  • 사전 정의된 경로 사용: Confluent Kafka의 경우 /path_to_kafka_home/config/server.properties 또는 /path_to_kafka_home/etc/kafka/server.properties .

앞에서 언급한 방법으로 server.properties 에 대한 경로를 찾을 수 없는 경우 에이전트는 /opt/kafka/config/server.properties 를 기본 경로로 사용합니다.

 SSL TLS 지원

Kafka 브로커 인스턴스에 SSL 클라이언트 연결이 필요한 경우 <agent_install_dir>/etc/instana/configuration.yaml 를 통해 Instana 에이전트를 구성하여 이용자 지연 메트릭을 수집할 수 있도록 해야 합니다.

com.instana.plugin.kafka:
  ...
  sslTrustStore: '/path/to/truststore.jks'
  sslTrustStorePassword: 'kafkaTsPassword'
  sslKeyStore: '/path/to/sslKeyStoreFile.jks'
  sslKeyStorePassword: 'kafkaKsPassword'

키는 Java키 저장소 형식 (JKS) 이어야 합니다. keytool 을 사용하여 이를 작성할 수 있습니다.

참고: 이를 통해 Instana 에이전트가 SSL을 통해 Kafka 브로커에 연결하고 이용자 그룹 지연 지표를 수집할 수 있습니다.

 Kafka 노드-지표 콜렉션

 구성 데이터

  • 버전
  • Zookeeper Connect
  • 프로세스 ID
  • 노드 ID
  • 토픽/파티션

 성능 지표

메트릭설명세분성
총 생성 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce에서 수집된 지정된 요청을 제공하기 위한 총 시간 (밀리초) 입니다. 1초
총 페치 이용자 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchConsumer에서 수집된 지정된 요청을 제공하기 위한 총 시간 (밀리초) 입니다. 1초
총 페치 팔로워 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchFollower에서 수집된 지정된 요청을 제공하기 위한 총 시간 (밀리초) 입니다. 1초

 브로커 트래픽

메트릭설명세분성
In 수신 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec에서 수집됩니다. 1초
출력 전송 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec에서 수집됩니다. 1초
거부됨 거부된 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesRejectedPerSec에서 수집됩니다. 1초

 브로커 메시지 수신

메트릭설명세분성
개수 수신 메시지 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec에서 수집됩니다. 1초

 요청 생성

메트릭설명세분성
개수 요청 비율이며 kafka.network:type=RequestMetrics,name=RequestsPerSec,request=Produce에서 수집됩니다. 1초
평균 대기 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Produce에서 수집된 지정된 요청을 제공하기 위해 총 시간 (밀리초) 및 계수의 몫 (위에서 언급됨) 으로 계산된 평균 대기 시간입니다. 1초

 이용자 요청 페치

메트릭설명세분성
개수 요청 비율이며 kafka.network:type=RequestMetrics,name=RequestsPerSec,request=FetchConsumer에서 수집됩니다. 1초
평균 대기 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchConsumer에서 수집된 지정된 요청을 제공하기 위해 총 시간 (밀리초) 및 계수의 몫 (위에서 언급됨) 으로 계산된 평균 대기 시간입니다. 1초

 팔로워 요청 페치

메트릭설명세분성
개수 요청 비율이며 kafka.network:type=RequestMetrics,name=RequestsPerSec,request=FetchFollower에서 수집됩니다. 1초
평균 대기 시간 kafka.network:type=RequestMetrics,name=TotalTimeMs,request=FetchFollower에서 수집된 지정된 요청을 제공하기 위해 총 시간 (밀리초) 및 계수의 몫 (위에서 언급됨) 으로 계산된 평균 대기 시간입니다. 1초

 평균 유휴 시간

메트릭설명세분성
네트워크 프로세서 네트워크 프로세서 스레드가 유휴 상태인 평균 시간 비율입니다. 값은 0% (모든 자원이 사용됨) - 100% (모든 자원이 사용 가능함) 사이이며 kafka.network:type=SocketServer,name=NetworkProcessorAvgIdlePercent에서 수집됩니다. 1초
요청 핸들러 요청 핸들러 스레드가 유휴 상태인 평균 시간 비율입니다. 값은 0% (모든 자원이 사용됨) - 100% (모든 자원이 사용 가능함) 사이이며 kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent에서 수집됩니다. 1초

 브로커 실패

메트릭설명세분성
페치 실패하여 kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec에서 수집된 요청에 대한 페치 요청 비율입니다. 1초
생성 실패하고 kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec에서 수집되는 요청에 대한 요청 비율을 생성합니다. 1초

 브로커 상태 지표

메트릭설명세분성
복제가 완료되지 않은 파티션 복제되지 않은 파티션 수 (ISR < 모든 복제본) 이며 kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions에서 수집됩니다. 1초
오프라인 파티션 활성 리더가 없으므로 쓰기 또는 읽기가 불가능하고 kafka.controller:type=KafkaController,name=OfflinePartitionsCount에서 수집되는 파티션의 수입니다. 1초
리더 선거 리더 선출 비율 및 대기 시간은 kafka.controller:type=ControllerStats,name=LeaderElectionRateAndTimeMs에서 수집됩니다. 1초
부정 리더 선거 kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSec에서 수집되는 명확하지 않은 리더 선출 비율입니다. 1초
ISR Shrink 브로커가 작동 중지되면 일부 파티션의 ISR이 축소됩니다. 해당 브로커가 다시 가동되면 복제본이 완전히 포착되면 ISR이 확장됩니다. 그 외에도 ISR 축소 비율 및 확장 비율 모두에 대한 예상 값은 0입니다. kafka.server:type=ReplicaManager,name=IsrShrinksPerSec에서 수집됩니다. 1초
ISR Expansion 실패 후 브로커가 발생하면 리더에서 읽어 따라잡기 시작합니다. 일단 발견되면 ISR에 다시 추가됩니다. kafka.server:type=ReplicaManager,name=IsrExpandsPerSec에서 수집됩니다. 1초
활성 컨트롤러 수 클러스터에 있는 활성 제어기의 수이며 kafka.controller:type=KafkaController,name=ActiveControllerCount에서 수집됩니다. 1초

 파티션

메트릭설명세분성
개수 이 브로커의 파티션 수입니다. 이는 대부분 모든 브로커에서도 발생해야 하며 kafka.server:type=ReplicaManager,name=PartitionCount에서 수집됩니다. 1초

 로그 플러시

메트릭설명세분성
평균 로그 플러시 비율이며 kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMs에서 수집됩니다. 1초
플러시 로그 플러시 수이며 kafka.log:type=LogFlushStats,name=LogFlushRateAndTimeMs에서 수집됩니다. 1초

 주제

메트릭설명세분성
이름 수신 메시지 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec에서 수집됩니다. 1초
파티션 수신 메시지 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec에서 수집됩니다. 1초
수신 바이트 토픽에 대한 수신 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec에서 수집됩니다. 1초
보낸 바이트 토픽에 대한 송신 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec에서 수집됩니다. 1초
거부된 바이트 주제에 대해 거부된 바이트 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=BytesRejectedPerSec에서 수집됩니다. 1초
수신 메시지 토픽에 대한 수신 메시지 비율을 집계하며 kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec에서 수집됩니다. 1초
동기화 복제본 동기화 복제본 수이며 kafka.cluster:type=Partition,name=InSyncReplicasCount에서 수집됩니다. 1초

 Kafka 클러스터-지표 콜렉션

  • 클러스터 이름
  • Zookeeper
  • 노드 (이름, 버전)

토픽/파티션

 성능 지표

메트릭설명세분성
모든 브로커 메시지 입력 모든 노드의 브로커 메시지 입력 지표의 합계입니다. 1초
거부된 트래픽 모든 노드에서 거부된 브로커 트래픽 지표의 합계입니다. 1초
총 페치 이용자 시간 모든 노드에서 총 페치 이용자 시간 지표의 합계입니다. 1초
총 페치 팔로워 시간 모든 노드의 총 페치 팔로워 시간 지표의 합계입니다. 1초

 평균 요청 대기 시간 대 처리량

메트릭설명세분성
처리량 생성 모든 노드에서 생성 요청 수 지표의 합계입니다. 1초
페치 컨슈머 처리량 모든 노드의 페치 이용자 요청 수 지표의 합계입니다. 1초
페치 팔로워 처리량 모든 노드의 페치 팔로워 요청 수 지표의 합계입니다. 1초
총 생성 시간 모든 노드에서 총 생성 시간의 합계입니다. 1초
총 페치 이용자 시간 모든 노드에서 총 페치 이용자 시간의 합계입니다. 1초
총 페치 팔로워 시간 모든 노드에서 총 페치 팔로워 시간의 합계입니다. 1초

 모든 브로커 트래픽

메트릭설명세분성
In 모든 노드에서 브로커 트래픽 인바운드의 합계입니다. 1초
출력 모든 노드에서 브로커 트래픽 출력의 합계입니다. 1초
거부됨 모든 노드에서 거부된 브로커 트래픽의 합계입니다. 1초

 모든 브로커 실패

메트릭설명세분성
페치 모든 노드에서 브로커 실패 페치의 합계입니다. 1초
생성 모든 노드에서 생성된 브로커 실패의 합계입니다. 1초

 모든 브로커 상태 지표

메트릭설명세분성
복제가 완료되지 않은 파티션 모든 노드에서 브로커 상태 메트릭 하위 복제 파티션의 합계입니다. 1초
오프라인 파티션 모든 노드에서 브로커 상태 지표 오프라인 파티션의 합계입니다. 1초
리더 선거 모든 노드에서 브로커 상태 메트릭 리더 선택의 합계입니다. 1초
부정 리더 선거 모든 노드에서 브로커 상태 지표 정리되지 않은 리더 선택의 합계입니다. 1초
ISR Shrink 모든 노드에서 브로커 상태 지표 ISR 축소의 합계입니다. 1초
ISR Expansion 모든 노드에서 브로커 상태 지표 ISR 확장의 합계입니다. 1초
활성 컨트롤러 수 모든 노드의 브로커 상태 지표 활성 컨트롤러 수의 합계입니다. 1초

 평균 유휴 시간 백분율

메트릭설명세분성
네트워크 프로세서 모든 노드에서 평균 유휴 시간 네트워크 프로세서의 평균입니다. 1초
요청 핸들러 모든 노드에서 평균 유휴 시간 요청 핸들러의 평균입니다. 1초

 로그 플러시

메트릭설명세분성
평균 모든 노드에서 로그 플러시 평균의 합계입니다. 1초
플러시 모든 노드에서 로그 플러시 플러시의 합계입니다. 1초

 클러스터 노드

메트릭설명세분성
제어기 노드 제어기입니까? 예/아니오 1초
수신 메시지 수신된 브로커 메시지 수를 포함하는 차트입니다. 1초
수신 바이트 수신된 브로커 바이트 수를 포함하는 차트입니다. 1초
보낸 바이트 출력된 브로커 바이트 수를 표시하는 차트입니다. 1초
평균 응답 시간 브로커 평균 응답 시간 수를 표시하는 차트입니다. 1초
상태 노드 상태 표시기. 1초

 클러스터 토픽

메트릭설명세분성
파티션 파티션 수입니다. 10분간 진행되는
수신 바이트 수신된 주제 바이트 수를 포함하는 차트입니다. 1초
보낸 바이트 송신된 주제 바이트 수를 포함하는 차트입니다. 1초
거부된 바이트 거부된 주제 바이트 수를 표시하는 차트입니다. 1초
수신 메시지 수신된 주제 메시지 수를 포함하는 차트입니다. 1초

 이용자 그룹 지연

메트릭설명세분성
시차 주제별 이용자 그룹 지연. 60초

 이용자

메트릭설명세분성
바이트 비율 초당 보낸 소비 바이트 수입니다. 1초
스로틀링 평균 조절 시간입니다. 1초
대기 시간 평균 페치 대기 시간입니다. 1초

 생산자

메트릭설명세분성
바이트 비율 초당 보낸 발신 바이트 수입니다. 1초
스로틀링 평균 조절 시간입니다. 1초
대기 시간 평균 요청 대기 시간입니다. 1초

Kafka 작업자-메트릭 콜렉션

 구성 데이터

  • Version
  • 이름
  • 브로커 수

 성능 지표

  • 커넥터 개수
  • 커넥터 시작 실패
  • 태스크 시작 실패

 리밸런싱

메트릭설명세분성
재조정 완료 이 작업자 kafka.connect:type=connect-worker-rebalance-metrics,name=completed-rebalances-total이 완료한 재조정의 총 수입니다. 1초
재조정 평균 시간 이 작업자가 kafka.connect:type=connect-worker-rebalance-metrics,name=rebalance-avg-time-ms재조정하는 데 소요된 평균 시간 (밀리초) 입니다. 1초
재조정 중 이 작업자가 현재 kafka.connect:type=connect-worker-rebalance-metrics,name=rebalancing재조정 중인지 여부입니다. 1초
마지막 재조정 이후 시간 이 작업자가 가장 최근의 재조정 kafka.connect:type=connect-worker-rebalance-metrics,name=time-since-last-rebalance-ms을 완료한 이후의 시간 (밀리초) 입니다. 1초

 

 Kafka 커넥터-메트릭 콜렉션

  • 커넥터 이름
  • 커넥터 클래스
  • 커넥터 유형
  • 커넥터 버전

 커넥터 태스크

메트릭설명세분성
총계 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-total-task-count의 태스크 수입니다. 1초
실행 중 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-running-task-count 의 실행 중인 태스크 수 1초
실패함 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-failed-task-count의 실패한 태스크 수입니다. 1초
삭제됨 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-destroyed-task-count의 손상된 태스크 수입니다. 1초
일시중지됨 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-paused-task-count의 일시정지된 태스크 수. 1초
지정되지 않습니다. 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-unassigned-task-count 의 지정되지 않은 태스크 수 1초

 태스크

메트릭설명세분성
이름 태스크 이름 kafka.connect:type=connector-task-metrics,connector={connectorName},task={taskName}입니다. 1초
Status 커넥터 태스크 kafka.connect:type=connector-task-metrics,connector={connectorName},task={taskName},name=status의 상태입니다. 1초
실행 비율 이 태스크가 kafka.connect:type=connector-task-metrics,connector={connectorName},task={taskName},name=running-ratio상태를 실행하는 데 소요한 시간입니다. 1초
일시정지 비율 이 태스크가 일시정지 상태 kafka.connect:type=connector-task-metrics,connector={connectorName},task={taskName},name=pause-ratio에서 소비한 분수 시간입니다. 1초

 태스크 링크 태스크

메트릭설명세분성
파티션 수 이 태스크 kafka.connect:type=sink-task-metrics,connector={connectorName},task={taskName},name=partition-count에 지정된 토픽 파티션의 수입니다. 1초
레코드 읽기 비율 이 태스크 kafka.connect:type=sink-task-metrics,connector={connectorName},task={taskName},name=sink-record-read-rate에 대해 Kafka 에서 읽은 초당 평균 레코드 수 1초
레코드 전송 비율 이 태스크 kafka.connect:type=sink-task-metrics,connector={connectorName},task={taskName},name=sink-record-send-rate에서 보낸 초당 평균 레코드 수. 1초
메트릭설명세분성
레코드 폴링 비율 이 태스크 kafka.connect:type=source-task-metrics,connector={connectorName},task={taskName},name=source-record-poll-rate에 의해 폴링된 초당 평균 레코드 수. 1초
레코드 쓰기 비율 이 태스크 kafka.connect:type=source-task-metrics,connector={connectorName},task={taskName},name=source-record-write-rate에 의해 Kafka 에 기록된 초당 평균 레코드 수입니다. 1초

 Kafka 클러스터 연결 클러스터-메트릭 콜렉션

 구성 데이터

  • Version

 작업자

메트릭설명세분성
커넥터 시작 실패 이 작업자 kafka.connect:type=connect-worker-rebalance-metrics,name=connector-startup-failure-total이 완료한 재조정의 총 수입니다. 1초
태스크 시작 실패 이 작업자 kafka.connect:type=connect-worker-rebalance-metrics,name=task-startup-failure-total이 완료한 재조정의 총 수입니다. 1초
재조정 완료 이 작업자 kafka.connect:type=connect-worker-rebalance-metrics,name=completed-rebalances-total이 완료한 재조정의 총 수입니다. 1초
재조정 평균 시간 이 작업자가 kafka.connect:type=connect-worker-rebalance-metrics,name=rebalance-avg-time-ms재조정하는 데 소요된 평균 시간 (밀리초) 입니다. 1초
재조정 중 이 작업자가 현재 kafka.connect:type=connect-worker-rebalance-metrics,name=rebalancing재조정 중인지 여부입니다. 1초
마지막 재조정 이후 시간 이 작업자가 가장 최근의 재조정 kafka.connect:type=connect-worker-rebalance-metrics,name=time-since-last-rebalance-ms을 완료한 이후의 시간 (밀리초) 입니다. 1초

 커넥터

메트릭설명세분성
이름 커넥터 이름 kafka.connect:type=connect-worker-metrics,connector={name}. 1초
총 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-total-task-count의 태스크 수입니다. 1초
실행 중인 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-running-task-count의 실행 중인 태스크 수입니다. 1초
실패한 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-failed-task-count의 실패한 태스크 수입니다. 1초
영구 삭제된 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-destroyed-task-count의 손상된 태스크 수입니다. 1초
일시정지된 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-paused-task-count의 일시정지된 태스크 수. 1초
지정되지 않은 태스크 커넥터 kafka.connect:type=connect-worker-metrics,connector={name},name=connector-unassigned-task-count의 지정되지 않은 태스크 수입니다. 1초

Nested Loop Join


1. 기본 메커니즘

아래는 중첩 루프문(Nested Loop)의 수행 구조이다.

for(i=0; i<100; i++){
    for(j=0; j<100; j++){
    }
}

뒤에서 설명할 Sort Merge Join과 Hash Join도 각각 소트 영역(Sort Area)과 해시 영역(Hash Area)에 가공해 둔 데이터를 이용한다는 점만 다를 뿐 기본적인 조인 프로세싱은 다르지 않다.

단, 기억할 것은, 각 단계를 완료하고 나서 다음 단계로 넘어가는 게 아니라 한 레코드씩 순차적으로 진행한다는 사실이다.


2. NL Join 수행 과정 분석

프로그래밍을 할 줄 아는 분들이면 매커니즘은 자연스럽게 넘어갈 것이라 사료되는데,

아래의 조인문에서 조건절 비교 순서를 분석해 보자.

 

/*Data ON-AIR 참조*/

select /*+ ordered use_nl(e) */ e.empno, e.ename, d.dname, e.job, e.sal 
from dept d, emp e 
where e.deptno = d.deptno …………… 
① and d.loc = 'SEOUL' …………… 
② and d.gb = '2' …………… 
③ and e.sal >= 1500 …………… 
④ order by sal desc;

인덱스 상황은 다음과 같다.

* pk_dept : dept.deptno 
* dept_loc_idx : dept.loc 
* pk_emp : emp.empno 
* emp_deptno_idx : emp.deptno 
* emp_sal_idx : emp.sal

조건절 비교 순서, 그리고 위 5개 인덱스 중 어떤 것이 사용될지도 함께 고민해 보면 재밌을 것이다.

Execution Plan --------------------------------------------------- 0 
SELECT STATEMENT 1 0 SORT ORDER BY 2 1 NESTED LOOPS 3 2 
TABLE ACCESS BY INDEX ROWID DEPT 4 3 INDEX RANGE SCAN DEPT_LOC_IDX 5 2 
TABLE ACCESS BY INDEX ROWID EMP 6 5 INDEX RANGE SCAN EMP_DEPTNO_IDX

 

사용되는 인덱스 : dept_loc_idx, emp_deptno_idx

조건절 비교순서 : ② → ③ → ① → ④ 

 

실행계획을 해석할 때, 형제(Sibling) 노드 간에는 위에서 아래로 읽는다.

부모-자식(Parent-Child) 노드 간에는 안쪽에서 바깥쪽으로, 즉 자식 노드부터 읽는다.

위 실행계획의 실행 순서를 나열하면 다음과 같다.

 

1. dept_loc_idx 인덱스 범위 스캔(ID = 4)

2. 인덱스 rowid로 dept 테이블 액세스(ID = 3)

3. emp_deptno_idx 인덱스 범위 스캔(ID = 6)

4. 인덱스 rowid로 emp 테이블 액세스(ID = 5)

5. sal 기준 내림차순(desc) 정렬(ID = 1)

 

아래는 도식화한 NL Join 실행계획이다.

형제 노드 간에는 좌에서 우로 읽고,

부모-자식 노드 간에는 아래에서 위쪽으로, 즉 자식 노드부터 읽는다.


3. NL Join의 특징

- Random 액세스 위주의 조인 방식

- 조인을 한 레코드씩 순차적으로 진행

 

NL Join은 소량의 데이터나 부분 범위 처리가 가능한 온라인 트랜잭션 환경에 적합한 조인 방식이라고 할 수 있다.

 


 

Sort Merge Join


NL Join은 인덱스에 조인 컬럼을 선두로 가지고 있는지가 매우 중요하다.

선두에 조건이 없으면 옵티마이저는 Sort Merge Join이나, Hash Join을 고려하게 된다.

이 중 Sort Merge Join의 Sort는 양쪽 집합을 조인 컬럼 기준으로 정렬함이고, Merge는 정렬된 양쪽 집합을 Merge 함을 의미한다.


1. 기본 메커니즘

아래는 dept 테이블을 기준으로 emp 테이블을 조인할 경우 Sort Merge Join을 이행하라는 힌트의 예제이다.

 

/*Data ON-AIR 참조*/

select /*+ ordered use_merge(e) */ d.deptno, d.dname, e.empno, e.ename 
from dept d, emp e 
where d.deptno = e.deptno 
Execution Plan ------------------------------------------------------------- 0 
SELECT STATEMENT Optimizer=CHOOSE (Cost=11 Card=654 Bytes=35K) 1 0 
MERGE JOIN (Cost=11 Card=654 Bytes=35K) 2 1 
SORT (JOIN) (Cost=6 Card=654 Bytes=14K) 3 2 
TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=654 Bytes=14K) 4 1 
SORT (JOIN) (Cost=5 Card=327 Bytes=11K) 5 4 
TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=327 Bytes=11K)

 

아래는 도식화된 Sort Merge 수행 과정이다.

 

실제 조인 수행 과정이 NL Join과 크게 다르지 않다. outer 집합과 inner 집합을 미리 정렬해 둔다는 점만 다르다. 다시 말하지만, 양쪽 집합을 먼저 정렬해 두었기 때문에 위와 같은 처리 로직이 가능하다.


2. Sort Merge Join의 특징

- 조인 하기 전에 양쪽 집합을 정렬한다.

- 부분적으로 부분 범위처리가 가능하다.

- 테이블별 검색 조건에 의해 전체 일량이 좌우된다.

- 스캔 위주의 조인 방식이다.

  - >Inner 테이블 반복 엑세스를 하지 않아서 Random 엑세스가 발생되지 않으나, 전혀없지는 않아서 랜덤 엑세스가 많으면 안 쓰는게 낫다.

 


Hash Join


1. 기본 메커니즘

Hash Join은 NL Join이나 Sort Merge Join이 효과적이지 못한 상황을 해결하고자 나온 조인 방식이다.

Hash Join 힌트를 사용해 보자.

 

/*Data ON-AIR 참조*/

select /*+ ordered use_hash(e) */ d.deptno, d.dname, e.empno, e.ename 
from dept d, emp e 
where d.deptno = e.deptno 
Execution Plan ------------------------------------------------------------- 0 
SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=654 Bytes=35K) 1 0 
HASH JOIN (Cost=5 Card=654 Bytes=35K) 2 1 
TABLE ACCESS (FULL) OF 'DEPT' (Cost=2 Card=654 Bytes=14K) 3 1 
TABLE ACCESS (FULL) OF 'EMP' (Cost=2 Card=327 Bytes=11K)

 

Hash Join은 둘 중 작은 집합(Build Input)을 읽어 해시 영역(Hash Area)에 해시 테이블(= 해시 맵)을 생성하고,

반대쪽 큰 집합(Probe Input)을 읽어 해시 테이블을 탐색하면서 조인하는 방식이다.

Hash Join 수행 과정

각 단계별로 살펴보자.

 

  • 1단계 : 두 집합 중 작다고 판단되는 집합을 읽어 해시 함수를 이용하여 해시 버킷으로 구성된 배열인 해시 테이블을 만든다. 해시 함수에서 리턴받은 해시 값이 같은 데이터를 같은 해시 버킷에 체인(연결 리스트)으로 연결한다.
  • 2단계 : 해시 테이블 생성을 위해 선택되지 않은 나머지 데이터 집합(Probe Input)을 스캔한다.
  • 3단계 : Probe Input에서 읽은 데이터로 해시 테이블을 탐색할 때도 해시 함수를 사용한다. 즉, 해시 함수에서 리턴받은 버킷 주소로 찾아가 해시 체인을 스캔하면서 데이터를 찾는다.

NL Join처럼 조인 과정에서 발생하는 Random 액세스 부하가 없고 Sort Merge Join처럼 조인 전에 미리 양쪽 집합을 정렬하는 부담도 없다. 다만, 해시 테이블을 생성하는 비용이 수반된다. 따라서 Build Input이 작을 때 효과적이다. Build Input이 대용량 테이블이면 디스크에 W/R 하는 과정을 거치기 때문에 성능이 저하된다. Build Input으로 선택된 테이블이 작은 것도 중요하지만  해시 키값으로 사용되는 컬럼에 중복값이 없을 때 효과적이다.


2. Build Input이 가용 메모리 공간을 초과할 때 처리 방식 

 In-Memory Hash Join이 불가능할 때 DBMS는 ‘Grace Hash Join’이라고 알려진 조인 알고리즘을 사용하는데,

두 단계로 나누어 진행된다.

 

1) 파티션 단계

조인되는 양쪽 집합 모두 조인 칼럼에 해시 함수를 적용하고, 반환된 해시 값에 따라 동적으로 파티셔닝을 실시한다. 독립적으로 처리할 수 있는 여러 개의 작은 서브 집합으로 분할함으로써 파티션 짝(pair)을 생성하는 단계다. 파티션 단계에서 양쪽 집합을 모두 읽어 디스크 상의 Temp 공간에 일단 저장해야 하므로 In-Memory Hash Join보다 성능이 크게 떨어지게 된다.

 

2) 조인 단계

파티션 단계가 완료되면 각 파티션 짝(pair)에 대해 하나씩 조인을 수행한다. 이때, 각각에 대한 Build Input과 Probe Input은 독립적으로 결정된다. 즉, 파티션하기 전 어느 쪽이 작은 테이블이었는지에 상관없이 각 파티션 짝(pair)별로 작은 쪽 파티션을 Build Input으로 선택해 해시 테이블을 생성한다. 해시 테이블이 생성되고 나면 반대 쪽 파티션 로우를 하나씩 읽으면서 해시 테이블을 탐색하며, 모든 파티션 짝에 대한 처리가 완료될 때까지 이런 과정을 반복한다. Grace Hash Join은 한마디로, 분할 정복(Divide & Conquer) 방식이라고 말할 수 있다. 실제로는 DBMS 벤더마다 조금씩 변형된 형태의 하이브리드(Hybrid) 방식을 사용하지만 두 개의 큰 테이블을 Hash Join하는 기본 알고리즘은 Grace Hash Join에 바탕을 두고 있다.


3. Build Input이 해시 키 값에 중복이 많을 때 발생하는 비효율

앞서 설명하였듯이 해시 알고리즘의 성능은 해시 충돌을 얼마나 최소화할 수 있느냐에 달렸으며, 이를 방지하려면 그만큼 많은 해시 버킷을 할당해야만 한다. DBMS는 가능하면 충분히 많은 개수의 버킷을 할당함으로써 버킷 하나당 하나의 키 값만 갖게 하려고 노력한다. 그런데 해시 버킷을 아무리 많이 할당하더라도 해시 테이블에 저장할 키 컬럼에 중복 값이 많다면 하나의 버킷에 많은 엔트리가 달릴 수 밖에 없다. 그러면 해시 버킷을 아무리 빨리 찾더라도 해시 버킷을 스캔하는 단계에서 많은 시간을 허비하기 때문에 탐색 속도가 현저히 저하된다. Build Input의 해시 키 컬럼에는 중복 값이 (거의) 없어야 Hash Join이 빠르게 수행될 수 있음을 이해할 것이다.


4. Hash Join 사용기준

 

아래는 Hash Join 성능을 좌우하는 두 가지 포인트이다.

 

  • 한 쪽 테이블이 가용 메모리에 담길 정도로 충분히 작아야 함
  • Build Input 해시 키 칼럼에 중복 값이 거의 없어야 함

아래는 Hash Join 이 효과적으로 사용될 경우이다.

 

  • 조인 칼럼에 적당한 인덱스가 없어 NL Join이 비효율적일 때
  • 조인 칼럼에 인덱스가 있더라도 NL Join 드라이빙 집합에서 Inner 쪽 집합으로의 조인 액세스량이 많아 Random 액세스 부하가 심할 때
  • Sort Merge Join 하기에는 두 테이블이 너무 커 소트 부하가 심할 때
  • 수행빈도가 낮고 조인할 때

 

Hash Join은 앞선 다른 조인과 다르게 영구적이지 못하고 소멸되는 치명적인 단점이 있어 수행빈도가 높은 쿼리에 Hash Join을 많이 사용한다면 CPU/Memory 작별을 고해야 할지 모른다.

 

즉 'Hash Join'은 수행 빈도가 낮고, 쿼리 수행 시간이 오래 걸리는 대용량 테이블을 조인할 경우에 주로 사용해야 한다. 



 

'DB' 카테고리의 다른 글

Index 3) 인덱스 튜닝  (0) 2023.10.25
Index 2) 인덱스 스캔  (2) 2023.10.24
Index 1) 인덱스 구조  (0) 2023.10.24

도메인 주도 설계 (DDD)


서비스 분리와 도메인 주도 설계

  • DDD는 MSA의 서비스를 식별할 수 있는 도구를 제공
  • DDD 중 전략적 설계가 MSA의 서비스를 식별하는데 도움

도메인이란?

  • 소프트웨어를 개발하는 대상 영역
  • 복잡한 비즈니스나 현실세계의 문제

도메인 주도 설계란?

  • 복잡한 현실세계의 문제를 해결할 좋은 SW를 만들기 위한 기법
  • 도메인 주도 설계는 도메인의 이해를 최우선시 하는 모델링 기법
  • 전문가와 개발자의 커뮤니케이션이 중요
  • 도메인과 도메인 모델 그리고 코드를 밀접하게 연관 시킴 (언어의 통일)
  • 도메인 모델 - 동일한 관점에서 이해할 수 있고, 공유할 수 있도록 단순화 (다이아그램 사용)
  • 코드에 도메인의 의미가 녹아 있도록 구현

DDD의 필요성 : Big Ball of Mud

  • 요구사항 추출 -> 분석 -> 설계 -> 구현
  • 계속되는 추가 요구사항
  • 중요한 것과 덜 중요한, 혹은 중요하지 않은 것들이 하나의 큰 덩어리로 얽히게 됨

Big Ball of Mud (CodeOpinion참조)

  • 각 클래스(엔티티)의 의미 파악 어려움

DDD의 필요성 : Big Ball of Mud 원인 by Vaughn Vernon

  • 조직에서 SW 설계에 충분한 노력을 들이지 않음
  • 개발자는 도메인 보다 기술에 너무 몰두, 많은 문제를 기술적으로만 해결하려 함
  • 도메인의 이해 없이 개발자 상상의 나래가 표출됨

 


전략적 설계

마이크로서비스 도출을 위해서 비즈니스 상 전략적으로 중요한 것을 찾아 중요도에 따라 이를 나눔

 


전략적 설계의 필요성

  • 애자일 프로젝트 관리 시스템을 개발 사례
  • 설계 초기에는 핵심이 되는 부분을 설계
  • Big Ball of Mud 방지

서브 도메인

  • 전체 비즈니스 도메인을 이해 가능한 하위 영역으로 분리 필요
  • 전체의 큰 도메인을 분리함
  • 핵심 서브 도메인, 지원 서브 도메인 (비즈니스 도메인), 일반 서브 도메인(큰 공수 없는 도메인)으로 분리

바운디드 컨텍스트

  • 유비쿼터스 언어로 표현이 됨
  • 의미적으로 동일한 맥락의 경계라는 것은 응집도 높은 일을 한다는 것
  • 바운디드 컨텍스트 마다 각각 분리된 소프트웨어의 코드 산출

서브도메인과 바운디드 컨텍스트의 관계

  • 서브 도메인은 Problem Space
  • 바운디드 컨텍스트는 Solution Space
  • Problem Space : 해결해야 하는 도메인 -  서브 도메인들의 집합
  • Solution Space : 해결책을 실제 구현 - 바운디드 컨텍스트들의 집합
  • 보통 하나의 서브도메인은 하나의 바운디드 컨텍스트를 갖는 1:1
  • 서브도메인이 하나 이상의 바운디드 컨텍스트가 매핑 가능 (ex). 상품 - 연관상품, 쿠폰, 할인정보 등)

유비쿼터스 언어와 바운디드 컨텍스트의 관계

  • 제품 책임자와 도메인 전문가 그리고 개발자 간 언어의 통일이 중요
  • SW 개발의 가장 큰 문제 중 하나 (개발언어 x,  사용언어 o)
  • 개발자가 아닌 사람도 도메인 모델 및 코드를 보고 이해할 수 있어야 함
  • 컨텍스트에 따라 비슷해 보이는 언어들이 실제로는 다를 수 있음
  • 각 문맥 별로 상품의 이름을 명확하게 재정의할 필요가 있음

       ex) - 카탈로그 컨텍스트에서의 상품은 Product

             - 재고 컨텍스트에서의 상품은 Stock

             - 주문 컨텍스트에서의 상품은 OrderedItem

 


결론

개발자가 아닌 사람이 이름만 딱 봐도 무엇인지 알 수 있도록 설계를 하자.



 

'Architecture' 카테고리의 다른 글

Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 4) MSA 분리 전략 : 분리 원칙  (0) 2023.11.01
MSA 3) MSA 역량/성숙도 모델  (4) 2023.10.18
MSA 2) Microservice Architecture 에 대해서  (0) 2023.10.18

+ Recent posts