clickhouse运维篇(三):生产环境一键生成配置并快速部署ck集群

请添加图片描述

前提条件:先了解集群搭建流程是什么样,需要改哪些配置,有哪些环境,这个文章目的是简化部署。

clickhouse运维篇(一):docker-compose 快速部署clickhouse集群
clickhouse运维篇(二):多机器手动部署ck集群

!https://i-blog.csdnimg.cn/direct/7677be0676904a7687c2f4cc8aef0a46.png

项目目录解析:

 $ tree .
.
├── cluster.conf   #集群配置,  集群包含哪些机器、端口分别为多少
├── config  
│   ├── config_node1.xml  # 生成的ck节点配置文件
│   ├── config_node2.xml
│   ├── config_template.xml  # config模版
│   ├── users_node1.xml     # 生成的ck节点用户配置文件
│   ├── users_node2.xml
│   └── users_template.xml   # users模版
├── dep   #下面包含需要的远程依赖, zookeeper、clickhouse、jdk,根据自己的需求更改
├── gen_cluster_config.sh  
├── gen_login_cmd.sh
├── install.conf  # 远程登录的主机conf,需要在跳板机或者中间机器上去ssh、scp使用
└── main.sh   #启动入口

1、main.sh

CUR_FOLDER=$(cd "/Users/admin/scripts/my_app/ckcluster";pwd). ${CUR_FOLDER}/cluster.conf
. ${CUR_FOLDER}/gen_cluster_config.sh
. ${CUR_FOLDER}/gen_login_cmd.shCONFIG_FOLDER="${CUR_FOLDER}/config"
DEP_FOLDER="${CUR_FOLDER}/dep"
TEMPLATE_FILE="${CONFIG_FOLDER}/config_template.xml"if [ ! -d "$CONFIG_FOLDER" ]; thenmkdir -p "$CONFIG_FOLDER"
fiif [ ! -d "$DEP_FOLDER" ]; thenmkdir -p "$DEP_FOLDER"
fizk_index=1
# 首先读取所有节点信息并根据 shard 进行分组
while true; dohost_var="zk_node_${zk_index}_host"# 检查所有变量是否为空,若有一个为空则跳出循环if [ -z "${!host_var}" ]; thenbreakfi# 远程安装jdk、zookeeperinstall_path=$(get_install_path ${!host_var})echo $(get_scp_command ${!host_var} . "${DEP_FOLDER}/jdk-8u202-nonroot.tar.gz ${DEP_FOLDER}/apache-zookeeper-3.7.2-bin.tar.gz")`get_scp_command ${!host_var} . "${DEP_FOLDER}/jdk-8u202-nonroot.tar.gz ${DEP_FOLDER}/apache-zookeeper-3.7.2-bin.tar.gz"`echo $(get_ssh_command ${!host_var} "cd ${install_path};tar -xzvf ${install_path}/jdk-8u202-nonroot.tar.gz")echo $(get_ssh_command ${!host_var} "cd ${install_path};tar -xzvf ${install_path}/apache-zookeeper-3.7.2-bin.tar.gz")`get_ssh_command ${!host_var} "cd ${install_path};tar -xzvf ${install_path}/jdk-8u202-nonroot.tar.gz"``get_ssh_command ${!host_var} "cd ${install_path};tar -xzvf ${install_path}/apache-zookeeper-3.7.2-bin.tar.gz"`zk_index=$((zk_index + 1))
done# 生成ck集群配置文件
gen_config# 远程安装clickhouse
ck_index=1
# 首先读取所有节点信息并根据 shard 进行分组
while true; dohost_var="ck_node_${ck_index}_host"# 检查所有变量是否为空,若有一个为空则跳出循环if [ -z "${!host_var}" ]; thenbreakfi
#     <users_config>/opt/appaduudit/my_app-2.4/clickhouse-23.4.2.9/ck_node_1/config/users_node.xml</users_config>    install_path=$(get_install_path ${!host_var})    `get_scp_command ${!host_var} . "${DEP_FOLDER}/clickhouse-23.4.2.9.tar.gz"`echo $(get_ssh_command ${!host_var} "cd ${install_path};tar -xzvf ${install_path}/clickhouse-23.4.2.9.tar.gz")NODE_CK_PATH="${BASE_CK_PATH}/ck_node_${ck_index}"echo $(get_scp_command ${!host_var} ${NODE_CK_PATH}/config  "${CONFIG_FOLDER}/user_node${ck_index}.xml")`get_scp_command ${!host_var} ${NODE_CK_PATH}/config "${CONFIG_FOLDER}/config_node${ck_index}.xml"``get_scp_command ${!host_var} ${NODE_CK_PATH}/config  "${CONFIG_FOLDER}/users_node${ck_index}.xml"`echo $(get_ssh_command ${!host_var} "${install_path}/clickhouse-23.4.2.9.tar.gz/bin/clickhouse server --config-file  ${install_path}/config_node${ck_index}.xml")`get_ssh_command ${!host_var} "${install_path}/clickhouse-23.4.2.9.tar.gz/bin/clickhouse server --config-file  ${install_path}/config_node${ck_index}.xml"`    ck_index=$((ck_index + 1))
done

2、cluster.conf

# 定义变量
target_install_path="/opt/app/ck_cluster"
BASE_CK_PATH="/opt/app/my_app-2.4/clickhouse-23.4.2.9"
CK_CLUSTER_NAME="my_ck_cluster_test"#port为zk的clientPort
zk_node_1_host=172.168.1.206
zk_node_1_port=8551zk_node_2_host=172.168.1.207
zk_node_2_port=8551zk_node_3_host=172.168.1.208
zk_node_3_port=8551ck_node_1_host=172.168.1.206
ck_node_1_tcp_port=8601
ck_node_1_http_port=8602
ck_node_1_interserver_http_port=8603
ck_node_1_user=default
ck_node_1_password=password
ck_node_1_shard=01
ck_node_1_replica=replica_63ck_node_2_host=172.168.1.207
ck_node_2_tcp_port=8611
ck_node_2_http_port=8612
ck_node_2_interserver_http_port=8613
ck_node_2_user=default
ck_node_2_password=password
ck_node_2_shard=02
ck_node_2_replica=replica_63#ck_node_3_host=ck_host_3
#ck_node_3_tcp_port=ck_tcp_port_3
#ck_node_3_http_port=ck_http_port_3
#ck_node_3_interserver_http_port=ck_interserver_http_port_3
#ck_node_3_user=user3
#ck_node_3_password=password3
#ck_node_3_shard=02
#ck_node_3_replica=replica_209

3、install.conf

ssh.172.168.1.206=root:app:/opt/app/ck_cluste
ssh.172.168.1.207=admin:adminpass:/opt/app/ck_cluste
ssh.172.168.1.208=admin:adminpass:/opt/app/ck_cluste

4、gen_login_cmd.sh

#!/bin/bash
cd /Users/admin/scripts/my_app/ckcluster
# 读取配置文件并解析
CONFIG_FILE="install.conf"
declare -A HOSTSwhile IFS='=' read -r key user_password || [[ -n "$key" ]]; dokey=$(echo "$key" | xargs)user_password=$(echo "$user_password" | xargs)if [[ $key == ssh.* ]]; thenhost=${key#ssh.}HOSTS["$host"]="$user_password"fi
done < "$CONFIG_FILE"# 获取 SSH 命令
get_ssh_command() {local host=$1local cmd=$2local user_password=${HOSTS["$host"]}IFS=':' read -r user password install_path<<< "$user_password"# echo "sshpass -p '$password' ssh $user@$host $cmd"echo "sshpass -p '$password' ssh $user@$host \"$cmd\""}# 获取 SCP 命令
get_scp_command() {local host=$1local extra_dir=$2local files=$3    local user_password=${HOSTS[$host]}# root:idss:/opt/idss/ck_clusteIFS=':' read -r user password install_path<<< "$user_password"if [ "$extra_dir" != "." ]; theninstall_path=$extra_dirfimkdir_cmd=$(get_ssh_command $host "mkdir -p $install_path")eval "$mkdir_cmd"echo "sshpass -p '$password' scp -r $files $user@$host:$install_path"
}get_install_path() {local host=$1local user_password=${HOSTS[$host]}# root:idss:/opt/idss/ck_clusteIFS=':' read -r user password install_path<<< "$user_password"echo $install_path
}
# ssh_command=$(get_scp_command "10.87.102.206" "/Users/admin/scripts/my_app/ckcluster/dep/jdk-8u202-nonroot.tar.gz /Users/admin/scripts/my_app/ckcluster/dep/apache-zookeeper-3.7.2-bin.tar.gz")
# echo $ssh_command
# scp_command=$(get_ssh_command "10.87.102.206" "ls /opt/idss/ck_cluste")
# echo $scp_command
# `$scp_command`

5、gen_cluster_config.sh

#!/bin/bash
# 定义基础路径和模板文件名function gen_config() {# 生成 zookeeper 配置
ZOOKEEPER_CONFIG="<zookeeper>\n"
# 循环遍历 zk_node_*_host 和 zk_node_*_port 变量
zk_index=1
while true; dohost_var="zk_node_${zk_index}_host"port_var="zk_node_${zk_index}_port"# 检查变量是否已定义,如果未定义则跳出循环if [ -z "${!host_var}" ] || [ -z "${!port_var}" ]; thenbreakfiZOOKEEPER_CONFIG+="    <node index=\"${zk_index}\">\n"ZOOKEEPER_CONFIG+="        <host>${!host_var}</host>\n"ZOOKEEPER_CONFIG+="        <port>${!port_var}</port>\n"ZOOKEEPER_CONFIG+="    </node>\n"zk_index=$((zk_index + 1))
done
ZOOKEEPER_CONFIG+="</zookeeper>"# 生成 remote_servers 配置
declare -A shard_nodes config_contentck_index=1
# 首先读取所有节点信息并根据 shard 进行分组
while true; dohost_var="ck_node_${ck_index}_host"tcp_port_var="ck_node_${ck_index}_tcp_port"http_port_var="ck_node_${ck_index}_http_port"interserver_port_var="ck_node_${ck_index}_interserver_http_port"user_var="ck_node_${ck_index}_user"password_var="ck_node_${ck_index}_password"shard_var="ck_node_${ck_index}_shard"replica_var="ck_node_${ck_index}_replica"# 检查所有变量是否为空,若有一个为空则跳出循环if [ -z "${!host_var}" ] || \[ -z "${!tcp_port_var}" ] || \[ -z "${!http_port_var}" ] || \[ -z "${!interserver_port_var}" ] || \[ -z "${!user_var}" ] || \[ -z "${!password_var}" ] || \[ -z "${!shard_var}" ] || \[ -z "${!replica_var}" ]; thenbreakfi# 将当前节点信息存入以 shard 为 key 的数组shard_nodes["${!shard_var}"]+=$(cat <<-NODE<replica><host>${!host_var}</host><port>${!tcp_port_var}</port><user>${!user_var}</user><password>${!password_var}</password></replica>\n
NODE)NODE_CK_PATH="${BASE_CK_PATH}/ck_node_${ck_index}"config_template=$(cat ${CONFIG_FOLDER}/config_template.xml)config_template=$(echo "$config_template" | sed "s|\${BASE_CK_PATH}|${NODE_CK_PATH}|g")config_template=$(echo "$config_template" | sed "s|\${HTTP_PORT}|${!http_port_var}|g")config_template=$(echo "$config_template" | sed "s|\${TCP_PORT}|${!tcp_port_var}|g")config_template=$(echo "$config_template" | sed "s|\${INTERSERVER_HTTP_PORT}|${!interserver_port_var}|g")config_template=$(echo "$config_template" | sed "s|\${MACROS_SHARD}|${!shard_var}|g")config_template=$(echo "$config_template" | sed "s|\${MACROS_REPLICA}|${!replica_var}|g")config_template=$(echo "$config_template" | sed "s|\${CK_PASSWORD}|${!password_var}|g")    config_template=$(echo "$config_template" | sed "s|\${ck_index}|${!ck_index}|g")        # 将生成的配置内容存入字典config_content["config_node${ck_index}"]="$config_template"# users文件生成users_template=$(cat ${CONFIG_FOLDER}/users_template.xml)users_template=$(echo "$users_template" | sed "s|\${CK_PASSWORD}|${!password_var}|g")    echo -e "$users_template" > "${CONFIG_FOLDER}/users_node${ck_index}.xml"ck_index=$((ck_index + 1))
done# 构建最终的 XML 配置
REMOTE_SERVERS_CONFIG="<remote_servers>\n"
REMOTE_SERVERS_CONFIG+="    <${CK_CLUSTER_NAME}>\n"
for shard in "${!shard_nodes[@]}"; doREMOTE_SERVERS_CONFIG+="        <shard>\n"REMOTE_SERVERS_CONFIG+="            <internal_replication>true</internal_replication>  \n"REMOTE_SERVERS_CONFIG+="${shard_nodes[$shard]}"REMOTE_SERVERS_CONFIG+="        </shard>\n"
done
REMOTE_SERVERS_CONFIG+="    </${CK_CLUSTER_NAME}>\n"
REMOTE_SERVERS_CONFIG+="</remote_servers>"# 动态修改配置文件(插入 Zookeeper\CK集群 配置)
for node_config in "${!config_content[@]}"; doecho "处理 $node_config ..."# 创建临时文件temp_file="${node_config}_tmp.xml"echo -e "${config_content[$node_config]}" > "$temp_file"sed -i '' '/<\/yandex>/d' "$temp_file"# linux下为# sed -i '/<\/yandex>/d' "$temp_file"    # 拼接 Zookeeper 和 Remote Servers 配置combined_insert="${ZOOKEEPER_CONFIG}
${REMOTE_SERVERS_CONFIG}"echo -e "$combined_insert" >> "$temp_file"echo "</yandex>" >> "$temp_file"mv "$temp_file" "$CONFIG_FOLDER/${node_config}.xml"echo "生成 $node_config 完成: ${node_config}.xml"
done}

6、config_template.xml

<?xml version="1.0"?>
<yandex><logger><level>notice</level><log>${BASE_CK_PATH}/log/clickhouse-server.log</log><errorlog>${BASE_CK_PATH}/log/clickhouse-server.err.log</errorlog><size>1000M</size><count>10</count></logger><path>${BASE_CK_PATH}/data/</path><tmp_path>${BASE_CK_PATH}/tmp/</tmp_path><user_files_path>${BASE_CK_PATH}/data/user_files/</user_files_path><users_config>${BASE_CK_PATH}/config/users_node${ck_index}.xml</users_config>    <users><default><password>${CK_PASSWORD}</password> <!-- 空密码 --><networks><ip>::/0</ip> <!-- 允许所有IP访问 --></networks><profile>default</profile><quota>default</quota><access_management>1</access_management></default></users>    <default_profile>default</default_profile><default_database>default</default_database><http><port>${HTTP_PORT}</port><max_connections>1024</max_connections><async_insert>1</async_insert></http><listen_host>0.0.0.0</listen_host><listen_host>::</listen_host><http_port>${HTTP_PORT}</http_port><tcp_port>${TCP_PORT}</tcp_port><interserver_http_port>${INTERSERVER_HTTP_PORT}</interserver_http_port><distributed_ddl><!-- Path in ZooKeeper to queue with DDL queries --><path>/clickhouse/task_queue/ddl</path></distributed_ddl><macros><shard>${MACROS_SHARD}</shard><replica>${MACROS_REPLICA}</replica></macros>
</yandex>

7、users_template.xml

<?xml version="1.0"?>
<yandex><!-- Profiles of settings. --><profiles><!-- Default settings. --><default><!-- Maximum memory usage for processing single query, in bytes. --><max_memory_usage>10000000000</max_memory_usage><load_balancing>random</load_balancing></default><!-- Profile that allows only read queries. --><readonly><readonly>1</readonly></readonly></profiles><users><default><password>${CK_PASSWORD}</password> <networks><ip>::/0</ip> <!-- 允许所有IP访问 --></networks><profile>default</profile><quota>default</quota><access_management>1</access_management></default></users>    <!-- Quotas. --><quotas><!-- Name of quota. --><default><!-- Limits for time interval. You could specify many intervals with different limits. --><interval><!-- Length of interval. --><duration>3600</duration><distributed_product_mode>allow</distributed_product_mode><!-- No limits. Just calculate resource usage for time interval. --><queries>0</queries><errors>0</errors><result_rows>0</result_rows><read_rows>0</read_rows><execution_time>0</execution_time></interval></default></quotas>
</yandex>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/696.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Hms?: 1渗透测试

靶机&#xff1a;Hms?: 1 Hms?: 1 ~ VulnHub 攻击机&#xff1a;kail linux 2024 主机扫描阶段发现不了靶机&#xff0c;所以需要按DriftingBlues2一样手动配置网卡 1,将两台虚拟机网络连接都改为NAT模式&#xff0c;并查看靶机的MAC地址 2&#xff0c;攻击机上做主机扫描发现…

论文阅读- --DeepI2P:通过深度分类进行图像到点云配准

目前存在的问题&#xff1a; 单模态配准具有局限性&#xff0c;多模态研究很少跨模态图像到点云配准问题是求解相机坐标系与点云之间的旋转矩阵R ∈ SO(3)和平移向量t ∈ R3。 这个问题很困难&#xff0c;因为由于缺乏点到像素的对应关系&#xff0c;无法使用 ICP、PnP 和捆绑调…

R语言贝叶斯分层、层次(Hierarchical Bayesian)模型房价数据空间分析

原文链接&#xff1a;https://tecdat.cn/?p38077 本文主要探讨了贝叶斯分层模型在分析区域数据方面的应用&#xff0c;以房价数据为例&#xff0c;详细阐述了如何帮助客户利用R进行模型拟合、分析及结果解读&#xff0c;展示了该方法在处理空间相关数据时的灵活性和有效性。&a…

警务辅助人员管理系统小程序ssm+论文源码调试讲解

2系统关键技术 2.1 微信小程序 微信小程序&#xff0c;简称小程序&#xff0c;英文名Mini Program&#xff0c;是一种全新的连接用户与服务的方式&#xff0c;可以快速访问、快速传播&#xff0c;并具有良好的使用体验。 小程序的主要开发语言是JavaScript&#xff0c;它与普…

Webserver(2.7)内存映射

目录 内存映射内存映射相关系统调用内存映射的注意事项如果对mmap的返回值(ptr)做操作&#xff0c;释放内存&#xff08;munmap&#xff09;是否能够成功&#xff1f;如果open时O_RDONLY&#xff0c;mmap时prot参数指定PROT_READ | PROT_WRITE会怎样&#xff1f;如果文件偏移量…

c++多线程处理数据

c查询可以调动的线程个数 #include <iostream> #include <thread>int main() {// 查询可调动线程数量std::thread::hardware_concurrency();// 如果函数返回0&#xff0c;表示不支持并发&#xff0c;或者无法确定// 如果返回非0值&#xff0c;表示可以同时激活的线…

51c大模型~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11547799 #Llama 3.1 美国太平洋时间 7 月 23 日&#xff0c;Meta 公司发布了其最新的 AI 模型 Llama 3.1&#xff0c;这是一个里程碑时刻。Llama 3.1 的发布让我们看到了开源 LLM 有与闭源 LLM 一较高下的能力。 Meta 表…

实习冲刺Day12

算法题 爬楼梯 70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 递推写法 class Solution { public:int climbStairs(int n) {int num[50];//开辟一个数组num[1]1,num[2]2;for(int i3;i<n;i){num[i]num[i-1]num[i-2];}return num[n];} }; 递归写法 class Solution…

开源免费的API网关介绍与选型

api网关的主要作用 API网关在现代微服务架构中扮演着至关重要的角色&#xff0c;它作为内外部系统通信的桥梁&#xff0c;不仅简化了服务调用过程&#xff0c;还增强了系统的安全性与可管理性。例如&#xff0c;当企业希望将内部的服务开放给外部合作伙伴使用时&#xff0c;直…

头歌——数据库系统原理(数据的简单查询)

文章目录 第1关&#xff1a;基本 SELECT 查询代码 第2关&#xff1a;带限制条件的查询和表达式查询代码 第3关&#xff1a;使用 WHERE 语句进行检索代码 第1关&#xff1a;基本 SELECT 查询 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a; 如何获取数据表中指…

推荐一款可视化和检查原始数据的工具:RawDigger

RawDigger是一款强大的工具&#xff0c;旨在可视化和检查相机记录的原始数据。它被称为一种“显微镜”&#xff0c;使用户能够深入分析原始图像数据&#xff0c;而不对其进行任何更改。RawDigger并不是一个原始转换器&#xff0c;而是一个帮助用户查看将由转换器使用的数据的工…

计算机毕业设计Python+大模型股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; Python大模型股票预测系统 …

Robot Framwork 介绍与使用

文章目录 Robot Framwork 介绍Robot Framwork的安装安装robotframework-ride建立一个简单的测试用例 Robot Framwork 介绍 Robot Framework是一款python编写的功能自动化测试框架。具备良好的可扩展性&#xff0c;支持关键字驱动&#xff0c;可以同时测试多种类型的客户端或者…

【RabbitMQ】01-RabbitMQ

1. MQ MQ可以有更好的并发性。 2. 安装 docker run \-e RABBITMQ_DEFAULT_USERitheima \-e RABBITMQ_DEFAULT_PASS123321 \-v mq-plugins:/plugins \--name mq \--hostname mq \-p 15672:15672 \-p 5672:5672 \--network hm-net\-d \rabbitmq:3.8-management3. 结构 4. 数据…

最新PHP校园源码系统开发(多客社区校园系统源码全套APP源码附搭建教程)

最新PHP校园源码系统开发、多客社区校园系统源码以及全套APP源码附搭建教程的需求 一、最新PHP校园源码系统开发 技术栈选择&#xff1a; 后端&#xff1a;PHP&#xff08;建议使用PHP 7.2或更高版本&#xff09;数据库&#xff1a;MySQL&#xff08;建议使用MySQL 5.6或更高版…

校招回顾 | “青春不散场,梦想正起航”,极限科技(INFINI Labs)亮相湖北工业大学 2025 秋季校园招聘会

10 月 31 日&#xff0c;极限科技&#xff08;INFINI Labs&#xff09; 受邀参加 湖北工业大学 2025 届秋季校园招聘会&#xff0c;这不仅是一次与满怀激情的青年学子们的深度碰撞&#xff0c;更是一场关于青春与未来的美好邂逅。让我们一起回顾校招现场的精彩瞬间&#xff0c;…

在使用 AMD GPU 的 PyTorch 中实现自动混合精度

Automatic mixed precision in PyTorch using AMD GPUs — ROCm Blogs 随着模型规模的增加&#xff0c;训练它们所需的时间和内存——以及因此而产生的成本——也在增加。因此&#xff0c;采取任何措施来减少训练时间和内存使用都是非常有益的。这就是自动混合精度&#xff08;…

安卓设备adb执行AT指令控制电话卡

文章目录 AT指令起源与发展&#xff1a;基本格式&#xff1a;常见应用领域及功能&#xff1a;不同设备中的应用&#xff1a; 安卓获取modem设备输入符入口安卓设备输入AT指令 AT指令 AT 指令是 Attention 的缩写&#xff0c;是一种用于控制调制解调器等通信设备的指令集。 起…

RSTP的工作过程

RSTP简介&#xff1a; 生成树协议&#xff08;STP&#xff09;用于在网络中防止环路产生&#xff0c;但 STP 的收敛速度较慢。 RSTP&#xff08;Rapid Spanning Tree Protocol &#xff09;快速生成树协议&#xff1a;RSTP 是对 STP 的改进&#xff0c;它能在网络拓扑发生变化…

Django-生成csv文件

定义&#xff1a; python中生成csv文件&#xff1a; csv文件下载&#xff1a; 事例&#xff1a; 例子&#xff1a; urls: from django.urls import path from . import views urlpatterns [path(test_csv,views.test_csv), ] views: def test_csv(request):response Htt…