파티션 키 사용
파티션 키는 파티션에 기반한 검색 최적화 솔루션입니다. 특정 스칼라 필드를 파티션 키로 지정하고 검색 시 파티션 키를 기반으로 필터링 조건을 지정하면 검색 범위를 여러 파티션으로 좁혀 검색 효율을 높일 수 있습니다. 이 문서에서는 파티션 키의 사용 방법과 관련 고려 사항을 소개합니다.
개요
Milvus에서는 파티션을 사용하여 검색 범위를 특정 파티션으로 제한함으로써 데이터 분리를 구현하고 검색 성능을 향상시킬 수 있습니다. 파티션을 수동으로 관리하기로 선택한 경우 컬렉션에 최대 1,024개의 파티션을 생성하고 특정 규칙에 따라 이러한 파티션에 엔티티를 삽입하여 특정 수의 파티션 내에서 검색을 제한하여 검색 범위를 좁힐 수 있습니다.
밀버스에서는 데이터 분리에서 파티션을 재사용할 수 있는 파티션 키를 도입하여 컬렉션에 생성할 수 있는 파티션 수의 제한을 극복할 수 있습니다. 컬렉션을 만들 때 스칼라 필드를 파티션 키로 사용할 수 있습니다. 컬렉션이 준비되면 Milvus는 컬렉션 내에 지정된 수의 파티션을 생성합니다. 삽입된 엔티티를 받으면 Milvus는 엔티티의 파티션 키 값을 사용하여 해시값을 계산하고 해시값과 컬렉션의 partitions_num 속성을 기반으로 모듈로 연산을 실행하여 대상 파티션 ID를 얻은 후 대상 파티션에 엔티티를 저장합니다.
파티션 대 파티션 키
다음 그림은 Milvus가 파티션 키 기능을 활성화하거나 활성화하지 않은 상태에서 컬렉션의 검색 요청을 처리하는 방법을 보여줍니다.
파티션 키 기능이 비활성화되어 있는 경우, Milvus는 컬렉션 내에서 쿼리 벡터와 가장 유사한 엔티티를 검색합니다. 가장 관련성이 높은 결과가 포함된 파티션을 알고 있는 경우 검색 범위를 좁힐 수 있습니다.
파티션 키가 활성화된 경우 Milvus는 검색 필터에 지정된 파티션 키 값에 따라 검색 범위를 결정하고 일치하는 파티션 내의 엔티티만 검색합니다.
파티션 키 사용 및 미사용
파티션 키 사용
파티션 키를 사용하려면 다음을 수행해야 합니다.
생성할 파티션 수 설정 (선택 사항), 그리고
파티션 키 설정
스칼라 필드를 파티션 키로 지정하려면 스칼라 필드를 추가할 때 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는 파티션 키 격리 기능을 도입했습니다.
파티션 키 격리
위 그림에서 볼 수 있듯이 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
}"
파티션 키 격리를 활성화한 후에도 파티션 번호 설정에 설명된 대로 파티션 키와 파티션 수를 설정할 수 있습니다. 파티션 키 기반 필터에는 특정 파티션 키 값만 포함되어야 한다는 점에 유의하세요.