尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ClickHouse 25.4 Docker单机部署实战:从零搭建到备份恢复

ClickHouse 25.4 Docker单机部署实战:从零搭建到备份恢复 ClickHouse 25.4 基于 Docker 单机部署实战指南ClickHouse 25.4 基于 Docker 单机部署是我这半年在测试环境和生产小集群里来回折腾后觉得最值得写下来的一套组合。很多人第一次接触 ClickHouse习惯直接去官网扒二进制包或者用 apt 装结果不是被系统依赖坑了就是升级的时候把自己搞到崩溃而 Docker 单机部署恰好能绕开这堆破事——镜像一拉目录一挂几分钟就能起来一个能跑查询、能接数据、能备份恢复的实例。这篇文章就是给那些准备上手 ClickHouse又不想在环境部署上浪费太多时间的人看的不管是做数据分析、日志存储还是简单的用户画像场景照着下面的步骤走一遍基本都能顺利落地。1. 部署选型为什么单机环境也要走 Docker1.1 三种部署方式对比别再一上来就 apt install先说结论单机部署 ClickHouseDocker 不一定是最“原生”的方式但一定是最省心的方式。我把三种常见方式都试过放在一起对比会更直观部署方式安装速度升级成本系统耦合适合场景官方DEB/RPM包快但依赖多中需停服操作高库版本可能冲突已用包管理维护的服务端二进制tar.gz解压快无依赖中需手动迁数据低但配置全靠手写对目录结构有洁癖的人Docker容器最快一条命令极低换镜像即可极低仅依赖内核个人开发、测试、快速交付我自己最早是在一台 CentOS 7 上用的二进制包部署当时图它“原生、没中间层”。后来做版本升级从 23.8 升到 24.3光备份数据、停服务、替换二进制、恢复权限就折腾了一个下午。换成 Docker 之后升级就是先 docker pull 新版本镜像再 docker compose up -d 重新创建容器数据目录原封不动挂进去起来就是新版本。这种体验上的差距只有被旧方式折磨过的人才懂。1.2 部署前先检查宿主机 Docker 环境不然全是坑很多人的 ClickHouse 还没开始部署先卡在 Docker 本身起不来。这里我把常见的宿主机环境检查项列出来你对照着过一遍省得后面踩坑。Windows 用户如果装的是 Docker Desktop最经典的问题就是启动时报错Virtualization support not detected 或者 Docker Desktop failed to start because virtualization support wasnt detected。这基本就是 Hyper-V 或者 WSL2 没开。我的建议是直接装 WSL2 内核然后在 Docker Desktop Settings 里把 Use WSL 2 based engine 勾上如果 BIOS 里虚拟化被关掉了那还得进 BIOS 把 Intel VT-x 或 AMD SVM 打开这一步没法绕过。还有一类报错是 Failed to connect to the docker api at npipe:////./pipe/docker_engine这个多半是 Docker Desktop 服务没起来或者装了之后没完全启动到 Windows 服务列表里确认 Docker Desktop Service 在运行再不行就以管理员身份重启一下 Docker Desktop。Linux 用户相对省事但也要注意两点。第一docker 服务启动失败时先 systemctl status docker 看日志常见原因是 selinux 拦截临时可以 setenforce 0 验证长期建议在 /etc/selinux/config 里改掉或者配置正确的策略。第二老系统上 docker 版本太低很多新镜像的配置项不支持干脆把老版本卸干净用官方脚本重装一版新的。我在 Ubuntu 20.04 上就处理过一次 docker 服务起不来的问题最后发现是 /var/lib/docker 所在分区满了日志和镜像把空间吃完了清理之后就恢复了。1.3 镜像拉取慢怎么办先配置镜像加速源国内网络环境下docker pull 拉官方镜像慢是常态ClickHouse 官方镜像有好几百 MB不快一点真的很影响心情。解决思路很简单就是给 Docker 配置镜像加速源。Linux 上改 /etc/docker/daemon.jsonWindows 上在 Docker Desktop 的 Settings - Docker Engine 里改同一份 JSON加一段 registry-mirrors 就可以。改完必须重启 docker 服务或重启 Docker Desktop 才生效可以 docker info 查看 Registry Mirrors 一栏确认是否生效。用的时候可以这样写{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ] }注意镜像加速源属于“尽力而为”的服务偶尔失效是正常的所以我一般同时配两个。如果拉取还是很慢就换个时间段再拉或者找一台网络好的机器把镜像 save 成 tar 包再 load 到目标机器上。这个方法在离线环境特别管用。提示配置完镜像源之后如果 docker pull 仍然报 timeout 或 EOF不要死磕一个源直接换一个再试多数情况是源又挂了。2. 镜像选择与核心配置解析搞懂这些参数再动手2.1 ClickHouse 25.4 版本号怎么看镜像 tag 怎么选ClickHouse 的版本号规则很多人看不懂其实非常简单主版本号前两位是年份后两位是月份。25.4 就是 2025 年 4 月发布的版本。这种按月发版的节奏意味着功能迭代很快但同时也说明你没必要追最新选一个够用、够稳的版本长期用就行。官方 Docker 镜像的命名是 clickhouse/clickhouse-servertag 直接对应版本号比如 clickhouse/clickhouse-server:25.4。镜像 tag 的选择我有一条比较保守的经验生产环境选 .2 或 .3 这种小版本比如 25.4.3 这种因为大版本刚发布时可能会有一些边角 bug后续小版本会针对性地修掉测试环境就无所谓latest 也能用但 latest 本质上是一个滚动标签今天拉的 latest 和三个月后拉的 latest 不是一个东西如果你需要可复现的环境千万别用 latest。我见过有人写 docker-compose.yml 时图省事用 latest结果半年后重新部署了一个新版本配置语法变了服务起不来排查了半天才发现是镜像变了。2.2 docker-compose.yml 逐项拆解每个参数都有讲究部署 ClickHouse 单机版我强烈建议用 docker compose而不是裸 docker run。docker compose 可以把端口、目录、环境变量、资源限制全部固化到文件里换机器迁移时只需要带上这个文件和数据目录其他什么都不用管。下面是我实测过的一套配置version: 3.8 services: clickhouse: image: clickhouse/clickhouse-server:25.4 container_name: clickhouse-server restart: unless-stopped ports: - 8123:8123 - 9000:9000 - 9009:9009 ulimits: nofile: soft: 262144 hard: 262144 volumes: - ./data:/var/lib/clickhouse - ./logs:/var/log/clickhouse-server - ./config.d:/etc/clickhouse-server/config.d:ro - ./users.d:/etc/clickhouse-server/users.d:ro environment: - TZAsia/Shanghai - CLICKHOUSE_PASSWORDyour_strong_password - CLICKHOUSE_DBdefault - CLICKHOUSE_USERdefault mem_limit: 4g先说端口。8123 是 HTTP 接口用来跑查询、接 BI 工具9000 是 native 协议端口clickhouse-client 和大部分驱动程序都走这个9009 是集群内部数据复制用的单机部署其实用不到但保留端口方便以后扩展成集群。如果 9000 端口被其他服务占了可以在宿主机侧改映射比如 19000:9000客户端连接时指定端口 19000 就行。再说挂载目录。/var/lib/clickhouse 是数据目录必须挂出来否则容器一删数据全没了/var/log/clickhouse-server 是日志目录挂出来是为了排查问题方便config.d 和 users.d 是自定义配置目录ClickHouse 会自动读取这两个目录下的 xml 文件用来覆盖镜像内的默认配置。这种“只读挂载配置文件”的做法相当于把配置变更和镜像解耦改配置不需要重做镜像只需要改宿主机上的文件再重启容器。ulimits 里 nofile 设置文件句柄数上限是必须的ClickHouse 官方文档也建议调高这个值。因为 ClickHouse 是列式存储查询时一个分区会打开很多文件默认的 1024 句柄根本不够用跑大查询时会出现 Too many open files 的报错。mem_limit 限制容器最大内存防止 ClickHouse 在测试机上吃光所有内存把系统拖死。TZ 设置时区不然 ClickHouse 的日志时间和你本地时间对不上排查问题会很难受。2.3 config.d 和 users.d 目录配置文件优先级要搞明白ClickHouse 的配置体系有一个继承和覆盖的关系。镜像内 /etc/clickhouse-server/config.xml 是主配置config.d 目录下的文件会覆盖主配置的对应项users.xml 是用户权限配置users.d 目录下的文件会覆盖用户配置。这个机制有点像 CSS 的层叠样式表后加载的、更具体的配置会覆盖默认值。我一般会在 config.d 目录下放一个 01_memory.xml用来调整内存相关的参数内容如下clickhouse max_server_memory_usage3000000000/max_server_memory_usage max_memory_usage_for_all_queries2000000000/max_memory_usage_for_all_queries max_concurrent_queries100/max_concurrent_queries background_pool_size8/background_pool_size /clickhousemax_server_memory_usage 的单位是字节我这里的 3000000000 约等于 3GB目的是给系统留 1GB 余量。max_memory_usage_for_all_queries 限制所有查询总共能用的内存防止某个大查询把内存吃爆。max_concurrent_queries 控制并发查询数默认值很大测试机上调小一点可以保护自己。background_pool_size 是后台合并线程数单机部署不需要太大8 个足够了。users.d 目录下放一个 01_user.xml 来覆盖用户密码不建议直接改 users.xml因为镜像升级时这个文件可能会被覆盖而 users.d 是独立目录升级不会动。示例clickhouse users default password remove1/ password_sha256_hex你的SHA256哈希/password_sha256_hex networks ip127.0.0.1/ip ip::1/ip ip你的内网网段/ip /networks profiledefault/profile quotadefault/quota /default /users /clickhousepassword_sha256_hex 的生成方法echo -n 你的密码 | sha256sum把输出的哈希值填进去。networks 里限制允许连接的 IP生产环境务必不要留 0.0.0.0/0否则相当于数据库裸奔在网络上谁都能连。3. 实操部署全流程从零到能查数据3.1 初始化目录结构和配置文件一次到位部署前先在宿主机上创建一个工作目录比如 /opt/clickhouse然后在里面建好 data、logs、config.d、users.d 这几个子目录mkdir -p /opt/clickhouse/{data,logs,config.d,users.d}接着把上面那段 docker-compose.yml 保存到 /opt/clickhouse/docker-compose.yml。然后创建 config.d/01_memory.xml 和 users.d/01_user.xml 这两个配置文件。注意用户密码配置我用的是 CLICKHOUSE_PASSWORD 环境变量来指定默认用户密码如果你在 users.d 里又指定了 default 用户密码两者可能会冲突新版本镜像里环境变量优先二选一就好。我个人的习惯是单机测试环境直接用 CLICKHOUSE_PASSWORD 环境变量设个临时密码省事一旦要长期使用就把环境变量从 compose 文件里删掉改用 users.d 方式管理密码这样密码能跟随配置文件一起走也更接近生产习惯。3.2 启动容器并验证别急着建表先看日志目录和文件准备好之后在 /opt/clickhouse 目录下执行docker compose up -d第一次启动要拉镜像耐心等一会儿。启动完成后看容器状态docker ps看到 clickhouse-server 的状态是 Up再去看日志有没有报错docker logs -f clickhouse-server正常情况下日志末尾会出现 Ready for connections 字样说明服务已经就绪。如果容器一直处于 Restarting 状态多半是配置文件写错了可以用 docker logs 看具体报错常见的就是 XML 格式不对或者配置文件里的标签层级错了。这里教大家一个绕过容器直接验证配置的方法docker run -it --rm \ -v /opt/clickhouse/config.d:/etc/clickhouse-server/config.d:ro \ -v /opt/clickhouse/users.d:/etc/clickhouse-server/users.d:ro \ clickhouse/clickhouse-server:25.4 \ clickhouse server --config-file/etc/clickhouse-server/config.xml \ --print-config这个命令会让 ClickHouse 解析配置并打印最终生效的配置项如果配置文件有语法错误会直接报出来。这一步排查配置问题非常高效比反复重启容器看日志省时间多了。3.3 用 clickhouse-client 建表验证数据能写能读才算完事容器起来之后进入容器内部执行 clickhouse-clientdocker exec -it clickhouse-server clickhouse-client --password your_strong_password看到 clickhouse-client 的提示符之后先验证版本SELECT version();如果返回 25.4.x说明版本正确。接着建一张最简单的 MergeTree 表试试CREATE TABLE test_events ( event_date Date, event_type String, event_value UInt64 ) ENGINE MergeTree() PARTITION BY event_date ORDER BY (event_date, event_type);然后插入几条测试数据INSERT INTO test_events VALUES (2025-04-01, view, 100), (2025-04-01, click, 50), (2025-04-02, view, 200);查询验证SELECT event_date, count() AS cnt, sum(event_value) AS total FROM test_events GROUP BY event_date ORDER BY event_date;能正确返回分组统计结果说明整个链路已经通了。这时再顺便查一下系统表看看刚建的表是否正常SELECT name, engine, partition_key FROM system.tables WHERE database default;单机部署到这里已经算成功了。不过我建议你再多做一步确认一下数据目录里真的写了文件。在宿主机执行ls -lh /opt/clickhouse/data/data/default/test_events/能看到按分区组织的目录结构和 .bin 数据文件说明数据确实持久化到宿主机磁盘了而不是停留在容器内部。这一步确认过之后你才可以放心地删除容器再重新创建数据不会丢。4. 备份恢复与整体迁移别等数据丢了才后悔4.1 单机备份两大利器clickhouse-client 导出与 BACKUP 命令数据是数据库的命根子单机部署尤其要重视备份因为没有别的节点帮你兜底。ClickHouse 25.4 版本支持 BACKUP 命令可以备份到本地目录或 S3。单机环境我一般备份到本地目录一条 SQL 搞定BACKUP TABLE test_events TO Disk(backup_disk, test_events_backup);但要注意使用 Disk 备份到本地需要先在 config.d 里配置备份磁盘。如果你不想折腾这块更通用的做法是直接用 clickhouse-client 把数据导出成 TSV 或 Parquet 文件docker exec clickhouse-server clickhouse-client \ --password your_strong_password \ --query SELECT * FROM test_events FORMAT TSV \ /opt/clickhouse/backup/test_events.tsv这种方式的好处是通用性强不管 ClickHouse 版本怎么升级数据都能导回来缺点是大表导出速度慢几十 GB 以上就不太适合了。我的习惯是小表用 TSV 导出大表用 BACKUP 命令两者结合。4.2 恢复流程把备份数据导入新容器恢复数据和备份是配套的。TSV 文件恢复很简单先建好同结构的表再用 clickhouse-client 把数据导入cat /opt/clickhouse/backup/test_events.tsv | \ docker exec -i clickhouse-server clickhouse-client \ --password your_strong_password \ --query INSERT INTO test_events FORMAT TSV导入完成后查一下 count() 是否等于备份前记录数做一次校验。如果是 BACKUP 命令备份出来的恢复时也是用 RESTORE 命令RESTORE TABLE test_events FROM Disk(backup_disk, test_events_backup);恢复之前最好先清空或重命名原表避免主键冲突或数据重复。这块没啥黑科技但一定要定期执行并验证我见过太多人配好了备份却从没恢复过真到恢复那天发现备份文件是坏的那才叫欲哭无泪。4.3 整体迁移思路换机器不是复制粘贴那么简单如果是把整个 ClickHouse 实例迁移到另一台机器比如从测试机迁到正式服务器最简单的方案就是“数据目录整体搬运”。这个方案我在实际环境验证过前提是两边的 ClickHouse 版本一致操作步骤是先在旧机器上停容器再用 rsync 或 tar 把 /opt/clickhouse/data 整个打包拷贝到新机器最后在新机器上挂载这个数据目录启动新容器。为啥要停容器再搬运因为 ClickHouse 写入时数据是先写内存再异步落盘的如果不停容器直接拷贝数据目录可能会拷到还没来得及 merge 的中间状态文件启动时容易报错。停服拷贝虽然会有一小段不可用时间但胜在安全可控。迁移完成后先用 SELECT count() 验证关键表的数据量再抽查几条数据和时间范围确认数据没丢没旧才算迁移成功。整体迁移这件事最忌讳的就是图快而省略验证环节数据完整性的确认永远值得多花几分钟。5. 常见问题与排查技巧实录把踩过的坑一次说清5.1 ClickHouse 容器起不来、连不上、查询报错的典型场景部署和使用过程中遇到的问题我整理成了一张速查表基本都是我实际踩过的问题现象可能原因解决办法容器启动后立刻退出或一直 Restarting配置文件 XML 格式错误或数据目录权限不对docker logs 看报错宿主机执行 chown -R 1000:1000 /opt/clickhouse/data 修复权限宿主机 curl localhost:8123 无响应端口没映射对或容器内服务未就绪docker ps 确认端口映射docker logs 看是否 Ready for connectionsclickhouse-client 连接报错密码不对或 networks 限制了来源 IP检查 users.d 配置和容器环境变量确认 CLICKHOUSE_PASSWORD查询报 Too many open files文件句柄数不够检查 docker-compose.yml 里 ulimits 配置调大后重启容器写入时报 Memory limit exceeded内存参数设置过低或真实内存不足调整 config.d 里的 max_server_memory_usage或给 Docker 加内存查询速度越来越慢分区过多且未及时合并执行 OPTIMIZE TABLE xxx FINAL或调整 merge 线程参数端口映射问题里还有一类很隐蔽的坑容器公网 IP 地址变了。如果宿主机配了多个 IPClickHouse 可能绑定到了内网 IP 而不是公网 IP导致你从外网访问不了。这种情况在 config.d 里监听配置改成 0.0.0.0 就能解决但记住改成 0.0.0.0 之后必须搭配密码和 IP 白名单不能裸奔。5.2 日志文件膨胀、磁盘空间不足这种慢性病最坑人ClickHouse 默认会把每次查询的日志写到 system.query_log 表这个表的数据默认会保留 30 天如果查询量大这个表会非常占空间。数据目录在宿主机上逐步膨胀最终把磁盘撑爆。我之前就遇到过一台测试机磁盘满了之后容器直接进入只读状态写入全部失败排查半天才发现是 system.query_log 太大。解决办法有两个方向。第一个是定期清理ALTER TABLE system.query_log DELETE WHERE event_time now() - INTERVAL 7 DAY;第二个是从根上控制保留时间在 config.d 里加一个配置clickhouse query_log databasesystem/database tablequery_log/table flush_interval_milliseconds7500/flush_interval_milliseconds partition_bytoYYYYMM(event_date)/partition_by retention_size1000000000/retention_size retention_time7/retention_time /query_log /clickhouseretention_size 和 retention_time 分别控制日志表保留的最大字节数和天数超过就自动清理。这样设置之后日志膨胀问题基本不用再手动管了。5.3 Docker 镜像下载慢、磁盘占用大两个实用技巧分享镜像下载慢的问题前面讲过配置镜像源这里再补充两个冷门但好用的技巧。第一个是给 Docker 配置镜像仓库的垃圾回收策略。ClickHouse 镜像升级几次之后旧镜像会残留不少空间用 docker system df 一看一堆 dangling 镜像占着好几十 GB。定期执行docker system prune -f可以清理悬空镜像和停止的容器。第二个技巧是把 Docker 的数据目录迁移到其他盘。很多人装 Docker 时默认把数据放在系统盘结果系统盘被镜像撑爆了我在做 Windows Docker Desktop 和 Linux 部署时都遇到过。Linux 上修改 /etc/docker/daemon.json 添加>{ data-root: /data/docker }然后重启 docker 服务旧数据如果有需要可以一并迁移过去。Windows 上 Docker Desktop 的 Settings - Resources - Advanced 里可以直接改 Disk image location。这个操作能很好地避免“系统盘被 Docker 占满导致服务各种诡异报错”的问题属于一劳永逸的基础配置。5.4 配置修改不生效、升级后行为变化三个排查大招改完配置重启容器后发现配置没生效这是非常常见的困惑。第一个排查大招是确认文件挂载是否生效。很多人改的是容器内部的路径比如 docker exec 进去改了 /etc/clickhouse-server/config.xml容器一删改动就没了因为根本没挂载出来。正确的做法是配置文件只放在宿主机 /opt/clickhouse/config.d 和 /opt/clickhouse/users.d 目录下容器内禁止手动改文件。第二个大招是分清 config.xml 和 config.d 的优先级。如果两个地方都配置了同一个参数config.d 会覆盖 config.xml但前提是 XML 的标签路径完全一致写错层级就会静默不生效。遇到这种情况用前面说的 clickhouse server --print-config 命令把最终生效的配置打印出来一目了然。第三个大招是版本行为差异。ClickHouse 每个版本都在升级25.4 相比旧版本改了不少默认值。比如旧版本默认允许 HTTP 接口不带密码访问新版本对空密码的默认策略更严格。升级后突然连不上了先想想是不是版本行为变化然后去官网查该版本的 changelog。这个思路能省下大量排查时间。部署 ClickHouse 25.4 单机版这件事真正跑通之后你会发现它其实比想象中简单真正花时间的往往是 Docker 环境本身和那些藏在细节里的配置项。我个人在实际操作中的体会是不要一开始就追求生产级别的高可用和分布式先把单机实例跑顺把备份恢复和配置管理的基本功练熟再往集群方向走会顺畅得多。最后再分享一个小技巧把 docker-compose.yml 和 config.d、users.d 这几个文件放到一个 git 仓库里管理每次改动都留痕这样万一哪次改配置改挂了回滚起来只要一条 git checkout 加重启容器的操作比靠脑子记住“上次到底改了什么”靠谱多了。
返回列表