原文链接:【KWDB创作者计划】_KWDB分布式部署过程与deploy.sh cluster -i命令分析 - OSCHINA - 中文开源技术交流社区
作者:万少
本博客是在完成了 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 数据库的分布式部署也是很容易的。
数据库分布式部署是指将数据库系统分散到多个地理位置或计算节点上,通过网络进行互联,共同提供数据存储和处理服务。这种部署方式有多种作用,主要包括:
提高系统的可用性和可靠性:通过在多个地点部署数据库实例,可以避免单点故障带来的风险。即使某个节点出现故障,其他节点仍然可以继续提供服务,从而提高了系统的可靠性和稳定性。
增强扩展性:分布式数据库可以通过添加更多的节点来轻松扩展系统性能和容量,以适应不断增长的数据量和访问请求,满足业务发展的需要。
提升性能:通过将数据分布存储于不同的节点,并允许这些节点并行处理查询请求,可以显著减少响应时间,提高数据处理速度。此外,合理的数据分区策略还可以减少跨节点的数据传输需求,进一步优化性能。
地理分布支持:对于跨国公司或拥有广泛地域覆盖的组织来说,分布式数据库可以让数据更接近用户,减少延迟,改善用户体验。
容灾与备份:分布式数据库通常包括自动化的数据复制功能,这为灾难恢复提供了便利条件。如果发生自然灾害或其他紧急情况导致某一数据中心不可用,其他位置的数据副本可以确保业务连续性。
灵活性和成本效益:可以根据实际需求灵活调整资源配置,同时利用云服务等现代技术降低硬件投资和维护成本。
在本地或云服务器安装 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 updatesudo apt install cmake -y sudo snap install go --classicsudo apt install libprotobuf-dev
设置环境变量
在~/.bashrc 与 /etc/profile 目录下新增一行
export GO111MODULE=off
生效~/.bashrc 与 /etc/profile 配置
source ~/.bashrcsource /etc/profile
在 node1,node2,node3 节点安装安装 systemd-timesyncd
systemd-timesyncd 用于后期的时间同步。
查看 systemd-timesyncd 是否安装
sudo systemctl status systemd-timesyncd
安装 systemd-timesyncd 命令
sudo apt updatesudo 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 onsudo apt update && sudo apt install ntp timedatectl status
重启
sudo systemctl restart ntpsudo ntpq -p
备注:这里用 node1 作为部署节点
登录 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
下载解压
下载
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 modesecure_mode=tls# Management KaiwuDB usermanagement_user=kaiwudb# KaiwuDB cluster http portrest_port=8080# KaiwuDB service portkaiwudb_port=26257# KaiwuDB data directorydata_root=/var/lib/kaiwudb# CPU usage[0-1]# cpu=1[local]# local node configurationnode_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 infossh_port=22ssh_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
集群初始化和启动命令如下。
./deploy.sh cluster -i
查看集群节点状态
./deploy.sh cluster -s ./deploy.sh cluster --status
启动 kwdb
systemctl start kaiwudb.servicesystemctl status kaiwudb.service
执行 add_user.sh 脚本创建数据库用户
./add_user.sh
通过 kwbase 命令行链接 kwbase
sudo /usr/local/kaiwudb/bin/kwbase sql --host=192.168.3.100:26257 --certs-dir=/etc/kaiwudb/certs
到此完成了 KWDB 的分布式部署,下面针对 deploy.sh cluster -i 的过程进行一下分析
deploy.sh 中,根据输入参数的不同,可以执行如下操作:
前文基于 install 完成了单节点安装,本文基于 uninstall 参数完成卸载步骤。
在前面博客中,
链接:【KWDB 创作者计划】_KWDB 部署之 deploy.sh install --single 命令分析
对 KWDB 的部署命令进行了分析,如果项更换 KWDB 版本,就需要使用更新或是卸载再安装的方式,本文提供基于 deploy.sh 的卸载 KWDB 再安装的方案分析。
关于 KWDB 的 deploy.sh 脚本,我们在上一篇博客中,已经从
脚本初始化
命令行参数解析
获取本地节点密码
初始化日志
安装前检查和准备
硬件检测
配置文件检测
SSH 免密检测
安装过程
10. 安装完成提示
等 10 个方面进行分析,前 4 个步骤是执行安装 KWDB 或卸载 KWDB 的通用步骤,前四个步骤的内容可参考上篇博客,本文接下来分析 KWDB 的卸载过程。
下面针对按照过程中的 deploy.sh cluster 进行分析,该脚本一共 870 行,下面对安装过程进行分析
执行
deploy.sh cluster -i
命令的主要目的是分布式部署 KaiwuDB 数据库。
脚本启动后,首先会进行一些基础的全局变量初始化:
# basic golbal variablesg_deploy_path=$(cd $(dirname $0);pwd) g_cur_usr=$(whoami) func_info=""# define export varsdeclare -a global_varssource $g_deploy_path/utils/KWDB_common.shsource $g_deploy_path/utils/utils.shsource $g_deploy_path/utils/KWDB_log.shfunction global_usage() { ... }
这部分代码解释如下:
g_deploy_path 对应当前目录
g_cur_usr 对应当前用户名
declare -a global_vars 声明一个名为 global_vars 的数组变量
source 命令会在当前 Shell 进程中读取并执行指定文件的内容。将指定路径下的三个脚本文件内容引入到当前的 deploy.sh 脚本中执行。关于这个是三个脚本的功能不进行拓展。
global_usage 函数用于输出一些提示信息
调用 cmd_check
函数对输入的命令行参数 install --single
进行解析:
# 350-351行# cmd line parameter parsingcmd_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
。
# 353-354行# fetch local node passwdlocal_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}
# init loglog_init $g_deploy_path $g_cur_usrpush_back "LOG_FILE"push_back "LOG_LEVEL"
调用 log_init
函数初始化日志系统。
log_init
函数位于 KWDB_log.sh 的 13-28 行
cluster
命令条件561-568 行用于获取参数,并进行判断
if [ "$g_kw_cmd" = "cluster" ];then source $g_deploy_path/utils/kaiwudb_cluster.sh source $g_deploy_path/utils/kaiwudb_operate.sh if [ "$g_cluster_opt" = "init" ];then
kaiwudb_cluster.sh
和 kaiwudb_operate.sh
脚本,获取集群操作和数据库操作相关的函数。g_cluster_opt
是否为 init
,确认用户是否执行 cluster -i
命令。565-568 行用于判断是否安装
if ! $(install_check >/dev/null 2>&1);then log_err "KaiwuDB does not exist. Please install KaiwuDB first." exit 1fi
调用 install_check
函数检查 KaiwuDB 是否已经安装,如果未安装则输出错误日志并退出脚本。
569 行
parse_addr
调用 parse_addr
函数解析集群节点的地址信息。
parse_addr
函数位于 kaiwudb_cluster.sh 中 73-82 行,
function parse_addr() { if [ ! -e /etc/kaiwudb/info/NODE ];then log_err "/etc/kaiwudb/info/NODE: No such file." exit 1 fi ip_arr=($(sed -n "1p" /etc/kaiwudb/info/NODE)) ssh_port=$(sed -n "2p" /etc/kaiwudb/info/NODE) ssh_user=$(sed -n "3p" /etc/kaiwudb/info/NODE) return 0}
571 行用于免密检查
# remote node passwd-free checkparallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "ssh_passwd_free"if [ $? -ne 0 ];then exit 1fi
调用 parallel_exec
函数并行检查远程节点是否实现 SSH 免密登录,如果检查失败则退出脚本。
parallel_exec
函数位于 kaiwudb_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}
575-578 行用于检查远程节点安装状态
parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "install_check"if [ $? -ne 0 ];then exit 1fi
调用 parallel_exec
函数并行检查远程节点是否已经安装 KaiwuDB,如果有节点未安装则退出脚本。
579-582 行检查当前 KWDB 是否是单节点模型
if [ "$(running_type)" = "single" ];then log_err "The current mode is not supported cluster init." exit 1fi
调用 running_type
函数检查当前 KaiwuDB 的运行模式,如果是单节点模式则输出错误日志并退出脚本,因为单节点模式不支持集群初始化。
583-586 行检查当前 kwdb 是否已经初始化完成
if [ ! -f /etc/kaiwudb/info/NODE ];then log_err "Cluster already init." exit 1fi
检查 /etc/kaiwudb/info/NODE
文件是否存在,如果不存在则表示集群已经初始化,输出错误日志并退出脚本。
587-590 行检查 KaiwuDB 运行状态
if $(kw_status >/dev/null 2>&1);then log_err "KaiwuDB already running." exit 1fi
调用 kw_status
函数检查 KaiwuDB 是否正在运行,如果正在运行则输出错误日志并退出脚本。
591-593 行 获取远程节点权限
if [ ${#ip_arr[*]} -ne 0 ];then remote_privileged "${ip_arr[0]}" $ssh_port $ssh_userfi
如果存在远程节点,则调用 remote_privileged
函数获取第一个远程节点的权限。
594-597 行用于检查远程节点运行状态
parallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "kw_status"if [ $? -ne 0 ];then exit 1fi
调用 parallel_exec
函数并行检查远程节点的 KaiwuDB 是否正在运行,如果有节点正在运行则退出脚本。
598-605 行用于启动本地节点的 KaiwuDB 并行启动远程节点的 KaiwuDB
if ! $(exec_start >/dev/null 2>&1);then log_err "Start KaiwuDB failed. For more information, check kwbase's log." exit 1fiparallel_exec "${ip_arr[*]}" $ssh_port $ssh_user "exec_start"if [ $? -ne 0 ];then exit 1fi
exec_start
函数启动本地节点的 KaiwuDB,如果启动失败则输出错误日志并退出脚本。parallel_exec
函数并行启动远程节点的 KaiwuDB,如果有节点启动失败则退出脚本。606-610 行用于初始化集群
func_info=$(cluster_init)if [ $? -ne 0 ];then log_err "Cluster init failed: $func_info" exit 1 fi
调用 cluster_init
函数初始化 KaiwuDB 集群,如果初始化失败则输出错误日志并退出脚本。
cluster_init
函数位于 kaiwudb.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/kaiwudb/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 kaiwudb-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}
611 到 612 行用于输出初始化完成提示
echo -e "\e[1;32m[INIT COMPLETED]:\e[0mCluster init successfully."exit 0
输出绿色粗体的初始化完成提示信息,并退出脚本。
综上所述,deploy.sh cluster -i
命令会依次完成参数解析、环境检查、节点状态检查、启动节点和初始化集群等步骤,最终完成 KaiwuDB 集群的初始化。
以上提供了 KWDB 的分布式安装以及脚本执行的分析过程,更详细参考对应文档。