/* * Licensed to the LF AI & Data foundation under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package quota import ( "math" "sync" "go.uber.org/zap" "github.com/milvus-io/milvus/pkg/v2/config" "github.com/milvus-io/milvus/pkg/v2/log" "github.com/milvus-io/milvus/pkg/v2/metrics" "github.com/milvus-io/milvus/pkg/v2/proto/internalpb" "github.com/milvus-io/milvus/pkg/v2/util/paramtable" ) var ( initOnce sync.Once limitConfigMap map[internalpb.RateScope]map[internalpb.RateType]*paramtable.ParamItem ) func initLimitConfigMaps() { initOnce.Do(func() { quotaConfig := ¶mtable.Get().QuotaConfig limitConfigMap = map[internalpb.RateScope]map[internalpb.RateType]*paramtable.ParamItem{ internalpb.RateScope_Cluster: { internalpb.RateType_DDLCollection: "aConfig.DDLCollectionRate, internalpb.RateType_DDLPartition: "aConfig.DDLPartitionRate, internalpb.RateType_DDLIndex: "aConfig.MaxIndexRate, internalpb.RateType_DDLFlush: "aConfig.MaxFlushRate, internalpb.RateType_DDLCompaction: "aConfig.MaxCompactionRate, internalpb.RateType_DMLInsert: "aConfig.DMLMaxInsertRate, internalpb.RateType_DMLUpsert: "aConfig.DMLMaxUpsertRate, internalpb.RateType_DMLDelete: "aConfig.DMLMaxDeleteRate, internalpb.RateType_DMLBulkLoad: "aConfig.DMLMaxBulkLoadRate, internalpb.RateType_DQLSearch: "aConfig.DQLMaxSearchRate, internalpb.RateType_DQLQuery: "aConfig.DQLMaxQueryRate, }, internalpb.RateScope_Database: { internalpb.RateType_DDLCollection: "aConfig.DDLCollectionRatePerDB, internalpb.RateType_DDLPartition: "aConfig.DDLPartitionRatePerDB, internalpb.RateType_DDLIndex: "aConfig.MaxIndexRatePerDB, internalpb.RateType_DDLFlush: "aConfig.MaxFlushRatePerDB, internalpb.RateType_DDLCompaction: "aConfig.MaxCompactionRatePerDB, internalpb.RateType_DMLInsert: "aConfig.DMLMaxInsertRatePerDB, internalpb.RateType_DMLUpsert: "aConfig.DMLMaxUpsertRatePerDB, internalpb.RateType_DMLDelete: "aConfig.DMLMaxDeleteRatePerDB, internalpb.RateType_DMLBulkLoad: "aConfig.DMLMaxBulkLoadRatePerDB, internalpb.RateType_DQLSearch: "aConfig.DQLMaxSearchRatePerDB, internalpb.RateType_DQLQuery: "aConfig.DQLMaxQueryRatePerDB, }, internalpb.RateScope_Collection: { internalpb.RateType_DMLInsert: "aConfig.DMLMaxInsertRatePerCollection, internalpb.RateType_DMLUpsert: "aConfig.DMLMaxUpsertRatePerCollection, internalpb.RateType_DMLDelete: "aConfig.DMLMaxDeleteRatePerCollection, internalpb.RateType_DMLBulkLoad: "aConfig.DMLMaxBulkLoadRatePerCollection, internalpb.RateType_DQLSearch: "aConfig.DQLMaxSearchRatePerCollection, internalpb.RateType_DQLQuery: "aConfig.DQLMaxQueryRatePerCollection, internalpb.RateType_DDLFlush: "aConfig.MaxFlushRatePerCollection, }, internalpb.RateScope_Partition: { internalpb.RateType_DMLInsert: "aConfig.DMLMaxInsertRatePerPartition, internalpb.RateType_DMLUpsert: "aConfig.DMLMaxUpsertRatePerPartition, internalpb.RateType_DMLDelete: "aConfig.DMLMaxDeleteRatePerPartition, internalpb.RateType_DMLBulkLoad: "aConfig.DMLMaxBulkLoadRatePerPartition, internalpb.RateType_DQLSearch: "aConfig.DQLMaxSearchRatePerPartition, internalpb.RateType_DQLQuery: "aConfig.DQLMaxQueryRatePerPartition, }, } pt := paramtable.Get() pt.Watch(quotaConfig.DMLMaxInsertRate.Key, config.NewHandler(quotaConfig.DMLMaxInsertRate.Key, func(event *config.Event) { metrics.MaxInsertRate.WithLabelValues(paramtable.GetStringNodeID(), "cluster").Set(quotaConfig.DMLMaxInsertRate.GetAsFloat()) })) pt.Watch(quotaConfig.DMLMaxInsertRatePerDB.Key, config.NewHandler(quotaConfig.DMLMaxInsertRatePerDB.Key, func(event *config.Event) { metrics.MaxInsertRate.WithLabelValues(paramtable.GetStringNodeID(), "db").Set(quotaConfig.DMLMaxInsertRatePerDB.GetAsFloat()) })) pt.Watch(quotaConfig.DMLMaxInsertRatePerCollection.Key, config.NewHandler(quotaConfig.DMLMaxInsertRatePerCollection.Key, func(event *config.Event) { metrics.MaxInsertRate.WithLabelValues(paramtable.GetStringNodeID(), "collection").Set(quotaConfig.DMLMaxInsertRatePerCollection.GetAsFloat()) })) pt.Watch(quotaConfig.DMLMaxInsertRatePerPartition.Key, config.NewHandler(quotaConfig.DMLMaxInsertRatePerPartition.Key, func(event *config.Event) { metrics.MaxInsertRate.WithLabelValues(paramtable.GetStringNodeID(), "partition").Set(quotaConfig.DMLMaxInsertRatePerPartition.GetAsFloat()) })) }) } func GetQuotaConfigMap(scope internalpb.RateScope) map[internalpb.RateType]*paramtable.ParamItem { initLimitConfigMaps() configMap, ok := limitConfigMap[scope] if !ok { log.Warn("Unknown rate scope", zap.Any("scope", scope)) return make(map[internalpb.RateType]*paramtable.ParamItem) } return configMap } func GetQuotaValue(scope internalpb.RateScope, rateType internalpb.RateType, params *paramtable.ComponentParam) float64 { configMap := GetQuotaConfigMap(scope) config, ok := configMap[rateType] if !ok { log.Warn("Unknown rate type", zap.Any("rateType", rateType)) return math.MaxFloat64 } return config.GetAsFloat() }