我来为您提供一个自动配置ClickHouse集群的脚本,这个脚本可以自动完成ClickHouse集群的安装和配置。

主配置文件
cluster-config.yaml
# ClickHouse集群配置
cluster:
name: clickhouse_cluster
shards: 2
replicas: 2
nodes:
- host: 192.168.1.10
hostname: node1
role: "leader"
shard: 1
replica: 1
user: root
- host: 192.168.1.11
hostname: node2
role: "follower"
shard: 1
replica: 2
user: root
- host: 192.168.1.12
hostname: node3
role: "follower"
shard: 2
replica: 1
user: root
- host: 192.168.1.13
hostname: node4
role: "follower"
shard: 2
replica: 2
user: root
clickhouse:
version: "22.8.15"
port: 9000
http_port: 8123
data_dir: /var/lib/clickhouse
log_dir: /var/log/clickhouse-server
zookeeper:
hosts:
- 192.168.1.10:2181
- 192.168.1.11:2181
- 192.168.1.12:2181
主安装脚本
install-clickhouse-cluster.sh
#!/bin/bash
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 日志函数
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查root权限
check_root() {
if [[ $EUID -ne 0 ]]; then
log_error "此脚本必须以root用户运行"
exit 1
fi
}
# 安装依赖
install_dependencies() {
log_info "安装依赖包..."
if command -v yum &> /dev/null; then
yum install -y curl wget tar python3-pip sshpass
elif command -v apt-get &> /dev/null; then
apt-get update
apt-get install -y curl wget tar python3-pip sshpass
fi
pip3 install pyyaml
}
# 配置SSH免密登录
setup_ssh() {
log_info "配置SSH免密登录..."
if [ ! -f ~/.ssh/id_rsa ]; then
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
fi
# 读取配置
local config_file=$1
# 获取所有节点信息(除自身)
python3 <<-EOF
import yaml
with open('$config_file', 'r') as f:
config = yaml.safe_load(f)
local_ip = "$(hostname -I | awk '{print $1}')"
for node in config['nodes']:
if node['host'] != local_ip:
print(f"正在配置免密登录到 {node['host']}...")
import os
os.system(f"sshpass -p '' ssh-copy-id -o StrictHostKeyChecking=no root@{node['host']}")
print(f"完成配置 {node['host']}")
EOF
}
# 安装ClickHouse
install_clickhouse() {
local version=$1
log_info "安装ClickHouse ${version}..."
# 下载RPM包
local base_url="https://packages.clickhouse.com/rpm/stable"
local packages=(
"clickhouse-common-static-${version}.x86_64.rpm"
"clickhouse-server-${version}.x86_64.rpm"
"clickhouse-client-${version}.x86_64.rpm"
)
for pkg in "${packages[@]}"; do
if [ ! -f "/tmp/${pkg}" ]; then
wget -q "${base_url}/${pkg}" -O "/tmp/${pkg}"
fi
rpm -ivh "/tmp/${pkg}" 2>/dev/null || true
done
}
# 生成集群配置
generate_cluster_config() {
local config_file=$1
log_info "生成集群配置..."
python3 <<-EOF
import yaml
import os
with open('$config_file', 'r') as f:
config = yaml.safe_load(f)
cluster_name = config['cluster']['name']
zookeeper_hosts = config['zookeeper']['hosts']
# 生成metrika.xml
metrika_config = f"""<yandex>
<clickhouse_remote_servers>
<{cluster_name}>
"""
for shard in range(1, config['cluster']['shards'] + 1):
metrika_config += f""" <shard>
<internal_replication>true</internal_replication>
"""
for node in config['nodes']:
if node['shard'] == shard:
metrika_config += f""" <replica>
<host>{node['host']}</host>
<port>{config['clickhouse']['port']}</port>
</replica>
"""
metrika_config += """ </shard>
"""
metrika_config += f""" </{cluster_name}>
</clickhouse_remote_servers>
<zookeeper>
"""
for zk_host in zookeeper_hosts:
host, port = zk_host.split(':')
metrika_config += f""" <node>
<host>{host}</host>
<port>{port}</port>
</node>
"""
metrika_config += """ </zookeeper>
<macros>
<shard>{shard}</shard>
<replica>{replica}</replica>
</macros>
<networks>
<ip>::/0</ip>
</networks>
<clickhouse_compression>
<case>
<min_part_size>10000000000</min_part_size>
<min_part_size_ratio>0.01</min_part_size_ratio>
<method>lz4</method>
</case>
</clickhouse_compression>
</yandex>"""
# 写入配置文件
with open('/etc/clickhouse-server/config.d/metrika.xml', 'w') as f:
f.write(metrika_config.format(shard=1, replica=1))
print("集群配置已生成")
EOF
}
# 创建分布式表
create_distributed_tables() {
local config_file=$1
log_info "创建分布式表..."
python3 <<-EOF
import yaml
import os
with open('$config_file', 'r') as f:
config = yaml.safe_load(f)
cluster_name = config['cluster']['name']
distributed_sql_commands = [
f"""
CREATE DATABASE IF NOT EXISTS cluster_db ON CLUSTER {cluster_name};
""",
f"""
CREATE TABLE IF NOT EXISTS cluster_db.local_table ON CLUSTER {cluster_name}
(
id UInt32,
name String,
timestamp DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{{shard}}/local_table', '{{replica}}')
ORDER BY id
PARTITION BY toYYYYMM(timestamp);
""",
f"""
CREATE TABLE IF NOT EXISTS cluster_db.distributed_table ON CLUSTER {cluster_name}
AS cluster_db.local_table
ENGINE = Distributed({cluster_name}, cluster_db, local_table, rand());
"""
]
# 保存SQL脚本
with open('/tmp/distributed_tables.sql', 'w') as f:
for cmd in distributed_sql_commands:
f.write(cmd + "\n")
print("分布式表创建脚本已生成")
EOF
}
# 配置防火墙
configure_firewall() {
log_info "配置防火墙规则..."
local ports=(9000 9009 8123 8443 2181)
if command -v firewall-cmd &> /dev/null; then
for port in "${ports[@]}"; do
firewall-cmd --permanent --add-port=${port}/tcp 2>/dev/null || true
done
firewall-cmd --reload
elif command -v ufw &> /dev/null; then
for port in "${ports[@]}"; do
ufw allow ${port}/tcp
done
ufw reload
fi
log_info "防火墙配置完成"
}
# 启动服务
start_services() {
log_info "启动ClickHouse服务..."
systemctl daemon-reload
systemctl enable clickhouse-server
systemctl start clickhouse-server
# 等待服务启动
sleep 5
if systemctl is-active --quiet clickhouse-server; then
log_info "ClickHouse服务启动成功"
else
log_error "ClickHouse服务启动失败"
tail -50 /var/log/clickhouse-server/clickhouse-server.err.log
exit 1
fi
}
# 验证集群
verify_cluster() {
log_info "验证集群状态..."
# 检查集群节点
clickhouse-client -q "SELECT * FROM system.clusters WHERE cluster = '$(grep -oP 'cluster: \K.*' cluster-config.yaml)'" FORMAT PrettyCompact
# 检查复制表
clickhouse-client -q "SELECT * FROM system.replicas" FORMAT PrettyCompact
log_info "集群验证完成"
}
# 主函数
main() {
check_root
local config_file=$1
if [ ! -f "$config_file" ]; then
log_error "配置文件 $config_file 不存在"
exit 1
fi
log_info "开始部署ClickHouse集群..."
# 安装依赖
install_dependencies
# 读取配置中的版本号
local version=$(python3 -c "import yaml; print(yaml.safe_load(open('$config_file'))['clickhouse']['version'])")
# 配置SSH免密登录
setup_ssh "$config_file"
# 安装ClickHouse
install_clickhouse "$version"
# 生成集群配置
generate_cluster_config "$config_file"
# 创建分布式表
create_distributed_tables "$config_file"
# 配置防火墙
configure_firewall
# 启动服务
start_services
# 创建分布式表
clickhouse-client --multiquery < /tmp/distributed_tables.sql
# 验证集群
verify_cluster
log_info "ClickHouse集群部署完成!"
log_info "以下节点已配置完成:"
python3 -c "
import yaml
with open('$config_file', 'r') as f:
config = yaml.safe_load(f)
for node in config['nodes']:
print(f\" - {node['hostname']} ({node['host']}): Shard {node['shard']}, Replica {node['replica']}\")
"
}
# 执行主函数
main "$@"
一键部署脚本
deploy-cluster.sh
#!/bin/bash
set -e
echo "=== ClickHouse集群快速部署脚本 ==="
echo ""
# 检查参数
if [ $# -lt 1 ]; then
echo "用法: $0 <配置文件路径>"
echo "示例: $0 cluster-config.yaml"
exit 1
fi
CONFIG_FILE=$1
# 配置检查
echo "1. 检查配置文件..."
python3 -c "
import yaml
try:
with open('$CONFIG_FILE', 'r') as f:
config = yaml.safe_load(f)
print('配置文件格式正确')
print(f'集群名称: {config[\"cluster\"][\"name\"]}')
print(f'分片数: {config[\"cluster\"][\"shards\"]}')
print(f'副本数: {config[\"cluster\"][\"replicas\"]}')
print(f'节点数: {len(config[\"nodes\"])}')
print(f'ClickHouse版本: {config[\"clickhouse\"][\"version\"]}')
except Exception as e:
print(f'配置文件错误: {e}')
exit(1)
"
# 确认部署
echo ""
echo "2. 确认部署信息"
read -p "是否继续部署? (y/n): " confirm
if [[ $confirm != "y" && $confirm != "Y" ]]; then
echo "部署已取消"
exit 0
fi
# 获取本地IP
LOCAL_IP=$(hostname -I | awk '{print $1}')
python3 -c "
import yaml
with open('$CONFIG_FILE', 'r') as f:
config = yaml.safe_load(f)
for node in config['nodes']:
if node['host'] == '$LOCAL_IP':
print(f'本机节点: {node[\"hostname\"]} (Shard {node[\"shard\"]}, Replica {node[\"replica\"]})')
break
"
# 开始部署
echo ""
echo "3. 开始部署..."
bash install-clickhouse-cluster.sh "$CONFIG_FILE"
# 检查部署结果
if [ $? -eq 0 ]; then
echo ""
echo "=== 部署完成! ==="
echo ""
echo "管理命令:"
echo " 查看集群状态: clickhouse-client -q \"SELECT * FROM system.clusters FORMAT PrettyCompact\""
echo " 查看复制表: clickhouse-client -q \"SELECT * FROM system.replicas FORMAT PrettyCompact\""
echo " 查询数据: clickhouse-client -q \"SELECT * FROM cluster_db.distributed_table\""
echo ""
echo "Web界面: http://$LOCAL_IP:8123/"
echo "用户名: default"
echo "密码: (空)"
else
echo "部署失败,请检查日志"
exit 1
fi
使用说明
配置使用步骤:
-
生成配置文件:
# 根据实际环境修改 cluster-config.yaml # 修改IP地址、主机名、分片配置等
-
在第一个节点执行:
# 上传脚本到第一个节点 scp install-clickhouse-cluster.sh deploy-cluster.sh cluster-config.yaml root@192.168.1.10:/root/
登录到第一个节点执行
ssh root@192.168.1.10 chmod +x install-clickhouse-cluster.sh deploy-cluster.sh ./deploy-cluster.sh cluster-config.yaml
3. **在其他节点执行**:
```bash
# 在其他节点重复相同的操作
scp install-clickhouse-cluster.sh deploy-cluster.sh cluster-config.yaml root@192.168.1.11:/root/
ssh root@192.168.1.11
chmod +x install-clickhouse-cluster.sh deploy-cluster.sh
./deploy-cluster.sh cluster-config.yaml
常见问题排查:
# 检查服务状态 systemctl status clickhouse-server # 查看日志 tail -f /var/log/clickhouse-server/clickhouse-server.log # 测试连接 clickhouse-client -h localhost -q "SELECT 1" # 检查集群配置 clickhouse-client -q "SELECT * FROM system.clusters" # 检查ZooKeeper连接 clickhouse-client -q "SELECT * FROM system.zookeeper WHERE path = '/'"
这个脚本会自动完成ClickHouse集群的安装、配置、表创建和验证,根据实际环境修改配置文件中的IP地址和配置参数后即可使用。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播