Kudu의 파티셔닝 방법

확장성을 제공하기 위해 Kudu 테이블은 여러 태블릿 서버에 분산된 태블릿 단위로 나뉩니다. 각 행은 항상 특정 태블릿에 속하며, 이는 테이블 생성 시 설정된 파티셔닝 규칙에 따라 결정됩니다. Kudu는 다음 3가지 방식으로 데이터를 파티셔닝할 수 있습니다:

범위 파티셔닝 (Range Partitioning)

범위 파티셔닝은 데이터량에 따라 균형있게 기계 간에 분배하여 부하 불균형을 방지합니다.
아래와 같이 파티셔닝된 테이블을 생성하는 예제입니다:
create table rangeTable(CompanyId Type.INT32 , WorkId Type.INT32 , Name Type.STRING , Gender Type.STRING , Photo Type.STRING)
RANGE (CompanyId) (
    PARTITION 0 <= VALUES < 10,
    PARTITION 10 <= VALUES < 20,
    PARTITION 20 <= VALUES < 30,
    PARTITION 30 <= VALUES < 40,
    PARTITION 40 <= VALUES < 50,
    PARTITION 50 <= VALUES < 60,
    PARTITION 60 <= VALUES < 70,
    PARTITION 70 <= VALUES < 80,
    PARTITION 80 <= VALUES < 90
)

코드 구현:

public class RangePartitionCreator {
    private static ColumnSchema defineColumn(String name, Type type, boolean isPrimary) {
        return new ColumnSchema.ColumnSchemaBuilder(name, type).key(isPrimary).build();
    }

    public static void main(String[] args) {
        String masterAddresses = "hadoop01,hadoop02,hadoop03";
        try (KuduClient client = new KuduClient.KuduClientBuilder(masterAddresses).defaultSocketReadTimeoutMs(6000).build()) {
            List<ColumnSchema> columns = Arrays.asList(
                defineColumn("CompanyId", Type.INT32, true),
                defineColumn("WorkId", Type.INT32, false),
                defineColumn("Name", Type.STRING, false),
                defineColumn("Gender", Type.STRING, false),
                defineColumn("Photo", Type.STRING, false)
            );
            Schema schema = new Schema(columns);
            CreateTableOptions options = new CreateTableOptions().setNumReplicas(1);

            List<String> partitionColumns = Collections.singletonList("CompanyId");
            options.setRangePartitionColumns(partitionColumns);

            for (int i = 0; i < 90; i += 10) {
                PartialRow lowerBound = schema.newPartialRow();
                lowerBound.addInt("CompanyId", i);

                PartialRow upperBound = schema.newPartialRow();
                upperBound.addInt("CompanyId", i + 10);

                options.addRangePartition(lowerBound, upperBound);
            }

            client.createTable("rangeTable", schema, options);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

해시 파티셔닝 (Hash Partitioning)

해시 파티셔닝은 해시 값에 따라 데이터를 여러 버킷으로 분배합니다. 순서대로 데이터를 접근할 필요가 없는 경우 효과적입니다. 이를 통해 핫스팟 및 태블릿 크기의 불균형을 줄이는 데 도움이 됩니다.

테이블 생성 예제:

create table hashTable(CompanyId Type.INT32 , WorkId Type.INT32 , Name Type.STRING , Gender Type.STRING , Photo Type.STRING)
HASH (CompanyId) PARTITIONS 6,
RANGE (CompanyId) (
    PARTITION UNBOUNDED
)

코드 구현:

public class HashPartitionCreator {
    private static ColumnSchema defineColumn(String name, Type type, boolean isPrimary) {
        return new ColumnSchema.ColumnSchemaBuilder(name, type).key(isPrimary).build();
    }

    public static void main(String[] args) {
        String masterAddresses = "hadoop01,hadoop02,hadoop03";
        try (KuduClient client = new KuduClient.KuduClientBuilder(masterAddresses).defaultSocketReadTimeoutMs(6000).build()) {
            List<ColumnSchema> columns = Arrays.asList(
                defineColumn("CompanyId", Type.INT32, true),
                defineColumn("WorkId", Type.INT32, false),
                defineColumn("Name", Type.STRING, false),
                defineColumn("Gender", Type.STRING, false),
                defineColumn("Photo", Type.STRING, false)
            );
            Schema schema = new Schema(columns);
            CreateTableOptions options = new CreateTableOptions().setNumReplicas(1);

            List<String> partitionColumns = Collections.singletonList("CompanyId");
            options.addHashPartitions(partitionColumns, 6);

            client.createTable("hashTable", schema, options);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

다단 파티셔닝 (Multilevel Partitioning)

Kudu는 단일 테이블에서 여러 단계의 파티셔닝을 조합할 수 있습니다. 적절히 사용하면 각 파티셔닝 유형의 장점을 보존하면서 단점들을 줄일 수 있습니다.

테이블 생성 예제:

create table multilevelTable(CompanyId Type.INT32 , WorkId Type.INT32 , Name Type.STRING , Gender Type.STRING , Photo Type.STRING)
HASH (CompanyId) PARTITIONS 10,
RANGE (CompanyId) (
    PARTITION 0 <= VALUES < 10,
    PARTITION 10 <= VALUES < 20,
    PARTITION 20 <= VALUES < 30,
    PARTITION 30 <= VALUES < 40,
    PARTITION 40 <= VALUES < 50,
    PARTITION 50 <= VALUES < 60,
    PARTITION 60 <= VALUES < 70,
    PARTITION 70 <= VALUES < 80,
    PARTITION 80 <= VALUES < 90
)

코드 구현:

public class MultilevelPartitionCreator {
    private static ColumnSchema defineColumn(String name, Type type, boolean isPrimary) {
        return new ColumnSchema.ColumnSchemaBuilder(name, type).key(isPrimary).build();
    }

    public static void main(String[] args) {
        String masterAddresses = "hadoop01,hadoop02,hadoop03";
        try (KuduClient client = new KuduClient.KuduClientBuilder(masterAddresses).defaultSocketReadTimeoutMs(6000).build()) {
            List<ColumnSchema> columns = Arrays.asList(
                defineColumn("CompanyId", Type.INT32, true),
                defineColumn("WorkId", Type.INT32, false),
                defineColumn("Name", Type.STRING, false),
                defineColumn("Gender", Type.STRING, false),
                defineColumn("Photo", Type.STRING, false)
            );
            Schema schema = new Schema(columns);
            CreateTableOptions options = new CreateTableOptions().setNumReplicas(1);

            List<String> partitionColumns = Collections.singletonList("CompanyId");
            options.addHashPartitions(partitionColumns, 10);
            options.setRangePartitionColumns(partitionColumns);

            for (int i = 0; i < 90; i += 10) {
                PartialRow lowerBound = schema.newPartialRow();
                lowerBound.addInt("CompanyId", i);

                PartialRow upperBound = schema.newPartialRow();
                upperBound.addInt("CompanyId", i + 10);

                options.addRangePartition(lowerBound, upperBound);
            }

            client.createTable("multilevelTable", schema, options);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

해시 파티셔닝은 쓰기 처리량을 최대화하는 데 유리하며, 범위 파티셔닝은 태블릿의 무한 성장을 방지합니다. 이 두 가지를 결합하면 Kudu의 성능을 크게 향상시킬 수 있습니다.

태그: Kudu partitioning java

7월 2일 04:40에 게시됨