KWDB 分布式部署过程与 deploy.sh cluster -i 命令分析

KWDB 分布式部署过程与 deploy.sh cluster -i 命令分析

K小二

2025-07-31 发布32 浏览 · 0 点赞 · 0 收藏

作者:万少

原文链接:https://my.oschina.net/u/2930230/blog/18233320

本博客是在完成了 KWDB 部署的基础上,进行 KWDB 分布式部署,并对部署过程的命令以及 deploy.sh 执行过程进行进一步分析,关于安装 Ubuntu22.04 和 KWDB 的文档可以参考官方或如下博客。

参考文档

KWDB2.2 的下载页面如下: https://gitee.com/kwdb/kwdb/releases/tag/V2.2.0

下载地址: https://gitee.com/kwdb/kwdb/releases/download/V2.2.0/KWDB-2.2.0-ubuntu22.04-x86_64-debs.tar.gz

安装的参考过程如下: https://gitee.com/kwdb/kwdb

安装的参考过程如下: https://blog.itpub.net/69947868/viewspace-3081066

KWDB 分布式部署及命令分析

分布式应用介绍

随着数据量的增加,分布式技术的成熟,分布式的各种应用也出现了。Hadoop 中有分布式文件系统 HDFS,数据库领域也出现了很多分布式数据库。如果读者有过大数据平台部署的经验,那么完成 KWDB 数据库的分布式部署也是很容易的。

数据库分布式部署是指将数据库系统分散到多个地理位置或计算节点上,通过网络进行互联,共同提供数据存储和处理服务。这种部署方式有多种作用,主要包括:

  • 提高系统的可用性和可靠性:通过在多个地点部署数据库实例,可以避免单点故障带来的风险。即使某个节点出现故障,其他节点仍然可以继续提供服务,从而提高了系统的可靠性和稳定性。

  • 增强扩展性:分布式数据库可以通过添加更多的节点来轻松扩展系统性能和容量,以适应不断增长的数据量和访问请求,满足业务发展的需要。

  • 提升性能:通过将数据分布存储于不同的节点,并允许这些节点并行处理查询请求,可以显著减少响应时间,提高数据处理速度。此外,合理的数据分区策略还可以减少跨节点的数据传输需求,进一步优化性能。

  • 地理分布支持:对于跨国公司或拥有广泛地域覆盖的组织来说,分布式数据库可以让数据更接近用户,减少延迟,改善用户体验。

  • 容灾与备份:分布式数据库通常包括自动化的数据复制功能,这为灾难恢复提供了便利条件。如果发生自然灾害或其他紧急情况导致某一数据中心不可用,其他位置的数据副本可以确保业务连续性。

  • 灵活性和成本效益:可以根据实际需求灵活调整资源配置,同时利用云服务等现代技术降低硬件投资和维护成本。

KWDB 分布式部署过程如下

1. 准备 3 台 Ubuntu22.04 的操作系统,设置网络,并配置基础环境

在本地或云服务器安装 3 台 Ubuntu22.04 的操作系统,设置用户名分别为

node1 node2 node3
sudo hostnamectl set-hostname node1
# 和
sudo vim/etc/hostname

设置 IP 地址分别为:

192.168.3.101,192.168.3.102,192.168.3.103

在 node1,node2,node3 节点上分别设置 /etc/hosts 如下:

192.168.3.101 node1 192.168.3.102 node2 192.168.3.103 node3

在 node1,node2,node3 节点上分别准备如下基础环境

准备基础环境
sudo apt update
sudo apt install cmake -y
sudo snap install go --classic
sudo apt install libprotobuf-dev

设置环境变量

在~/.bashrc 与 /etc/profile 目录下新增一行

export GO111MODULE=off

生效~/.bashrc 与 /etc/profile 配置

source ~/.bashrc
source /etc/profile

在 node1,node2,node3 节点安装安装 systemd-timesyncd

systemd-timesyncd 用于后期的时间同步。

查看 systemd-timesyncd 是否安装

sudo systemctl status systemd-timesyncd

安装 systemd-timesyncd 命令

sudo apt update
sudo apt install systemd-timesyncd

查看是否安装成功状态

timedatectl status 

设定时区为东八区

sudo timedatectl set-timezone Asia/Shanghai

查看服务状态:

打开终端,输入以下命令查看 systemd-timesyncd 服务的状态:

sudo systemctl status systemd-timesyncd

如果服务正在运行,输出中会显示 active (running)。

启动服务:

如果服务未运行,可以使用以下命令启动它:

sudo systemctl start systemd-timesyncd

设置开机自启:

为了在系统启动时自动启动 systemd-timesyncd 服务,可以使用以下命令:

sudo systemctl enable systemd-timesyncd

在 node1,node2,node3 节点安装安装 NTP 服务并重启

set-ntp on 表示启用 NTP 自动时间同步,确保系统时间与互联网时间服务器保持一致。

sudo timedatectl set-ntp on
sudo apt update && sudo apt install ntp
timedatectl status

重启

sudo systemctl restart ntp
sudo ntpq -p

备注:这里用 node1 作为部署节点

2. 在 3 个服务器节点上配置免密登录

  • 登录 node1 节点,生成公私密钥对,每个节点均操作
ssh-keygen -f ~/.ssh/id_rsa -N ""

参数说明: 该命令用于生成 SSH 密钥对。

ssh-keygen 是生成密钥的工具,

-f ~/.ssh/id_rsa 指定生成密钥的文件路径为 ~/.ssh/id_rsa

-N "" 设置密钥的密码为空(无密码)。

在 node1 节点上,执行后会生成私钥 (id_rsa) 和公钥 (id_rsa.pub),用于 SSH 认证,方便安全地访问远程服务器。

  • 在 node1 节点上,将生成好的密钥发送给各个节点
 ssh-copy-id -f -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no node1 
 ssh-copy-id -f -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no node2 
 ssh-copy-id -f -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no node3 

上述命令中

此命令使用 ssh-copy-id 将本地公钥 ~/.ssh/id_rsa.pub 安装到名为 node3 的远程服务器,以实现免密登录。参数 -f 确保即使公钥已存在也不报错,-o StrictHostKeyChecking=no 禁用首次连接时的主机密钥确认,便于自动化操作而无需人工干预,从而简化了 SSH 密钥认证配置过程,提高了工作效率。

  • 在 node1 节点上,通过如下命令判断是否免密设置成功
ssh node1
ssh node2
ssh node3 

3. 单节点部署

下载解压

下载

wget https://gitee.com/kwdb/kwdb/releases/download/V2.2.0/KWDB-2.2.0-ubuntu22.04-x86_64-debs.tar.gz

解压 KWDB

tar zxvf KWDB-2.2.0-ubuntu22.04-x86_64-debs.tar.gz

修改配置文件

进入 kwdb 安装目录

cd kwdb_install/

编辑配置文件

sudo vi deploy.cfg

配置文件如下:

[global]
# Whether to turn on secure mode
secure_mode=tls
# Management KWDB user
management_user=KWDB
# KWDB cluster http port
rest_port=8080
# KWDB service port
KWDB_port=26257
# KWDB data directory
data_root=/var/lib/KWDB
# CPU usage[0-1]
# cpu=1
[local]
# local node configuration
node_addr=192.168.3.101
# section cluster is optional
[cluster]
# remote node addr,split by ','
node_addr=192.168.3.101,192.168.3.102,192.168.3.103
# ssh info
ssh_port=22
ssh_user=root

为 deploy.sh 脚本增加运行权限

chmod +x ./deploy.sh

执行安装命令

多副本集群,多副本架构:每个数据分片配置 3 副本(1 Leader + 2 Followers),通过 Raft/Paxos 协议保证数据一致性

./deploy.sh install --multi-replica

单副本集群

./deploy.sh install --single-replica

上面安装命令选择一个即可。

重载 kwdb

systemctl daemon-reload

##4. 初始化并启动集群

集群初始化和启动命令如下。

./deploy.sh cluster -i

查看集群节点状态

 ./deploy.sh cluster -s
 ./deploy.sh cluster --status 

启动 kwdb

systemctl start KWDB.service
systemctl status KWDB.service

执行 add_user.sh 脚本创建数据库用户

./add_user.sh

通过 kwbase 命令行链接 kwbase

sudo /usr/local/KWDB/bin/kwbase sql --host=192.168.3.100:26257 --certs-dir=/etc/KWDB/certs

到此完成了 KWDB 的分布式部署,下面针对 deploy.sh cluster -i 的过程进行一下分析

安装脚本分析

deploy.sh 中,根据输入参数的不同,可以执行如下操作:

前文基于 install 完成了单节点安装,本文基于 uninstall 参数完成卸载步骤。

deploy.sh cluster 分析

部署或使用删除 KWDB 时,可以使用 deploy.sh 脚本,如 deploy.sh install --single 命令用于完成 KWDB 部署。deploy.sh uninstall 用于完成 KWDB 卸载,deploy.sh cluster 命令用于 KWDB 集群部署,下面针对按照过程中的 deploy.sh cluster 进行分析,该脚本一共 870 行,下面对安装过程进行分析

操作目的

执行 deploy.sh cluster -i 命令的主要目的是分布式部署 KWDB 数据库。

执行流程

1. 脚本初始化

脚本启动后,首先会进行一些基础的全局变量初始化:

# basic golbal variables
g_deploy_path=$(cd $(dirname $0);pwd)
g_cur_usr=$(whoami)

func_info=""
# define export vars
declare -a global_vars

source $g_deploy_path/utils/KWDB_common.sh
source $g_deploy_path/utils/utils.sh
source $g_deploy_path/utils/KWDB_log.sh

function global_usage() {
...
}

这部分代码解释如下:

g_deploy_path 对应当前目录

g_cur_usr 对应当前用户名

declare -a global_vars 声明一个名为 global_vars 的数组变量

source 命令会在当前 Shell 进程中读取并执行指定文件的内容。将指定路径下的三个脚本文件内容引入到当前的 deploy.sh 脚本中执行。关于这个是三个脚本的功能不进行拓展。

global_usage 函数用于输出一些提示信息

2. 命令行参数解析

调用 cmd_check 函数对输入的命令行参数 install --single 进行解析:

# 350-351行
# cmd line parameter parsing
cmd_check $@

cmd_check 函数中,会使用 getopt 工具解析参数,识别出 install 命令,并调用 install_usage 函数处理 --single 选项:

# 182-238行
function cmd_check() {
    # ... 其他代码 ...
    case "$g_kw_cmd" in
        install)
            install_usage $options
        ;;
        # ... 其他代码 ...
    esac
}
# 33-65行
function install_usage() {
    eval set -- "$@"
    push_back "g_install_mode"
    if [ $# -eq 3 ];then
        case "$1" in
            --single)
                g_install_mode="single"
                return
                ;;
            # ... 其他代码 ...
        esac
    fi
}

这一步将安装模式设置为 single

3. 获取本地节点密码

# 353-354行
# fetch local node passwd
local_privileged

调用 local_privileged 函数获取本地节点的密码。

local_privileged 函数位于 KWDB_common.sh 的第 271-288 行

function local_privileged() {
  if privileged;then
    local_cmd_prefix="sudo"
  else
    local_cmd_prefix="echo '$(read_passwd $g_cur_usr)' | sudo -S -p \"\""
    echo
    eval $local_cmd_prefix -k -s >/dev/null 2>&1
    if [ $? -ne 0 ];then
      echo -e "\033[31m[ERROR]\033[0m Incorrect password." >&2
      exit 1
    fi
  fi
  eval $local_cmd_prefix bash -c "exit" >/dev/null 2>&1
  if [ $? -ne 0 ];then
    echo -e "\033[31m[ERROR]\033[0m Can not use command: 'sudo bash'." >&2
    exit 1
  fi
}

4. 初始化日志

# init log
log_init $g_deploy_path $g_cur_usr
push_back "LOG_FILE"
push_back "LOG_LEVEL"

调用 log_init 函数初始化日志系统。

log_init 函数位于 KWDB_log.sh 的 13-28 行

5. 检查 cluster 命令条件

561-568 行用于获取参数,并进行判断

if [ "$g_kw_cmd" = "cluster" ];then
    source $g_deploy_path/utils/KWDB_cluster.sh
    source $g_deploy_path/utils/KWDB_operate.sh
    if [ "$g_cluster_opt" = "init" ];then
  • 引入 KWDB_cluster.shKWDB_operate.sh 脚本,获取集群操作和数据库操作相关的函数。

  • 检查 g_cluster_opt 是否为 init,确认用户是否执行cluster -i命令。

6. 检查 KWDB 安装状态

565-568 行用于判断是否安装

if ! $(install_check  >/dev/null 2>&1);then
    log_err "KWDB does not exist. Please install KWDB first."
    exit 1
fi

调用 install_check 函数检查 KWDB 是否已经安装,如果未安装则输出错误日志并退出脚本。

7. 解析地址信息 以及 远程节点免密检查

569 行

parse_addr

调用 parse_addr 函数解析集群节点的地址信息。

parse_addr 函数位于 KWDB_cluster.sh 中 73-82 行,

function parse_addr() {
  if [ ! -e /etc/KWDB/info/NODE ];then
    log_err "/etc/KWDB/info/NODE: No such file."
    exit 1
  fi
  ip_arr=($(sed -n "1p" /etc/KWDB/info/NODE))
  ssh_port=$(sed -n "2p" /etc/KWDB/info/NODE)
  ssh_user=$(sed -n "3p" /etc/KWDB/info/NODE)
  return 0
}

571 行用于免密检查

# remote node passwd-free check
parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "ssh_passwd_free"
if [ $? -ne 0 ];then
    exit 1
fi

调用 parallel_exec 函数并行检查远程节点是否实现 SSH 免密登录,如果检查失败则退出脚本。

parallel_exec 函数位于 KWDB_common.sh 的 328-343 行。

function parallel_exec() {
  declare -a array
  local node_array=($1)
  local ret_value=""
  cd $g_deploy_path
  if [ ${#node_array[@]} -ne 0 ];then
    for ((i=0; i<${#node_array[@]}; i++))
    do
      array[$i]="${node_array[$i]} $2 $3"
    done
    echo ${array[@]} | xargs -n3 | xargs -P 5 -I {} bash -c "$(declare -p ${global_vars[*]});$(declare -f);$(declare -p global_vars);remote_exec {} $4"
    ret_value=$?
  fi
  unset array
  return $ret_value
}

8. 检查远程节点安装状态

575-578 行用于检查远程节点安装状态

parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "install_check"
if [ $? -ne 0 ];then
    exit 1
fi

调用 parallel_exec 函数并行检查远程节点是否已经安装 KWDB,如果有节点未安装则退出脚本。

##9. 检查当前运行模式

579-582 行检查当前 KWDB 是否是单节点模型

if [ "$(running_type)" = "single" ];then
    log_err "The current mode is not supported cluster init."
    exit 1
fi

调用 running_type 函数检查当前 KWDB 的运行模式,如果是单节点模式则输出错误日志并退出脚本,因为单节点模式不支持集群初始化。

10. 检查集群是否已初始化

583-586 行检查当前 kwdb 是否已经初始化完成

if [ ! -f /etc/KWDB/info/NODE ];then
    log_err "Cluster already init."
    exit 1
fi

检查 /etc/KWDB/info/NODE 文件是否存在,如果不存在则表示集群已经初始化,输出错误日志并退出脚本。

11. 检查 KWDB 运行状态

587-590 行检查 KWDB 运行状态

if $(kw_status >/dev/null 2>&1);then
    log_err "KWDB already running."
    exit 1
fi

调用 kw_status 函数检查 KWDB 是否正在运行,如果正在运行则输出错误日志并退出脚本。

12. 获取远程节点权限

591-593 行 获取远程节点权限

if [ ${#ip_arr[*]} -ne 0 ];then
    remote_privileged "${ip_arr[0]}" $ssh_port $ssh_user
fi

如果存在远程节点,则调用 remote_privileged 函数获取第一个远程节点的权限。

13. 检查远程节点运行状态

594-597 行用于检查远程节点运行状态

parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "kw_status"
if [ $? -ne 0 ];then
    exit 1
fi

调用 parallel_exec 函数并行检查远程节点的 KWDB 是否正在运行,如果有节点正在运行则退出脚本。

14. 启动 KWDB

598-605 行用于启动本地节点的 KWDB 并行启动远程节点的 KWDB

if ! $(exec_start >/dev/null 2>&1);then
    log_err "Start KWDB failed. For more information, check kwbase's log."
    exit 1
fi
parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "exec_start"
if [ $? -ne 0 ];then
    exit 1
fi
  • 调用 exec_start 函数启动本地节点的 KWDB,如果启动失败则输出错误日志并退出脚本。

  • 调用 parallel_exec 函数并行启动远程节点的 KWDB,如果有节点启动失败则退出脚本。

15. 初始化集群

606-610 行用于初始化集群

func_info=$(cluster_init)
if [ $? -ne 0 ];then
    log_err "Cluster init failed: $func_info"
    exit 1
fi

调用 cluster_init 函数初始化 KWDB 集群,如果初始化失败则输出错误日志并退出脚本。

cluster_init 函数位于 KWDB.sh 的 50-71 行

function cluster_init() {
  if [ "$REMOTE" = "ON" ];then
    prefix=$node_cmd_prefix
  else
    prefix=$local_cmd_prefix
  fi
  local ret=""
  if [ "$(install_type)" = "bare" ];then
    cd /usr/local/KWDB/bin
    ret=$(sudo -u $(user_name) bash -c "./kwbase init $(secure_opt) --host=127.0.0.1:$(local_port)" 2>&1)
    if [ $? -ne 0 ];then
      echo "$ret"
      return 1
    fi
  else
    ret=$(docker exec -it KWDB-container bash -c "./kwbase init $(secure_opt) --host=127.0.0.1:26257" 2>&1)
    if [ $? -ne 0 ];then
      echo "$ret"
      return 1
    fi
  fi
}

16. 输出初始化完成提示

611 到 612 行用于输出初始化完成提示

echo -e "\e[1;32m[INIT COMPLETED]:\e[0mCluster init successfully."
exit 0

输出绿色粗体的初始化完成提示信息,并退出脚本。

综上所述,deploy.sh cluster -i 命令会依次完成参数解析、环境检查、节点状态检查、启动节点和初始化集群等步骤,最终完成 KWDB 集群的初始化。

以上提供了 KWDB 的分布式安装以及脚本执行的分析过程,更详细参考对应文档。

请前往 登录/注册 即可发表您的看法…