파티션 키 사용

파티션 키는 파티션에 기반한 검색 최적화 솔루션입니다. 특정 스칼라 필드를 파티션 키로 지정하고 검색 시 파티션 키를 기반으로 필터링 조건을 지정하면 검색 범위를 여러 파티션으로 좁혀 검색 효율을 높일 수 있습니다. 이 문서에서는 파티션 키의 사용 방법과 관련 고려 사항을 소개합니다.

개요

Milvus에서는 파티션을 사용하여 검색 범위를 특정 파티션으로 제한함으로써 데이터 분리를 구현하고 검색 성능을 향상시킬 수 있습니다. 파티션을 수동으로 관리하기로 선택한 경우 컬렉션에 최대 1,024개의 파티션을 생성하고 특정 규칙에 따라 이러한 파티션에 엔티티를 삽입하여 특정 수의 파티션 내에서 검색을 제한하여 검색 범위를 좁힐 수 있습니다.

밀버스에서는 데이터 분리에서 파티션을 재사용할 수 있는 파티션 키를 도입하여 컬렉션에 생성할 수 있는 파티션 수의 제한을 극복할 수 있습니다. 컬렉션을 만들 때 스칼라 필드를 파티션 키로 사용할 수 있습니다. 컬렉션이 준비되면 Milvus는 컬렉션 내에 지정된 수의 파티션을 생성합니다. 삽입된 엔티티를 받으면 Milvus는 엔티티의 파티션 키 값을 사용하여 해시값을 계산하고 해시값과 컬렉션의 partitions_num 속성을 기반으로 모듈로 연산을 실행하여 대상 파티션 ID를 얻은 후 대상 파티션에 엔티티를 저장합니다.

Partition Vs Partition Key 파티션 대 파티션 키

다음 그림은 Milvus가 파티션 키 기능을 활성화하거나 활성화하지 않은 상태에서 컬렉션의 검색 요청을 처리하는 방법을 보여줍니다.

  • 파티션 키 기능이 비활성화되어 있는 경우, Milvus는 컬렉션 내에서 쿼리 벡터와 가장 유사한 엔티티를 검색합니다. 가장 관련성이 높은 결과가 포함된 파티션을 알고 있는 경우 검색 범위를 좁힐 수 있습니다.

  • 파티션 키가 활성화된 경우 Milvus는 검색 필터에 지정된 파티션 키 값에 따라 검색 범위를 결정하고 일치하는 파티션 내의 엔티티만 검색합니다.

With And Without Partition Key 파티션 키 사용 및 미사용

파티션 키 사용

파티션 키를 사용하려면 다음을 수행해야 합니다.

파티션 키 설정

스칼라 필드를 파티션 키로 지정하려면 스칼라 필드를 추가할 때 is_partition_key 속성을 true 으로 설정해야 합니다.

스칼라 필드를 파티션 키로 설정할 때 필드 값은 비어 있거나 null일 수 없습니다.

from pymilvus import (
    MilvusClient, DataType
)

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus"
)

schema = client.create_schema()

schema.add_field(field_name="id",
    datatype=DataType.INT64,
    is_primary=True)
    
schema.add_field(field_name="vector",
    datatype=DataType.FLOAT_VECTOR,
    dim=5)

# Add the partition key
schema.add_field(
    field_name="my_varchar", 
    datatype=DataType.VARCHAR, 
    max_length=512,
    is_partition_key=True,
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .token("root:Milvus")
        .build());

// Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();

schema.addField(AddFieldReq.builder()
        .fieldName("id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("vector")
        .dataType(DataType.FloatVector)
        .dimension(5)
        .build());
        
// Add the partition key
schema.addField(AddFieldReq.builder()
        .fieldName("my_varchar")
        .dataType(DataType.VarChar)
        .maxLength(512)
        .isPartitionKey(true)
        .build());
import (
    "context"
    "fmt"

    "github.com/milvus-io/milvus/client/v2/column"
    "github.com/milvus-io/milvus/client/v2/entity"
    "github.com/milvus-io/milvus/client/v2/index"
    "github.com/milvus-io/milvus/client/v2/milvusclient"
)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: milvusAddr,
})
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
defer client.Close(ctx)

schema := entity.NewSchema().WithDynamicFieldEnabled(false)
schema.WithField(entity.NewField().
    WithName("id").
    WithDataType(entity.FieldTypeInt64).
    WithIsPrimaryKey(true),
).WithField(entity.NewField().
    WithName("my_varchar").
    WithDataType(entity.FieldTypeVarChar).
    WithIsPartitionKey(true).
    WithMaxLength(512),
).WithField(entity.NewField().
    WithName("vector").
    WithDataType(entity.FieldTypeFloatVector).
    WithDim(5),
)
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

const address = "http://localhost:19530";
const token = "root:Milvus";
const client = new MilvusClient({address, token});

// 3. Create a collection in customized setup mode
// 3.1 Define fields
const fields = [
    {
        name: "my_varchar",
        data_type: DataType.VarChar,
        max_length: 512,
        is_partition_key: true
    }
]
export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "vector",
                "dataType": "FloatVector",
                "elementTypeParams": {
                    "dim": "5"
                }
            },
            {
                "fieldName": "my_varchar",
                "dataType": "VarChar",
                "isPartitionKey": true,
                "elementTypeParams": {
                    "max_length": 512
                }
            }
        ]
    }'

파티션 번호 설정

컬렉션의 스칼라 필드를 파티션 키로 지정하면 Milvus는 컬렉션에 자동으로 16개의 파티션을 생성합니다. 엔티티를 받으면 Milvus는 이 엔티티의 파티션 키 값에 따라 파티션을 선택하고 해당 파티션에 엔티티를 저장하므로 일부 또는 모든 파티션에 다른 파티션 키 값을 가진 엔티티가 저장됩니다.

컬렉션과 함께 생성할 파티션의 수를 결정할 수도 있습니다. 이는 파티션 키로 지정된 스칼라 필드가 있는 경우에만 유효합니다.

client.create_collection(
    collection_name="my_collection",
    schema=schema,
    num_partitions=128
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
                .collectionName("my_collection")
                .collectionSchema(schema)
                .numPartitions(128)
                .build();
        client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
    milvusclient.NewCreateCollectionOption("my_collection", schema).
        WithNumPartitions(128))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
await client.create_collection({
    collection_name: "my_collection",
    schema: schema,
    num_partitions: 128
})
export params='{
    "partitionsNum": 128
}'

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"my_collection\",
    \"schema\": $schema,
    \"params\": $params
}"

필터링 조건 생성

파티션 키 기능이 활성화된 컬렉션에서 ANN 검색을 수행할 때는 검색 요청에 파티션 키와 관련된 필터링 표현식을 포함시켜야 합니다. 필터링 표현식에서 파티션 키 값을 특정 범위 내로 제한하면 밀버스에서 해당 파티션 내로 검색 범위를 제한할 수 있습니다.

삭제 작업을 수행할 때 보다 효율적인 삭제를 위해 단일 파티션 키를 지정하는 필터 표현식을 포함하는 것이 좋습니다. 이 접근 방식은 삭제 작업을 특정 파티션으로 제한하여 압축 중에 쓰기 증폭을 줄이고 압축 및 인덱싱을 위한 리소스를 절약합니다.

다음 예제에서는 특정 파티션 키 값과 파티션 키 값 집합을 기반으로 한 파티션 키 기반 필터링을 보여줍니다.

# Filter based on a single partition key value, or
filter='partition_key == "x" && <other conditions>'

# Filter based on multiple partition key values
filter='partition_key in ["x", "y", "z"] && <other conditions>'
// Filter based on a single partition key value, or
String filter = "partition_key == 'x' && <other conditions>";

// Filter based on multiple partition key values
String filter = "partition_key in ['x', 'y', 'z'] && <other conditions>";
// Filter based on a single partition key value, or
filter = "partition_key == 'x' && <other conditions>"

// Filter based on multiple partition key values
filter = "partition_key in ['x', 'y', 'z'] && <other conditions>"
// Filter based on a single partition key value, or
const filter = 'partition_key == "x" && <other conditions>'

// Filter based on multiple partition key values
const filter = 'partition_key in ["x", "y", "z"] && <other conditions>'
# Filter based on a single partition key value, or
export filter='partition_key == "x" && <other conditions>'

# Filter based on multiple partition key values
export filter='partition_key in ["x", "y", "z"] && <other conditions>'

partition_key 을 파티션 키로 지정된 필드의 이름으로 바꿔야 합니다.

파티션 키 격리 사용

멀티테넌시 시나리오에서는 테넌트 ID와 관련된 스칼라 필드를 파티션 키로 지정하고 이 스칼라 필드의 특정 값을 기반으로 필터를 만들 수 있습니다. 유사한 시나리오에서 검색 성능을 더욱 향상시키기 위해 Milvus는 파티션 키 격리 기능을 도입했습니다.

Partition Key Isolation 파티션 키 격리

위 그림에서 볼 수 있듯이 Milvus는 파티션 키 값을 기준으로 엔티티를 그룹화하고 각 그룹에 대해 별도의 인덱스를 생성합니다. 검색 요청을 받으면 밀버스는 필터링 조건에 지정된 파티션 키 값을 기준으로 인덱스를 찾고 인덱스에 포함된 엔터티 내에서 검색 범위를 제한하여 검색 시 관련 없는 엔터티를 검색하지 않도록 하여 검색 성능을 크게 향상시킵니다.

파티션 키 격리를 활성화한 후에는 Milvus가 일치하는 인덱스에 포함된 엔티티 내에서 검색 범위를 제한할 수 있도록 파티션 키 기반 필터에 특정 값을 하나만 포함해야 합니다.

현재 파티션 키 격리 기능은 인덱스 유형이 HNSW로 설정된 검색에만 적용됩니다.

파티션 키 격리 사용

다음 코드 예제는 파티션 키 격리를 활성화하는 방법을 보여줍니다.

client.create_collection(
    collection_name="my_collection",
    schema=schema,
    properties={"partitionkey.isolation": True}
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;

Map<String, String> properties = new HashMap<>();
properties.put("partitionkey.isolation", "true");

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
        .collectionName("my_collection")
        .collectionSchema(schema)
        .properties(properties)
        .build();
client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
    milvusclient.NewCreateCollectionOption("my_collection", schema).
        WithProperty("partitionkey.isolation", true))
if err != nil {
    fmt.Println(err.Error())
    // handle error
}
res = await client.alterCollection({
    collection_name: "my_collection",
    properties: {
        "partitionkey.isolation": true
    }
})
export params='{
    "partitionKeyIsolation": true
}'

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"my_collection\",
    \"schema\": $schema,
    \"params\": $params
}"

파티션 키 격리를 활성화한 후에도 파티션 번호 설정에 설명된 대로 파티션 키와 파티션 수를 설정할 수 있습니다. 파티션 키 기반 필터에는 특정 파티션 키 값만 포함되어야 한다는 점에 유의하세요.

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
피드백

이 페이지가 도움이 되었나요?