diff --git a/cpp/CHANGELOG.md b/cpp/CHANGELOG.md index 76e6ec2f3bbf2cfeb4bb9c5a9b3ec4e2f1e64bb2..2612062263d0424e174396bb6e9f30baf8d359c1 100644 --- a/cpp/CHANGELOG.md +++ b/cpp/CHANGELOG.md @@ -18,7 +18,8 @@ Please mark all change in change log and use the ticket from JIRA. - MS-562 - Add JobMgr and TaskCreator in Scheduler - MS-566 - Refactor cmake - MS-555 - Remove old scheduler -- MS-578 - Makesure milvus5.0 don't crack 0.3.1 data +- MS-574 - Milvus configuration refactor +- MS-578 - Make sure milvus5.0 don't crack 0.3.1 data - MS-585 - Update namespace in scheduler ## New Feature diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 4fffe6622074f183d92663d7b9ce06f609bc0805..cc807d43ed4cfa238283566f8a8fb9bf7f1c12b8 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -44,7 +44,6 @@ set(MILVUS_VERSION "${GIT_BRANCH_NAME}") string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]" MILVUS_VERSION "${MILVUS_VERSION}") find_package(ClangTools) -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(BUILD_SUPPORT_DIR "${CMAKE_SOURCE_DIR}/build-support") if(CMAKE_BUILD_TYPE STREQUAL "Release") @@ -57,6 +56,9 @@ message(STATUS "Build type = ${BUILD_TYPE}") project(milvus VERSION "${MILVUS_VERSION}") project(milvus_engine LANGUAGES CUDA CXX) +unset(CMAKE_EXPORT_COMPILE_COMMANDS CACHE) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + set(MILVUS_VERSION_MAJOR "${milvus_VERSION_MAJOR}") set(MILVUS_VERSION_MINOR "${milvus_VERSION_MINOR}") set(MILVUS_VERSION_PATCH "${milvus_VERSION_PATCH}") diff --git a/cpp/conf/server_config.template b/cpp/conf/server_config.template index 8253788cb729d0e1e0b16602899e40becb2c7760..6364698100e43de7dda50b3a5da74565e1656e02 100644 --- a/cpp/conf/server_config.template +++ b/cpp/conf/server_config.template @@ -1,42 +1,39 @@ server_config: - address: 0.0.0.0 # milvus server ip address (IPv4) - port: 19530 # the port milvus listen to, default: 19530, range: 1025 ~ 65534 - mode: single # milvus deployment type: single, cluster, read_only - time_zone: UTC+8 # Use the UTC-x or UTC+x to specify a time zone. eg. UTC+8 for China Standard Time + address: 0.0.0.0 # milvus server ip address (IPv4) + port: 19530 # port range: 1025 ~ 65534 + mode: single # deployment type: single, cluster, read_only + time_zone: UTC+8 db_config: - db_path: @MILVUS_DB_PATH@ # milvus data storage path - db_slave_path: # secondry data storage path, split by semicolon + path: @MILVUS_DB_PATH@ # milvus database path + slave_path: # secondary database path, split by semicolon # URI format: dialect://username:password@host:port/database # All parts except dialect are optional, but you MUST include the delimiters # Currently dialect supports mysql or sqlite - db_backend_url: sqlite://:@:/ + backend_url: sqlite://:@:/ - archive_disk_threshold: 0 # triger archive action if storage size exceed this value, 0 means no limit, unit: GB - archive_days_threshold: 0 # files older than x days will be archived, 0 means no limit, unit: day - insert_buffer_size: 4 # maximum insert buffer size allowed, default: 4, unit: GB, should be at least 1 GB. - # the sum of insert_buffer_size and cpu_cache_capacity should be less than total memory, unit: GB - build_index_gpu: 0 # which gpu is used to build index, default: 0, range: 0 ~ gpu number - 1 + archive_disk_threshold: 0 # GB, file will be archived when disk usage exceed, 0 for no limit + archive_days_threshold: 0 # DAYS, older files will be archived, 0 for no limit + buffer_size: 4 # GB, maximum insert buffer size allowed + build_index_gpu: 0 # gpu id used for building index metric_config: - is_startup: off # if monitoring start: on, off - collector: prometheus # metrics collector: prometheus - prometheus_config: # following are prometheus configure - port: 8080 # the port prometheus use to fetch metrics - push_gateway_ip_address: 127.0.0.1 # push method configure: push gateway ip address - push_gateway_port: 9091 # push method configure: push gateway port + auto_bootup: off # whether enable monitoring when bootup + collector: prometheus # prometheus + prometheus_config: + port: 8080 # port prometheus used to fetch metrics cache_config: - cpu_cache_capacity: 16 # how many memory are used as cache, unit: GB, range: 0 ~ less than total memory - cpu_cache_free_percent: 0.85 # old data will be erased from cache when cache is full, this value specify how much memory should be kept, range: greater than zero ~ 1.0 - insert_cache_immediately: false # insert data will be load into cache immediately for hot query + cpu_mem_capacity: 16 # GB, CPU memory size used for cache + cpu_mem_threshold: 0.85 # percent of data kept when cache cleanup triggered + cache_insert_data: false # whether load data into cache when insert engine_config: - use_blas_threshold: 20 + blas_threshold: 20 resource_config: mode: simple - resources: -# - cpu + pool: + - cpu - gpu0 diff --git a/cpp/src/cache/CpuCacheMgr.cpp b/cpp/src/cache/CpuCacheMgr.cpp index e47d768f347e881f95c8b75567322825f781ff04..1f93ec92bdd006d4e445f2308d9fb3e860e5e0e8 100644 --- a/cpp/src/cache/CpuCacheMgr.cpp +++ b/cpp/src/cache/CpuCacheMgr.cpp @@ -17,7 +17,7 @@ #include "CpuCacheMgr.h" -#include "server/ServerConfig.h" +#include "server/Config.h" #include "utils/Log.h" namespace zilliz { @@ -29,17 +29,27 @@ namespace { } CpuCacheMgr::CpuCacheMgr() { - server::ConfigNode& config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_CACHE); - int64_t cap = config.GetInt64Value(server::CONFIG_CPU_CACHE_CAPACITY, 16); - cap *= unit; + server::Config& config = server::Config::GetInstance(); + Status s; + + int32_t cpu_mem_cap; + s = config.GetCacheConfigCpuMemCapacity(cpu_mem_cap); + if (!s.ok()) { + SERVER_LOG_ERROR << s.message(); + } + int64_t cap = cpu_mem_cap * unit; cache_ = std::make_shared>(cap, 1UL<<32); - double free_percent = config.GetDoubleValue(server::CACHE_FREE_PERCENT, 0.85); - if(free_percent > 0.0 && free_percent <= 1.0) { - cache_->set_freemem_percent(free_percent); + float cpu_mem_threshold; + s = config.GetCacheConfigCpuMemThreshold(cpu_mem_threshold); + if (!s.ok()) { + SERVER_LOG_ERROR << s.message(); + } + if (cpu_mem_threshold > 0.0 && cpu_mem_threshold <= 1.0) { + cache_->set_freemem_percent(cpu_mem_threshold); } else { - SERVER_LOG_ERROR << "Invalid cache_free_percent: " << free_percent << - ", defaultly set to " << cache_->freemem_percent(); + SERVER_LOG_ERROR << "Invalid cpu_mem_threshold: " << cpu_mem_threshold + << ", by default set to " << cache_->freemem_percent(); } } diff --git a/cpp/src/cache/GpuCacheMgr.cpp b/cpp/src/cache/GpuCacheMgr.cpp index bd6f2adfe19c316fc77012f8efea074a67a2789d..5c104ba0e7452fa9eea6de8c0dc30bf566664d9b 100644 --- a/cpp/src/cache/GpuCacheMgr.cpp +++ b/cpp/src/cache/GpuCacheMgr.cpp @@ -19,7 +19,7 @@ #include #include "utils/Log.h" #include "GpuCacheMgr.h" -#include "server/ServerConfig.h" +#include "server/Config.h" namespace zilliz { namespace milvus { @@ -33,18 +33,27 @@ namespace { } GpuCacheMgr::GpuCacheMgr() { - server::ConfigNode& config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_CACHE); + server::Config& config = server::Config::GetInstance(); + Status s; - int64_t cap = config.GetInt64Value(server::CONFIG_GPU_CACHE_CAPACITY, 0); - cap *= G_BYTE; + int32_t gpu_mem_cap; + s = config.GetCacheConfigGpuMemCapacity(gpu_mem_cap); + if (!s.ok()) { + SERVER_LOG_ERROR << s.message(); + } + int32_t cap = gpu_mem_cap * G_BYTE; cache_ = std::make_shared>(cap, 1UL<<32); - double free_percent = config.GetDoubleValue(server::GPU_CACHE_FREE_PERCENT, 0.85); - if (free_percent > 0.0 && free_percent <= 1.0) { - cache_->set_freemem_percent(free_percent); + float gpu_mem_threshold; + s = config.GetCacheConfigGpuMemThreshold(gpu_mem_threshold); + if (!s.ok()) { + SERVER_LOG_ERROR << s.message(); + } + if (gpu_mem_threshold > 0.0 && gpu_mem_threshold <= 1.0) { + cache_->set_freemem_percent(gpu_mem_threshold); } else { - SERVER_LOG_ERROR << "Invalid gpu_cache_free_percent: " << free_percent << - ", defaultly set to " << cache_->freemem_percent(); + SERVER_LOG_ERROR << "Invalid gpu_mem_threshold: " << gpu_mem_threshold + << ", by default set to " << cache_->freemem_percent(); } } diff --git a/cpp/src/db/engine/ExecutionEngineImpl.cpp b/cpp/src/db/engine/ExecutionEngineImpl.cpp index 83c69e6db330e1fcdad1391e9e6f06ae2ee05705..45a7699c10e22bb54a8552ccf099529ca8e04b2c 100644 --- a/cpp/src/db/engine/ExecutionEngineImpl.cpp +++ b/cpp/src/db/engine/ExecutionEngineImpl.cpp @@ -26,6 +26,7 @@ #include "src/wrapper/vec_index.h" #include "src/wrapper/vec_impl.h" #include "knowhere/common/Exception.h" +#include "server/Config.h" #include @@ -326,9 +327,9 @@ Status ExecutionEngineImpl::GpuCache(uint64_t gpu_id) { // TODO(linxj): remove. Status ExecutionEngineImpl::Init() { using namespace zilliz::milvus::server; - ServerConfig &config = ServerConfig::GetInstance(); - ConfigNode server_config = config.GetConfig(CONFIG_DB); - gpu_num_ = server_config.GetInt32Value(CONFIG_DB_BUILD_INDEX_GPU, 0); + server::Config &config = server::Config::GetInstance(); + Status s = config.GetDBConfigBuildIndexGPU(gpu_num_); + if (!s.ok()) return s; return Status::OK(); } diff --git a/cpp/src/db/engine/ExecutionEngineImpl.h b/cpp/src/db/engine/ExecutionEngineImpl.h index cb08c50ad4e6fedc6ab41bd1ac1392f458d037db..44d59d83e87f254f160fb8344c5de36a0192558e 100644 --- a/cpp/src/db/engine/ExecutionEngineImpl.h +++ b/cpp/src/db/engine/ExecutionEngineImpl.h @@ -101,7 +101,7 @@ protected: std::string location_; int32_t nlist_ = 0; - int64_t gpu_num_ = 0; + int32_t gpu_num_ = 0; }; diff --git a/cpp/src/main.cpp b/cpp/src/main.cpp index 5a61c5bfb4508d2d1ef2f560ff7e32f00a431c17..dc17733a8ba4b57e1a045fea5985af87e8638f6d 100644 --- a/cpp/src/main.cpp +++ b/cpp/src/main.cpp @@ -110,7 +110,7 @@ main(int argc, char *argv[]) { signal(SIGUSR2, server::SignalUtil::HandleSignal); signal(SIGTERM, server::SignalUtil::HandleSignal); - server::Server &server = server::Server::Instance(); + server::Server &server = server::Server::GetInstance(); server.Init(start_daemonized, pid_filename, config_filename, log_config_file); server.Start(); diff --git a/cpp/src/metrics/MetricBase.h b/cpp/src/metrics/MetricBase.h index aa181fb3f3df68ab8585d8acd77774c0760cecf5..8a3f11d7df7fb9edd27a244ba0bd8c1692421e9a 100644 --- a/cpp/src/metrics/MetricBase.h +++ b/cpp/src/metrics/MetricBase.h @@ -19,7 +19,6 @@ #pragma once #include "utils/Error.h" -#include "server/ServerConfig.h" #include "SystemInfo.h" namespace zilliz { @@ -83,11 +82,6 @@ class MetricsBase{ virtual void CPUTemperature() {}; }; - - - - - } } } \ No newline at end of file diff --git a/cpp/src/metrics/Metrics.cpp b/cpp/src/metrics/Metrics.cpp index 10ddd7ee3ce2879fcb4b70659bb203d71cbc5730..612f5e7fcedca408e8f3dc9bfc2717cd8794ce9b 100644 --- a/cpp/src/metrics/Metrics.cpp +++ b/cpp/src/metrics/Metrics.cpp @@ -16,6 +16,7 @@ // under the License. #include "Metrics.h" +#include "server/Config.h" #include "PrometheusMetrics.h" @@ -31,8 +32,10 @@ Metrics::GetInstance() { MetricsBase & Metrics::CreateMetricsCollector() { - ConfigNode &config = ServerConfig::GetInstance().GetConfig(CONFIG_METRIC); - std::string collector_type_str = config.GetValue(CONFIG_METRIC_COLLECTOR); + Config &config = Config::GetInstance(); + std::string collector_type_str; + + config.GetMetricConfigCollector(collector_type_str); if (collector_type_str == "prometheus") { return PrometheusMetrics::GetInstance(); diff --git a/cpp/src/metrics/PrometheusMetrics.cpp b/cpp/src/metrics/PrometheusMetrics.cpp index f4d70a21c340048b4f5bf87273969c2db8ed4767..b607dbb020f885ddbeef77fc713d1aefb0bd15a4 100644 --- a/cpp/src/metrics/PrometheusMetrics.cpp +++ b/cpp/src/metrics/PrometheusMetrics.cpp @@ -16,8 +16,9 @@ // under the License. -#include +#include "cache/GpuCacheMgr.h" #include "PrometheusMetrics.h" +#include "server/Config.h" #include "utils/Log.h" #include "SystemInfo.h" @@ -26,15 +27,19 @@ namespace zilliz { namespace milvus { namespace server { - ErrorCode +ErrorCode PrometheusMetrics::Init() { try { - ConfigNode &configNode = ServerConfig::GetInstance().GetConfig(CONFIG_METRIC); - startup_ = configNode.GetValue(CONFIG_METRIC_IS_STARTUP) == "on"; - if(!startup_) return SERVER_SUCCESS; + Config &config = Config::GetInstance(); + Status s = config.GetMetricConfigAutoBootup(startup_); + if (!s.ok()) return s.code(); + if (!startup_) return SERVER_SUCCESS; + // Following should be read from config file. - const std::string bind_address = configNode.GetChild(CONFIG_PROMETHEUS).GetValue(CONFIG_METRIC_PROMETHEUS_PORT); - const std::string uri = std::string("/metrics"); + std::string bind_address; + s = config.GetMetricConfigPrometheusPort(bind_address); + if (!s.ok()) return s.code(); + const std::string uri = std::string("/tmp/metrics"); const std::size_t num_threads = 2; // Init Exposer diff --git a/cpp/src/metrics/PrometheusMetrics.h b/cpp/src/metrics/PrometheusMetrics.h index 5a3379305ab9c5bc110fc034c85d615966b53490..4ee6699b77c73df65c743be58514f1f342c2729c 100644 --- a/cpp/src/metrics/PrometheusMetrics.h +++ b/cpp/src/metrics/PrometheusMetrics.h @@ -17,15 +17,13 @@ #pragma once -#include "utils/Error.h" #include #include - - #include #include #include -#include "server/ServerConfig.h" + +#include "utils/Error.h" #include "MetricBase.h" @@ -38,10 +36,6 @@ namespace zilliz { namespace milvus { namespace server { - - - - class PrometheusMetrics: public MetricsBase { public: @@ -107,11 +101,6 @@ class PrometheusMetrics: public MetricsBase { void GPUTemperature() override; void CPUTemperature() override; - - - - - std::shared_ptr &exposer_ptr() {return exposer_ptr_; } // prometheus::Exposer& exposer() { return exposer_;} std::shared_ptr ®istry_ptr() {return registry_; } @@ -125,8 +114,6 @@ class PrometheusMetrics: public MetricsBase { // .Register(*registry_); // prometheus::Counter &connection_total_ = connect_request_.Add({}); - - ////all from DBImpl.cpp using BucketBoundaries = std::vector; //record add_group request @@ -472,10 +459,8 @@ class PrometheusMetrics: public MetricsBase { .Name("CPU_temperature") .Help("CPU temperature") .Register(*registry_); - }; - } } } diff --git a/cpp/src/scheduler/SchedInst.cpp b/cpp/src/scheduler/SchedInst.cpp index a13640073d0f0fa4e0bc58034f3b3074726663db..5d65d35993d8207ad9b60dddf9c5c7b457b9e228 100644 --- a/cpp/src/scheduler/SchedInst.cpp +++ b/cpp/src/scheduler/SchedInst.cpp @@ -17,7 +17,7 @@ #include "SchedInst.h" -#include "server/ServerConfig.h" +#include "server/Config.h" #include "ResourceFactory.h" #include "knowhere/index/vector_index/IndexGPUIVF.h" #include "Utils.h" @@ -38,13 +38,15 @@ std::mutex JobMgrInst::mutex_; void load_simple_config() { - server::ConfigNode &config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_RESOURCE); - auto mode = config.GetValue("mode", "simple"); + server::Config &config = server::Config::GetInstance(); + std::string mode; + config.GetResourceConfigMode(mode); + std::vector pool; + config.GetResourceConfigPool(pool); - auto resources = config.GetSequence("resources"); bool cpu = false; std::set gpu_ids; - for (auto &resource : resources) { + for (auto &resource : pool) { if (resource == "cpu") { cpu = true; break; @@ -82,7 +84,7 @@ load_simple_config() { void load_advance_config() { // try { -// server::ConfigNode &config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_RESOURCE); +// server::ConfigNode &config = server::Config::GetInstance().GetConfig(server::CONFIG_RESOURCE); // // if (config.GetChildren().empty()) throw "resource_config null exception"; // diff --git a/cpp/src/server/Config.cpp b/cpp/src/server/Config.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ee2f7c62b30632f388765654ad6f73785c26d33 --- /dev/null +++ b/cpp/src/server/Config.cpp @@ -0,0 +1,999 @@ +// Licensed to the Apache Software Foundation (ASF) 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. + +#include "Config.h" + +#include +#include +#include +#include +#include +#include + +#include "config/ConfigMgr.h" +#include "utils/CommonUtil.h" +#include "utils/ValidationUtil.h" + + +namespace zilliz { +namespace milvus { +namespace server { + +constexpr uint64_t GB = 1UL << 30; + +Config & +Config::GetInstance() { + static Config config_inst; + return config_inst; +} + +Status +Config::LoadConfigFile(const std::string &filename) { + if (filename.empty()) { + std::cerr << "ERROR: need specify config file" << std::endl; + exit(1); + } + struct stat dirStat; + int statOK = stat(filename.c_str(), &dirStat); + if (statOK != 0) { + std::cerr << "ERROR: Config file not exist: " << filename << std::endl; + exit(1); + } + + try { + ConfigMgr *mgr = const_cast(ConfigMgr::GetInstance()); + ErrorCode err = mgr->LoadConfigFile(filename); + if (err != 0) { + std::cerr << "Server failed to load config file: " << filename << std::endl; + exit(1); + } + } + catch (YAML::Exception &e) { + std::cerr << "Server failed to load config file: " << filename << std::endl; + exit(1); + } + + return Status::OK(); +} + +void +Config::PrintConfigSection(const std::string& config_node_name) { + std::cout << std::endl; + std::cout << config_node_name << ":" << std::endl; + if (config_map_.find(config_node_name) != config_map_.end()) { + for (auto item: config_map_[config_node_name]) { + std::cout << item.first << ": " << item.second << std::endl; + } + } +} + +void +Config::PrintAll() { + PrintConfigSection(CONFIG_SERVER); + PrintConfigSection(CONFIG_DB); + PrintConfigSection(CONFIG_CACHE); + PrintConfigSection(CONFIG_METRIC); + PrintConfigSection(CONFIG_ENGINE); + PrintConfigSection(CONFIG_RESOURCE); +} + +//////////////////////////////////////////////////////////////////////////////// +Status +Config::CheckServerConfigAddress(const std::string &value) { + if (!ValidationUtil::ValidateIpAddress(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config address: " + value); + } + return Status::OK(); +} + +Status +Config::CheckServerConfigPort(const std::string &value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config port: " + value); + } else { + int32_t port = std::stoi(value); + if (!(port > 1024 && port < 65535)) { + return Status(SERVER_INVALID_ARGUMENT, "Server config port out of range (1024, 65535): " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckServerConfigMode(const std::string &value) { + if (value != "single" && value != "cluster" && value != "read_only") { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config mode [single, cluster, read_only]: " + value); + } + return Status::OK(); +} + +Status +Config::CheckServerConfigTimeZone(const std::string &value) { + if (value.length() <= 3) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config time_zone: " + value); + } else { + if (value.substr(0, 3) != "UTC") { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config time_zone: " + value); + } else { + try { + stoi(value.substr(3)); + } catch (...) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid server config time_zone: " + value); + } + } + } + return Status::OK(); +} + +Status +Config::CheckDBConfigPath(const std::string &value) { + if (value.empty()) { + return Status(SERVER_INVALID_ARGUMENT, "DB config path empty"); + } + return Status::OK(); +} + +Status +Config::CheckDBConfigSlavePath(const std::string &value) { + return Status::OK(); +} + +Status +Config::CheckDBConfigBackendUrl(const std::string &value) { + if (!ValidationUtil::ValidateDbURI(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config backend_url: " + value); + } + return Status::OK(); +} + +Status +Config::CheckDBConfigArchiveDiskThreshold(const std::string &value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config archive_disk_threshold: " + value); + } + return Status::OK(); +} + +Status +Config::CheckDBConfigArchiveDaysThreshold(const std::string &value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config archive_days_threshold: " + value); + } + return Status::OK(); +} + +Status +Config::CheckDBConfigBufferSize(const std::string &value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config buffer_size: " + value); + } else { + int64_t buffer_size = std::stoi(value) * GB; + unsigned long total_mem = 0, free_mem = 0; + CommonUtil::GetSystemMemInfo(total_mem, free_mem); + if (buffer_size >= total_mem) { + return Status(SERVER_INVALID_ARGUMENT, "DB config buffer_size exceed system memory: " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckDBConfigBuildIndexGPU(const std::string &value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config build_index_gpu: " + value); + } else { + int32_t gpu_index = std::stoi(value); + if (!ValidationUtil::ValidateGpuIndex(gpu_index).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid DB config build_index_gpu: " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckMetricConfigAutoBootup(const std::string& value) { + if (!ValidationUtil::ValidateStringIsBool(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid metric config auto_bootup: " + value); + } + return Status::OK(); +} + +Status +Config::CheckMetricConfigCollector(const std::string& value) { + if (value != "prometheus") { + return Status(SERVER_INVALID_ARGUMENT, "Invalid metric config collector: " + value); + } + return Status::OK(); +} + +Status +Config::CheckMetricConfigPrometheusPort(const std::string& value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid metric config prometheus_port: " + value); + } + return Status::OK(); +} + +Status +Config::CheckCacheConfigCpuMemCapacity(const std::string& value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config cpu_mem_capacity: " + value); + } else { + uint64_t cpu_cache_capacity = std::stoi(value) * GB; + unsigned long total_mem = 0, free_mem = 0; + CommonUtil::GetSystemMemInfo(total_mem, free_mem); + if (cpu_cache_capacity >= total_mem) { + return Status(SERVER_INVALID_ARGUMENT, "Cache config cpu_mem_capacity exceed system memory: " + value); + } else if (cpu_cache_capacity > (double) total_mem * 0.9) { + std::cerr << "Warning: cpu_mem_capacity value is too big" << std::endl; + } + + int32_t buffer_size; + Status s = GetDBConfigBufferSize(buffer_size); + if (!s.ok()) return s; + int64_t insert_buffer_size = buffer_size * GB; + if (insert_buffer_size + cpu_cache_capacity >= total_mem) { + return Status(SERVER_INVALID_ARGUMENT, "Sum of cpu_mem_capacity and buffer_size exceed system memory"); + } + } + return Status::OK(); +} + +Status +Config::CheckCacheConfigCpuMemThreshold(const std::string& value) { + if (!ValidationUtil::ValidateStringIsFloat(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config cpu_mem_threshold: " + value); + } else { + float cpu_mem_threshold = std::stof(value); + if (cpu_mem_threshold <= 0.0 || cpu_mem_threshold >= 1.0) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config cpu_mem_threshold: " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckCacheConfigGpuMemCapacity(const std::string& value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + std::cerr << "ERROR: gpu_cache_capacity " << value << " is not a number" << std::endl; + } else { + uint64_t gpu_cache_capacity = std::stoi(value) * GB; + int gpu_index; + Status s = GetDBConfigBuildIndexGPU(gpu_index); + if (!s.ok()) return s; + size_t gpu_memory; + if (!ValidationUtil::GetGpuMemory(gpu_index, gpu_memory).ok()) { + return Status(SERVER_UNEXPECTED_ERROR, + "Fail to get GPU memory for GPU device: " + std::to_string(gpu_index)); + } else if (gpu_cache_capacity >= gpu_memory) { + return Status(SERVER_INVALID_ARGUMENT, + "Cache config gpu_mem_capacity exceed GPU memory: " + std::to_string(gpu_memory)); + } else if (gpu_cache_capacity > (double) gpu_memory * 0.9) { + std::cerr << "Warning: gpu_mem_capacity value is too big" << std::endl; + } + } + return Status::OK(); +} + +Status +Config::CheckCacheConfigGpuMemThreshold(const std::string& value) { + if (!ValidationUtil::ValidateStringIsFloat(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config gpu_mem_threshold: " + value); + } else { + float gpu_mem_threshold = std::stof(value); + if (gpu_mem_threshold <= 0.0 || gpu_mem_threshold >= 1.0) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config gpu_mem_threshold: " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckCacheConfigCacheInsertData(const std::string& value) { + if (!ValidationUtil::ValidateStringIsBool(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid cache config cache_insert_data: " + value); + } + return Status::OK(); +} + +Status +Config::CheckEngineConfigBlasThreshold(const std::string& value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid engine config blas threshold: " + value); + } + return Status::OK(); +} + +Status +Config::CheckEngineConfigOmpThreadNum(const std::string& value) { + if (!ValidationUtil::ValidateStringIsNumber(value).ok()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid engine config omp_thread_num: " + value); + } else { + int32_t omp_thread = std::stoi(value); + uint32_t sys_thread_cnt = 8; + if (omp_thread > CommonUtil::GetSystemAvailableThreads(sys_thread_cnt)) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid engine config omp_thread_num: " + value); + } + } + return Status::OK(); +} + +Status +Config::CheckResourceConfigMode(const std::string& value) { + if (value != "simple") { + return Status(SERVER_INVALID_ARGUMENT, "Invalid resource config mode: " + value); + } + return Status::OK(); +} + +Status +Config::CheckResourceConfigPool(const std::vector& value) { + if (value.empty()) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid resource config pool"); + } + return Status::OK(); +} + +//////////////////////////////////////////////////////////////////////////////// +ConfigNode & +Config::GetConfigNode(const std::string &name) { + ConfigMgr *mgr = ConfigMgr::GetInstance(); + ConfigNode &root_node = mgr->GetRootNode(); + return root_node.GetChild(name); +} + +Status +Config::GetConfigValueInMem(const std::string &parent_key, + const std::string &child_key, + std::string &value) { + std::lock_guard lock(mutex_); + if (config_map_.find(parent_key) != config_map_.end() && + config_map_[parent_key].find(child_key) != config_map_[parent_key].end()) { + value = config_map_[parent_key][child_key]; + return Status::OK(); + } else { + return Status(SERVER_UNEXPECTED_ERROR, "key not exist"); + } +} + +void +Config::SetConfigValueInMem(const std::string &parent_key, + const std::string &child_key, + const std::string &value) { + std::lock_guard lock(mutex_); + config_map_[parent_key][child_key] = value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* server config */ +std::string +Config::GetServerConfigStrAddress() { + std::string value; + if (!GetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_ADDRESS, value).ok()) { + value = GetConfigNode(CONFIG_SERVER).GetValue(CONFIG_SERVER_ADDRESS, + CONFIG_SERVER_ADDRESS_DEFAULT); + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_ADDRESS, value); + } + return value; +} + +std::string +Config::GetServerConfigStrPort() { + std::string value; + if (!GetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_PORT, value).ok()) { + value = GetConfigNode(CONFIG_SERVER).GetValue(CONFIG_SERVER_PORT, + CONFIG_SERVER_PORT_DEFAULT); + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_PORT, value); + } + return value; +} + +std::string +Config::GetServerConfigStrMode() { + std::string value; + if (!GetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_MODE, value).ok()) { + value = GetConfigNode(CONFIG_SERVER).GetValue(CONFIG_SERVER_MODE, + CONFIG_SERVER_MODE_DEFAULT); + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_MODE, value); + } + return value; +} + +std::string +Config::GetServerConfigStrTimeZone() { + std::string value; + if (!GetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_TIME_ZONE, value).ok()) { + value = GetConfigNode(CONFIG_SERVER).GetValue(CONFIG_SERVER_TIME_ZONE, + CONFIG_SERVER_TIME_ZONE_DEFAULT); + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_TIME_ZONE, value); + } + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* db config */ +std::string +Config::GetDBConfigStrPath() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_PATH, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_PATH, + CONFIG_DB_PATH_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_PATH, value); + } + return value; +} + +std::string +Config::GetDBConfigStrSlavePath() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_SLAVE_PATH, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_SLAVE_PATH, + CONFIG_DB_SLAVE_PATH_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_SLAVE_PATH, value); + } + return value; +} + +std::string +Config::GetDBConfigStrBackendUrl() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_BACKEND_URL, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_BACKEND_URL, + CONFIG_DB_BACKEND_URL_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BACKEND_URL, value); + } + return value; +} + +std::string +Config::GetDBConfigStrArchiveDiskThreshold() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DISK_THRESHOLD, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_ARCHIVE_DISK_THRESHOLD, + CONFIG_DB_ARCHIVE_DISK_THRESHOLD_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DISK_THRESHOLD, value); + } + return value; +} + +std::string +Config::GetDBConfigStrArchiveDaysThreshold() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DAYS_THRESHOLD, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_ARCHIVE_DAYS_THRESHOLD, + CONFIG_DB_ARCHIVE_DAYS_THRESHOLD_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DAYS_THRESHOLD, value); + } + return value; +} + +std::string +Config::GetDBConfigStrBufferSize() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUFFER_SIZE, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_BUFFER_SIZE, + CONFIG_DB_BUFFER_SIZE_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUFFER_SIZE, value); + } + return value; +} + +std::string +Config::GetDBConfigStrBuildIndexGPU() { + std::string value; + if (!GetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUILD_INDEX_GPU, value).ok()) { + value = GetConfigNode(CONFIG_DB).GetValue(CONFIG_DB_BUILD_INDEX_GPU, + CONFIG_DB_BUILD_INDEX_GPU_DEFAULT); + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUILD_INDEX_GPU, value); + } + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* metric config */ +std::string +Config::GetMetricConfigStrAutoBootup() { + std::string value; + if (!GetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_AUTO_BOOTUP, value).ok()) { + value = GetConfigNode(CONFIG_METRIC).GetValue(CONFIG_METRIC_AUTO_BOOTUP, + CONFIG_METRIC_AUTO_BOOTUP_DEFAULT); + SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_AUTO_BOOTUP, value); + } + return value; +} + +std::string +Config::GetMetricConfigStrCollector() { + std::string value; + if (!GetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_COLLECTOR, value).ok()) { + value = GetConfigNode(CONFIG_METRIC).GetValue(CONFIG_METRIC_COLLECTOR, + CONFIG_METRIC_COLLECTOR_DEFAULT); + SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_COLLECTOR, value); + } + return value; +} + +std::string +Config::GetMetricConfigStrPrometheusPort() { + std::string value; + if (!GetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_PROMETHEUS_PORT, value).ok()) { + value = GetConfigNode(CONFIG_METRIC).GetValue(CONFIG_METRIC_PROMETHEUS_PORT, + CONFIG_METRIC_PROMETHEUS_PORT_DEFAULT); + SetConfigValueInMem(CONFIG_METRIC, CONFIG_METRIC_PROMETHEUS_PORT, value); + } + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* cache config */ +std::string +Config::GetCacheConfigStrCpuMemCapacity() { + std::string value; + if (!GetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_MEM_CAPACITY, value).ok()) { + value = GetConfigNode(CONFIG_CACHE).GetValue(CONFIG_CACHE_CPU_MEM_CAPACITY, + CONFIG_CACHE_CPU_MEM_CAPACITY_DEFAULT); + SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_MEM_CAPACITY, value); + } + return value; +} + +std::string +Config::GetCacheConfigStrCpuMemThreshold() { + std::string value; + if (!GetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_MEM_THRESHOLD, value).ok()) { + value = GetConfigNode(CONFIG_CACHE).GetValue(CONFIG_CACHE_CPU_MEM_THRESHOLD, + CONFIG_CACHE_CPU_MEM_THRESHOLD_DEFAULT); + SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CPU_MEM_THRESHOLD, value); + } + return value; +} + +std::string +Config::GetCacheConfigStrGpuMemCapacity() { + std::string value; + if (!GetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_MEM_CAPACITY, value).ok()) { + value = GetConfigNode(CONFIG_CACHE).GetValue(CONFIG_CACHE_GPU_MEM_CAPACITY, + CONFIG_CACHE_GPU_MEM_CAPACITY_DEFAULT); + SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_MEM_CAPACITY, value); + } + return value; +} + +std::string +Config::GetCacheConfigStrGpuMemThreshold() { + std::string value; + if (!GetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_MEM_THRESHOLD, value).ok()) { + value = GetConfigNode(CONFIG_CACHE).GetValue(CONFIG_CACHE_GPU_MEM_THRESHOLD, + CONFIG_CACHE_GPU_MEM_THRESHOLD_DEFAULT); + SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_GPU_MEM_THRESHOLD, value); + } + return value; +} + +std::string +Config::GetCacheConfigStrCacheInsertData() { + std::string value; + if (!GetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CACHE_INSERT_DATA, value).ok()) { + value = GetConfigNode(CONFIG_CACHE).GetValue(CONFIG_CACHE_CACHE_INSERT_DATA, + CONFIG_CACHE_CACHE_INSERT_DATA_DEFAULT); + SetConfigValueInMem(CONFIG_CACHE, CONFIG_CACHE_CACHE_INSERT_DATA, value); + } + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* engine config */ +std::string +Config::GetEngineConfigStrBlasThreshold() { + std::string value; + if (!GetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_BLAS_THRESHOLD, value).ok()) { + value = GetConfigNode(CONFIG_ENGINE).GetValue(CONFIG_ENGINE_BLAS_THRESHOLD, + CONFIG_ENGINE_BLAS_THRESHOLD_DEFAULT); + SetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_BLAS_THRESHOLD, value); + } + return value; +} + +std::string +Config::GetEngineConfigStrOmpThreadNum() { + std::string value; + if (!GetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_OMP_THREAD_NUM, value).ok()) { + value = GetConfigNode(CONFIG_ENGINE).GetValue(CONFIG_ENGINE_OMP_THREAD_NUM, + CONFIG_ENGINE_OMP_THREAD_NUM_DEFAULT); + SetConfigValueInMem(CONFIG_ENGINE, CONFIG_ENGINE_OMP_THREAD_NUM, value); + } + return value; +} + +//////////////////////////////////////////////////////////////////////////////// +/* resource config */ +std::string +Config::GetResourceConfigStrMode() { + std::string value; + if (!GetConfigValueInMem(CONFIG_RESOURCE, CONFIG_RESOURCE_MODE, value).ok()) { + value = GetConfigNode(CONFIG_RESOURCE).GetValue(CONFIG_RESOURCE_MODE, + CONFIG_RESOURCE_MODE_DEFAULT); + SetConfigValueInMem(CONFIG_RESOURCE, CONFIG_RESOURCE_MODE, value); + } + return value; +} + + +//////////////////////////////////////////////////////////////////////////////// +Status +Config::GetServerConfigAddress(std::string& value) { + value = GetServerConfigStrAddress(); + return CheckServerConfigAddress(value); +} + +Status +Config::GetServerConfigPort(std::string& value) { + value = GetServerConfigStrPort(); + return CheckServerConfigPort(value); +} + +Status +Config::GetServerConfigMode(std::string& value) { + value = GetServerConfigStrMode(); + return CheckServerConfigMode(value); +} + +Status +Config::GetServerConfigTimeZone(std::string& value) { + value = GetServerConfigStrTimeZone(); + return CheckServerConfigTimeZone(value); +} + +Status +Config::GetDBConfigPath(std::string& value) { + value = GetDBConfigStrPath(); + return CheckDBConfigPath(value); +} + +Status +Config::GetDBConfigSlavePath(std::string& value) { + value = GetDBConfigStrSlavePath(); + return Status::OK(); +} + +Status +Config::GetDBConfigBackendUrl(std::string& value) { + value = GetDBConfigStrBackendUrl(); + return CheckDBConfigBackendUrl(value); +} + +Status +Config::GetDBConfigArchiveDiskThreshold(int32_t& value) { + std::string str = GetDBConfigStrArchiveDiskThreshold(); + Status s = CheckDBConfigArchiveDiskThreshold(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetDBConfigArchiveDaysThreshold(int32_t& value) { + std::string str = GetDBConfigStrArchiveDaysThreshold(); + Status s = CheckDBConfigArchiveDaysThreshold(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetDBConfigBufferSize(int32_t& value) { + std::string str = GetDBConfigStrBufferSize(); + Status s = CheckDBConfigBufferSize(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetDBConfigBuildIndexGPU(int32_t& value) { + std::string str = GetDBConfigStrBuildIndexGPU(); + Status s = CheckDBConfigBuildIndexGPU(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetMetricConfigAutoBootup(bool& value) { + std::string str = GetMetricConfigStrAutoBootup(); + Status s = CheckMetricConfigPrometheusPort(str); + if (!s.ok()) return s; + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + value = (str == "true" || str == "on" || str == "yes" || str == "1"); + return Status::OK(); +} + +Status +Config::GetMetricConfigCollector(std::string& value) { + value = GetMetricConfigStrCollector(); + return Status::OK(); +} + +Status +Config::GetMetricConfigPrometheusPort(std::string& value) { + value = GetMetricConfigStrPrometheusPort(); + return CheckMetricConfigPrometheusPort(value); +} + +Status +Config::GetCacheConfigCpuMemCapacity(int32_t& value) { + std::string str = GetCacheConfigStrCpuMemCapacity(); + Status s = CheckCacheConfigCpuMemCapacity(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetCacheConfigCpuMemThreshold(float& value) { + std::string str = GetCacheConfigStrCpuMemThreshold(); + Status s = CheckCacheConfigCpuMemThreshold(str); + if (!s.ok()) return s; + value = std::stof(str); + return Status::OK(); +} + +Status +Config::GetCacheConfigGpuMemCapacity(int32_t& value) { + std::string str = GetCacheConfigStrGpuMemCapacity(); + Status s = CheckCacheConfigGpuMemCapacity(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetCacheConfigGpuMemThreshold(float& value) { + std::string str = GetCacheConfigStrGpuMemThreshold(); + Status s = CheckCacheConfigGpuMemThreshold(str); + if (!s.ok()) return s; + value = std::stof(str); + return Status::OK(); +} + +Status +Config::GetCacheConfigCacheInsertData(bool& value) { + std::string str = GetCacheConfigStrCacheInsertData(); + Status s = CheckCacheConfigCacheInsertData(str); + if (!s.ok()) return s; + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + value = (str == "true" || str == "on" || str == "yes" || str == "1"); + return Status::OK(); +} + +Status +Config::GetEngineConfigBlasThreshold(int32_t& value) { + std::string str = GetEngineConfigStrBlasThreshold(); + Status s = CheckEngineConfigBlasThreshold(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetEngineConfigOmpThreadNum(int32_t& value) { + std::string str = GetEngineConfigStrOmpThreadNum(); + Status s = CheckEngineConfigOmpThreadNum(str); + if (!s.ok()) return s; + value = std::stoi(str); + return Status::OK(); +} + +Status +Config::GetResourceConfigMode(std::string& value) { + value = GetResourceConfigStrMode(); + return CheckResourceConfigMode(value); +} + +Status +Config::GetResourceConfigPool(std::vector& value) { + ConfigNode resource_config = GetConfigNode(CONFIG_RESOURCE); + value = resource_config.GetSequence(CONFIG_RESOURCE_POOL); + return CheckResourceConfigPool(value); +} + +/////////////////////////////////////////////////////////////////////////////// +/* server config */ +Status +Config::SetServerConfigAddress(const std::string& value) { + Status s = CheckServerConfigAddress(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_ADDRESS, value); + return Status::OK(); +} + +Status +Config::SetServerConfigPort(const std::string& value) { + Status s = CheckServerConfigPort(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_PORT, value); + return Status::OK(); +} + +Status +Config::SetServerConfigMode(const std::string& value) { + Status s = CheckServerConfigMode(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_MODE, value); + return Status::OK(); +} + +Status +Config::SetServerConfigTimeZone(const std::string& value) { + Status s = CheckServerConfigTimeZone(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_SERVER, CONFIG_SERVER_TIME_ZONE, value); + return Status::OK(); +} + +/* db config */ +Status +Config::SetDBConfigPath(const std::string& value) { + Status s = CheckDBConfigPath(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_PATH, value); + return Status::OK(); +} + +Status +Config::SetDBConfigSlavePath(const std::string& value) { + Status s = CheckDBConfigSlavePath(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_SLAVE_PATH, value); + return Status::OK(); +} + +Status +Config::SetDBConfigBackendUrl(const std::string& value) { + Status s = CheckDBConfigBackendUrl(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BACKEND_URL, value); + return Status::OK(); +} + +Status +Config::SetDBConfigArchiveDiskThreshold(const std::string& value) { + Status s = CheckDBConfigArchiveDiskThreshold(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DISK_THRESHOLD, value); + return Status::OK(); +} + +Status +Config::SetDBConfigArchiveDaysThreshold(const std::string& value) { + Status s = CheckDBConfigArchiveDaysThreshold(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_ARCHIVE_DAYS_THRESHOLD, value); + return Status::OK(); +} + +Status +Config::SetDBConfigBufferSize(const std::string& value) { + Status s = CheckDBConfigBufferSize(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUFFER_SIZE, value); + return Status::OK(); +} + +Status +Config::SetDBConfigBuildIndexGPU(const std::string& value) { + Status s = CheckDBConfigBuildIndexGPU(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_DB_BUILD_INDEX_GPU, value); + return Status::OK(); +} + +/* metric config */ +Status +Config::SetMetricConfigAutoBootup(const std::string& value) { + Status s = CheckMetricConfigAutoBootup(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_METRIC_AUTO_BOOTUP, value); + return Status::OK(); +} + +Status +Config::SetMetricConfigCollector(const std::string& value) { + Status s = CheckMetricConfigCollector(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_METRIC_COLLECTOR, value); + return Status::OK(); +} + +Status +Config::SetMetricConfigPrometheusPort(const std::string& value) { + Status s = CheckMetricConfigPrometheusPort(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_METRIC_PROMETHEUS_PORT, value); + return Status::OK(); +} + +/* cache config */ +Status +Config::SetCacheConfigCpuMemCapacity(const std::string& value) { + Status s = CheckCacheConfigCpuMemCapacity(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_CACHE_CPU_MEM_CAPACITY, value); + return Status::OK(); +} + +Status +Config::SetCacheConfigCpuMemThreshold(const std::string& value) { + Status s = CheckCacheConfigCpuMemThreshold(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_CACHE_CPU_MEM_THRESHOLD, value); + return Status::OK(); +} + +Status +Config::SetCacheConfigGpuMemCapacity(const std::string& value) { + Status s = CheckCacheConfigGpuMemCapacity(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_CACHE_GPU_MEM_CAPACITY, value); + return Status::OK(); +} + +Status +Config::SetCacheConfigGpuMemThreshold(const std::string& value) { + Status s = CheckCacheConfigGpuMemThreshold(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_CACHE_GPU_MEM_THRESHOLD, value); + return Status::OK(); +} + +Status +Config::SetCacheConfigCacheInsertData(const std::string& value) { + Status s = CheckCacheConfigCacheInsertData(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_CACHE_CACHE_INSERT_DATA, value); + return Status::OK(); +} + +/* engine config */ +Status +Config::SetEngineConfigBlasThreshold(const std::string& value) { + Status s = CheckEngineConfigBlasThreshold(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_ENGINE_BLAS_THRESHOLD, value); + return Status::OK(); +} + +Status +Config::SetEngineConfigOmpThreadNum(const std::string& value) { + Status s = CheckEngineConfigOmpThreadNum(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_ENGINE_OMP_THREAD_NUM, value); + return Status::OK(); +} + +/* resource config */ +Status +Config::SetResourceConfigMode(const std::string& value) { + Status s = CheckResourceConfigMode(value); + if (!s.ok()) return s; + SetConfigValueInMem(CONFIG_DB, CONFIG_RESOURCE_MODE, value); + return Status::OK(); +} + +} +} +} diff --git a/cpp/src/server/Config.h b/cpp/src/server/Config.h new file mode 100644 index 0000000000000000000000000000000000000000..956c08100f4b19468e08c848b3b544d2ba3ee94c --- /dev/null +++ b/cpp/src/server/Config.h @@ -0,0 +1,265 @@ +// Licensed to the Apache Software Foundation (ASF) 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. + +#pragma once + +#include +#include +#include "yaml-cpp/yaml.h" +#include "utils/Status.h" +#include "config/ConfigNode.h" + + +namespace zilliz { +namespace milvus { +namespace server { + +/* server config */ +static const char* CONFIG_SERVER = "server_config"; +static const char* CONFIG_SERVER_ADDRESS = "address"; +static const char* CONFIG_SERVER_ADDRESS_DEFAULT = "127.0.0.1"; +static const char* CONFIG_SERVER_PORT = "port"; +static const char* CONFIG_SERVER_PORT_DEFAULT = "19530"; +static const char* CONFIG_SERVER_MODE = "mode"; +static const char* CONFIG_SERVER_MODE_DEFAULT = "single"; +static const char* CONFIG_SERVER_TIME_ZONE = "time_zone"; +static const char* CONFIG_SERVER_TIME_ZONE_DEFAULT = "UTC+8"; + +/* db config */ +static const char* CONFIG_DB = "db_config"; +static const char* CONFIG_DB_PATH = "path"; +static const char* CONFIG_DB_PATH_DEFAULT = "/tmp/milvus"; +static const char* CONFIG_DB_SLAVE_PATH = "slave_path"; +static const char* CONFIG_DB_SLAVE_PATH_DEFAULT = ""; +static const char* CONFIG_DB_BACKEND_URL = "backend_url"; +static const char* CONFIG_DB_BACKEND_URL_DEFAULT = "sqlite://:@:/"; +static const char* CONFIG_DB_ARCHIVE_DISK_THRESHOLD = "archive_disk_threshold"; +static const char* CONFIG_DB_ARCHIVE_DISK_THRESHOLD_DEFAULT = "0"; +static const char* CONFIG_DB_ARCHIVE_DAYS_THRESHOLD = "archive_days_threshold"; +static const char* CONFIG_DB_ARCHIVE_DAYS_THRESHOLD_DEFAULT = "0"; +static const char* CONFIG_DB_BUFFER_SIZE = "buffer_size"; +static const char* CONFIG_DB_BUFFER_SIZE_DEFAULT = "4"; +static const char* CONFIG_DB_BUILD_INDEX_GPU = "build_index_gpu"; +static const char* CONFIG_DB_BUILD_INDEX_GPU_DEFAULT = "0"; + +/* cache config */ +static const char* CONFIG_CACHE = "cache_config"; +static const char* CONFIG_CACHE_CPU_MEM_CAPACITY = "cpu_mem_capacity"; +static const char* CONFIG_CACHE_CPU_MEM_CAPACITY_DEFAULT = "16"; +static const char* CONFIG_CACHE_GPU_MEM_CAPACITY = "gpu_mem_capacity"; +static const char* CONFIG_CACHE_GPU_MEM_CAPACITY_DEFAULT = "0"; +static const char* CONFIG_CACHE_CPU_MEM_THRESHOLD = "cpu_mem_threshold"; +static const char* CONFIG_CACHE_CPU_MEM_THRESHOLD_DEFAULT = "0.85"; +static const char* CONFIG_CACHE_GPU_MEM_THRESHOLD = "gpu_mem_threshold"; +static const char* CONFIG_CACHE_GPU_MEM_THRESHOLD_DEFAULT = "0.85"; +static const char* CONFIG_CACHE_CACHE_INSERT_DATA = "cache_insert_data"; +static const char* CONFIG_CACHE_CACHE_INSERT_DATA_DEFAULT = "false"; + +/* metric config */ +static const char* CONFIG_METRIC = "metric_config"; +static const char* CONFIG_METRIC_AUTO_BOOTUP = "auto_bootup"; +static const char* CONFIG_METRIC_AUTO_BOOTUP_DEFAULT = "false"; +static const char* CONFIG_METRIC_COLLECTOR = "collector"; +static const char* CONFIG_METRIC_COLLECTOR_DEFAULT = "prometheus"; +static const char* CONFIG_METRIC_PROMETHEUS = "prometheus_config"; +static const char* CONFIG_METRIC_PROMETHEUS_PORT = "port"; +static const char* CONFIG_METRIC_PROMETHEUS_PORT_DEFAULT = "8080"; + +/* engine config */ +static const char* CONFIG_ENGINE = "engine_config"; +static const char* CONFIG_ENGINE_BLAS_THRESHOLD = "blas_threshold"; +static const char* CONFIG_ENGINE_BLAS_THRESHOLD_DEFAULT = "20"; +static const char* CONFIG_ENGINE_OMP_THREAD_NUM = "omp_thread_num"; +static const char* CONFIG_ENGINE_OMP_THREAD_NUM_DEFAULT = "0"; + +/* resource config */ +static const char* CONFIG_RESOURCE = "resource_config"; +static const char* CONFIG_RESOURCE_MODE = "mode"; +static const char* CONFIG_RESOURCE_MODE_DEFAULT = "simple"; +static const char* CONFIG_RESOURCE_POOL = "pool"; + + +class Config { + public: + static Config& GetInstance(); + Status LoadConfigFile(const std::string& filename); + void PrintAll(); + + private: + ConfigNode& GetConfigNode(const std::string& name); + + Status GetConfigValueInMem(const std::string& parent_key, + const std::string& child_key, + std::string& value); + + void SetConfigValueInMem(const std::string& parent_key, + const std::string& child_key, + const std::string& value); + + void PrintConfigSection(const std::string& config_node_name); + + /////////////////////////////////////////////////////////////////////////// + /* server config */ + Status CheckServerConfigAddress(const std::string& value); + Status CheckServerConfigPort(const std::string& value); + Status CheckServerConfigMode(const std::string& value); + Status CheckServerConfigTimeZone(const std::string& value); + + /* db config */ + Status CheckDBConfigPath(const std::string& value); + Status CheckDBConfigSlavePath(const std::string& value); + Status CheckDBConfigBackendUrl(const std::string& value); + Status CheckDBConfigArchiveDiskThreshold(const std::string& value); + Status CheckDBConfigArchiveDaysThreshold(const std::string& value); + Status CheckDBConfigBufferSize(const std::string& value); + Status CheckDBConfigBuildIndexGPU(const std::string& value); + + /* metric config */ + Status CheckMetricConfigAutoBootup(const std::string& value); + Status CheckMetricConfigCollector(const std::string& value); + Status CheckMetricConfigPrometheusPort(const std::string& value); + + /* cache config */ + Status CheckCacheConfigCpuMemCapacity(const std::string& value); + Status CheckCacheConfigCpuMemThreshold(const std::string& value); + Status CheckCacheConfigGpuMemCapacity(const std::string& value); + Status CheckCacheConfigGpuMemThreshold(const std::string& value); + Status CheckCacheConfigCacheInsertData(const std::string& value); + + /* engine config */ + Status CheckEngineConfigBlasThreshold(const std::string& value); + Status CheckEngineConfigOmpThreadNum(const std::string& value); + + /* resource config */ + Status CheckResourceConfigMode(const std::string& value); + Status CheckResourceConfigPool(const std::vector& value); + + /////////////////////////////////////////////////////////////////////////// + /* server config */ + std::string GetServerConfigStrAddress(); + std::string GetServerConfigStrPort(); + std::string GetServerConfigStrMode(); + std::string GetServerConfigStrTimeZone(); + + /* db config */ + std::string GetDBConfigStrPath(); + std::string GetDBConfigStrSlavePath(); + std::string GetDBConfigStrBackendUrl(); + std::string GetDBConfigStrArchiveDiskThreshold(); + std::string GetDBConfigStrArchiveDaysThreshold(); + std::string GetDBConfigStrBufferSize(); + std::string GetDBConfigStrBuildIndexGPU(); + + /* metric config */ + std::string GetMetricConfigStrAutoBootup(); + std::string GetMetricConfigStrCollector(); + std::string GetMetricConfigStrPrometheusPort(); + + /* cache config */ + std::string GetCacheConfigStrCpuMemCapacity(); + std::string GetCacheConfigStrCpuMemThreshold(); + std::string GetCacheConfigStrGpuMemCapacity(); + std::string GetCacheConfigStrGpuMemThreshold(); + std::string GetCacheConfigStrCacheInsertData(); + + /* engine config */ + std::string GetEngineConfigStrBlasThreshold(); + std::string GetEngineConfigStrOmpThreadNum(); + + /* resource config */ + std::string GetResourceConfigStrMode(); + + public: + /* server config */ + Status GetServerConfigAddress(std::string& value); + Status GetServerConfigPort(std::string& value); + Status GetServerConfigMode(std::string& value); + Status GetServerConfigTimeZone(std::string& value); + + /* db config */ + Status GetDBConfigPath(std::string& value); + Status GetDBConfigSlavePath(std::string& value); + Status GetDBConfigBackendUrl(std::string& value); + Status GetDBConfigArchiveDiskThreshold(int32_t& value); + Status GetDBConfigArchiveDaysThreshold(int32_t& value); + Status GetDBConfigBufferSize(int32_t& value); + Status GetDBConfigBuildIndexGPU(int32_t& value); + + /* metric config */ + Status GetMetricConfigAutoBootup(bool& value); + Status GetMetricConfigCollector(std::string& value); + Status GetMetricConfigPrometheusPort(std::string& value); + + /* cache config */ + Status GetCacheConfigCpuMemCapacity(int32_t& value); + Status GetCacheConfigCpuMemThreshold(float& value); + Status GetCacheConfigGpuMemCapacity(int32_t& value); + Status GetCacheConfigGpuMemThreshold(float& value); + Status GetCacheConfigCacheInsertData(bool& value); + + /* engine config */ + Status GetEngineConfigBlasThreshold(int32_t& value); + Status GetEngineConfigOmpThreadNum(int32_t& value); + + /* resource config */ + Status GetResourceConfigMode(std::string& value); + Status GetResourceConfigPool(std::vector& value); + + public: + /* server config */ + Status SetServerConfigAddress(const std::string& value); + Status SetServerConfigPort(const std::string& value); + Status SetServerConfigMode(const std::string& value); + Status SetServerConfigTimeZone(const std::string& value); + + /* db config */ + Status SetDBConfigPath(const std::string& value); + Status SetDBConfigSlavePath(const std::string& value); + Status SetDBConfigBackendUrl(const std::string& value); + Status SetDBConfigArchiveDiskThreshold(const std::string& value); + Status SetDBConfigArchiveDaysThreshold(const std::string& value); + Status SetDBConfigBufferSize(const std::string& value); + Status SetDBConfigBuildIndexGPU(const std::string& value); + + /* metric config */ + Status SetMetricConfigAutoBootup(const std::string& value); + Status SetMetricConfigCollector(const std::string& value); + Status SetMetricConfigPrometheusPort(const std::string& value); + + /* cache config */ + Status SetCacheConfigCpuMemCapacity(const std::string& value); + Status SetCacheConfigCpuMemThreshold(const std::string& value); + Status SetCacheConfigGpuMemCapacity(const std::string& value); + Status SetCacheConfigGpuMemThreshold(const std::string& value); + Status SetCacheConfigCacheInsertData(const std::string& value); + + /* engine config */ + Status SetEngineConfigBlasThreshold(const std::string& value); + Status SetEngineConfigOmpThreadNum(const std::string& value); + + /* resource config */ + Status SetResourceConfigMode(const std::string& value); + + private: + std::unordered_map> config_map_; + std::mutex mutex_; +}; + +} +} +} + diff --git a/cpp/src/server/DBWrapper.cpp b/cpp/src/server/DBWrapper.cpp index e7767aac1c2fec8f5bd326ffad21baabf31c9524..16b13a1249dff4fff281eada993590a34530b235 100644 --- a/cpp/src/server/DBWrapper.cpp +++ b/cpp/src/server/DBWrapper.cpp @@ -17,7 +17,7 @@ #include "DBWrapper.h" -#include "ServerConfig.h" +#include "Config.h" #include "db/DBFactory.h" #include "utils/CommonUtil.h" #include "utils/Log.h" @@ -35,22 +35,34 @@ DBWrapper::DBWrapper() { } Status DBWrapper::StartService() { + Config& config = Config::GetInstance(); + Status s; //db config engine::DBOptions opt; - ConfigNode& db_config = ServerConfig::GetInstance().GetConfig(CONFIG_DB); - opt.meta_.backend_uri_ = db_config.GetValue(CONFIG_DB_URL); - std::string db_path = db_config.GetValue(CONFIG_DB_PATH); - opt.meta_.path_ = db_path + "/db"; - std::string db_slave_path = db_config.GetValue(CONFIG_DB_SLAVE_PATH); + s = config.GetDBConfigBackendUrl(opt.meta_.backend_uri_); + if (!s.ok()) return s; + + std::string path; + s = config.GetDBConfigPath(path); + if (!s.ok()) return s; + + opt.meta_.path_ = path + "/db"; + + std::string db_slave_path; + s = config.GetDBConfigSlavePath(db_slave_path); + if (!s.ok()) return s; + StringHelpFunctions::SplitStringByDelimeter(db_slave_path, ";", opt.meta_.slave_paths_); // cache config - ConfigNode& cache_config = ServerConfig::GetInstance().GetConfig(CONFIG_CACHE); - opt.insert_cache_immediately_ = cache_config.GetBoolValue(CONFIG_INSERT_CACHE_IMMEDIATELY, false); + s = config.GetCacheConfigCacheInsertData(opt.insert_cache_immediately_); + if (!s.ok()) return s; + + std::string mode; + s = config.GetServerConfigMode(mode); + if (!s.ok()) return s; - ConfigNode& serverConfig = ServerConfig::GetInstance().GetConfig(CONFIG_SERVER); - std::string mode = serverConfig.GetValue(CONFIG_CLUSTER_MODE, "single"); if (mode == "single") { opt.mode_ = engine::DBOptions::MODE::SINGLE; } @@ -66,9 +78,10 @@ Status DBWrapper::StartService() { } // engine config - ConfigNode& engine_config = ServerConfig::GetInstance().GetConfig(CONFIG_ENGINE); - int32_t omp_thread = engine_config.GetInt32Value(CONFIG_OMP_THREAD_NUM, 0); - if(omp_thread > 0) { + int32_t omp_thread; + s = config.GetEngineConfigOmpThreadNum(omp_thread); + if (!s.ok()) return s; + if (omp_thread > 0) { omp_set_num_threads(omp_thread); SERVER_LOG_DEBUG << "Specify openmp thread number: " << omp_thread; } else { @@ -79,16 +92,24 @@ Status DBWrapper::StartService() { } } - faiss::distance_compute_blas_threshold = engine_config.GetInt32Value(CONFIG_DCBT, 20);//init faiss global variable + //init faiss global variable + int32_t blas_threshold; + s = config.GetEngineConfigBlasThreshold(blas_threshold); + if (!s.ok()) return s; + faiss::distance_compute_blas_threshold = blas_threshold; //set archive config engine::ArchiveConf::CriteriaT criterial; - int64_t disk = db_config.GetInt64Value(CONFIG_DB_ARCHIVE_DISK, 0); - int64_t days = db_config.GetInt64Value(CONFIG_DB_ARCHIVE_DAYS, 0); - if(disk > 0) { + int32_t disk, days; + s = config.GetDBConfigArchiveDiskThreshold(disk); + if (!s.ok()) return s; + if (disk > 0) { criterial[engine::ARCHIVE_CONF_DISK] = disk; } - if(days > 0) { + + s = config.GetDBConfigArchiveDaysThreshold(days); + if (!s.ok()) return s; + if (days > 0) { criterial[engine::ARCHIVE_CONF_DAYS] = days; } opt.meta_.archive_conf_.SetCriterias(criterial); diff --git a/cpp/src/server/Server.cpp b/cpp/src/server/Server.cpp index 8dacf04d41cdb9e15281f2cb4309e0d559a94fc6..57081845a51bc382eac14850de4466a0555e3a04 100644 --- a/cpp/src/server/Server.cpp +++ b/cpp/src/server/Server.cpp @@ -16,14 +16,6 @@ // under the License. #include -#include "Server.h" -#include "server/grpc_impl/GrpcServer.h" -#include "utils/Log.h" -#include "utils/LogUtil.h" -#include "utils/SignalUtil.h" -#include "utils/TimeRecorder.h" -#include "metrics/Metrics.h" - #include #include #include @@ -31,10 +23,17 @@ //#include #include #include -#include -#include "src/wrapper/KnowhereResource.h" +#include "Server.h" +#include "server/grpc_impl/GrpcServer.h" +#include "server/Config.h" +#include "utils/Log.h" +#include "utils/LogUtil.h" +#include "utils/SignalUtil.h" +#include "utils/TimeRecorder.h" #include "metrics/Metrics.h" +#include "scheduler/SchedInst.h" +#include "wrapper/KnowhereResource.h" #include "DBWrapper.h" @@ -43,18 +42,11 @@ namespace milvus { namespace server { Server & -Server::Instance() { +Server::GetInstance() { static Server server; return server; } -Server::Server() { - -} -Server::~Server() { - -} - void Server::Init(int64_t daemonized, const std::string &pid_filename, @@ -168,10 +160,14 @@ Server::Start() { } /* log path is defined in Config file, so InitLog must be called after LoadConfig */ - ServerConfig &config = ServerConfig::GetInstance(); - ConfigNode server_config = config.GetConfig(CONFIG_SERVER); + Config &config = Config::GetInstance(); + std::string time_zone; + Status s = config.GetServerConfigTimeZone(time_zone); + if (!s.ok()) { + std::cerr << "Fail to get server config timezone" << std::endl; + return; + } - std::string time_zone = server_config.GetValue(CONFIG_TIME_ZONE, "UTC+8"); if (time_zone.length() == 3) { time_zone = "CUT"; } else { @@ -239,13 +235,12 @@ Server::Stop() { ErrorCode Server::LoadConfig() { - ServerConfig::GetInstance().LoadConfigFile(config_filename_); - auto status = ServerConfig::GetInstance().ValidateConfig(); - if (!status.ok()) { + Config& config = Config::GetInstance(); + Status s = config.LoadConfigFile(config_filename_); + if (!s.ok()) { std::cerr << "Failed to load config file: " << config_filename_ << std::endl; exit(0); } - return SERVER_SUCCESS; } diff --git a/cpp/src/server/Server.h b/cpp/src/server/Server.h index 710170f8e9b4924120a0a068382436fc75e0710b..8507552b75ee7b0e9baef2c2df15b139fbb529de 100644 --- a/cpp/src/server/Server.h +++ b/cpp/src/server/Server.h @@ -29,7 +29,7 @@ namespace server { class Server { public: - static Server &Instance(); + static Server &GetInstance(); void Init(int64_t daemonized, const std::string &pid_filename, @@ -40,8 +40,8 @@ class Server { void Stop(); private: - Server(); - ~Server(); + Server() = default; + ~Server() = default; void Daemonize(); diff --git a/cpp/src/server/ServerConfig.cpp b/cpp/src/server/ServerConfig.cpp deleted file mode 100644 index 687490cf5e4e4cf5ec492bc9c69289dbb881f3fc..0000000000000000000000000000000000000000 --- a/cpp/src/server/ServerConfig.cpp +++ /dev/null @@ -1,625 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) 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. - -#include "ServerConfig.h" - -#include -#include -#include -#include -#include - -#include "config/ConfigMgr.h" -#include "utils/CommonUtil.h" -#include "utils/ValidationUtil.h" - - -namespace zilliz { -namespace milvus { -namespace server { - -constexpr uint64_t MB = 1024 * 1024; -constexpr uint64_t GB = MB * 1024; - -ServerConfig & -ServerConfig::GetInstance() { - static ServerConfig config; - return config; -} - -Status -ServerConfig::LoadConfigFile(const std::string &config_filename) { - std::string filename = config_filename; - if (filename.empty()) { - std::cerr << "ERROR: a config file is required" << std::endl; - exit(1);//directly exit program if config file not specified - } - struct stat directoryStat; - int statOK = stat(filename.c_str(), &directoryStat); - if (statOK != 0) { - std::cerr << "ERROR: " << filename << " not found!" << std::endl; - exit(1);//directly exit program if config file not found - } - - try { - ConfigMgr *mgr = const_cast(ConfigMgr::GetInstance()); - ErrorCode err = mgr->LoadConfigFile(filename); - if (err != 0) { - std::cerr << "Server failed to load config file" << std::endl; - exit(1);//directly exit program if the config file is illegal - } - } - catch (YAML::Exception &e) { - std::cerr << "Server failed to load config file: " << std::endl; - exit(1);//directly exit program if the config file is illegal - } - - return Status::OK(); -} - -Status -ServerConfig::ValidateConfig() { - - bool okay = true; - if (!CheckServerConfig().ok()) { - okay = false; - } - if (!CheckDBConfig().ok()) { - okay = false; - } - if (!CheckMetricConfig().ok()) { - okay = false; - } - if (!CheckCacheConfig().ok()) { - okay = false; - } - if (!CheckEngineConfig().ok()) { - okay = false; - } - if (!CheckResourceConfig().ok()) { - okay = false; - } - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Config validation not pass")); -} - -Status -ServerConfig::CheckServerConfig() { -/* - server_config: - address: 0.0.0.0 # milvus server ip address (IPv4) - port: 19530 # the port milvus listen to, default: 19530, range: 1025 ~ 65534 - mode: single # milvus deployment type: single, cluster, read_only - time_zone: UTC+8 # Use the UTC-x or UTC+x to specify a time zone. eg. UTC+8 for China Standard Time - -*/ - bool okay = true; - ConfigNode server_config = GetConfig(CONFIG_SERVER); - - std::string ip_address = server_config.GetValue(CONFIG_SERVER_ADDRESS, "127.0.0.1"); - if (!ValidationUtil::ValidateIpAddress(ip_address).ok()) { - std::cerr << "ERROR: invalid server IP address: " << ip_address << std::endl; - okay = false; - } - - std::string port_str = server_config.GetValue(CONFIG_SERVER_PORT, "19530"); - if (!ValidationUtil::ValidateStringIsNumber(port_str).ok()) { - std::cerr << "ERROR: port " << port_str << " is not a number" << std::endl; - okay = false; - } else { - int32_t port = std::stol(port_str); - if (port < 1025 | port > 65534) { - std::cerr << "ERROR: port " << port_str << " out of range [1025, 65534]" << std::endl; - okay = false; - } - } - - std::string mode = server_config.GetValue(CONFIG_CLUSTER_MODE, "single"); - if (mode != "single" && mode != "cluster" && mode != "read_only") { - std::cerr << "ERROR: mode " << mode << " is not one of ['single', 'cluster', 'read_only']" << std::endl; - okay = false; - } - - std::string time_zone = server_config.GetValue(CONFIG_TIME_ZONE, "UTC+8"); - int flag = 0; - if(time_zone.length() < 3) - flag = 1; - else if(time_zone.substr(0, 3) != "UTC") - flag = 1; - else if(time_zone.length() > 3){ - try { - stoi(time_zone.substr(3, std::string::npos)); - } - catch (std::invalid_argument &) { - flag = 1; - } - } - if(flag == 1){ - std::cerr << "ERROR: time_zone " << time_zone << " is not in a right format" << std::endl; - okay = false; - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Server config is illegal")); -} - -Status -ServerConfig::CheckDBConfig() { -/* - db_config: - db_path: @MILVUS_DB_PATH@ # milvus data storage path - db_slave_path: # secondry data storage path, split by semicolon - - # URI format: dialect://username:password@host:port/database - # All parts except dialect are optional, but you MUST include the delimiters - # Currently dialect supports mysql or sqlite - db_backend_url: sqlite://:@:/ - - archive_disk_threshold: 0 # triger archive action if storage size exceed this value, 0 means no limit, unit: GB - archive_days_threshold: 0 # files older than x days will be archived, 0 means no limit, unit: day - insert_buffer_size: 4 # maximum insert buffer size allowed, default: 4, unit: GB, should be at least 1 GB. - # the sum of insert_buffer_size and cpu_cache_capacity should be less than total memory, unit: GB - build_index_gpu: 0 # which gpu is used to build index, default: 0, range: 0 ~ gpu number - 1 -*/ - bool okay = true; - ConfigNode db_config = GetConfig(CONFIG_DB); - - std::string db_path = db_config.GetValue(CONFIG_DB_PATH); - if (db_path.empty()) { - std::cerr << "ERROR: db_path is empty" << std::endl; - okay = false; - } - - std::string db_backend_url = db_config.GetValue(CONFIG_DB_URL); - if (!ValidationUtil::ValidateDbURI(db_backend_url).ok()) { - std::cerr << "ERROR: invalid db_backend_url: " << db_backend_url << std::endl; - okay = false; - } - - std::string archive_disk_threshold_str = db_config.GetValue(CONFIG_DB_INSERT_BUFFER_SIZE, "0"); - if (!ValidationUtil::ValidateStringIsNumber(archive_disk_threshold_str).ok()) { - std::cerr << "ERROR: archive_disk_threshold " << archive_disk_threshold_str << " is not a number" << std::endl; - okay = false; - } - - std::string archive_days_threshold_str = db_config.GetValue(CONFIG_DB_INSERT_BUFFER_SIZE, "0"); - if (!ValidationUtil::ValidateStringIsNumber(archive_days_threshold_str).ok()) { - std::cerr << "ERROR: archive_days_threshold " << archive_days_threshold_str << " is not a number" << std::endl; - okay = false; - } - - std::string insert_buffer_size_str = db_config.GetValue(CONFIG_DB_INSERT_BUFFER_SIZE, "4"); - if (!ValidationUtil::ValidateStringIsNumber(insert_buffer_size_str).ok()) { - std::cerr << "ERROR: insert_buffer_size " << insert_buffer_size_str << " is not a number" << std::endl; - okay = false; - } - else { - uint64_t insert_buffer_size = (uint64_t) std::stol(insert_buffer_size_str); - insert_buffer_size *= GB; - unsigned long total_mem = 0, free_mem = 0; - CommonUtil::GetSystemMemInfo(total_mem, free_mem); - if (insert_buffer_size >= total_mem) { - std::cerr << "ERROR: insert_buffer_size exceed system memory" << std::endl; - okay = false; - } - } - - std::string gpu_index_str = db_config.GetValue(CONFIG_DB_BUILD_INDEX_GPU, "0"); - if (!ValidationUtil::ValidateStringIsNumber(gpu_index_str).ok()) { - std::cerr << "ERROR: gpu_index " << gpu_index_str << " is not a number" << std::endl; - okay = false; - } else { - int32_t gpu_index = std::stol(gpu_index_str); - if (!ValidationUtil::ValidateGpuIndex(gpu_index).ok()) { - std::cerr << "ERROR: invalid gpu_index " << gpu_index_str << std::endl; - okay = false; - } - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "DB config is illegal")); -} - -Status -ServerConfig::CheckMetricConfig() { -/* - metric_config: - is_startup: off # if monitoring start: on, off - collector: prometheus # metrics collector: prometheus - prometheus_config: # following are prometheus configure - port: 8080 # the port prometheus use to fetch metrics - (not used) push_gateway_ip_address: 127.0.0.1 # push method configure: push gateway ip address - (not used) push_gateway_port: 9091 # push method configure: push gateway port -*/ - bool okay = true; - ConfigNode metric_config = GetConfig(CONFIG_METRIC); - - std::string is_startup_str = metric_config.GetValue(CONFIG_METRIC_IS_STARTUP, "off"); - if (!ValidationUtil::ValidateStringIsBool(is_startup_str).ok()) { - std::cerr << "ERROR: invalid is_startup config: " << is_startup_str << std::endl; - okay = false; - } - - std::string port_str = metric_config.GetChild(CONFIG_PROMETHEUS).GetValue(CONFIG_METRIC_PROMETHEUS_PORT, "8080"); - if (!ValidationUtil::ValidateStringIsNumber(port_str).ok()) { - std::cerr << "ERROR: port specified in prometheus_config " << port_str << " is not a number" << std::endl; - okay = false; - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Metric config is illegal")); -} - -Status -ServerConfig::CheckCacheConfig() { -/* - cache_config: - cpu_cache_capacity: 16 # how many memory are used as cache, unit: GB, range: 0 ~ less than total memory - cpu_cache_free_percent: 0.85 # old data will be erased from cache when cache is full, this value specify how much memory should be kept, range: greater than zero ~ 1.0 - insert_cache_immediately: false # insert data will be load into cache immediately for hot query - gpu_cache_capacity: 5 # how many memory are used as cache in gpu, unit: GB, RANGE: 0 ~ less than total memory - gpu_cache_free_percent: 0.85 # old data will be erased from cache when cache is full, this value specify how much memory should be kept, range: greater than zero ~ 1.0 - -*/ - bool okay = true; - ConfigNode cache_config = GetConfig(CONFIG_CACHE); - - std::string cpu_cache_capacity_str = cache_config.GetValue(CONFIG_CPU_CACHE_CAPACITY, "16"); - if (!ValidationUtil::ValidateStringIsNumber(cpu_cache_capacity_str).ok()) { - std::cerr << "ERROR: cpu_cache_capacity " << cpu_cache_capacity_str << " is not a number" << std::endl; - okay = false; - } - else { - uint64_t cpu_cache_capacity = (uint64_t) std::stol(cpu_cache_capacity_str); - cpu_cache_capacity *= GB; - unsigned long total_mem = 0, free_mem = 0; - CommonUtil::GetSystemMemInfo(total_mem, free_mem); - if (cpu_cache_capacity >= total_mem) { - std::cerr << "ERROR: cpu_cache_capacity exceed system memory" << std::endl; - okay = false; - } - else if (cpu_cache_capacity > (double) total_mem * 0.9) { - std::cerr << "Warning: cpu_cache_capacity value is too aggressive" << std::endl; - } - - uint64_t insert_buffer_size = (uint64_t) GetConfig(CONFIG_DB).GetInt32Value(CONFIG_DB_INSERT_BUFFER_SIZE, 4); - insert_buffer_size *= GB; - if (insert_buffer_size + cpu_cache_capacity >= total_mem) { - std::cerr << "ERROR: sum of cpu_cache_capacity and insert_buffer_size exceed system memory" << std::endl; - okay = false; - } - } - - std::string cpu_cache_free_percent_str = cache_config.GetValue(CACHE_FREE_PERCENT, "0.85"); - double cpu_cache_free_percent; - if (!ValidationUtil::ValidateStringIsDouble(cpu_cache_free_percent_str, cpu_cache_free_percent).ok()) { - std::cerr << "ERROR: cpu_cache_free_percent " << cpu_cache_free_percent_str << " is not a double" << std::endl; - okay = false; - } - else if (cpu_cache_free_percent < std::numeric_limits::epsilon() || cpu_cache_free_percent > 1.0) { - std::cerr << "ERROR: invalid cpu_cache_free_percent " << cpu_cache_free_percent_str << std::endl; - okay = false; - } - - std::string insert_cache_immediately_str = cache_config.GetValue(CONFIG_INSERT_CACHE_IMMEDIATELY, "false"); - if (!ValidationUtil::ValidateStringIsBool(insert_cache_immediately_str).ok()) { - std::cerr << "ERROR: invalid insert_cache_immediately config: " << insert_cache_immediately_str << std::endl; - okay = false; - } - - std::string gpu_cache_capacity_str = cache_config.GetValue(CONFIG_GPU_CACHE_CAPACITY, "0"); - if (!ValidationUtil::ValidateStringIsNumber(gpu_cache_capacity_str).ok()) { - std::cerr << "ERROR: gpu_cache_capacity " << gpu_cache_capacity_str << " is not a number" << std::endl; - okay = false; - } - else { - uint64_t gpu_cache_capacity = (uint64_t) std::stol(gpu_cache_capacity_str); - gpu_cache_capacity *= GB; - int gpu_index = GetConfig(CONFIG_DB).GetInt32Value(CONFIG_DB_BUILD_INDEX_GPU, 0); - size_t gpu_memory; - if (!ValidationUtil::GetGpuMemory(gpu_index, gpu_memory).ok()) { - std::cerr << "ERROR: could not get gpu memory for device " << gpu_index << std::endl; - okay = false; - } - else if (gpu_cache_capacity >= gpu_memory) { - std::cerr << "ERROR: gpu_cache_capacity " << gpu_cache_capacity - << " exceed total gpu memory " << gpu_memory << std::endl; - okay = false; - } - else if (gpu_cache_capacity > (double) gpu_memory * 0.9) { - std::cerr << "Warning: gpu_cache_capacity value is too aggressive" << std::endl; - } - } - - std::string gpu_cache_free_percent_str = cache_config.GetValue(GPU_CACHE_FREE_PERCENT, "0.85"); - double gpu_cache_free_percent; - if (!ValidationUtil::ValidateStringIsDouble(gpu_cache_free_percent_str, gpu_cache_free_percent).ok()) { - std::cerr << "ERROR: gpu_cache_free_percent " << gpu_cache_free_percent_str << " is not a double" << std::endl; - okay = false; - } - else if (gpu_cache_free_percent < std::numeric_limits::epsilon() || gpu_cache_free_percent > 1.0) { - std::cerr << "ERROR: invalid gpu_cache_free_percent " << gpu_cache_free_percent << std::endl; - okay = false; - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Cache config is illegal")); -} - -Status -ServerConfig::CheckEngineConfig() { -/* - engine_config: - use_blas_threshold: 20 - omp_thread_num: 0 # how many compute threads be used by engine, 0 means use all cpu core to compute -*/ - bool okay = true; - ConfigNode engine_config = GetConfig(CONFIG_ENGINE); - - std::string use_blas_threshold_str = engine_config.GetValue(CONFIG_DCBT, "20"); - if (!ValidationUtil::ValidateStringIsNumber(use_blas_threshold_str).ok()) { - std::cerr << "ERROR: use_blas_threshold " << use_blas_threshold_str << " is not a number" << std::endl; - okay = false; - } - - std::string omp_thread_num_str = engine_config.GetValue(CONFIG_OMP_THREAD_NUM, "0"); - if (!ValidationUtil::ValidateStringIsNumber(omp_thread_num_str).ok()) { - std::cerr << "ERROR: omp_thread_num " << omp_thread_num_str << " is not a number" << std::endl; - okay = false; - } else { - int32_t omp_thread = std::stol(omp_thread_num_str); - uint32_t sys_thread_cnt = 8; - if (omp_thread > CommonUtil::GetSystemAvailableThreads(sys_thread_cnt)) { - std::cerr << "ERROR: omp_thread_num " << omp_thread_num_str << " > system available thread " - << sys_thread_cnt << std::endl; - okay = false; - } - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Engine config is illegal")); -} - -Status -ServerConfig::CheckResourceConfig() { - /* - resource_config: - mode: simple - resources: - - cpu - - gpu0 - - gpu100 - */ - bool okay = true; - server::ConfigNode &config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_RESOURCE); - auto mode = config.GetValue("mode", "simple"); - if (mode != "simple") { - std::cerr << "ERROR: invalid resource config: mode is " << mode << std::endl; - okay = false; - } - auto resources = config.GetSequence("resources"); - if (resources.empty()) { - std::cerr << "ERROR: invalid resource config: resources empty" << std::endl; - okay = false; - } - - return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Resource config is illegal")); -} - -//Status -//ServerConfig::CheckResourceConfig() { -/* - resource_config: - # resource list, length: 0~N - # please set a DISK resource and a CPU resource least, or system will not return query result. - # - # example: - # resource_name: # resource name, just using in connections below - # type: DISK # resource type, optional: DISK/CPU/GPU - # device_id: 0 - # enable_executor: false # if is enable executor, optional: true, false - - resources: - ssda: - type: DISK - device_id: 0 - enable_executor: false - - cpu: - type: CPU - device_id: 0 - enable_executor: true - - gpu0: - type: GPU - device_id: 0 - enable_executor: false - gpu_resource_num: 2 - pinned_memory: 300 - temp_memory: 300 - - # connection list, length: 0~N - # example: - # connection_name: - # speed: 100 # unit: MS/s - # endpoint: ${resource_name}===${resource_name} - connections: - io: - speed: 500 - endpoint: ssda===cpu - pcie0: - speed: 11000 - endpoint: cpu===gpu0 -*/ -// bool okay = true; -// server::ConfigNode resource_config = GetConfig(CONFIG_RESOURCE); -// if (resource_config.GetChildren().empty()) { -// std::cerr << "ERROR: no context under resource" << std::endl; -// okay = false; -// } -// -// auto resources = resource_config.GetChild(CONFIG_RESOURCES).GetChildren(); -// -// if (resources.empty()) { -// std::cerr << "no resources specified" << std::endl; -// okay = false; -// } -// -// bool resource_valid_flag = false; -// bool hasDisk = false; -// bool hasCPU = false; -// bool hasExecutor = false; -// std::set resource_list; -// for (auto &resource : resources) { -// resource_list.emplace(resource.first); -// auto &resource_conf = resource.second; -// auto type = resource_conf.GetValue(CONFIG_RESOURCE_TYPE); -// -// std::string device_id_str = resource_conf.GetValue(CONFIG_RESOURCE_DEVICE_ID, "0"); -// int32_t device_id = -1; -// if (!ValidationUtil::ValidateStringIsNumber(device_id_str).ok()) { -// std::cerr << "ERROR: device_id " << device_id_str << " is not a number" << std::endl; -// okay = false; -// } else { -// device_id = std::stol(device_id_str); -// } -// -// std::string enable_executor_str = resource_conf.GetValue(CONFIG_RESOURCE_ENABLE_EXECUTOR, "off"); -// if (!ValidationUtil::ValidateStringIsBool(enable_executor_str).ok()) { -// std::cerr << "ERROR: invalid enable_executor config: " << enable_executor_str << std::endl; -// okay = false; -// } -// -// if (type == "DISK") { -// hasDisk = true; -// } else if (type == "CPU") { -// hasCPU = true; -// if (resource_conf.GetBoolValue(CONFIG_RESOURCE_ENABLE_EXECUTOR, false)) { -// hasExecutor = true; -// } -// } -// else if (type == "GPU") { -// int build_index_gpu_index = GetConfig(CONFIG_DB).GetInt32Value(CONFIG_DB_BUILD_INDEX_GPU, 0); -// if (device_id == build_index_gpu_index) { -// resource_valid_flag = true; -// } -// if (resource_conf.GetBoolValue(CONFIG_RESOURCE_ENABLE_EXECUTOR, false)) { -// hasExecutor = true; -// } -// std::string gpu_resource_num_str = resource_conf.GetValue(CONFIG_RESOURCE_NUM, "2"); -// if (!ValidationUtil::ValidateStringIsNumber(gpu_resource_num_str).ok()) { -// std::cerr << "ERROR: gpu_resource_num " << gpu_resource_num_str << " is not a number" << std::endl; -// okay = false; -// } -// bool mem_valid = true; -// std::string pinned_memory_str = resource_conf.GetValue(CONFIG_RESOURCE_PIN_MEMORY, "300"); -// if (!ValidationUtil::ValidateStringIsNumber(pinned_memory_str).ok()) { -// std::cerr << "ERROR: pinned_memory " << pinned_memory_str << " is not a number" << std::endl; -// okay = false; -// mem_valid = false; -// } -// std::string temp_memory_str = resource_conf.GetValue(CONFIG_RESOURCE_TEMP_MEMORY, "300"); -// if (!ValidationUtil::ValidateStringIsNumber(temp_memory_str).ok()) { -// std::cerr << "ERROR: temp_memory " << temp_memory_str << " is not a number" << std::endl; -// okay = false; -// mem_valid = false; -// } -// if (mem_valid) { -// size_t gpu_memory; -// if (!ValidationUtil::GetGpuMemory(device_id, gpu_memory).ok()) { -// std::cerr << "ERROR: could not get gpu memory for device " << device_id << std::endl; -// okay = false; -// } -// else { -// size_t prealoc_mem = std::stol(pinned_memory_str) + std::stol(temp_memory_str); -// if (prealoc_mem >= gpu_memory) { -// std::cerr << "ERROR: sum of pinned_memory and temp_memory " << prealoc_mem -// << " exceeds total gpu memory " << gpu_memory << " for device " << device_id << std::endl; -// okay = false; -// } -// } -// } -// } -// } -// -// if (!resource_valid_flag) { -// std::cerr << "Building index GPU can't be found in resource config." << std::endl; -// okay = false; -// } -// if (!hasDisk || !hasCPU) { -// std::cerr << "No DISK or CPU resource" << std::endl; -// okay = false; -// } -// if (!hasExecutor) { -// std::cerr << "No CPU or GPU resource has executor enabled" << std::endl; -// okay = false; -// } -// -// auto connections = resource_config.GetChild(CONFIG_RESOURCE_CONNECTIONS).GetChildren(); -// for (auto &connection : connections) { -// auto &connection_conf = connection.second; -// -// std::string speed_str = connection_conf.GetValue(CONFIG_SPEED_CONNECTIONS); -// if (ValidationUtil::ValidateStringIsNumber(speed_str) != SERVER_SUCCESS) { -// std::cerr << "ERROR: speed " << speed_str << " is not a number" << std::endl; -// okay = false; -// } -// -// std::string endpoint_str = connection_conf.GetValue(CONFIG_ENDPOINT_CONNECTIONS); -// std::string delimiter = "==="; -// auto delimiter_pos = endpoint_str.find(delimiter); -// if (delimiter_pos == std::string::npos) { -// std::cerr << "ERROR: invalid endpoint format: " << endpoint_str << std::endl; -// okay = false; -// } else { -// std::string left_resource = endpoint_str.substr(0, delimiter_pos); -// if (resource_list.find(left_resource) == resource_list.end()) { -// std::cerr << "ERROR: left resource " << left_resource << " does not exist" << std::endl; -// okay = false; -// } -// std::string right_resource = endpoint_str.substr(delimiter_pos + delimiter.length(), endpoint_str.length()); -// if (resource_list.find(right_resource) == resource_list.end()) { -// std::cerr << "ERROR: right resource " << right_resource << " does not exist" << std::endl; -// okay = false; -// } -// } -// } -// -// return (okay ? Status::OK() : Status(SERVER_INVALID_ARGUMENT, "Resource config is illegal")); -//} - -void -ServerConfig::PrintAll() const { - if (const ConfigMgr *mgr = ConfigMgr::GetInstance()) { - std::string str = mgr->DumpString(); -// SERVER_LOG_INFO << "\n" << str; - std::cout << "\n" << str << std::endl; - } -} - -ConfigNode -ServerConfig::GetConfig(const std::string &name) const { - const ConfigMgr *mgr = ConfigMgr::GetInstance(); - const ConfigNode &root_node = mgr->GetRootNode(); - return root_node.GetChild(name); -} - -ConfigNode & -ServerConfig::GetConfig(const std::string &name) { - ConfigMgr *mgr = ConfigMgr::GetInstance(); - ConfigNode &root_node = mgr->GetRootNode(); - return root_node.GetChild(name); -} - - -} -} -} diff --git a/cpp/src/server/ServerConfig.h b/cpp/src/server/ServerConfig.h deleted file mode 100644 index d0f3e30d6b4bf9b5acc844af847856d67556a280..0000000000000000000000000000000000000000 --- a/cpp/src/server/ServerConfig.h +++ /dev/null @@ -1,100 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) 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. - -#pragma once - -#include "utils/Status.h" -#include "config/ConfigNode.h" - -#include "yaml-cpp/yaml.h" - -namespace zilliz { -namespace milvus { -namespace server { - -static const char* CONFIG_SERVER = "server_config"; -static const char* CONFIG_SERVER_ADDRESS = "address"; -static const char* CONFIG_SERVER_PORT = "port"; -static const char* CONFIG_CLUSTER_MODE = "mode"; -static const char* CONFIG_TIME_ZONE = "time_zone"; - -static const char* CONFIG_DB = "db_config"; -static const char* CONFIG_DB_URL = "db_backend_url"; -static const char* CONFIG_DB_PATH = "db_path"; -static const char* CONFIG_DB_SLAVE_PATH = "db_slave_path"; -static const char* CONFIG_DB_ARCHIVE_DISK = "archive_disk_threshold"; -static const char* CONFIG_DB_ARCHIVE_DAYS = "archive_days_threshold"; -static const char* CONFIG_DB_INSERT_BUFFER_SIZE = "insert_buffer_size"; -static const char* CONFIG_DB_PARALLEL_REDUCE = "parallel_reduce"; -static const char* CONFIG_DB_BUILD_INDEX_GPU = "build_index_gpu"; - -static const char* CONFIG_LOG = "log_config"; - -static const char* CONFIG_CACHE = "cache_config"; -static const char* CONFIG_CPU_CACHE_CAPACITY = "cpu_cache_capacity"; -static const char* CONFIG_GPU_CACHE_CAPACITY = "gpu_cache_capacity"; -static const char* CACHE_FREE_PERCENT = "cpu_cache_free_percent"; -static const char* CONFIG_INSERT_CACHE_IMMEDIATELY = "insert_cache_immediately"; -static const char *GPU_CACHE_FREE_PERCENT = "gpu_cache_free_percent"; - -static const char* CONFIG_METRIC = "metric_config"; -static const char* CONFIG_METRIC_IS_STARTUP = "is_startup"; -static const char* CONFIG_METRIC_COLLECTOR = "collector"; -static const char* CONFIG_PROMETHEUS = "prometheus_config"; -static const char* CONFIG_METRIC_PROMETHEUS_PORT = "port"; - -static const char* CONFIG_ENGINE = "engine_config"; -static const char* CONFIG_DCBT = "use_blas_threshold"; -static const char* CONFIG_OMP_THREAD_NUM = "omp_thread_num"; - -static const char* CONFIG_RESOURCE = "resource_config"; -static const char* CONFIG_RESOURCES = "resources"; -static const char* CONFIG_RESOURCE_TYPE = "type"; -static const char* CONFIG_RESOURCE_DEVICE_ID = "device_id"; -static const char* CONFIG_RESOURCE_ENABLE_EXECUTOR = "enable_executor"; -static const char* CONFIG_RESOURCE_NUM = "gpu_resource_num"; -static const char* CONFIG_RESOURCE_PIN_MEMORY = "pinned_memory"; -static const char* CONFIG_RESOURCE_TEMP_MEMORY = "temp_memory"; -static const char* CONFIG_RESOURCE_CONNECTIONS = "connections"; -static const char* CONFIG_SPEED_CONNECTIONS = "speed"; -static const char* CONFIG_ENDPOINT_CONNECTIONS = "endpoint"; - - -class ServerConfig { - public: - static ServerConfig &GetInstance(); - - Status LoadConfigFile(const std::string& config_filename); - Status ValidateConfig(); - void PrintAll() const; - - ConfigNode GetConfig(const std::string& name) const; - ConfigNode& GetConfig(const std::string& name); - - private: - Status CheckServerConfig(); - Status CheckDBConfig(); - Status CheckMetricConfig(); - Status CheckCacheConfig(); - Status CheckEngineConfig(); - Status CheckResourceConfig(); -}; - -} -} -} - diff --git a/cpp/src/server/grpc_impl/GrpcRequestTask.cpp b/cpp/src/server/grpc_impl/GrpcRequestTask.cpp index 0a8a84855d53b253a25530c8203f50b2637f692a..111104c4231b2264cf760cb2648d0d3a0a0c38bd 100644 --- a/cpp/src/server/grpc_impl/GrpcRequestTask.cpp +++ b/cpp/src/server/grpc_impl/GrpcRequestTask.cpp @@ -15,8 +15,9 @@ // specific language governing permissions and limitations // under the License. +#include + #include "GrpcRequestTask.h" -#include "../ServerConfig.h" #include "utils/CommonUtil.h" #include "utils/Log.h" #include "utils/TimeRecorder.h" @@ -28,9 +29,8 @@ #include "scheduler/SchedInst.h" //#include -#include "src/server/Server.h" +#include "server/Server.h" -#include namespace zilliz { namespace milvus { diff --git a/cpp/src/server/grpc_impl/GrpcServer.cpp b/cpp/src/server/grpc_impl/GrpcServer.cpp index 4ff7a8200fabca4bcd6b8b490879dbc731b63418..7e209215491bb7e31c7d70143cb147187e1cf16f 100644 --- a/cpp/src/server/grpc_impl/GrpcServer.cpp +++ b/cpp/src/server/grpc_impl/GrpcServer.cpp @@ -17,7 +17,7 @@ #include "milvus.grpc.pb.h" #include "GrpcServer.h" -#include "server/ServerConfig.h" +#include "server/Config.h" #include "server/DBWrapper.h" #include "utils/Log.h" #include "GrpcRequestHandler.h" @@ -73,13 +73,20 @@ GrpcServer::Stop() { Status GrpcServer::StartService() { - ServerConfig &config = ServerConfig::GetInstance(); - ConfigNode server_config = config.GetConfig(CONFIG_SERVER); - ConfigNode engine_config = config.GetConfig(CONFIG_ENGINE); - std::string address = server_config.GetValue(CONFIG_SERVER_ADDRESS, "127.0.0.1"); - int32_t port = server_config.GetInt32Value(CONFIG_SERVER_PORT, 19530); + Config &config = Config::GetInstance(); + std::string address, port; + Status s; - std::string server_address(address + ":" + std::to_string(port)); + s = config.GetServerConfigAddress(address); + if (!s.ok()) { + return s; + } + s = config.GetServerConfigPort(port); + if (!s.ok()) { + return s; + } + + std::string server_address(address + ":" + port); ::grpc::ServerBuilder builder; builder.SetOption(std::unique_ptr<::grpc::ServerBuilderOption>(new NoReusePortOption)); diff --git a/cpp/src/utils/LogUtil.cpp b/cpp/src/utils/LogUtil.cpp index cfdbbdc768e9ab56cdb45ffc2fb0180e8d93f5d0..3a3fe0c7e2b5cac52b848ad066a10a0288425d68 100644 --- a/cpp/src/utils/LogUtil.cpp +++ b/cpp/src/utils/LogUtil.cpp @@ -15,13 +15,11 @@ // specific language governing permissions and limitations // under the License. -#include "LogUtil.h" -#include "server/ServerConfig.h" - #include #include #include +#include "LogUtil.h" namespace zilliz { namespace milvus { diff --git a/cpp/src/utils/SignalUtil.cpp b/cpp/src/utils/SignalUtil.cpp index 6c68f702d20312628308b341e10dd0e7d2adb507..92678cfe6bb58f8e0d6c37e748e89871b2636979 100644 --- a/cpp/src/utils/SignalUtil.cpp +++ b/cpp/src/utils/SignalUtil.cpp @@ -34,7 +34,7 @@ void SignalUtil::HandleSignal(int signum) { case SIGUSR2: { SERVER_LOG_INFO << "Server received signal: " << signum; - server::Server &server = server::Server::Instance(); + server::Server &server = server::Server::GetInstance(); server.Stop(); exit(0); @@ -43,7 +43,7 @@ void SignalUtil::HandleSignal(int signum) { SERVER_LOG_INFO << "Server received critical signal: " << signum; SignalUtil::PrintStacktrace(); - server::Server &server = server::Server::Instance(); + server::Server &server = server::Server::GetInstance(); server.Stop(); exit(1); diff --git a/cpp/src/utils/ValidationUtil.cpp b/cpp/src/utils/ValidationUtil.cpp index c993a4ae14ac10ec31a2ffe1391af8daef38dbec..c9ec2d046b38e068ec5b46fb68b717c4a6c79a9b 100644 --- a/cpp/src/utils/ValidationUtil.cpp +++ b/cpp/src/utils/ValidationUtil.cpp @@ -206,38 +206,40 @@ ValidationUtil::ValidateIpAddress(const std::string &ip_address) { } Status -ValidationUtil::ValidateStringIsNumber(const std::string &string) { - if (!string.empty() && std::all_of(string.begin(), string.end(), ::isdigit)) { - return Status::OK(); +ValidationUtil::ValidateStringIsNumber(const std::string &str) { + if (str.empty() || !std::all_of(str.begin(), str.end(), ::isdigit)) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid number"); } - else { - return Status(SERVER_INVALID_ARGUMENT, "Not a number"); + try { + int32_t value = std::stoi(str); + } catch(...) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid number"); } + return Status::OK(); } Status -ValidationUtil::ValidateStringIsBool(std::string &str) { - std::transform(str.begin(), str.end(), str.begin(), ::tolower); - if (str == "true" || str == "on" || str == "yes" || str == "1" || - str == "false" || str == "off" || str == "no" || str == "0" || - str.empty()) { +ValidationUtil::ValidateStringIsBool(const std::string &str) { + std::string s = str; + std::transform(s.begin(), s.end(), s.begin(), ::tolower); + if (s == "true" || s == "on" || s == "yes" || s == "1" || + s == "false" || s == "off" || s == "no" || s == "0" || + s.empty()) { return Status::OK(); } else { - return Status(SERVER_INVALID_ARGUMENT, "Not a boolean: " + str); + return Status(SERVER_INVALID_ARGUMENT, "Invalid boolean: " + str); } } Status -ValidationUtil::ValidateStringIsDouble(const std::string &str, double &val) { - char *end = nullptr; - val = std::strtod(str.c_str(), &end); - if (end != str.c_str() && *end == '\0' && val != HUGE_VAL) { - return Status::OK(); - } - else { - return Status(SERVER_INVALID_ARGUMENT, "Not a double value: " + str); +ValidationUtil::ValidateStringIsFloat(const std::string &str) { + try { + float val = std::stof(str); + } catch(...) { + return Status(SERVER_INVALID_ARGUMENT, "Invalid float: " + str); } + return Status::OK(); } Status diff --git a/cpp/src/utils/ValidationUtil.h b/cpp/src/utils/ValidationUtil.h index ad8ba5fee9ed3f3521d88b6a8c748eae8b85b30f..789da0de40eae5c08daeb43be9f2f8fc89c36ad2 100644 --- a/cpp/src/utils/ValidationUtil.h +++ b/cpp/src/utils/ValidationUtil.h @@ -67,10 +67,10 @@ public: ValidateStringIsNumber(const std::string &str); static Status - ValidateStringIsBool(std::string &str); + ValidateStringIsBool(const std::string &str); static Status - ValidateStringIsDouble(const std::string &str, double &val); + ValidateStringIsFloat(const std::string &str); static Status ValidateDbURI(const std::string &uri); diff --git a/cpp/src/wrapper/KnowhereResource.cpp b/cpp/src/wrapper/KnowhereResource.cpp index 9c2b4d31e2e948e018d072d1d26ccef43efcf3c7..8ba38a77b09db288277675d123838c6574e7ac39 100644 --- a/cpp/src/wrapper/KnowhereResource.cpp +++ b/cpp/src/wrapper/KnowhereResource.cpp @@ -18,7 +18,7 @@ #include "KnowhereResource.h" #include "knowhere/index/vector_index/helpers/FaissGpuResourceMgr.h" -#include "server/ServerConfig.h" +#include "server/Config.h" #include @@ -37,19 +37,24 @@ KnowhereResource::Initialize() { }; using GpuResourcesArray = std::map; GpuResourcesArray gpu_resources; + Status s; //get build index gpu resource - server::ServerConfig& root_config = server::ServerConfig::GetInstance(); - server::ConfigNode& db_config = root_config.GetConfig(server::CONFIG_DB); + server::Config& config = server::Config::GetInstance(); + + int32_t build_index_gpu; + s = config.GetDBConfigBuildIndexGPU(build_index_gpu); + if (!s.ok()) return s; - int32_t build_index_gpu = db_config.GetInt32Value(server::CONFIG_DB_BUILD_INDEX_GPU, 0); gpu_resources.insert(std::make_pair(build_index_gpu, GpuResourceSetting())); //get search gpu resource - server::ConfigNode& res_config = root_config.GetConfig(server::CONFIG_RESOURCE); - auto resources = res_config.GetSequence("resources"); + std::vector pool; + s = config.GetResourceConfigPool(pool); + if (!s.ok()) return s; + std::set gpu_ids; - for (auto &resource : resources) { + for (auto &resource : pool) { if (resource.length() < 4 || resource.substr(0, 3) != "gpu") { // invalid continue; diff --git a/cpp/unittest/db/engine_test.cpp b/cpp/unittest/db/engine_test.cpp index e06e9038c8e3e80137ea402a2522bbd640a483f2..f55d8d9e27f6eeb51248578f779bec9357e39013 100644 --- a/cpp/unittest/db/engine_test.cpp +++ b/cpp/unittest/db/engine_test.cpp @@ -21,7 +21,6 @@ #include "db/engine/EngineFactory.h" #include "db/engine/ExecutionEngineImpl.h" -#include "server/ServerConfig.h" #include "utils.h" using namespace zilliz::milvus; diff --git a/cpp/unittest/db/search_test.cpp b/cpp/unittest/db/search_test.cpp index b1c83c6db79143c53d8fe1280726ff60cb38e94e..0e8f19949f82006df24af28ef9b5efc1c971e535 100644 --- a/cpp/unittest/db/search_test.cpp +++ b/cpp/unittest/db/search_test.cpp @@ -15,13 +15,12 @@ // specific language governing permissions and limitations // under the License. -#include "server/ServerConfig.h" -#include "utils/TimeRecorder.h" - #include #include #include -#include + +#include "scheduler/task/SearchTask.h" +#include "utils/TimeRecorder.h" using namespace zilliz::milvus; diff --git a/cpp/unittest/main.cpp b/cpp/unittest/main.cpp index 33a860945dfa035354d2e329cd76b7089c669aa5..7a28bbf45ffafc12393dc6ec3d3d00c295fad779 100644 --- a/cpp/unittest/main.cpp +++ b/cpp/unittest/main.cpp @@ -15,13 +15,12 @@ // specific language governing permissions and limitations // under the License. -#include "utils/easylogging++.h" -#include "server/ServerConfig.h" -#include "utils/CommonUtil.h" - #include #include +#include "utils/easylogging++.h" +#include "utils/CommonUtil.h" + INITIALIZE_EASYLOGGINGPP using namespace zilliz::milvus; diff --git a/cpp/unittest/scheduler/schedinst_test.cpp b/cpp/unittest/scheduler/schedinst_test.cpp index 26ecce9f64cfb836e2321d5a76b35159db620ec9..a02e0f1d41a43f479d26562e2d220a0b3f0df626 100644 --- a/cpp/unittest/scheduler/schedinst_test.cpp +++ b/cpp/unittest/scheduler/schedinst_test.cpp @@ -15,12 +15,10 @@ // specific language governing permissions and limitations // under the License. - -#include "scheduler/SchedInst.h" -#include "server/ServerConfig.h" #include #include +#include "scheduler/SchedInst.h" namespace zilliz { namespace milvus { diff --git a/cpp/unittest/server/cache_test.cpp b/cpp/unittest/server/cache_test.cpp index 593911212d5ac515d75403f09195f6121799632e..3587846085f13e70372fbc68973eded9f61676c3 100644 --- a/cpp/unittest/server/cache_test.cpp +++ b/cpp/unittest/server/cache_test.cpp @@ -20,7 +20,7 @@ #include "cache/GpuCacheMgr.h" #include "server/ServerConfig.h" #include "utils/Error.h" -#include "src/wrapper/vec_index.h" +#include "wrapper/vec_index.h" using namespace zilliz::milvus; diff --git a/cpp/unittest/server/config_test.cpp b/cpp/unittest/server/config_test.cpp index 13089e914b84fe311b8aa8b390061a53c917dca4..65ce56272249575b4c290438e9ada806301a972a 100644 --- a/cpp/unittest/server/config_test.cpp +++ b/cpp/unittest/server/config_test.cpp @@ -19,7 +19,6 @@ #include #include "config/ConfigMgr.h" -#include "server/ServerConfig.h" #include "utils/CommonUtil.h" #include "utils/ValidationUtil.h" diff --git a/cpp/unittest/server/rpc_test.cpp b/cpp/unittest/server/rpc_test.cpp index cf3ba8598ccc0efa5be9874caa775b969034f57d..fccebefb82613e2047a5006fdfa43f1eab706967 100644 --- a/cpp/unittest/server/rpc_test.cpp +++ b/cpp/unittest/server/rpc_test.cpp @@ -29,7 +29,6 @@ #include "grpc/gen-status/status.pb.h" #include "server/DBWrapper.h" -#include "server/ServerConfig.h" #include "scheduler/SchedInst.h" #include "scheduler/ResourceFactory.h" #include "utils/CommonUtil.h" @@ -67,7 +66,7 @@ class RpcHandlerTest : public testing::Test { engine::DBOptions opt; server::ConfigNode &db_config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_DB); - db_config.SetValue(server::CONFIG_DB_URL, "sqlite://:@:/"); + db_config.SetValue(server::CONFIG_DB_BACKEND_URL, "sqlite://:@:/"); db_config.SetValue(server::CONFIG_DB_PATH, "/tmp/milvus_test"); db_config.SetValue(server::CONFIG_DB_SLAVE_PATH, ""); db_config.SetValue(server::CONFIG_DB_ARCHIVE_DISK, ""); @@ -77,7 +76,7 @@ class RpcHandlerTest : public testing::Test { cache_config.SetValue(server::CONFIG_INSERT_CACHE_IMMEDIATELY, ""); server::ConfigNode &engine_config = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_ENGINE); - engine_config.SetValue(server::CONFIG_OMP_THREAD_NUM, ""); + engine_config.SetValue(server::CONFIG_ENGINE_OMP_THREAD_NUM, ""); server::ConfigNode &serverConfig = server::ServerConfig::GetInstance().GetConfig(server::CONFIG_SERVER); // serverConfig.SetValue(server::CONFIG_CLUSTER_MODE, "cluster");