Skip to content

Commit

Permalink
Merge pull request #5421 from Xuanwo/rfc-5324-meta-config
Browse files Browse the repository at this point in the history
refactor(meta/config): Adapt RFC Config Backward Compatibility
  • Loading branch information
BohuTANG authored May 18, 2022
2 parents c2be1df + b821805 commit 75d7336
Show file tree
Hide file tree
Showing 16 changed files with 689 additions and 110 deletions.
26 changes: 21 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions common/meta/embedded/src/meta_embedded.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ impl MetaEmbedded {
/// - `common_meta_sled_store::init_sled_db`
/// - `common_meta_sled_store::init_temp_sled_db`
pub async fn new(name: &str) -> common_exception::Result<MetaEmbedded> {
let mut config = RaftConfig::empty();

config.sled_tree_prefix = format!("{}-local-kv", name);
let mut config = RaftConfig {
sled_tree_prefix: format!("{}-local-kv", name),
..Default::default()
};

if cfg!(target_os = "macos") {
tracing::warn!("Disabled fsync for meta data tests. fsync on mac is quite slow");
Expand Down
1 change: 0 additions & 1 deletion common/meta/raft-store/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ common-tracing = { path = "../../tracing" }
anyhow = "1.0.56"
async-trait = "0.1.53"
bytes = "1.1.0"
clap = { version = "3.1.8", features = ["derive", "env"] }
derive_more = "0.99.17"
hostname = "0.3.1"
maplit = "1.0.2"
Expand Down
54 changes: 2 additions & 52 deletions common/meta/raft-store/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,13 @@

use std::net::Ipv4Addr;

use clap::Parser;
use common_exception::Result;
use common_grpc::DNSResolver;
use common_meta_types::Endpoint;
use common_meta_types::MetaError;
use common_meta_types::MetaResult;
use common_meta_types::NodeId;
use once_cell::sync::Lazy;
use serde::Deserialize;
use serde::Serialize;

pub static DATABEND_COMMIT_VERSION: Lazy<String> = Lazy::new(|| {
let build_semver = option_env!("VERGEN_BUILD_SEMVER");
Expand All @@ -43,97 +40,63 @@ pub static DATABEND_COMMIT_VERSION: Lazy<String> = Lazy::new(|| {
ver
});

pub const KVSRV_LISTEN_HOST: &str = "KVSRV_LISTEN_HOST";
pub const KVSRV_ADVERTISE_HOST: &str = "KVSRV_ADVERTISE_HOST";
pub const KVSRV_API_PORT: &str = "KVSRV_API_PORT";
pub const KVSRV_RAFT_DIR: &str = "KVSRV_RAFT_DIR";
pub const KVSRV_NO_SYNC: &str = "KVSRV_NO_SYNC";
pub const KVSRV_SNAPSHOT_LOGS_SINCE_LAST: &str = "KVSRV_SNAPSHOT_LOGS_SINCE_LAST";
pub const KVSRV_HEARTBEAT_INTERVAL: &str = "KVSRV_HEARTBEAT_INTERVAL";
pub const KVSRV_INSTALL_SNAPSHOT_TIMEOUT: &str = "KVSRV_INSTALL_SNAPSHOT_TIMEOUT";
pub const KVSRV_BOOT: &str = "KVSRV_BOOT";
pub const KVSRV_SINGLE: &str = "KVSRV_SINGLE";
pub const KVSRV_ID: &str = "KVSRV_ID";

pub const DEFAULT_LISTEN_HOST: &str = "127.0.0.1";

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Parser)]
#[serde(default)]
#[derive(Clone, Debug, PartialEq)]
pub struct RaftConfig {
/// Identify a config.
/// This is only meant to make debugging easier with more than one Config involved.
#[clap(long, default_value = "")]
pub config_id: String,

/// The local listening host for metadata communication.
/// This config does not need to be stored in raft-store,
/// only used when metasrv startup and listen to.
#[clap(long, env = KVSRV_LISTEN_HOST, default_value = DEFAULT_LISTEN_HOST)]
pub raft_listen_host: String,

/// The hostname that other nodes will use to connect this node.
/// This host should be stored in raft store and be replicated to the raft cluster,
/// i.e., when calling add_node().
/// Use `localhost` by default.
#[clap(long, env = KVSRV_ADVERTISE_HOST, default_value = "localhost")]
pub raft_advertise_host: String,

/// The listening port for metadata communication.
#[clap(long, env = KVSRV_API_PORT, default_value = "28004")]
pub raft_api_port: u32,

/// The dir to store persisted meta state, including raft logs, state machine etc.
#[clap(long, env = KVSRV_RAFT_DIR, default_value = "./_meta")]
pub raft_dir: String,

/// Whether to fsync meta to disk for every meta write(raft log, state machine etc).
/// No-sync brings risks of data loss during a crash.
/// You should only use this in a testing environment, unless YOU KNOW WHAT YOU ARE DOING.
#[clap(long, env = KVSRV_NO_SYNC)]
pub no_sync: bool,

/// The number of logs since the last snapshot to trigger next snapshot.
#[clap(long, env = KVSRV_SNAPSHOT_LOGS_SINCE_LAST, default_value = "1024")]
pub snapshot_logs_since_last: u64,

/// The interval in milli seconds at which a leader send heartbeat message to followers.
/// Different value of this setting on leader and followers may cause unexpected behavior.
#[clap(long, env = KVSRV_HEARTBEAT_INTERVAL, default_value = "1000")]
pub heartbeat_interval: u64,

/// The max time in milli seconds that a leader wait for install-snapshot ack from a follower or non-voter.
#[clap(long, env = KVSRV_INSTALL_SNAPSHOT_TIMEOUT, default_value = "4000")]
pub install_snapshot_timeout: u64,

/// The maximum number of applied logs to keep before purging
#[clap(long, env = "RAFT_MAX_APPLIED_LOG_TO_KEEP", default_value = "1000")]
pub max_applied_log_to_keep: u64,

/// Single node metasrv. It creates a single node cluster if meta data is not initialized.
/// Otherwise it opens the previous one.
/// This is mainly for testing purpose.
#[clap(long, env = KVSRV_SINGLE)]
pub single: bool,

/// Bring up a metasrv node and join a cluster.
///
/// The value is one or more addresses of a node in the cluster, to which this node sends a `join` request.
#[clap(
long,
env = "METASRV_JOIN",
multiple_occurrences = true,
multiple_values = true
)]
pub join: Vec<String>,

/// The node id. Only used when this server is not initialized,
/// e.g. --boot or --single for the first time.
/// Otherwise this argument is ignored.
#[clap(long, env = KVSRV_ID, default_value = "0")]
pub id: NodeId,

/// For test only: specifies the tree name prefix
#[clap(long, default_value = "")]
pub sled_tree_prefix: String,
}

Expand All @@ -147,15 +110,11 @@ pub fn get_default_raft_advertise_host() -> String {
}
}

pub fn get_default_raft_listen_host() -> String {
DEFAULT_LISTEN_HOST.to_string()
}

impl Default for RaftConfig {
fn default() -> Self {
Self {
config_id: "".to_string(),
raft_listen_host: get_default_raft_listen_host(),
raft_listen_host: "127.0.0.1".to_string(),
raft_advertise_host: get_default_raft_advertise_host(),
raft_api_port: 28004,
raft_dir: "./_meta".to_string(),
Expand All @@ -173,15 +132,6 @@ impl Default for RaftConfig {
}

impl RaftConfig {
/// StructOptToml provides a default Default impl that loads config from cli args,
/// which conflicts with unit test if case-filter arguments passed, e.g.:
/// `cargo test my_unit_test_fn`
///
/// Thus we need another method to generate an empty default instance.
pub fn empty() -> Self {
<Self as Parser>::parse_from(&Vec::<&'static str>::new())
}

pub fn raft_api_listen_host_string(&self) -> String {
format!("{}:{}", self.raft_listen_host, self.raft_api_port)
}
Expand Down
7 changes: 4 additions & 3 deletions common/meta/raft-store/tests/it/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ pub struct RaftTestContext {
/// Create a new context for testing sled
pub fn new_raft_test_context() -> RaftTestContext {
// config for unit test of sled db, meta_sync() is true by default.
let mut config = RaftConfig::empty();

config.sled_tree_prefix = format!("test-{}-", 30900 + GlobalSequence::next());
let config = RaftConfig {
sled_tree_prefix: format!("test-{}-", 30900 + GlobalSequence::next()),
..Default::default()
};

RaftTestContext {
raft_config: config,
Expand Down
4 changes: 4 additions & 0 deletions metasrv/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ poem = { version = "=1.3.16", features = ["rustls"] }
prometheus = { version = "0.13.0", features = ["process"] }
prost = "=0.9.0"
serde = { version = "1.0.136", features = ["derive"] }
serde-bridge = "0.0.3"
serde_json = "1.0.79"
serfig = "0.0.2"
tempfile = "3.3.0"
tokio-stream = "0.1.8"
tonic = { version = "=0.6.2", features = ["tls"] }
Expand All @@ -64,3 +66,5 @@ maplit = "1.0.2"
pretty_assertions = "1.2.1"
regex = "1.5.5"
reqwest = { version = "0.11.10", features = ["json"] }
temp-env = "0.2.0"
env_logger = "0.9.0"
80 changes: 80 additions & 0 deletions metasrv/src/configs/inner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2022 Datafuse Labs.
//
// Licensed 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.

use common_meta_raft_store::config::RaftConfig;
use common_meta_types::MetaResult;

use super::outer_v0::Config as OuterV0Config;

#[derive(Clone, Debug, PartialEq)]
pub struct Config {
pub config_file: String,
pub log_level: String,
pub log_dir: String,
pub metric_api_address: String,
pub admin_api_address: String,
pub admin_tls_server_cert: String,
pub admin_tls_server_key: String,
pub grpc_api_address: String,
/// Certificate for server to identify itself
pub grpc_tls_server_cert: String,
pub grpc_tls_server_key: String,
pub raft_config: RaftConfig,
}

impl Default for Config {
fn default() -> Self {
Self {
config_file: "".to_string(),
log_level: "INFO".to_string(),
log_dir: "./_logs".to_string(),
metric_api_address: "127.0.0.1:28001".to_string(),
admin_api_address: "127.0.0.1:28002".to_string(),
admin_tls_server_cert: "".to_string(),
admin_tls_server_key: "".to_string(),
grpc_api_address: "127.0.0.1:9191".to_string(),
grpc_tls_server_cert: "".to_string(),
grpc_tls_server_key: "".to_string(),
raft_config: Default::default(),
}
}
}

impl Config {
/// As requires by [RFC: Config Backward Compatibility](https://github.com/datafuselabs/databend/pull/5324), we will load user's config via wrapper [`OuterV0Config`] and than convert from [`OuterV0Config`] to [`Config`].
///
/// In the future, we could have `ConfigV1` and `ConfigV2`.
pub fn load() -> MetaResult<Self> {
let cfg = OuterV0Config::load()?.try_into()?;

Ok(cfg)
}

/// Transform config into the outer style.
///
/// This function should only be used for end-users.
///
/// For examples:
///
/// - system config table
/// - HTTP Handler
/// - tests
pub fn into_outer(self) -> OuterV0Config {
OuterV0Config::from(self)
}

pub fn tls_rpc_server_enabled(&self) -> bool {
!self.grpc_tls_server_key.is_empty() && !self.grpc_tls_server_cert.is_empty()
}
}
5 changes: 3 additions & 2 deletions metasrv/src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

pub mod config;
mod inner;
mod outer_v0;

pub use config::Config;
pub use inner::Config;
Loading

0 comments on commit 75d7336

Please sign in to comment.