diff --git a/apps/emqx_conf/etc/emqx_conf.conf b/apps/emqx_conf/etc/emqx_conf.conf index fcb7a2947..e57bc4869 100644 --- a/apps/emqx_conf/etc/emqx_conf.conf +++ b/apps/emqx_conf/etc/emqx_conf.conf @@ -306,14 +306,32 @@ cluster { ## Default: default namespace = default } +} - db_backend = mnesia +##================================================================== +## Internal database +##================================================================== +db { + ## Database backend + ## + ## @doc db.backend + ## ValueType: mnesia | rlog + ## Default: mnesia + backend = mnesia - rlog { - # role: core - # core_nodes: [] - } + ## RLOG role + ## + ## @doc db.role + ## ValueType: core | replicant + ## Default: core + role = core + ## Replicant core nodes + ## + ## @doc db.core_nodes + ## ValueType: comma-separated node list + ## Default: "" + core_nodes = "" } ##================================================================== diff --git a/apps/emqx_conf/src/emqx_conf_schema.erl b/apps/emqx_conf/src/emqx_conf_schema.erl index ba3ac31b6..350ee9e3a 100644 --- a/apps/emqx_conf/src/emqx_conf_schema.erl +++ b/apps/emqx_conf/src/emqx_conf_schema.erl @@ -72,8 +72,7 @@ roots() -> sc(hoconsc:ref("cluster"), #{ desc => "EMQ X nodes can form a cluster to scale up the total capacity.
" "Here holds the configs to instruct how individual nodes " - "can discover each other, also the database replication " - "role of this node etc." + "can discover each other." })} , {"log", sc(hoconsc:ref("log"), @@ -101,6 +100,10 @@ natively in the EMQ X node;
'postgresql' etc. to look up clients or rules from external databases;
""" })} + , {"db", + sc(ref("db"), + #{ desc => "Settings of the embedded database." + })} ] ++ emqx_schema:roots(medium) ++ emqx_schema:roots(low) ++ @@ -146,14 +149,6 @@ fields("cluster") -> , {"k8s", sc(ref(cluster_k8s), #{})} - , {"db_backend", - sc(hoconsc:enum([mnesia, rlog]), - #{ mapping => "mria.db_backend" - , default => mnesia - })} - , {"rlog", - sc(ref("rlog"), - #{})} ]; fields(cluster_static) -> @@ -251,19 +246,6 @@ fields(cluster_k8s) -> })} ]; -fields("rlog") -> - [ {"role", - sc(hoconsc:enum([core, replicant]), - #{ mapping => "mria.node_role" - , default => core - })} - , {"core_nodes", - sc(emqx_schema:comma_separated_atoms(), - #{ mapping => "mria.core_nodes" - , default => [] - })} - ]; - fields("node") -> [ {"name", sc(string(), @@ -328,6 +310,46 @@ fields("node") -> )} ]; +fields("db") -> + [ {"backend", + sc(hoconsc:enum([mnesia, rlog]), + #{ mapping => "mria.db_backend" + , default => mnesia + , desc => """ +Select the backend for the embedded database.
+Important! This setting should be the same on all nodes in the cluster.
+Important! Changing this setting in the runtime is not allowed.
+mnesia is the default backend, that offers decent performance in small clusters.
+rlog is a new experimantal backend that is suitable for very large clusters. +""" + })} + , {"role", + sc(hoconsc:enum([core, replicant]), + #{ mapping => "mria.node_role" + , default => core + , desc => """ +Select a node role.
+core nodes provide durability of the data, and take care of writes. +It is recommended to place core nodes in different racks or different availability zones.
+replicant nodes are ephemeral worker nodes. Removing them from the cluster +doesn't affect database redundancy
+It is recommended to have more replicant nodes than core nodes.
+Note: this parameter only takes effect when the backend is set +to rlog. +""" + })} + , {"core_nodes", + sc(emqx_schema:comma_separated_atoms(), + #{ mapping => "mria.core_nodes" + , default => [] + , desc => """ +List of core nodes that the replicant will connect to.
+Note: this parameter only takes effect when the backend is set +to rlog and the role is set to replicant. +""" + })} + ]; + fields("cluster_call") -> [ {"retry_interval", sc(emqx_schema:duration(), @@ -719,22 +741,10 @@ sort_log_levels(Levels) -> %% utils -spec(conf_get(string() | [string()], hocon:config()) -> term()). conf_get(Key, Conf) -> - V = hocon_schema:get_value(Key, Conf), - case is_binary(V) of - true -> - binary_to_list(V); - false -> - V - end. + ensure_list(hocon_schema:get_value(Key, Conf)). conf_get(Key, Conf, Default) -> - V = hocon_schema:get_value(Key, Conf, Default), - case is_binary(V) of - true -> - binary_to_list(V); - false -> - V - end. + ensure_list(hocon_schema:get_value(Key, Conf, Default)). filter(Opts) -> [{K, V} || {K, V} <- Opts, V =/= undefined]. @@ -790,5 +800,14 @@ to_atom(Str) when is_list(Str) -> to_atom(Bin) when is_binary(Bin) -> binary_to_atom(Bin, utf8). +-spec ensure_list(binary() | list(char())) -> list(char()). +ensure_list(V) -> + case is_binary(V) of + true -> + binary_to_list(V); + false -> + V + end. + roots(Module) -> lists:map(fun({_BinName, Root}) -> Root end, hocon_schema:roots(Module)).