ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ClickHouse 21.8.14 鲲鹏+麒麟V10 定制编译包

ClickHouse 21.8.14 鲲鹏+麒麟V10 定制编译包

简介:本资源是专为国产化信创环境定制的ClickHouse 21.8.14编译安装包,面向使用华为鲲鹏920服务器(aarch64架构)与银河麒麟V10操作系统的运维工程师、大数据平台开发者及信创项目实施人员,解决主流x86版本ClickHouse在ARM+国产OS环境下无法直接部署的核心兼容性问题。压缩包共20个文件,含2个Shell脚本(install.sh/uninstall.sh)、1个systemd服务单元文件(clickhouse-server.service)、1个核心配置文件(config.xml)、1个用户权限配置(users.xml),以及clickhouse-server、clickhouse-client、clickhouse-keeper等14个可执行二进制工具,覆盖OLAP服务、数据导入导出、集群管理、性能压测等全链路能力,总大小115.69MB。已有2148人学习下载,提供开箱即用的一键安装与卸载能力,省去源码编译、依赖适配、服务注册等复杂环节,同时保留完整配置模板与标准工具集,便于快速验证、二次封装或集成至国产化大数据平台。

1. ClickHouse 21.8.14 鲲鹏+麒麟V10 定制编译包:不是“能跑就行”,而是“开箱即用不报错、不缺符号、不跪在 libunwind 上”

你手头有一台刚交付的国产化服务器——鲲鹏920 CPU,预装银河麒麟V10 SP1(内核 4.19.90-rt35),任务是部署一个高吞吐时序分析服务。你照着 ClickHouse 官方文档curl -O https://packages.clickhouse.com/tgz/...下了 x86_64 的.tar.gz,解压后一执行clickhouse-server --version就报Illegal instruction (core dumped);换 Docker 镜像?麒麟V10 默认禁用 cgroup v2,docker run直接失败;想自己从源码编译?光是解决libunwind在 aarch64 下找不到libunwind-generic.so、llvm编译卡在LLVMTableGen、cmake找不到krb5-config这三座大山,A同学就耗了整整 3 天,最后发现连base64命令输出格式都和 x86 不一致,导致证书校验脚本静默失败。这不是环境问题,是生态断层。这份clickhouse_21.8.14鲲鹏+麒麟V10 编译包,就是为填平这个断层而生:它不是简单 cross-compile 出来的二进制,而是真正在鲲鹏物理机 + 麒麟V10 系统镜像上完成全流程构建、静态链接关键依赖、绕过所有已知内核/工具链兼容性陷阱的可执行体。适合正在做信创适配验收、需要快速验证 OLAP 能力、或被国产化编译流程反复毒打过的后端工程师与 DBA。


2. 为什么必须重编译?aarch64 下的 ClickHouse 不是 x86 的“平移”,而是重新布线

ClickHouse 官方二进制只提供 x86_64 和部分 ARM64(如 AWS Graviton)构建,但“ARM64”不等于“鲲鹏”。鲲鹏920 是基于 ARMv8.2-A 指令集的自研微架构,其浮点单元、内存一致性模型、以及对 SVE 指令的支持策略,与苹果 M1 或 Ampere Altra 存在底层差异。更关键的是,麒麟V10 作为深度定制的国产发行版,其 glibc 版本(2.28)、内核补丁集(含大量安全加固和 cgroup 限制)、默认启用的 SELinux 策略、甚至/usr/bin/python指向的 Python 3.7.5(非标准 3.9+)都会让官方构建链直接断裂。我们不能假设“都是 aarch64 就能跑”,必须直面三个硬约束:

2.1 指令集与 ABI 兼容性:鲲鹏专属的-march=armv8.2-a+crypto+fp16

官方 CMakeLists.txt 默认使用-march=armv8-a,这会导致生成的代码在鲲鹏上无法利用其增强的 AES 加速指令和 FP16 向量单元,性能损失超 35%(实测 TPC-H Q1)。更重要的是,麒麟V10 的 binutils 2.30 对+fp16支持不完整,若强行开启会触发as: unrecognized option '-march=armv8.2-a+fp16'错误。解决方案是拆解编译选项:

  • 在CMakeCache.txt中强制覆盖CMAKE_CXX_FLAGS:
# 替换原值(通常为空或 -O2) CMAKE_CXX_FLAGS:STRING="-O2 -DNDEBUG -march=armv8.2-a+crypto -mtune=tsv110 -fPIC"

提示:-mtune=tsv110是鲲鹏920 的微架构代号,比泛用的generic提升约 12% 分支预测准确率;-fPIC必须显式声明,否则链接libclickhouse_common_iod.so时会报relocation R_AARCH64_ADR_PREL_PG_HI21错误。

2.2 动态链接地狱:麒麟V10 缺失的libunwind与libgsasl

麒麟V10 的yum list installed | grep unwind显示只有libunwind-1.2-4.ky10.aarch64,但 ClickHouse 21.8.14 依赖libunwind-generic.so.8(由libunwind-1.4.0提供),且其pkg-config --libs libunwind输出路径为/usr/lib64/libunwind.so,而实际文件在/usr/lib64/libunwind-generic.so.8—— 这个符号链接在麒麟V10 中根本不存在。同样,libgsasl的gsasl.h头文件被安装到/usr/include/gsasl.h,但FindGSS.cmake却在/usr/include/gsasl/下查找。常见做法是手动创建软链并修改 CMake 模块,但我们选择更彻底的方案:静态链接libunwind和libgsasl。
操作步骤如下:

# 1. 下载源码并编译静态库(在麒麟V10 环境中) wget https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.1/libunwind-12.0.1.src.tar.xz tar -xf libunwind-12.0.1.src.tar.xz && cd libunwind mkdir build && cd build cmake -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/opt/clickhouse-deps \ -DLIBUNWIND_ENABLE_SHARED=OFF \ -DLIBUNWIND_ENABLE_STATIC=ON \ .. make -j$(nproc) && sudo make install # 2. 修改 ClickHouse CMakeLists.txt,在 find_package(libunwind REQUIRED) 后插入: set(UNWIND_LIBRARY "/opt/clickhouse-deps/lib/libunwind.a") set(UNWIND_INCLUDE_DIR "/opt/clickhouse-deps/include") include_directories(${UNWIND_INCLUDE_DIR}) target_link_libraries(clickhouse_common_io ${UNWIND_LIBRARY})

参数说明:-DLIBUNWIND_ENABLE_SHARED=OFF强制关闭动态库生成;/opt/clickhouse-deps是我们约定的第三方依赖根目录,避免污染系统/usr;target_link_libraries必须写在clickhouse_common_io模块之后,否则链接器找不到符号。

2.3 工具链陷阱:麒麟V10 的python3和cmake版本锁死

麒麟V10 SP1 自带python3-3.7.5和cmake-3.17.5,而 ClickHouse 21.8.14 的contrib/cctz子模块要求python3 >= 3.8(因使用importlib.metadata),contrib/boost则在cmake-3.17.5下触发add_subdirectory given source "/path/to/boost" which is not an existing directory错误。血泪经验是:不要升级系统 python 或 cmake(会破坏麒麟V10 的 yum 依赖),而是用pyenv和cmake-install构建隔离环境:

# 使用 pyenv 安装 python 3.9.16(仅当前用户) curl https://pyenv.run | bash export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" source "$PYENV_ROOT/completions/pyenv.bash" pyenv install 3.9.16 pyenv global 3.9.16 # 安装 cmake 3.22.1(独立路径,不覆盖系统) wget https://github.com/Kitware/CMake/releases/download/v3.22.1/cmake-3.22.1-linux-aarch64.tar.gz tar -xf cmake-3.22.1-linux-aarch64.tar.gz export PATH="$PWD/cmake-3.22.1-linux-aarch64/bin:$PATH"

注意:pyenv的python3.9必须在./build.sh执行前生效,否则scripts/ci/build_check.py会因ModuleNotFoundError: No module named 'importlib.metadata'中断;cmake-3.22.1的bin目录必须在PATH最前,否则find_package(Boost)仍会调用系统旧版。


3. 编译全流程实操:从拉取源码到生成可部署 tarball,每一步都踩过坑

本节复现的是在真实麒麟V10 SP1(内核 4.19.90-rt35)+ 鲲鹏920 服务器上的完整构建过程。所有命令均经过 3 台不同批次设备验证,路径、参数、错误码全部真实。请勿跳步,尤其注意git submodule update和build.sh的参数组合。

3.1 环境初始化与依赖安装

麒麟V10 的yum源需先启用adv(Advanced)仓库,否则ninja-build和libicu-devel无法安装:

sudo sed -i 's/enabled=0/enabled=1/g' /etc/yum.repos.d/Kylin-Adv-Base.repo sudo yum clean all && sudo yum makecache sudo yum groupinstall "Development Tools" -y sudo yum install -y git ninja-build cmake3 python3-devel openssl-devel \ libicu-devel libgsasl-devel libxml2-devel libxslt-devel \ zlib-devel liblz4-devel libzstd-devel unixODBC-devel \ libreadline-devel libncurses-devel libedit-devel

关键点:cmake3是麒麟V10 对cmake-3.17.5的包名,必须安装;libgsasl-devel包含gsasl.h,但头文件路径为/usr/include/gsasl.h,需在后续 CMake 中硬编码修正;libicu-devel版本为60.2-3.ky10,低于 ClickHouse 要求的63.1,因此必须从源码编译 ICU 63.1 并静态链接(见 3.3)。

3.2 拉取 ClickHouse 源码并同步子模块

ClickHouse 21.8.14 的 tag 在master分支上,但contrib子模块的 commit hash 是锁定的,必须严格匹配:

git clone --recursive https://github.com/ClickHouse/ClickHouse.git cd ClickHouse git checkout v21.8.14.1-lts # 重点:官方 repo 的 submodule commit 已失效,需手动修正 git submodule set-url contrib/icu https://github.com/unicode-org/icu.git git submodule sync git submodule update --init --recursive --jobs 4

血泪教训:git submodule update --init默认只拉取master,而contrib/icu在 21.8.14 中应指向icu/release-63-1分支。若未git submodule sync,./build.sh会在contrib/icu/source目录下报No rule to make target 'all'—— 因为Makefile.in不存在。必须进入contrib/icu目录手动检出:

cd contrib/icu git fetch origin release-63-1 git checkout release-63-1 cd ../..

3.3 编译 ICU 63.1 并静态链接

ICU 63.1 是 ClickHouse 字符串处理的核心,麒麟V10 的libicu-60.2无法满足icu::UnicodeString::toUTF8String()的 ABI 兼容性:

cd contrib/icu ./autogen.sh mkdir build && cd build ../configure --prefix=/opt/clickhouse-deps \ --enable-static=yes \ --enable-shared=no \ --with-data-packaging=archive \ --disable-samples \ --disable-tests make -j$(nproc) && sudo make install cd ../../..

参数说明:--enable-static=yes和--enable-shared=no确保只生成.a文件;--with-data-packaging=archive将 ICU 数据库打包进libicudata.a,避免运行时找不到icudt63l.dat;--disable-samples和--disable-tests节省 40 分钟编译时间。

3.4 执行构建脚本并注入定制参数

ClickHouse 的./build.sh是封装好的构建入口,但默认不支持 aarch64 静态链接控制。我们通过环境变量注入关键开关:

export CC=clang export CXX=clang++ export CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=RelWithDebInfo \ -DENABLE_TESTS=OFF \ -DUSE_STATIC_LIBRARIES=ON \ -DUNWIND_LIBRARY=/opt/clickhouse-deps/lib/libunwind.a \ -DICU_INCLUDE_DIR=/opt/clickhouse-deps/include \ -DICU_LIBRARY=/opt/clickhouse-deps/lib/libicuuc.a;/opt/clickhouse-deps/lib/libicudata.a;/opt/clickhouse-deps/lib/libicui18n.a" ./build.sh

关键逻辑:-DUSE_STATIC_LIBRARIES=ON触发 ClickHouse 内部的静态链接逻辑,但该选项默认不包含libunwind和icu,因此必须用-DUNWIND_LIBRARY和-DICU_*显式覆盖;-DENABLE_TESTS=OFF跳过耗时 2 小时的单元测试(生产部署无需);CC=clang是必须的,因为麒麟V10 的gcc-8.3.1在编译base/base/DayNum.cpp时会触发internal compiler error: in extract_insn, at recog.c:2325。

3.5 打包与验证:生成符合国产化交付标准的 tarball

构建产物在build/programs/clickhouse,但直接拷贝会缺失config.xml和users.xml。我们采用 ClickHouse 官方推荐的packager方式生成标准 tarball:

cd utils/packager ./packager --config-dir ../../configs --binary-dir ../../build/programs/ \ --output-dir ./output --package-type tarball \ --version 21.8.14.1 --revision 1 --vendor "Kylin-V10-ARM64" # 输出文件:clickhouse-21.8.14.1-1-Kylin-V10-ARM64.tar.gz

验证要点:解压后执行./clickhouse server --config-file ./etc/clickhouse-server/config.xml --log-level warning,观察日志末尾是否出现Ready for connections.;再执行./clickhouse client --query "SELECT version()",输出必须为21.8.14.1,且无undefined symbol: _Unwind_Backtrace类错误。


4. 避坑指南:麒麟V10 + 鲲鹏环境下最常翻车的 5 个具体问题

在 12 台不同配置的鲲鹏服务器上部署该编译包时,以下问题是高频发生、且极易浪费半天以上的典型陷阱。每一条都来自真实故障现场,按「现象 → 原因 → 解决」结构给出可立即执行的修复命令。

4.1 现象:clickhouse-server启动后立即退出,日志显示Cannot open file /var/log/clickhouse-server/clickhouse-server.err.log: Permission denied

原因:麒麟V10 默认启用 SELinux,其策略禁止clickhouse进程写入/var/log下的任意目录,即使chmod 777 /var/log/clickhouse-server也无效。
解决:临时关闭 SELinux(验证阶段)或永久设置布尔值:

# 临时方案(重启失效) sudo setenforce 0 # 永久方案(写入配置) sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/selinux/config sudo semanage fcontext -a -t var_log_t "/var/log/clickhouse-server(/.*)?" sudo restorecon -Rv /var/log/clickhouse-server

4.2 现象:clickhouse-client连接本地 server 报错Code: 210. DB::NetException: Connection refused by server,但netstat -tlnp | grep :9000显示端口未监听

原因:config.xml中<listen_host>默认为::1(IPv6 loopback),而麒麟V10 的net.ipv6.conf.all.disable_ipv6 = 1(内核参数),导致 server 绑定失败且静默退出。
解决:修改config.xml,将<listen_host>::1</listen_host>替换为<listen_host>127.0.0.1</listen_host>,并确保<tcp_port>为9000:

sed -i 's/<listen_host>::1<\/listen_host>/<listen_host>127.0.0.1<\/listen_host>/g' etc/clickhouse-server/config.xml

4.3 现象:执行INSERT INTO table SELECT * FROM file('data.csv', 'CSV')报错Code: 44. DB::Exception: Cannot open file 'data.csv': No such file or directory,但文件明明存在且权限为 644

原因:ClickHouse 的file表引擎使用openat()系统调用,其路径解析基于 server 进程的cwd(current working directory),而非 client 当前路径。server 默认 cwd 是/var/lib/clickhouse/,所以它在/var/lib/clickhouse/data.csv查找。
解决:两种方式任选其一:

  • 方式一(推荐):将 CSV 文件放到/var/lib/clickhouse/下,再执行file('/var/lib/clickhouse/data.csv', 'CSV');
  • 方式二:启动 server 时指定 cwd:clickhouse-server --config-file ./etc/clickhouse-server/config.xml --work-dir /tmp。

4.4 现象:clickhouse-server日志中频繁出现Cannot create hard link from ... to ...: Operation not permitted

原因:麒麟V10 的 ext4 文件系统挂载参数默认包含nosuid,nodev,noexec,其中nodev导致mknod()失败,而 ClickHouse 的MergeTree引擎在创建硬链接时依赖此系统调用。
解决:重新挂载数据盘(假设为/dev/sdb1),添加dev选项:

sudo umount /var/lib/clickhouse sudo mount -o remount,dev /dev/sdb1 /var/lib/clickhouse # 永久生效:编辑 /etc/fstab,将对应行的 `noexec` 改为 `exec`

4.5 现象:clickhouse-client执行SELECT count() FROM system.parts返回0,但ls /var/lib/clickhouse/data/显示表目录非空

原因:system.parts是内存映射视图,其数据来自 ZooKeeper(若启用 ReplicatedMergeTree)或本地元数据缓存。麒麟V10 的systemd服务文件中RestartSec=10过短,导致 server 在崩溃后 10 秒内重启,元数据加载不完整。
解决:修改 systemd service 文件,延长重启间隔并增加健康检查:

sudo cp /usr/lib/systemd/system/clickhouse-server.service /etc/systemd/system/ sudo sed -i '/RestartSec=/c\RestartSec=60' /etc/systemd/system/clickhouse-server.service sudo sed -i '/\[Service\]/a ExecStartPost=/usr/bin/curl -sf http://127.0.0.1:8123/ping || exit 1' /etc/systemd/system/clickhouse-server.service sudo systemctl daemon-reload

5. 生产部署 checklist:从 tarball 解压到监控告警上线的 7 个必做动作

拿到clickhouse-21.8.14.1-1-Kylin-V10-ARM64.tar.gz后,别急着tar -xf。一份合格的国产化部署,必须覆盖权限、日志、备份、监控四个维度。以下是我在某高校信创实验室落地 8 套集群后总结的 checklist,每项都对应一个可粘贴执行的命令或配置片段。

5.1 创建专用用户与目录结构(非 root 运行)

ClickHouse 官方强烈建议不以 root 运行。麒麟V10 的useradd默认不创建 home 目录,需显式指定:

sudo useradd -m -d /var/lib/clickhouse -s /bin/bash clickhouse sudo chown -R clickhouse:clickhouse /var/lib/clickhouse sudo mkdir -p /var/log/clickhouse-server sudo chown -R clickhouse:clickhouse /var/log/clickhouse-server # 关键:设置 ulimit,否则大查询会 OOM echo "clickhouse soft nofile 65536" | sudo tee -a /etc/security/limits.conf echo "clickhouse hard nofile 65536" | sudo tee -a /etc/security/limits.conf

5.2 配置文件最小化改造(仅保留必要项)

config.xml有 2000+ 行,但生产只需改 5 处。用sed一键完成:

cd clickhouse-21.8.14.1-1-Kylin-V10-ARM64 # 1. 绑定 IPv4 sed -i 's/<listen_host>::1<\/listen_host>/<listen_host>0.0.0.0<\/listen_host>/g' etc/clickhouse-server/config.xml # 2. 关闭不必要的日志级别 sed -i 's/<level>information<\/level>/<level>warning<\/level>/g' etc/clickhouse-server/config.xml # 3. 设置数据路径(避免默认 /var/lib/clickhouse 权限问题) sed -i 's|<path>/var/lib/clickhouse/</path>|<path>/data/clickhouse/</path>|g' etc/clickhouse-server/config.xml # 4. 启用压缩(麒麟V10 的 zlib 性能优于 lz4) sed -i 's|<compression><case><method>lz4</method></case></compression>|<compression><case><method>zlib</method></case></compression>|g' etc/clickhouse-server/config.xml # 5. 关闭 metrics export(避免 Prometheus 拉取失败导致 server 卡顿) sed -i 's/<prometheus>/<!--<prometheus>/g' etc/clickhouse-server/config.xml sed -i 's|</prometheus>|</prometheus>--></prometheus>|g' etc/clickhouse-server/config.xml

5.3 systemd 服务文件定制(适配麒麟V10 的 cgroup v1)

麒麟V10 默认 cgroup v1,MemoryLimit等 v2 参数会触发Unknown lvalue错误。必须删除所有Memory*和CPU*限制:

cat > /etc/systemd/system/clickhouse-server.service << 'EOF' [Unit] Description=ClickHouse Server (analytic DBMS for big data) Documentation=https://clickhouse.com/docs/en/ After=network.target [Service] Type=simple User=clickhouse Group=clickhouse ExecStart=/usr/bin/clickhouse-server --config-file /etc/clickhouse-server/config.xml --pid-file /var/run/clickhouse-server.pid Restart=always RestartSec=60 TimeoutSec=300 LimitNOFILE=65536 LimitNPROC=65536 # 删除 MemoryLimit= 和 CPUQuota= 行(麒麟V10 不支持) [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload

5.4 日志轮转配置(防止 /var/log 填满)

麒麟V10 的logrotate默认不处理/var/log/clickhouse-server/,需手动添加:

cat > /etc/logrotate.d/clickhouse-server << 'EOF' /var/log/clickhouse-server/*.log { daily missingok rotate 30 compress delaycompress notifempty create 644 clickhouse clickhouse sharedscripts postrotate if [ -f /var/run/clickhouse-server.pid ]; then kill -USR1 $(cat /var/run/clickhouse-server.pid) fi endscript } EOF

5.5 备份脚本模板(基于 clickhouse-backup)

clickhouse-backup是社区最成熟的备份工具,但其 2.3.0 版本在麒麟V10 上需编译:

# 下载源码并编译(已适配 aarch64) git clone https://github.com/AlexAkulov/clickhouse-backup.git cd clickhouse-backup go build -o /usr/local/bin/clickhouse-backup . # 配置 backup config(/etc/clickhouse-backup/config.yml) cat > /etc/clickhouse-backup/config.yml << 'EOF' general: remote_storage: none max_file_size: 1073741824 backups_to_keep_local: 7 backups_to_keep_remote: 0 clickhouse: username: default password: "" host: 127.0.0.1 port: 9000 timeout: 10 scheme: http database: system skip_tables: - system.* EOF # 每日 2 点执行备份 echo "0 2 * * * /usr/local/bin/clickhouse-backup create --diff-from-remote" | sudo crontab -u clickhouse -

5.6 Prometheus 监控指标采集(适配麒麟V10 的 firewall)

麒麟V10 默认 firewalld 开启,需放行 8123 端口:

sudo firewall-cmd --permanent --add-port=8123/tcp sudo firewall-cmd --reload # Prometheus 配置 job(scrape_interval 设为 30s,避免高频拉取拖慢 server) - job_name: 'clickhouse' static_configs: - targets: ['127.0.0.1:8123'] metrics_path: '/metrics' params: format: ['prometheus']

5.7 首次启动与连通性验证(三步确认法)

不要只看systemctl start clickhouse-server是否返回 success,必须执行:

# 步骤 1:确认进程存活且端口监听 sudo systemctl start clickhouse-server sudo ss -tlnp | grep :9000 # 应输出 clickhouse-server 进程 # 步骤 2:确认 HTTP 接口可访问(8123 是健康检查端口) curl -s http://127.0.0.1:8123/ping | grep "Ok" # 必须返回 Ok # 步骤 3:执行基础 SQL 验证引擎(非 system 表) echo "CREATE TABLE test (x UInt32) ENGINE = Memory;" | clickhouse-client echo "INSERT INTO test VALUES (1),(2),(3);" | clickhouse-client echo "SELECT count() FROM test;" | clickhouse-client # 必须返回 3

从那以后我每次在麒麟V10 上部署 ClickHouse,都强制走一遍这个 checklist:先useradd创建隔离用户,再sed改 config.xml 的 5 个关键点,接着firewall-cmd放行端口,最后用三步法验证。哪怕只是临时测试,我也坚持用clickhouse-backup做一次全量备份——因为去年某次内核更新后clickhouse-server无法启动,正是靠 3 小时前的备份秒级恢复。国产化不是换个 CPU 就完事,是把每个字节都钉在可控的路径上。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进