Kafka

Kafka Cruise-Control 사용해보기

재심 2023. 8. 31. 14:53

목차

    [Cruise Control?]

    Cruise Control은 Apache Kafka 클러스터를 대규모로 실행하는 데 도움이 되는 제품입니다.
    Apache Kafka의 인기로 인해 많은 회사에서 점점 더 큰 Kafka 클러스터를 보유하고 있습니다. LinkedIn에는 ~7K+ Kafka 브로커가 있습니다. 이는 브로커 사망이 거의 매일 발생하고 Kafka의 작업 부하 균형도 큰 오버헤드가 된다는 것을 의미합니다.
    Kafka Cruise Control은 이러한 작업 확장성 문제를 해결하도록 설계되었습니다.
    Kafka 클러스터를 원격으로 관리하는데 도움이 되는 REST 인터페이스를 추가했습니다.

    Cruise Control은 큰 규모의 Kafka 클러스터를 운영하는데 있어 운영관리를 단순하게 해주는 오픈소스 도구..!

    기본적인 클러스터 상태 모니터링은 물론 이상징후 감지 등을 지원한다고 한다. 

     

    또 goal을 세팅해서 리밸런싱 전략을 세울 수 있다고 한다. 

     

    주요기능

    Kafka broker 자원 활용도 추적
    broker 에서 최신 복제본 상태 (오프라인, URP, 동기화되지 않음) 를 쿼리하는 기능
    목표 기반 자원 분재
    자가 치유를 통한 이상 감지
    Kafka 에 대한 관리 작업 ( broker 추가 / 제거 / 강등, 클러스터 재조정, PLE 실행)
    PLE : Preferred replica Leader Election
    • Multi-goal rebalance proposal generation for:
      • Rack-awareness
      • Resource capacity violation checks (CPU, DISK, Network I/O)
      • Per-broker replica count violation check
      • Resource utilization balance (CPU, DISK, Network I/O)
      • Leader traffic distributionㄹ
      • Replica distribution for topics
      • Global replica distribution
      • Global leader replica distribution
      • Custom goals that you wrote and plugged in
    • Anomaly detection, alerting, and self-healing for the Kafka cluster, including:
      • Goal violation
      • Broker failure detection
      • Metric anomaly detection
      • Disk failure detection (not available in kafka_0_11_and_1_0 branch)
      • Slow broker detection (not available in kafka_0_11_and_1_0 branch)
    • Admin operations, including:
      • Add brokers
      • Remove brokers
      • Demote brokers
      • Rebalance the cluster
      • Fix offline replicas (not available in kafka_0_11_and_1_0 branch)
      • Perform preferred leader election (PLE)
      • Fix offline replicas
      • Adjust replication factor

    github

    [Cruise-Control Architecture]

    REST API를 통해 명령을 수행할 수 있음.

    Analyzer, Anomaly Detector, Executor 등의 컴포넌트로 구성됨. 

     

    자체적인 Metric Reporter를 통해 카프카 클러스터의 메트릭을 수집함. 

     

    Metric Reporter

    카프카 클러스터의 메트릭을 내부 토픽에 수집함

    Monitor

    수집된 메트릭을 기반으로 현재 상태를 나타내주는 모델을 생성함.

    Metric Sampler는 5분마다 Metric Reporter가 생성한 메트릭을 수집한다. 

    Sample Store는 load history를 생성해서 Load History 토픽에 넣는다. 이를 바탕으로 failure 등에서 활용하게 된다. 

    Capacity Resolver는 브로커의 Capacity는 수집한다. 

     

    수집 종류

    • Topology: rack, host 상태
    • Placement: replica, leader, partition 분배 상태
    • Load: 리소스 부하 상태 (ex: CPU, Network In-Out, Disk etc..)

    Analyzer

    Goal을 달성하기 위한 Proprosal을 생성한다.

     

    Executor

    Proposal을 실제로 수행하는 역할을 한다.

     

    동적으로 현재 leader/replica assignment를 조절한다. 

    동시에 하나의 execution만 수행한다. 

    취소시 graceful 하게 취소하는 것을 보장한다. 

    KIP-73의 Replica Quota와 통합되어있다. (KIP-73: leader/replica 조정 시 트래픽의 상한을 둘 수 있도록 제안한 것. reassign-partitions를 수행할 때 throttle 옵션을 줄 수 있게되었다) 

    https://cwiki.apache.org/confluence/display/KAFKA/KIP-73+Replication+Quotas 

     

    KIP-73 Replication Quotas - Apache Kafka - Apache Software Foundation

    Contents: Status Current state: Adopted Jira:  KAFKA-1464.  here is no specific config for the number of throttled replica fetcher threads as the config for the number of replica  Relates to: KIP-13: Quotas, KIP-74: Add Fetch Response Size Limit in By

    cwiki.apache.org

     

    Anomaly Detector

    Goal 충돌을 감지. Broker Failure, Disk Failure 등을 감지.

    Self-Healing 트리거가 클러스터 리밸런싱을 수행함. 

     

    수행결과 예시

     

    [Goal]

    Cruise Control은 카프카 클러스터를 재조정하기 위해 최적화 목표를 사용하여 제안(Proposal)을 생성한다고 한다.

    지원되는 최적화 목표들은 내림차순으로 아래와 같다고 한다. 

    참고 :

     

    • Rack-awareness (Rack 인식):랙 인식을 통한 파티션 분산 관리
    • Replica capacity (Replica 용량):시스템 자원 사용 안정성
    • Capacity: Disk capacity, Network inbound capacity, Network outbound capacity (디스크 용량, 네트워크 인/아웃 바운드 용량, CPU용량): CPU, DISK, Network I/O
    • Replica distribution (Replica 분배)
    • Potential network output (잠재적 네트워크 아웃풋)
    • Resource distribution: Disk utilization distribution, Network inbound utilization distribution, Network outbound utilization distribution:디스크 활용도 분포, 네트워크 인/아웃 바운드 활용도 분포, CPU 사용률 분포
    • Leader bytes-in rate distribution (리더 bytes-in 비율)
    • Topic replica distribution (토픽 Replica 배포):토픽 가용성을 위한 replica 분산 배치
    • Leader replica distribution (리더 Relica 배포):브로커 별 leader replica 분산 배치
    • Preferred leader election (Preferred Leader Election)

    Hard goal, Soft goal

    • Hard goal: 최적화 proposal에서 "충족 되어야" 하는 목표. 
    • Soft goal: Hard goal이 아닌 목표 (최선형 목표)
      • 모든 hard goal 를 충족할 수 있는 경우, 충족되지 않은 상태로 남아 있을 수 있음

     

    Cruise Control은 모든 hard goal을 충족 + 가능한 많은 soft goal을 달성하는 제안을 준다고 한다. 

    그래서 soft goal은 일부 누락될 수 있지만 hard goal은 반드시 충족하는 제안을 주게되는 것이라 한다. 

    그래서 hard goal을 달성하지 못하는 제안은 하지 않는다고 한다. 

    → 최적화된 결과가 hard goal 을 위반하게 되면 최적화에 실패 하게 됨

     

    ex) soft gal 중에 topic replica distribution goal이 있는데, 이건 토픽의 replica를 전체 클러스터에 배분하는 것이다. 근데 이것도 hard goal이 달성되어야 고려되는 요소라고 한다. 

     

    Cruise Control에서 Goal들은 미리 정의가 되어 있다. 

    RackAwareGoal; ReplicaCapacityGoal; DiskCapacityGoal; NetworkInboundCapacityGoal; NetworkOutboundCapacityGoal

    그리고 hard goals에 이러한 목표를 정의할 수 있다고 한다. 이러한 hard goal들의 수를 늘리면 유효한 제안을 생성할 가능성이 줄어든다고 한다. 

    hard.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal

    Goal 정의 예시

    # The list of supported goals
    goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.BrokerSetAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PotentialNwOutGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderReplicaDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderBytesInDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerDiskUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerEvenRackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PreferredLeaderElectionGoal
     
    default.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PotentialNwOutGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderReplicaDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderBytesInDistributionGoal
     
    # The list of supported intra-broker goals
    intra.broker.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.IntraBrokerDiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.IntraBrokerDiskUsageDistributionGoal
     
    # The list of supported hard goals -- consider using RackAwareDistributionGoal instead of RackAwareGoal in clusters with partitions whose replication factor > number of racks
    hard.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal

    Master Optimization Goals 

    goal 목록인듯 하다. 이 목록에 있는 goal들만 hard goal이나 soft goal에 설정할 수 있다는 뜻으로 보임. 

    goals라는 옵션에 정의되어 있다. 

    goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.BrokerSetAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundCapacityGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuCapacityGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.PotentialNwOutGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.DiskUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkInboundUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.NetworkOutboundUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.CpuUsageDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.TopicReplicaDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderReplicaDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.LeaderBytesInDistributionGoal,com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerDiskUsageDistributionGoal,
    com.linkedin.kafka.cruisecontrol.analyzer.kafkaassigner.KafkaAssignerEvenRackAwareGoal,com.linkedin.kafka.cruisecontrol.analyzer.goals.PreferredLeaderElectionGoal

     

    Default Optimization Goals

    default goal을 사용해서 "캐시된 최적화 제안" 을 생성한다고 한다. 

    만약 default goals를 지정하지 않으면 master goal 목록에서 최적화 제안을 작성한다고 한다. 

     

    "캐시된 최적화 제안"

    Cruise Control은 구성되어있는 goal들에 따라 캐시된 최적화 제안을 관리한다고 한다. 

    이러한 캐싱은 15분마다 업데이트 된다고 한다. (proposal.expiration.ms 값으로 조절 가능. 줄일경우 부하 증가)

    http://localhost:9090/kafkacruisecontrol/proposals?json=true

    최적화 제안을 반환한다고 한다. 최적화 전후의 작업 요약도 제공한다고 한다. 

     

    속성 설명 비교
    numIntraBrokerReplicaMovements 클러스터 브로커의 디스크 간 전송될 Replica수 브로커 내부의 디스크 간 이동으로 보임
    numReplicaMovements 브로커 간 Replica 이동  
    onDemandBalancednessScoreAfter 최적화 제안 전 후 균형 상태 지표 값 100에서 각 Soft Goal의 합을 빼서 계산한다고 함. 
    monitoredPartitionsPercentage 최적화 제안이 적용되는 카프카 클러스터의 파티션 비율 excludedTopics에 영향을 받는다고 함. 
    onDemandBalancednessScoreBefore 최적화 제안 전 후 전반적인 균형 상태 지표   
    intraBrokerDataToMoveDB 동일한 브로커의 디스크간 이동될 각 파티션 Replica의 크기 합계  

     

    {
      "summary": {
        "numIntraBrokerReplicaMovements": 0,
        "numReplicaMovements": 23,
        "onDemandBalancednessScoreAfter": 83.00380800916568,
        "intraBrokerDataToMoveMB": 0,
        "monitoredPartitionsPercentage": 100,
        "provisionRecommendation": "",
        "excludedBrokersForReplicaMove": [],
        "excludedBrokersForLeadership": [],
        "provisionStatus": "RIGHT_SIZED",
        "onDemandBalancednessScoreBefore": 83.00380800916568,
        "recentWindows": 5,
        "dataToMoveMB": 0,
        "excludedTopics": [],
        "numLeaderMovements": 4
      },
      "goalSummary": [
        {
          "clusterModelStats": {
            "metadata": {
              "replicas": 148,
              "brokers": 8,
              "topics": 4
            },
    ...생략

    User-Provided Optiomization Goals

    사용자 제공 최적화 목표. Master Goal 목록에 있어야 하며 Hard Goal을 충족해야 달성가능하다고 한다. 

    즉, goals 목록에 추가하여야 한다. 

     

    최적화 제안 승인 (Approving an optimization proposals)

    Cruise-Control이 goal들을 기반으로 최적화 제안을 하게되면 "승인"할 수 있다. 승인하게되면 실제로 카프카 클러스터에 적용한다. 

    Proposal Ready 상태임을 확인하면 된다고 한다. 

     

    GET /kafkacruisecontrol/state (isProposalReady: true)

    Goal 목록

    https://github.com/linkedin/cruise-control/wiki/Pluggable-Components#goals

     

    Goal Detailed Goals 설명 비고
    RackAware   각 파티션의 Replica가 Rack을 인식하여 할당될 수 있도록 함.   
    RackAwareDistributionGoal   RackAware와 달리 Replica가 Rack전체에 균등배포가능한 상태라면 파티션의 여러 Replica를 단일 Rack에 배치할 수 있다고 한다.  ex) Replica > Rack Count이면 RackAware가 아닌 RackAwareDistributionGoal을 사용하라고 한다. 
    ReplicaCapacityGoal   모든 브로커가 지정된 Replica수보다 적게 갖도록 시도. 무슨말이지..? 
    CapacityGoals
    • DiskCapacityGoal
    • NetworkInboundCapacityGoal
    • NetworkOutboundCapacityGoal
    • CpuCapacityGoal
    브로커 리소스 사용률이 해당 리소스에 지정된 임계값 미만인지 확인하는 목표  
    ReplicaDistributionGoal   클러스터의 모든 브로커가 비슷한 수의 복제본을 갖도록 시도.  
    PotentialNwOutGoal   네트워크 사용 대역을 초과하지 않도록 하는 목표  
    ResourceDistributionGoals
    • DiskUtilDistributionGoal
    • NetworkInboundUtilDistributionGoal
    • NetworkOutboundUtilDistributionGoal
    • CpuUtilDistributionGoal
    모든 브로커간 리소스 사용률이 특정 범위 내에 있도록 함.  
    TopicReplicaDistributionGoal   동일한 토픽의 복제본을 전체 클러스터에 균등 분배하려고 시도  
    LeaderReplicaDistributionGoal   클러스터의 모든 브로커가 비슷한 리더수를 가지도록 시도  
    LeaderBytesInDistributionGoal   리더 파티션의 사용률을 비슷하게 맞추려고 시도.   
    PreferredLeaderElectionGoal      
    KafkaAssignerGoals

     
    KafkaAssignerDiskUsageDistributionGoal    
    KafkaAssignerEvenRackAwareGoal    
    IntraBrokerDiskCapacityGoal      
    IntraBrokerDiskUsageDistributionGoal      

     

    [Quick Start - 로컬 세팅]

    로컬 윈도우PC의 WSL 환경에서 진행하였다. 
    리눅스 환경의 서버가 있다면 거기서 진행해도 무방하다. 

    Step1. 소스 내려받고 빌드하기

    공식적으로 컨테이너 이미지를 제공하고 있지 않은듯 하다. 

    가이드대로 git으로 소스를 내려받은 후 gradle로 빌드해야 한다. 

    git clone https://github.com/linkedin/cruise-control.git && cd cruise-control/

    소스를 내려받은 후 jar파일을 생성한다.

    ./gradlew jar

    Step2. metrics-reporter jar 파일 준비하기

    jar파일로 생성하면 /build/libs/cruise-control-metrics-reporter-A.B.C.jar 라는 파일이 생긴다. 필요하다면 아래 링크로 다운받을 수 있다. 

    cruise-control-metrics-reporter-2.5.125-SNAPSHOT.jar
    0.05MB

     

    Cruise-Control은 메트릭 수집을 metric reporter로 수행하기 때문에 해당 파일을 카프카 브로커가 구동될 때 jar파일이 로딩되는 path에 넣어줘야 한다. Step3에서 docker-compose 파일을 세팅하면서 세팅해줄 것이다. 

     

    Step3. docker-compose.yml 파일 작성하기

    로컬에서 카프카를 구동하여 테스트하기 위해 docker-compose.yml 파일을 작성한다. 

    zookeeper는 1대이며 kafka-ui를 어드민으로 사용한다.

     

    브로커 숫자별로 필요한 파일을 사용한다. 

    docker-compose-8brk.yml
    0.01MB
    docker-compose-16brk.yml
    0.02MB

     

    이 때 아래 2가지가 중요하다.

    • volumes: step2에서 생성한 cruise-control-metrics-reporter.jar 파일을 /usr/share/java/kafka 경로에 마운트 시켜준다. (브로커가 로드되면서 해당 jar파일도 JVM에 올릴 것이다)
    • environment.KAFKA_METRIC_REPORTERS: "com.linkedin.kafka.cruisecontrol.metricsreporter.CruiseControlMetricsReporter"를 명시하여 CruiseControl의 Metric Reporter를 사용할 것이다. (위의 jar파일)
     
    version: '2.1'
     
    services:
      zoo1:
        image: confluentinc/cp-zookeeper:7.3.2
        hostname: zoo1
        container_name: zoo1
        ports:
          - "2181:2181"
     
    ...생략. 첨부파일 참조

     

    컨테이너를 구동하고, 정상적으로 카프카가 정상적으로 구동 되는지 확인한다.

    • 상단에서 작성한 docker-compose.yml 파일이 존재하는 위치에서 compose up 으로 컨테이너 구동 실행
    $ docker-compose up

    http://localhost:8080 

    Step4. Cruise-Control Config 설정 및 구동

    4.1 config/cruisecontrol.properties에서 필수로 2가지 값을 수정해야 한다.

    • bootstrap.servers=localhost:9092,localhost:9093,localhost:9094,localhost:9095,localhost:9096,localhost:9097,localhost:9098,localhost:9099
    • zookeeper.connect=localhost:2181

    cruisecontrol.properties
    0.02MB

     

    4.2 config/capacity.config.file 파일 선택

    상황에 따라 브로커 스로틀을 어떻게 줄지 선택하는 파일을 정의해야 한다고 한다. 기본값으로 해도되는데, 상세한 조정이 필요한듯하다. 

    가이드: https://github.com/linkedin/cruise-control/wiki/Configurations#brokercapacityconfigurationfileresolver-configurations 

     

    capacity 파일을 정의한 후 cruisecontrol.properties 파일내에서 capacity.config.file에 해당 파일을 설정해준다. 

    우선은 기본값으로 진행한다. (추후 수정하여 사용)

     

    예시. capacity.json

    {
      "brokerCapacities":[
        {
          "brokerId": "-1",
          "capacity": {
            "DISK": "100000",
            "CPU": "100",
            "NW_IN": "10000",
            "NW_OUT": "10000"
          },
          "doc": "This is the default capacity. Capacity unit used for disk is in MB, cpu is in percentage, network throughput is in KB."
        },
        {
          "brokerId": "0",
          "capacity": {
            "DISK": "500000",
            "CPU": "100",
            "NW_IN": "50000",
            "NW_OUT": "50000"
          },
          "doc": "This overrides the capacity for broker 0."
        }
      ]
    }

     

    Step5. CruiseControl Jar파일 생성 및 의존성 파일 함께 생성

    $ ./gradlew jar copyDependantLibs

    빌드 후 jar파일이 모두 생성되었으니 이제 cruise control을 구동할 수 있다.

    이 때 윈도우에서 빌드했다면 줄바꿈 문자가 스크립트파일에 추가되기 때문에 아래 명령어로 제거하는 작업을 먼저해준다.

    # 윈도우에서 만든 스크립트는 개행문자가 붙어서 제거
    $ sed -i -e 's/\r//g' kafka-cruise-control-start.sh
    $ sed -i -e 's/\r//g' kafka-cruise-control-stop.sh

    cruise-control을 구동한다.

     
    $ ./kafka-cruise-control-start.sh -jars cruise-control/build/libs/cruise-control-2.5.125-SNAPSHOT.jar config/cruisecontrol.properties

    웹에서 제대로 뜨는지 확인한다.

    http://localhost:9090/kafkacruisecontrol/state?json=true 

     

    Step6. Cruise Control UI 추가

    cruise control은 기본적으로 UI를 제공하지 않는다. 그래서 별도의 프로젝트에서 소스를 내려받아 작업해주어야 한다. 

    github: https://github.com/linkedin/cruise-control-ui/

    가이드: https://catalog.workshops.aws/msk-labs/en-US/cruisecontrol/cruisecontrol-ui

     

    가이드대로 진행한다. 

    # 소스 내려받기
    $ wget https://github.com/linkedin/cruise-control-ui/releases/download/v0.4.0/cruise-control-ui-0.4.0.tar.gz
     
    # 압축풀기
    $ tar -xvzf ./cruise-control-ui-0.3.4.tar.gz
     
    # cruise-control 디렉토리로 이동
    $ mv cruise-control-ui ~/cruise-control/
     
    # config 파일 수정. cruise-control-ui/dist/static로 이동. config.csv 파일을 수정한다.
    $ cd ./cruise-control-ui/dist/static
     
    $ vim config.csv
    #아래 내용 기입
    dev,dev,http://localhost:9090/kafkacruisecontrol/
      
    # cruise-control 재시작
    $ ./kafka-cruise-control-start.sh -jars cruise-control/build/libs/cruise-control-2.5.125-SNAPSHOT.jar config/cruisecontrol.properties

    http://localhost:9090 으로 이동하여 확인

     

    Cluster Load 화면은 MetricReporter가 제대로 세팅되어 있어야 나온다. 그리고 메트릭 수집이 일정기간 필요하기 때문에 구동 후 10분 정도 뒤에 확인한다.

     

    [CCFE]

    Cruise Control REST API 는 강력하고 많은 기능을 가지고 활용 할 수 있으며 Kafka 클러스터와 클러스터를 운영하는 팀의 분산 특성을 감안할 때 모든 사람이 같은 페이지에 있도록 하는 일은 어려웠으나 CCFE 는 해당 문제를 해결하기 위한 스트리밍 SRE 에 의해 만들어짐

     

    -> Cruise Control 또는 표준 웹 서버와 함께 배포 할 수 있는 단일 페이지 웹 응용 프로그램

     

     

    [REST API]

    지원하는 API에 대한 정리

    https://github.com/linkedin/cruise-control/wiki/REST-APIs 

    GET

    Cruise Control State 

    http://localhost:9090/kafkacruisecontrol/state?json=true

    응답예시

     

    {
      "AnalyzerState": {
        "isProposalReady": true,
        "readyGoals": [
          "NetworkInboundUsageDistributionGoal",
          "CpuUsageDistributionGoal",
          "PotentialNwOutGoal",
          "LeaderReplicaDistributionGoal",
          "NetworkInboundCapacityGoal",
          "LeaderBytesInDistributionGoal",
          "DiskCapacityGoal",
          "ReplicaDistributionGoal",
          "RackAwareGoal",
          "TopicReplicaDistributionGoal",
          "NetworkOutboundCapacityGoal",
          "CpuCapacityGoal",
          "DiskUsageDistributionGoal",
          "NetworkOutboundUsageDistributionGoal",
          "ReplicaCapacityGoal"
        ]
      },
      "MonitorState": {
        "trainingPct": 20,
        "trained": false,
        "numFlawedPartitions": 0,
        "state": "RUNNING",
        "numTotalPartitions": 74,
        "numMonitoredWindows": 5,
        "monitoringCoveragePct": 100,
        "reasonOfLatestPauseOrResume": "Resumed-By-Cruise-Control-Before-Starting-Execution (Date: 2023-08-17T00:57:13Z)",
        "numValidPartitions": 74
      },
      "ExecutorState": {
        "state": "NO_TASK_IN_PROGRESS"
      },
      "AnomalyDetectorState": {
        "recentBrokerFailures": [
          {
            "anomalyId": "ed44d177-a5b4-4918-a215-66e363c26e5a",
            "failedBrokersByTimeMs": {
              "4": 1692233504482
            },
            "detectionMs": 1692233504485,
            "statusUpdateMs": 1692233504487,
            "status": "CHECK_WITH_DELAY"
          },
          {
            "anomalyId": "9d0a8f79-597e-4075-a2b0-25bed607378a",
            "failedBrokersByTimeMs": {
              "4": 1692233939023
            },
            "detectionMs": 1692233939024,
            "statusUpdateMs": 1692233939024,
            "status": "CHECK_WITH_DELAY"
          }
        ],
        "recentGoalViolations": [],
        "selfHealingDisabled": [
          "BROKER_FAILURE",
          "DISK_FAILURE",
          "GOAL_VIOLATION",
          "METRIC_ANOMALY",
          "TOPIC_ANOMALY",
          "MAINTENANCE_EVENT"
        ],
        "balancednessScore": 100,
        "selfHealingEnabled": [],
        "recentDiskFailures": [],
        "metrics": {
          "meanTimeBetweenAnomaliesMs": {
            "METRIC_ANOMALY": 0.6234860405321706,
            "GOAL_VIOLATION": 0,
            "BROKER_FAILURE": 0.41565735367717976,
            "TOPIC_ANOMALY": 0,
            "DISK_FAILURE": 0,
            "MAINTENANCE_EVENT": 0
          },
          "ongoingAnomalyDurationMs": 1732462,
          "numSelfHealingStarted": 0,
          "numSelfHealingFailedToStart": 0,
          "meanTimeToStartFixMs": 329435
        },
        "recentMetricAnomalies": [
          {
            "anomalyId": "c9390f31-343a-4be9-a89e-1ddc4d890215",
            "detectionMs": 1692234623875,
            "description": "Metric value 4.000 of BROKER_CONSUMER_FETCH_LOCAL_TIME_MS_999TH for brokerId=4,host=127.0.0.1 in window 2023-08-17T01:10:00Z is out of the normal range for percentile: [10.00, 90.00] (value: [0.000, 2.800] with margins (lower: 0.200, upper: 0.500)) in 12 history windows from 2023-08-17T01:05:00Z to 2023-08-17T00:10:00Z.",
            "statusUpdateMs": 1692234623875,
            "status": "IGNORED"
          },
          {
            "anomalyId": "5c94694a-facb-4f9b-bea3-6eaddef8687e",
            "detectionMs": 1692234623875,
            "description": "Metric value 2.000 of BROKER_CONSUMER_FETCH_LOCAL_TIME_MS_50TH for brokerId=4,host=127.0.0.1 in window 2023-08-17T01:10:00Z is out of the normal range for percentile: [10.00, 90.00] (value: [0.000, 1.575] with margins (lower: 0.200, upper: 0.500)) in 12 history windows from 2023-08-17T01:05:00Z to 2023-08-17T00:10:00Z.",
            "statusUpdateMs": 1692234623875,
            "status": "IGNORED"
          },
          {
            "anomalyId": "a76c736b-f2a4-491d-b524-2546846172bd",
            "detectionMs": 1692235523878,
            "description": "Metric value 0.000 of BROKER_FOLLOWER_FETCH_LOCAL_TIME_MS_999TH for brokerId=8,host=127.0.0.1 in window 2023-08-17T01:25:00Z is out of the normal range for percentile: [10.00, 90.00] (value: [0.071, 204.319] with margins (lower: 0.200, upper: 0.500)) in 15 history windows from 2023-08-17T01:20:00Z to 2023-08-17T00:10:00Z.",
            "statusUpdateMs": 1692235523878,
            "status": "IGNORED"
          }
        ],
        "recentTopicAnomalies": [],
        "selfHealingEnabledRatio": {
          "BROKER_FAILURE": 0,
          "DISK_FAILURE": 0,
          "GOAL_VIOLATION": 0,해
          "METRIC_ANOMALY": 0,
          "TOPIC_ANOMALY": 0,
          "MAINTENANCE_EVENT": 0
        },
        "recentMaintenanceEvents": []
      },
      "version": 1
    }

     

    상태 종류는 여러개 있는 듯 하다.

    • Monitor State
    • Executor State
    • Analyzer State
    • Anomaly Detector State

     

    cruise-control ui 페이지

    http://localhost:9090/#/dev/dev/state/executor

     

    클러스터 부하 

    http://localhost:9090/kafkacruisecontrol/load?json=true

    브로커 호스트 정보와 리소스 사용률 등을 나타내 주는 듯 하다. 

    응답예시

    {
      "brokers": [
        {
          "FollowerNwInRate": 0.056687785778194666,
          "BrokerState": "ALIVE",
          "Broker": 1,
          "NwOutRate": 0.0068745999597013,
          "NumCore": 1,
          "Host": "127.0.0.1",
          "CpuPct": 0.2997756600379944,
          "Replicas": 16,
          "NetworkInCapacity": 50000,
          "Rack": "md",
          "Leaders": 9,
          "DiskCapacityMB": 500000,
          "DiskMB": 0.33643531799316406,
          "PnwOutRate": 0.16803793609142303,
          "NetworkOutCapacity": 50000,
          "LeaderNwInRate": 0.0068745999597013,
          "DiskPct": 0.00006728706359863281
        },
        ...생략
      "version": 1
    }

    cruise-control-ui에서는 아래 페이지인듯하다.

    http://localhost:9090/#/dev/dev/load

    • 브로커가 내보댄 메트릭을 내부적으로 활용하고 REST API 를 통해 추가로 노출되는 리소스 사용량 (ex. CPU, 네트워크 및 디스크) 를 계산함
    • 브로커와 서버 관점 모두에서 계산된 로드를 볼 수 있음
      • kafka 서버 및 broker 성능 지표를 이해하는데 도움이 됨
    • 제공하는 리소스 세부 정보 이외에도 리더 대 팔로워 비율 및 입력/출력 비율과 같은 몇 가지 다른 메트릭이 표시되어 브로커의 메시지 패턴을 명확하게 파악 가능
      • LF Ratio (Leader-to-Follower Ratio) : leader 대 follower 비율

    파티션 리소스 사용률

    http://localhost:9090/kafkacruisecontrol/partition_load?json=true 

     

    결과는 리소스 사용률 기준으로 정렬된 파티션 목록을 나타내준다고 한다. 

     

    파티션과 Replica 상태

    http://localhost:9090/kafkacruisecontrol/kafka_cluster_state?json=true

     

    브로커별 Replica수, Leader Count, Offline 파티션 수 등을 알려주는듯하다. 

    {
      "KafkaPartitionState": {
        "offline": [],
        "urp": [],
        "with-offline-replicas": [],
        "under-min-isr": []
      },
      "KafkaBrokerState": {
        "ReplicaCountByBrokerId": {
          "1": 16,
          "2": 21,
          "3": 16,
          "4": 21,
          "5": 21,
          "6": 16,
          "7": 16,
          "8": 21
        },
        "OfflineLogDirsByBrokerId": {
          "1": [],
          "2": [],
          "3": [],
          "4": [],
          "5": [],
          "6": [],
          "7": [],
          "8": []
        },
        "BrokerSetByBrokerId": {},
        "OnlineLogDirsByBrokerId": {
          "1": [
            "/var/lib/kafka/data"
          ],
          "2": [
            "/var/lib/kafka/data"
          ],
          "3": [
            "/var/lib/kafka/data"
          ],
          "4": [
            "/var/lib/kafka/data"
          ],
          "5": [
            "/var/lib/kafka/data"
          ],
          "6": [
            "/var/lib/kafka/data"
          ],
          "7": [
            "/var/lib/kafka/data"
          ],
          "8": [
            "/var/lib/kafka/data"
          ]
        },
        "LeaderCountByBrokerId": {
          "1": 9,
          "2": 9,
          "3": 8,
          "4": 11,
          "5": 11,
          "6": 9,
          "7": 6,
          "8": 11
        },
        "OutOfSyncCountByBrokerId": {},
        "Summary": {
          "StdLeadersPerBroker": 1.6393596310755,
          "Leaders": 74,
          "MaxLeadersPerBroker": 11,
          "Topics": 4,
          "MaxReplicasPerBroker": 21,
          "StdReplicasPerBroker": 2.5,
          "Brokers": 8,
          "AvgReplicationFactor": 2,
          "AvgLeadersPerBroker": 9.25,
          "Replicas": 148,
          "AvgReplicasPerBroker": 18.5
        },
        "IsController": {
          "1": false,
          "2": false,
          "3": false,
          "4": false,
          "5": false,
          "6": false,
          "7": false,
          "8": true
        },
        "OfflineReplicaCountByBrokerId": {}
      },
      "version": 1
    }

     

    kafka-ui에서는 아래 화면인듯 하다.

    http://localhost:9090/#/dev/dev/kafka_cluster_state

     

    [테스트]

    시나리오1. 리더, 레플리카 불균형 발생 후 확인 

     

    여러개의 토픽을 만드는데 이 때 브로커1, 2에 몰아준다. 

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
     
    sudo kafka-topics --describe     --bootstrap-server localhost:9092     --topic test-topic1
     
    # 삭제 시 사용
    #sudo kafka-topics --bootstrap-server localhost:9092 --delete --topic test-topic;
    #sudo kafka-topics --bootstrap-server localhost:9092 --delete --topic test-topic2;
    #sudo kafka-topics --bootstrap-server localhost:9092 --delete --topic test-topic3;
    #sudo kafka-topics --bootstrap-server localhost:9092 --delete --topic test-topic4;
    #sudo kafka-topics --bootstrap-server localhost:9092 --delete --topic test-topic5;

    토픽 생성 후 확인

     

    cruise-control에서도 불균형이 확인된다.

    cruise-control에서 proposal로 뜨는지 확인한다.

    http://localhost:9090/#/dev/dev/proposals

     

    RackAware, Replica 같이 파티션 불균형 관련 Goal들이 FIXED상태로 변한다. 

    할 게 없으면 NO-ACTION으로 나오는듯하고, FIXED면 수정이 필요한 상태라고 생각된다. 

    (VIOLATED는 무슨뜻인지 잘모르겠음)

     

    리밸런싱을 수동으로 진행해본다.

     

    HTTP POST: http://localhost:9090/kafkacruisecontrol/rebalance?dryrun=false&json=true

    cruise-control-ui에서는 execute 버튼을 누른다. 

     

    task 목록에서 정상적으로 실행되는지 확인한다.

    완료된 후 확인. rack구분에 따라 leader,replica가 배치되었고으나 리더 불균형이 있어보인다. 

     

    클러스터 전체적인 측면으로보면 골고루 배치되긴 했다.

    확인한 것

    Rebalance를 수동으로 하지 않는 이상 가만히 두면 아무 일도 일어나지 않고 proposal만 하고 있다. 

    모든 토픽을 대상으로 리밸런싱 하기 때문에 리밸런싱 후에 뭔가 깔끔한 모양은 아닌듯 하다.

     

    시나리오2. 브로커 Rack 밸런스가 맞지 않을 때 리밸런싱 어떻게 되는지 확인하기 

    브로커 총 8대 중 6대를 md, 2대를 md2로 가정하고 구동한다.  

    토픽 20개 생성. Broker 1,2에 몰아서 배치한다. 

    리밸런싱 후 결과 확인

     

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
     
    sudo kafka-topics --describe     --bootstrap-server localhost:9092     --topic test-topic1

    리밸런싱 수행 후 리더가 md2쪽의 노드로 몰려서 배치되었다. (7,8번만 md2임)

    시나리오3. Goal을 지정해서 진행한 후 Proposal대로 진행해보기

    리밸런싱을 수행할 때 Goal 목표를 수동으로 지정해서 지정해본다.

    이러면 원하는 Goal만 수행될 것이다. 이후 Proposal대로 진행하면 변화가 있을지 확인. 

     

    브로커 8대 중 7대를 md, 1대를 md2 극단적으로 배치한 후 ReplicaDistribution만 수행하면 rack에 상관없이 Replica가 균등배포 될 것이다.

    이후 RackAware를 포함한 Proposal을 수행하면 Rack을 감지해서 재배치할 것이다. 

     

    토픽 생성

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;

    Replica가 매우 불균형하게 배치되었다. 

    ReplicaDistributionGoal

    클러스터의 모든 브로커가 비슷한 수의 복제본을 갖도록 시도합니다. 

    POST /kafkacruisecontrol/rebalance?dryrun=false&goals=ReplicaDistributionGoal&skip_hard_goal_check=true&json=true

     

    리더가 왜 움직였는지는 모르겠지만 일단 Replica는 균등해졌다.

     

    이 상태에서 Leader Replica Distribution, Topic Replica Distribution만 선택해서 돌려본다. 

    리더가 꽤나 완화되었다.

    하지만 토픽 내부에서 Replica가 여전히 겹친다. 

    이 상태에서 Proposal을 수행한다. 

     

    수행결과 유일하게 broker.rack=md2인 broker8에 replica가 몰렸다. 

    시나리오4. 브로커가 다운 된 후 Rebalance를 수행한 경우

    아래와 같이 골고루 분배된 상태에서 브로커를 다운시켜본 후 Rebalance를 수행하면 어떻게 되는지 확인해본다. 

    under-replicated 도 없는상태. 

    브로커1번을 내려본다 (rack:md). 내린 후 Under Replicated 다수 발생.

     

    이 상태에서 Rebalance를 수행해본다. 일단 디테일만 Goal은 지정하지 않고 제안대로 수행해본다.

    브로커1을 빼고 리밸런싱이 진행되었다.

     

    브로커1을 다시 살려본다. 아래 상태가 되었다.

     

    리밸런싱을 다시 수행한다.

    돌아오긴 함. 

    시나리오5. Replica > Rack 일 때 RackAware, RackAwareDistribution 차이 확인하기

    RackAware

    토픽 20개를 생성하되, 파티션10개, Replica 3으로 구성하기

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    이 때 goal 목록에서 RackAware를 사용하도록 한다. 
    hard.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal,com...

    토픽 배치는 아래처럼 되었다. 

    Topic: test-topic1      TopicId: B7TNy7_gST-xOJHY1W11Sw PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 1    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 2    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 3    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 4    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 5    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 6    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 7    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 8    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 9    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:

    Replica가 3인데, 여기에 RackAware를 충족하려고 하니 아예 안된다고 오류가 난다.

    RackAwareDistribution

    default.goals와 hard.goals에 RackAware가 아닌 RackAwareDistribution을 명시한다.

    default.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareDistributionGoal...생략
    hard.goals=com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareDistributionGoal...생략

    goals 목록에서도 RackAwareDistributionGoal이 뜬다.

    리밸런스를 Dry-Run해본다.

    ReplicaMove가 215개 발생한다고 한다. 

    리더 변경도 9개 정도 발생한다고 함. 

    "summary": {
        "numIntraBrokerReplicaMovements": 0,
        "numReplicaMovements": 215,
        "onDemandBalancednessScoreAfter": 93.21842452909542,
        "intraBrokerDataToMoveMB": 0,
        "monitoredPartitionsPercentage": 100,
        "provisionRecommendation": "",
        "excludedBrokersForReplicaMove": [],
        "excludedBrokersForLeadership": [],
        "provisionStatus": "RIGHT_SIZED",
        "onDemandBalancednessScoreBefore": 67.76162263796938,
        "recentWindows": 3,
        "dataToMoveMB": 0,
        "excludedTopics": [],
        "numLeaderMovements": 9

    완료 후 클러스터 상태 조회. 일단 골고루 분배되었다.

    토픽 수준에서 확인해본다. 리밸런싱은 진행되었으나 토픽 내부에서 파티션끼리 겹치는 양상을 보인다. 

     

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2
    Topic: test-topic1      TopicId: B7TNy7_gST-xOJHY1W11Sw PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 1       Replicas: 1,7,6 Isr: 1,6,7      Offline:
            Topic: test-topic1      Partition: 1    Leader: 6       Replicas: 6,1,8 Isr: 1,6,8      Offline:
            Topic: test-topic1      Partition: 2    Leader: 1       Replicas: 1,6,8 Isr: 1,6,8      Offline:
            Topic: test-topic1      Partition: 3    Leader: 6       Replicas: 6,4,1 Isr: 1,6,4      Offline:
            Topic: test-topic1      Partition: 4    Leader: 4       Replicas: 4,6,8 Isr: 6,8,4      Offline:
            Topic: test-topic1      Partition: 5    Leader: 6       Replicas: 6,4,8 Isr: 6,8,4      Offline:
            Topic: test-topic1      Partition: 6    Leader: 5       Replicas: 5,2,6 Isr: 5,6,2      Offline:
            Topic: test-topic1      Partition: 7    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic1      Partition: 8    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
            Topic: test-topic1      Partition: 9    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
    Topic: test-topic2      TopicId: yF99NowrSauUrcppy9v99Q PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 1       Replicas: 1,4,7 Isr: 1,7,4      Offline:
            Topic: test-topic2      Partition: 1    Leader: 1       Replicas: 1,4,7 Isr: 1,7,4      Offline:
            Topic: test-topic2      Partition: 2    Leader: 1       Replicas: 1,7,8 Isr: 1,7,8      Offline:
            Topic: test-topic2      Partition: 3    Leader: 7       Replicas: 7,4,8 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 4    Leader: 8       Replicas: 8,7,4 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 5    Leader: 4       Replicas: 4,7,8 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 6    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 7    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 8    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 9    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:

    TopicReplicaDistributionGoal의 정의를 보면 "동일한 토픽의 복제본을 전체 클러스터에 균등하게 분산시키려고 시도" 라고 한다.

    그럼 토픽 내에서 겹치는 부분을 해소해주진 않으려나 싶어서 돌려봄. 

    수행결과 일단 결과에 큰 차이는 없다. 

    토픽 수준으로도 조회. 변경이 안되었음. 

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2
    Topic: test-topic1      TopicId: B7TNy7_gST-xOJHY1W11Sw PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 1       Replicas: 1,7,6 Isr: 1,6,7      Offline:
            Topic: test-topic1      Partition: 1    Leader: 6       Replicas: 6,1,8 Isr: 1,6,8      Offline:
            Topic: test-topic1      Partition: 2    Leader: 1       Replicas: 1,6,8 Isr: 1,6,8      Offline:
            Topic: test-topic1      Partition: 3    Leader: 6       Replicas: 6,4,1 Isr: 1,6,4      Offline:
            Topic: test-topic1      Partition: 4    Leader: 4       Replicas: 4,6,8 Isr: 6,8,4      Offline:
            Topic: test-topic1      Partition: 5    Leader: 6       Replicas: 6,4,8 Isr: 6,8,4      Offline:
            Topic: test-topic1      Partition: 6    Leader: 5       Replicas: 5,2,6 Isr: 5,6,2      Offline:
            Topic: test-topic1      Partition: 7    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic1      Partition: 8    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
            Topic: test-topic1      Partition: 9    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
    Topic: test-topic2      TopicId: yF99NowrSauUrcppy9v99Q PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 1       Replicas: 1,4,7 Isr: 1,7,4      Offline:
            Topic: test-topic2      Partition: 1    Leader: 1       Replicas: 1,4,7 Isr: 1,7,4      Offline:
            Topic: test-topic2      Partition: 2    Leader: 1       Replicas: 1,7,8 Isr: 1,7,8      Offline:
            Topic: test-topic2      Partition: 3    Leader: 7       Replicas: 7,4,8 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 4    Leader: 8       Replicas: 8,7,4 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 5    Leader: 4       Replicas: 4,7,8 Isr: 7,8,4      Offline:
            Topic: test-topic2      Partition: 6    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 7    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 8    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:
            Topic: test-topic2      Partition: 9    Leader: 2       Replicas: 2,5,3 Isr: 2,3,5      Offline:

    추측: 이미 리밸런싱을 수행했는데, soft goal만 별도로 돌리려고하니 바뀔게 없어서 그냥 그대로인듯하다.

     

    시나리오6. Rack이 1개 밖에 없을 때 Replica 분배가 어떻게되는지 확인하기 

    RackAware는 애초에 동작하지 않을 것. (시나리오5에서 확인)

    RackAwareDistribution을 goal 목표에 추가해놓은 상태에서 진행한다. 

    브로커의 rack을 모두 md로 지정한 후 진행. (broker.rack=md)

     

    토픽생성

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;

    의도한대로 Leader, Replica가 몰려서 배치되었다. 

    proposal이 생성될 때 까지 대기한다. 

    Proposal Ready이니 Rebalance를 수행한다. 진행상황을 볼 수 있다.

    완료 후 골고루 일단 배치되었다. 

    토픽수준에서 확인. 중복되는 상황이 좀 보인다. 

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2
    Topic: test-topic1      TopicId: cOud32oiSmS3rnbhCXBISw PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 8       Replicas: 8,5,7 Isr: 5,7,8      Offline:
            Topic: test-topic1      Partition: 1    Leader: 7       Replicas: 7,6,4 Isr: 6,7,4      Offline:
            Topic: test-topic1      Partition: 2    Leader: 6       Replicas: 6,4,7 Isr: 6,7,4      Offline:
            Topic: test-topic1      Partition: 3    Leader: 4       Replicas: 4,6,7 Isr: 6,7,4      Offline:
            Topic: test-topic1      Partition: 4    Leader: 6       Replicas: 6,4,5 Isr: 5,6,4      Offline:
            Topic: test-topic1      Partition: 5    Leader: 5       Replicas: 5,8,3 Isr: 5,3,8      Offline:
            Topic: test-topic1      Partition: 6    Leader: 5       Replicas: 5,2,8 Isr: 5,2,8      Offline:
            Topic: test-topic1      Partition: 7    Leader: 1       Replicas: 1,2,8 Isr: 1,2,8      Offline:
            Topic: test-topic1      Partition: 8    Leader: 3       Replicas: 3,1,2 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 9    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
    Topic: test-topic2      TopicId: Fd_Fp-5lTTKkO8pEUwKlDg PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 7       Replicas: 7,5,4 Isr: 5,7,4      Offline:
            Topic: test-topic2      Partition: 1    Leader: 7       Replicas: 7,6,4 Isr: 6,7,4      Offline:
            Topic: test-topic2      Partition: 2    Leader: 6       Replicas: 6,4,7 Isr: 6,7,4      Offline:
            Topic: test-topic2      Partition: 3    Leader: 7       Replicas: 7,6,4 Isr: 6,7,4      Offline:
            Topic: test-topic2      Partition: 4    Leader: 3       Replicas: 3,8,5 Isr: 5,3,8      Offline:
            Topic: test-topic2      Partition: 5    Leader: 5       Replicas: 5,8,3 Isr: 5,3,8      Offline:
            Topic: test-topic2      Partition: 6    Leader: 2       Replicas: 2,1,8 Isr: 1,2,8      Offline:
            Topic: test-topic2      Partition: 7    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic2      Partition: 8    Leader: 3       Replicas: 3,1,2 Isr: 1,2,3      Offline:
            Topic: test-topic2      Partition: 9    Leader: 3       Replicas: 3,2,1 Isr: 1,2,3      Offline:

     

    시나리오7. 특정 브로커 제외하고 리밸런싱 해보기

    브로커 8대중 1대를 제외하고 리밸런싱을 수행할 수 있는지 검증해본다. 

     

    add: https://docs.cloudera.com/cdp-private-cloud-base/7.1.6/cctrl-managing/topics/cctrl-add-broker.html

    remove: https://docs.cloudera.com/cdp-private-cloud-base/7.1.6/cctrl-managing/topics/cctrl-remove-broker.html

    demote: https://docs.cloudera.com/cdp-private-cloud-base/7.1.6/cctrl-managing/topics/cctrl-demote-broker.html 

     

    브로커를 선택하면 3가지 선택지가 보인다. 

    • Add Brokers: 브로커를 추가하는 경우 사용합니다. 
    • Remove Brokers: 브로커를 제거하는 경우 사용합니다. 
    • Demote Brokers: 브로커가 유지보수가 필요한 경우 강등을 사용하여 할당된 파티션을 제거할 수 있습니다. demote기능의 경우 리더만 이동합니다. 
      • **demote: 강등시키다. 좌천시키다. 

     

    Demote

    브로커 1번을 선택 - demote broker 선택 - dry run

    Optimization has 0 inter-broker replica(0 MB) moves, 0 intra-broker replica(0 MB) moves and 33 leadership moves with a cluster model of 5 recent windows and 100.000% of the partitions covered.
    Excluded Topics: [].
    Excluded Brokers For Leadership: [].
    Excluded Brokers For Replica Move: [].
    Counts: 8 brokers 538 replicas 23 topics.
    On-demand Balancedness Score Before (0.000) After(100.000).
    Provision Status: UNDECIDED.
     
    [     1 ms] Stats for PreferredLeaderElectionGoal(FIXED):
    AVG:{cpu:       0.184 networkInbound:       0.082 networkOutbound:       0.094 disk:      18.350 potentialNwOut:       0.188 replicas:67.25 leaderReplicas:33.625 topicReplicas:2.9239130434782608}
    MAX:{cpu:       1.218 networkInbound:       0.392 networkOutbound:       0.731 disk:      64.211 potentialNwOut:       0.637 replicas:190 leaderReplicas:69 topicReplicas:23}
    MIN:{cpu:       0.255 networkInbound:       0.260 networkOutbound:       0.019 disk:       0.302 potentialNwOut:       0.009 replicas:27 leaderReplicas:0 topicReplicas:0}
    STD:{cpu:       0.071 networkInbound:       0.178 networkOutbound:       0.074 disk:      18.803 potentialNwOut:       0.181 replicas:48.527698276345234 leaderReplicas:18.90064483026968 topicReplicas:2.264919595009294
     
    Cluster load after demoting broker [1]:
     
     
         HOST         BROKER      RACK         DISK_CAP(MB)            DISK(MB)/_(%)_            CORE_NUM         CPU(%)          NW_IN_CAP(KB/s)       LEADER_NW_IN(KB/s)     FOLLOWER_NW_IN(KB/s)         NW_OUT_CAP(KB/s)        NW_OUT(KB/s)       PNW_OUT(KB/s)    LEADERS/REPLICAS
    127.0.0.1,             1,       md,          100000.000,              9.000/00.01,                  1,         0.060,               10000.000,                   0.000,                   0.054,               10000.000,              0.000,              0.101,             0/48
    127.0.0.1,             2,       md,          100000.000,              5.139/00.01,                  1,         0.194,               10000.000,                   0.039,                   0.011,               10000.000,              0.067,              0.078,            39/70
    127.0.0.1,             3,       md,          100000.000,             15.768/00.02,                  1,         0.143,               10000.000,                   0.056,                   0.000,               10000.000,              0.153,              0.153,            29/29
    127.0.0.1,             4,       md,          100000.000,             24.716/00.02,                  1,         0.148,               10000.000,                   0.073,                   0.005,               10000.000,              0.219,              0.224,            29/52
    127.0.0.1,             5,       md,          100000.000,             18.813/00.02,                  1,         0.137,               10000.000,                   0.073,                   0.001,               10000.000,              0.181,              0.181,            19/27
    ...생략

    일단 수행

        POST /kafkacruisecontrol/demote_broker?dryrun=false&brokerid=1 

     

    완료 후 결과를 보면 리더배치가 0으로 되었다.

    작업이 끝났다고 가정하고, 리밸런싱을 다시 수행해본다. 다시 복구되긴했다.

    토픽 describe를 해본다. 토픽 내 배치가 불균형하긴하다. 

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2,test-topic3
    Topic: test-topic1      TopicId: J0-oqQYcROWkVOwE1MD2wQ PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 8       Replicas: 8,5,7 Isr: 5,7,8      Offline:
            Topic: test-topic1      Partition: 1    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic1      Partition: 2    Leader: 8       Replicas: 8,6,5 Isr: 5,6,8      Offline:
            Topic: test-topic1      Partition: 3    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic1      Partition: 4    Leader: 8       Replicas: 8,6,7 Isr: 6,7,8      Offline:
            Topic: test-topic1      Partition: 5    Leader: 7       Replicas: 7,4,3 Isr: 7,3,4      Offline:
            Topic: test-topic1      Partition: 6    Leader: 7       Replicas: 7,2,4 Isr: 2,7,4      Offline:
            Topic: test-topic1      Partition: 7    Leader: 2       Replicas: 2,4,1 Isr: 1,2,4      Offline:
            Topic: test-topic1      Partition: 8    Leader: 3       Replicas: 3,1,2 Isr: 1,2,3      Offline:
            Topic: test-topic1      Partition: 9    Leader: 1       Replicas: 1,3,2 Isr: 1,2,3      Offline:
    Topic: test-topic2      TopicId: 0qpye_swTg2wvmWg5I4q7Q PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 8       Replicas: 8,5,7 Isr: 5,7,8      Offline:
            Topic: test-topic2      Partition: 1    Leader: 5       Replicas: 5,8,6 Isr: 5,6,8      Offline:
            Topic: test-topic2      Partition: 2    Leader: 5       Replicas: 5,8,6 Isr: 5,6,8      Offline:
            Topic: test-topic2      Partition: 3    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic2      Partition: 4    Leader: 4       Replicas: 4,7,3 Isr: 7,3,4      Offline:
            Topic: test-topic2      Partition: 5    Leader: 7       Replicas: 7,4,3 Isr: 7,3,4      Offline:
            Topic: test-topic2      Partition: 6    Leader: 2       Replicas: 2,1,4 Isr: 1,2,4      Offline:
            Topic: test-topic2      Partition: 7    Leader: 2       Replicas: 2,3,1 Isr: 1,2,3      Offline:
            Topic: test-topic2      Partition: 8    Leader: 3       Replicas: 3,1,2 Isr: 1,2,3      Offline:
            Topic: test-topic2      Partition: 9    Leader: 3       Replicas: 3,2,1 Isr: 1,2,3      Offline:
    Topic: test-topic3      TopicId: 9QR0L3g-RXmTnmCzMIBfGg PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic3      Partition: 0    Leader: 6       Replicas: 6,7,5 Isr: 5,6,7      Offline:
            Topic: test-topic3      Partition: 1    Leader: 5       Replicas: 5,8,6 Isr: 5,6,8      Offline:
            Topic: test-topic3      Partition: 2    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic3      Partition: 3    Leader: 8       Replicas: 8,6,5 Isr: 5,6,8      Offline:
            Topic: test-topic3      Partition: 4    Leader: 4       Replicas: 4,7,3 Isr: 7,3,4      Offline:
            Topic: test-topic3      Partition: 5    Leader: 7       Replicas: 7,4,3 Isr: 7,3,4      Offline:
            Topic: test-topic3      Partition: 6    Leader: 1       Replicas: 1,4,2 Isr: 1,2,4      Offline:
            Topic: test-topic3      Partition: 7    Leader: 3       Replicas: 3,2,1 Isr: 1,2,3      Offline:
            Topic: test-topic3      Partition: 8    Leader: 2       Replicas: 2,3,1 Isr: 1,2,3      Offline:
            Topic: test-topic3      Partition: 9    Leader: 3       Replicas: 3,2,1 Isr: 1,2,3      Offline:

    Remove, Add

    브로커1번을 선택하고 Run해본다. 

    POST /kafkacruisecontrol/remove_broker?dryrun=false&brokerid=1&json=true

    결과를 대략적으로 알려준다. 

    {
      "summary": {
        "numIntraBrokerReplicaMovements": 0,
        "numReplicaMovements": 99,
        "onDemandBalancednessScoreAfter": 92.12014398282543,
        "intraBrokerDataToMoveMB": 0,
        "monitoredPartitionsPercentage": 100,
        "provisionRecommendation": "",
        "excludedBrokersForReplicaMove": [
          1
        ],
        "excludedBrokersForLeadership": [],
        "provisionStatus": "RIGHT_SIZED",
        "onDemandBalancednessScoreBefore": 74.26993546445864,
        "recentWindows": 4,
        "dataToMoveMB": 0,
        "excludedTopics": [],
        "numLeaderMovements": 8
      },
    ...생략

    수행결과 브로커1번의 Leader, Replica가 모두 제거되고 재배치되었다.

    다른 브로커에 일단 골고루 분배되었다. 

    주키퍼에서 실제로 클러스터가 빠지는 건지 확인해본다. 실제로 빠지는건 아니다. 

    ls /brokers/ids
    [1, 2, 3, 4, 5, 6, 7, 8]

    다시 Add를 진행해본다.

    POST /kafkacruisecontrol/add_broker?dryrun=false&brokerid=1&json=true

    완료 후에도 아직 그대로있다. 결과를 대략적으로 알려준다.

    {
      "summary": {
        "numIntraBrokerReplicaMovements": 0,
        "numReplicaMovements": 88,
        "onDemandBalancednessScoreAfter": 92.12014398282543,
        "intraBrokerDataToMoveMB": 0,
        "monitoredPartitionsPercentage": 100,
        "provisionRecommendation": "",
        "excludedBrokersForReplicaMove": [],
        "excludedBrokersForLeadership": [],
        "provisionStatus": "RIGHT_SIZED",
        "onDemandBalancednessScoreBefore": 82.89826042994001,
        "recentWindows": 5,
        "dataToMoveMB": 0,
        "excludedTopics": [],
        "numLeaderMovements": 0
    ...생략

    수행결과 다시 균등 배치되었다.

    토픽 describe를 해본다. 

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2,test-topic3
    Topic: test-topic1      TopicId: J0-oqQYcROWkVOwE1MD2wQ PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 1       Replicas: 1,3,7 Isr: 7,3,1      Offline:
            Topic: test-topic1      Partition: 1    Leader: 1       Replicas: 1,3,5 Isr: 5,3,1      Offline:
            Topic: test-topic1      Partition: 2    Leader: 8       Replicas: 8,6,1 Isr: 6,8,1      Offline:
            Topic: test-topic1      Partition: 3    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic1      Partition: 4    Leader: 8       Replicas: 8,6,5 Isr: 6,8,5      Offline:
            Topic: test-topic1      Partition: 5    Leader: 1       Replicas: 1,4,7 Isr: 7,4,1      Offline:
            Topic: test-topic1      Partition: 6    Leader: 7       Replicas: 7,5,4 Isr: 7,4,5      Offline:
            Topic: test-topic1      Partition: 7    Leader: 6       Replicas: 6,4,1 Isr: 4,6,1      Offline:
            Topic: test-topic1      Partition: 8    Leader: 3       Replicas: 3,7,2 Isr: 2,3,7      Offline:
            Topic: test-topic1      Partition: 9    Leader: 7       Replicas: 7,3,2 Isr: 2,3,7      Offline:
    Topic: test-topic2      TopicId: 0qpye_swTg2wvmWg5I4q7Q PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 7       Replicas: 7,8,1 Isr: 7,8,1      Offline:
            Topic: test-topic2      Partition: 1    Leader: 1       Replicas: 1,8,6 Isr: 6,8,1      Offline:
            Topic: test-topic2      Partition: 2    Leader: 5       Replicas: 5,8,1 Isr: 5,8,1      Offline:
            Topic: test-topic2      Partition: 3    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic2      Partition: 4    Leader: 4       Replicas: 4,7,1 Isr: 7,4,1      Offline:
            Topic: test-topic2      Partition: 5    Leader: 7       Replicas: 7,4,3 Isr: 7,3,4      Offline:
            Topic: test-topic2      Partition: 6    Leader: 5       Replicas: 5,7,4 Isr: 4,7,5      Offline:
            Topic: test-topic2      Partition: 7    Leader: 3       Replicas: 3,2,4 Isr: 2,3,4      Offline:
            Topic: test-topic2      Partition: 8    Leader: 3       Replicas: 3,8,2 Isr: 2,3,8      Offline:
            Topic: test-topic2      Partition: 9    Leader: 3       Replicas: 3,2,8 Isr: 2,3,8      Offline:
    Topic: test-topic3      TopicId: 9QR0L3g-RXmTnmCzMIBfGg PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic3      Partition: 0    Leader: 1       Replicas: 1,7,5 Isr: 5,7,1      Offline:
            Topic: test-topic3      Partition: 1    Leader: 5       Replicas: 5,8,1 Isr: 5,8,1      Offline:
            Topic: test-topic3      Partition: 2    Leader: 6       Replicas: 6,8,5 Isr: 5,6,8      Offline:
            Topic: test-topic3      Partition: 3    Leader: 8       Replicas: 8,6,5 Isr: 5,6,8      Offline:
            Topic: test-topic3      Partition: 4    Leader: 4       Replicas: 4,5,1 Isr: 4,5,1      Offline:
            Topic: test-topic3      Partition: 5    Leader: 7       Replicas: 7,4,3 Isr: 7,3,4      Offline:
            Topic: test-topic3      Partition: 6    Leader: 7       Replicas: 7,4,8 Isr: 4,7,8      Offline:
            Topic: test-topic3      Partition: 7    Leader: 3       Replicas: 3,2,4 Isr: 2,3,4      Offline:
            Topic: test-topic3      Partition: 8    Leader: 2       Replicas: 2,3,5 Isr: 2,3,5      Offline:
            Topic: test-topic3      Partition: 9    Leader: 3       Replicas: 3,2,5 Isr: 2,3,5      Offline:

     

    시나리오8. 브로커 수를 늘렸을 때 토픽 내 Leader-Replica 배치가 어떻게 되는지 살펴보기

    브로커를 기존에 테스트하던 8개에서 16개로 늘린다. 

    위 세팅에 있는 docker-compose-brk16.yml 파일을 사용한다. 

     

    파티션을 1,2,3번 브로커에 몰아서 배치시킨다. 

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3,1:2:3;

    리밸런싱 수행 후 일단 골고루 배치되었다. 

     

    토픽 describe 수행. 생각보다 꽤나 골고루 배치되긴 했다. 

    하지만 여전히 중복되는 부분이 일부 보이긴한다. 

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2,test-topic3
    Topic: test-topic1      TopicId: iPy22t9DSUWfMNjzEn4snA PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic1      Partition: 0    Leader: 14      Replicas: 14,7,10       Isr: 10,14,7    Offline:
            Topic: test-topic1      Partition: 1    Leader: 8       Replicas: 8,4,10        Isr: 10,8,4     Offline:
            Topic: test-topic1      Partition: 2    Leader: 4       Replicas: 4,8,11        Isr: 11,8,4     Offline:
            Topic: test-topic1      Partition: 3    Leader: 11      Replicas: 11,5,9        Isr: 5,9,11     Offline:
            Topic: test-topic1      Partition: 4    Leader: 12      Replicas: 12,5,9        Isr: 5,9,12     Offline:
            Topic: test-topic1      Partition: 5    Leader: 15      Replicas: 15,6,12       Isr: 6,12,15    Offline:
            Topic: test-topic1      Partition: 6    Leader: 15      Replicas: 15,6,13       Isr: 6,13,15    Offline:
            Topic: test-topic1      Partition: 7    Leader: 16      Replicas: 16,11,13      Isr: 13,16,11   Offline:
            Topic: test-topic1      Partition: 8    Leader: 14      Replicas: 14,2,7        Isr: 14,2,7     Offline:
            Topic: test-topic1      Partition: 9    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
    Topic: test-topic2      TopicId: Ukj4vGcXRV65pnsDCRhmSQ PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic2      Partition: 0    Leader: 10      Replicas: 10,8,4        Isr: 10,8,4     Offline:
            Topic: test-topic2      Partition: 1    Leader: 4       Replicas: 4,8,10        Isr: 10,8,4     Offline:
            Topic: test-topic2      Partition: 2    Leader: 11      Replicas: 11,9,5        Isr: 5,9,11     Offline:
            Topic: test-topic2      Partition: 3    Leader: 5       Replicas: 5,9,11        Isr: 5,9,11     Offline:
            Topic: test-topic2      Partition: 4    Leader: 6       Replicas: 6,15,12       Isr: 6,12,15    Offline:
            Topic: test-topic2      Partition: 5    Leader: 15      Replicas: 15,6,7        Isr: 6,7,15     Offline:
            Topic: test-topic2      Partition: 6    Leader: 13      Replicas: 13,14,16      Isr: 14,13,16   Offline:
            Topic: test-topic2      Partition: 7    Leader: 16      Replicas: 16,10,13      Isr: 10,13,16   Offline:
            Topic: test-topic2      Partition: 8    Leader: 2       Replicas: 2,1,3 Isr: 1,2,3      Offline:
            Topic: test-topic2      Partition: 9    Leader: 2       Replicas: 2,1,3 Isr: 1,2,3      Offline:
    Topic: test-topic3      TopicId: lU51HNNkSg226u8gOg6juQ PartitionCount: 10      ReplicationFactor: 3    Configs:
            Topic: test-topic3      Partition: 0    Leader: 8       Replicas: 8,4,10        Isr: 10,8,4     Offline:
            Topic: test-topic3      Partition: 1    Leader: 8       Replicas: 8,4,10        Isr: 10,8,4     Offline:
            Topic: test-topic3      Partition: 2    Leader: 9       Replicas: 9,5,11        Isr: 5,9,11     Offline:
            Topic: test-topic3      Partition: 3    Leader: 9       Replicas: 9,5,11        Isr: 5,9,11     Offline:
            Topic: test-topic3      Partition: 4    Leader: 15      Replicas: 15,6,12       Isr: 6,12,15    Offline:
            Topic: test-topic3      Partition: 5    Leader: 15      Replicas: 15,6,14       Isr: 14,6,15    Offline:
            Topic: test-topic3      Partition: 6    Leader: 16      Replicas: 16,10,13      Isr: 10,13,16   Offline:
            Topic: test-topic3      Partition: 7    Leader: 12      Replicas: 12,16,14      Isr: 14,12,16   Offline:
            Topic: test-topic3      Partition: 8    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:
            Topic: test-topic3      Partition: 9    Leader: 1       Replicas: 1,2,3 Isr: 1,2,3      Offline:

    Replica와 파티션수를 줄인 후 테스트해본다. (좀 더 실제 운영환경과 비슷하게)

    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic1 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic2 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic3 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic4 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic5 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic6 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic7 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic8 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic9 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic10 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic11 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic12 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic13 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic14 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic15 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic16 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic17 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic18 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic19 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;
    sudo kafka-topics --bootstrap-server localhost:9092 --create --topic test-topic20 --replica-assignment 1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2;

    리밸런싱 후 골고루 분배되었는지 확인

    topic describe

    sudo kafka-topics --describe --bootstrap-server localhost:9092 --topic test-topic1,test-topic2,test-topic3,test-topic4
    Topic: test-topic1      TopicId: GjKoQluYQpWmpsoQSu_lWA PartitionCount: 8       ReplicationFactor: 2    Configs:
            Topic: test-topic1      Partition: 0    Leader: 15      Replicas: 15,4  Isr: 15,4       Offline:
            Topic: test-topic1      Partition: 1    Leader: 7       Replicas: 7,15  Isr: 15,7       Offline:
            Topic: test-topic1      Partition: 2    Leader: 11      Replicas: 11,13 Isr: 13,11      Offline:
            Topic: test-topic1      Partition: 3    Leader: 12      Replicas: 12,14 Isr: 14,12      Offline:
            Topic: test-topic1      Partition: 4    Leader: 16      Replicas: 16,7  Isr: 16,7       Offline:
            Topic: test-topic1      Partition: 5    Leader: 6       Replicas: 6,9   Isr: 6,9        Offline:
            Topic: test-topic1      Partition: 6    Leader: 10      Replicas: 10,12 Isr: 10,12      Offline:
            Topic: test-topic1      Partition: 7    Leader: 11      Replicas: 11,8  Isr: 11,8       Offline:
    Topic: test-topic2      TopicId: EYAjmELMRFaJVFTPI0v6aQ PartitionCount: 8       ReplicationFactor: 2    Configs:
            Topic: test-topic2      Partition: 0    Leader: 5       Replicas: 5,8   Isr: 5,8        Offline:
            Topic: test-topic2      Partition: 1    Leader: 8       Replicas: 8,13  Isr: 13,8       Offline:
            Topic: test-topic2      Partition: 2    Leader: 5       Replicas: 5,3   Isr: 5,3        Offline:
            Topic: test-topic2      Partition: 3    Leader: 16      Replicas: 16,14 Isr: 14,16      Offline:
            Topic: test-topic2      Partition: 4    Leader: 4       Replicas: 4,6   Isr: 4,6        Offline:
            Topic: test-topic2      Partition: 5    Leader: 9       Replicas: 9,16  Isr: 9,16       Offline:
            Topic: test-topic2      Partition: 6    Leader: 2       Replicas: 2,1   Isr: 1,2        Offline:
            Topic: test-topic2      Partition: 7    Leader: 1       Replicas: 1,2   Isr: 1,2        Offline:
    Topic: test-topic3      TopicId: Rll_xm_HRcq8ZRF12sYXdg PartitionCount: 8       ReplicationFactor: 2    Configs:
            Topic: test-topic3      Partition: 0    Leader: 6       Replicas: 6,15  Isr: 15,6       Offline:
            Topic: test-topic3      Partition: 1    Leader: 8       Replicas: 8,13  Isr: 8,13       Offline:
            Topic: test-topic3      Partition: 2    Leader: 3       Replicas: 3,5   Isr: 5,3        Offline:
            Topic: test-topic3      Partition: 3    Leader: 13      Replicas: 13,7  Isr: 7,13       Offline:
            Topic: test-topic3      Partition: 4    Leader: 4       Replicas: 4,6   Isr: 6,4        Offline:
            Topic: test-topic3      Partition: 5    Leader: 9       Replicas: 9,16  Isr: 16,9       Offline:
            Topic: test-topic3      Partition: 6    Leader: 14      Replicas: 14,11 Isr: 11,14      Offline:
            Topic: test-topic3      Partition: 7    Leader: 1       Replicas: 1,2   Isr: 1,2        Offline:
    Topic: test-topic4      TopicId: cAhvSVcHSXis3sitH_nz5w PartitionCount: 8       ReplicationFactor: 2    Configs:
            Topic: test-topic4      Partition: 0    Leader: 6       Replicas: 6,15  Isr: 15,6       Offline:
            Topic: test-topic4      Partition: 1    Leader: 5       Replicas: 5,3   Isr: 5,3        Offline:
            Topic: test-topic4      Partition: 2    Leader: 3       Replicas: 3,5   Isr: 5,3        Offline:
            Topic: test-topic4      Partition: 3    Leader: 13      Replicas: 13,7  Isr: 7,13       Offline:
            Topic: test-topic4      Partition: 4    Leader: 4       Replicas: 4,6   Isr: 4,6        Offline:
            Topic: test-topic4      Partition: 5    Leader: 2       Replicas: 2,8   Isr: 2,8        Offline:
            Topic: test-topic4      Partition: 6    Leader: 14      Replicas: 14,11 Isr: 11,14      Offline:
            Topic: test-topic4      Partition: 7    Leader: 2       Replicas: 2,1   Isr: 1,2        Offline:

     

     

    [궁금증 체크]

    Q: master goal을 정의한 후 default goal과 hard goal을 다시 구분한 이유?  master goal의 정의가 굳이 필요할까? 
    A: Proposal을 받을 목록만 default.goals 내부에 정의하고, 수동으로 하고 싶은 경우가 있을 수 있으니 그때를 위해 master.goal에 정의해놓는다.

     

    goals 목록에서 RackAwareGoal을 제외한 후 수동으로 rebalance를 하려고 하면, NotAwareException이 터진다. 그 말은 아예 해당 Goal을 인지하지 못한다는 뜻이다. 

    반면 goals 목록에 추가하는 경우 제안은 한다. 즉, Goal은 인지한다. 하지만 default.goals에 없으므로 proposal 목록에서는 제외된다. 

     

    Q: Goal에 안넣은 것이 Show All Options에 뜨는이유? Rack Aware는 넣지 않았는데, 뜬다.

    A: 하드코딩이다.

    https://github.com/linkedin/cruise-control-ui/blob/b1208a6f020c21ff967297814c2e893eed3f3183/src/goals.js#L5

     

    Q: 왜 프론트에서 Bold 처리된 Goal이 있을까?

    A: 하드코딩이다. hardGoal 이라고 세팅해놓은 값들은 bold 처리해서 보여주는듯하다. 

    우리가 hardGoal 설정을 변경하더라도 동적으로 이 목록을 읽어서 표현해주지는 않는듯하다. 

     

     

    [참고자료]

     

    'Kafka' 카테고리의 다른 글

    KRaft  (0) 2023.11.28
    MirrorMaker2 Basic  (0) 2023.07.24
    MirrorMaker2 - 테스트  (0) 2023.07.24
    클러스터간 메시지 복제  (0) 2023.07.24
    Kafka KRaft Protocol 정리  (0) 2023.05.28