新闻详情

新闻详情

首页 / 资讯中心 / 详情

ClickHouse行存能力全解析:从列存原理到KeeperMap等引擎实战

发布时间:2026/10/2 14:49:17来源:尧图网络
ClickHouse行存能力全解析:从列存原理到KeeperMap等引擎实战
“ClickHouse支持行存吗什么时候开始支持的”这个问题在我所在的几个技术群里几乎每个月都会被翻出来问一次。问的人大多是同一类场景用Flink把MySQL表实时同步到ClickHouse做宽表结果发现聚合查询飞快但业务想按订单号点查一条记录时速度却不太好看于是开始怀疑自己是不是用错了工具。这篇文章我会把ClickHouse的行存能力讲透包括默认列存的原理、哪些引擎和模式提供了真正的行式存储、从什么版本开始有这些能力以及遇到这类需求时到底怎么选型。无论你是正在做MySQL同步ClickHouse的数据开发还是在Doris和ClickHouse之间纠结选型这篇都值得看完再动手。1. 先给结论ClickHouse的行存能力到底支不支持1.1 一句话版本默认列存但有多种方式实现行存直接说结论ClickHouse默认是纯列式存储这是它能在海量数据上跑出惊人聚合速度的根本原因。但如果你的业务确实需要行存能力ClickHouse并不是完全没给路它提供了几种“行存”的实现方式只是这些方式分散在不同的表引擎和存储模式里没有像MySQL那种开箱即用的“行级存储”概念。很多人问“ClickHouse支持行存吗”本质上是遇到两类问题一类是点查慢比如给一个主键值想快速取回一行完整记录的字段另一类是更新场景比如从MySQL同步过来的数据要修改某几行的值而不是批量覆盖。这两类需求ClickHouse都有对应的解法但各有边界。注意ClickHouse的“行存”和你印象里的“行存”可能不完全一样。它不是把整张表都改成B树那种行式组织而是通过不同的表引擎、数据排布方式、或专用场景引擎在特定条件下提供行式存储带来的效果。理解这一点你的选型才不会跑偏。1.2 三个层面理解行存支持要彻底搞清楚这个问题我建议从三个层面来看不要只盯着“支持”或“不支持”这种非黑即白的答案。第一个层面是MergeTree家族引擎内部的存储格式。默认情况下MergeTree系列的表都是列式存储数据按列文件保存。但当part数据量较小时ClickHouse会采用一种叫Compact紧凑的排布方式把多列的数据连续写在一个文件里物理上非常接近行式布局。这个特性从早期版本就有所以严格来说“存储层面的类行存”一直存在。第二个层面是专用表引擎层面的行存。ClickHouse的JOIN引擎、KeeperMap引擎、Memory引擎、File引擎等它们的存储组织方式本质上就是行式的。JOIN引擎底层是哈希表KeeperMap底层是键值结构数据按“行”的思路存放可以支持高频点查和更新操作。第三个层面是官方路线图中的原生行存能力。ClickHouse团队在近年来确实在讨论和推进真正的行存支持用于解决高并发点查和高频更新问题但到这篇文章写作时还没有以一个成熟的、完全GA的“原生行存表”形态交付给所有人用。这部分的进展需要关注版本更新日志。我见过不少朋友因为在网上搜到“ClickHouse 23.x支持行存”的说法跑去下载新版本结果发现并不能像MySQL一样建一张“行存表”最后一脸懵。历史上确实出现过相关实验性讨论和开发分支但距离“装完就能用”还有一段距离。所以如果你是在做生产选型请优先把JOIN、KeeperMap这些已经稳定可用的能力吃透原生行存可以跟踪但别作为当前的技术依赖。2. 为什么ClickHouse默认是列存搞懂原理才能真正用好它2.1 列式存储的核心机制按列组织文件、按granule切分要理解ClickHouse为什么默认列存得先看它底层的数据组织方式。一张MergeTree表的数据目录里每个part会按列拆成独立的文件比如id.bin、name.bin、amount.bin每一列的数据连续存放。同时数据按granule默认8192行切分每个granule对应一组稀疏主键索引标记文件记录了每个granule在列文件中的偏移量。这个设计导致查询行为跟行存数据库完全不同。你执行一个SELECT city, count(*) FROM orders WHERE date 2024-01-01 GROUP BY city列存引擎只需要读取date列和city列对应的文件跳过其他不相干的列配合granule级别的索引裁剪扫描量可以小到极致。我用一个生活化的类比帮助理解列存像一个大型仓库货物按品类分区存放所有同品类的货都堆在同一区域行存则像按订单整包备货一个包裹里什么品类都有取出一个包裹就能拿到完整订单。聚合统计相当于你只想数仓库里有多少台冰箱列存直接去冰箱区数就行点查相当于你想找一个包含某订单号的完整包裹行存数据库很快列存则可能要翻遍整个仓库的流水台账才能定位到那一包。2.2 列存带来的三个红利压缩、向量化、只读必要列列存第一个红利是压缩率。同一列的数据类型相同、业务含义一致、取值范围相近压缩算法能发挥出远比行存高的压缩比。我做过一个实际案例一张8亿行的订单流水表MySQL导出后的原始文本约700GB导入ClickHouse后压缩到约55GB压缩比超过12倍。这意味着一台普通服务器就能存下原本需要几台机器的数据量。第二个红利是向量化执行。ClickHouse的查询引擎天然面向批处理它从列文件里读出来的是一整列的连续内存数据可以走SIMD指令进行批量计算而不是像行存数据库那样一行一行地处理。这也是ClickHouse单机聚合能力碾压传统关系型数据库的关键原因。第三个红利是“只读需要的列”。分析型查询往往只需要宽表中的少数几个字段列存可以直接跳过不需要的列文件IO量大幅减少。像那种MySQL里几十个字段的宽表同步到ClickHouse后做聚合查询速度比源库快几十倍是非常常见的现象。2.3 列存的软肋点查和更新的高成本列存并不是没有代价。它的第一个软肋是点查。如果按主键查一行你有一个订单号想取回这个订单的全部字段。列存引擎需要先通过稀疏索引定位到可能包含该主键的granule然后把该granule涉及的所有列文件的数据都读出来再做合并过滤。因为数据是分布在不同列文件里的这个“按行拼装”的过程比行存数据库直接走B树找到记录要慢不少。第二个软肋是更新和删除。ClickHouse的Mutation变更机制不是就地修改数据而是对part进行异步重写先标记需要修改的行再重写整个受影响的数据part最后替换旧part。高频小批量的更新操作在这种模型下会产生严重的写放大这也是为什么MySQL同步到ClickHouse后业务想频繁修改几行记录时会觉得非常痛苦。第三个软肋是高并发点查场景。ClickHouse的设计目标是“一次查询扫描尽量多的数据”而不是“一秒钟响应成千上万个单行请求”。如果业务要求一秒钟几千次主键点查列存模式下的资源消耗会非常高这时候才需要认真考虑行存方案。搞清楚了这些你会明白为什么“ClickHouse是否支持行存”这个问题值得认真研究不是因为它缺这个功能而是因为很多团队把ClickHouse当MySQL用把一份数据硬塞进列存模型里结果用错了姿势。行存能力的意义恰恰是让ClickHouse在保留分析优势的同时能接住一部分偏“在线服务”的负载。3. “什么时候开始支持行存”版本演进时间线3.1 Compact存储最接近行存的物理布局很多资料不写这一点但它其实是最早、最广泛存在的“行存影子”。MergeTree引擎写入数据时一开始生成的是小part当part内的行数比较少时ClickHouse不会为每个列单独生成文件而是把所有列紧凑地写进同一个数据文件这就是Compact格式。这个模式从早期版本就一直存在它的特点是文件数量少、连续读取一行数据时IO路径短。当part数据量增长到一定阈值由min_rows_for_compact_part、min_bytes_for_compact_part等参数控制ClickHouse会自动把part转换为Wide格式每列独立文件。所以你可以把Compact理解为“小part时期的类行存布局”它并不是给用户手动控制的行存开关而是系统自动选择的存储策略。3.2 JOIN引擎和KeeperMap真正的行式存储引擎如果你要的是真正意义上的行式存储ClickHouse提供了两个值得重点关注的引擎。第一个是JOIN引擎从很早期的版本19.x时代就存在具体实现是内存哈希表。它的查询方式比较特殊不能直接SELECT * FROM join_table而是要在其他查询里通过JOIN语句来使用。右表数据全部加载到内存左表可以按需匹配。它本质上是行式哈希表存储支持高频的键值匹配查询非常适合维表关联场景。第二个是KeeperMap引擎这个才是我眼中的“真·行存表”。KeeperMap在ClickHouse 22.6版本正式引入它把数据存储在ClickHouse Keeper上底层是日志的键值结构表在逻辑上可以执行INSERT、UPDATE、DELETE支持按主键快速点查。虽然功能不像传统数据库那么丰富不支持复杂JOIN、不适合大宽表但对元数据存储、配置表、小维表这类场景非常合适。22.6版本是一个值得记住的时间节点。很多网上的提问“ClickHouse什么时候开始支持行存”其实指的就是KeeperMap这类能力的出现。但也要注意如果你的环境是21.8这种较老的版本KeeperMap是不存在的。这也解释了为什么网上会有“ClickHouse不支持行存”和“ClickHouse支持行存”两种截然不同的答案大家用的版本不一样。3.3 原生行存的江湖传闻实验性与路线图除了上面这些已经稳定可用的能力ClickHouse社区和官方团队确实一直在探索更原生的行存支持。从2023年前后的Roadmap和讨论来看方向主要集中在解决高并发单行点查和高频更新场景目标是让ClickHouse在保持分析性能的同时也能承接一部分在线查询负载。不过到这篇文章写作时点“原生行存”依然没有达到像MergeTree列存那样开箱即用的成熟度更多还停留在实验性功能、开发分支和内部测试阶段。不同版本可能会有一些隐藏参数或实验开关但在生产环境直接依赖这些不稳定能力是有风险的。我的建议是持续关注新版本发布日志但选型还是以JOIN、KeeperMap这些官方文档明确支持的能力为准。这里整理一个版本对照表方便你快速定位自己环境的能力范围能力起始版本存储结构典型场景Compact存储模式早期版本即存在列数据紧凑连续存放小part自动启用JOIN引擎19.x时代即存在内存哈希表行式维表JOIN、点查匹配KeeperMap引擎22.6基于Keeper的键值行存小表实时更新、配置存储原生行存进行中/实验性尚未成熟技术跟踪不建议生产依赖4. 实际怎么用四类行存方案实操笔记4.1 JOIN引擎维表JOIN和高频点查的利器JOIN引擎是我最早接触到的ClickHouse行存能力。它的核心就是一个内存哈希表建表语句很简单CREATE TABLE dim_city ( city_id UInt32, city_name String ) ENGINE Join(ANY, LEFT, city_id);使用方式需要特别注意你不能直接查这张表必须通过在其他查询中JOIN它来使用。比如SELECT o.order_id, o.user_id, c.city_name FROM orders AS o ANY LEFT JOIN dim_city AS c ON o.city_id c.city_id;这种引擎在21.8甚至更早的版本里就能用我当年就是用它在老的ClickHouse版本上实现了MySQL维表的实时关联不需要额外引入Redis也没有同步链路。它的限制是右表必须整体进内存所以只适合数据量可控的维表几百MB以内比较舒服另外JOIN引擎的数据虽然会持久化到磁盘但启动时会全量加载到内存。如果内存不足或维表过大资源占用会非常难看。4.2 KeeperMap引擎可更新的行式键值表如果业务要求一张表能像KV一样支持实时更新和点查KeeperMap是目前ClickHouse家族里最接近这个目标的选择。从22.6版本开始KeeperMap进入可用状态建表方式如下CREATE TABLE kv_config ( config_key String, config_value String ) ENGINE KeeperMap(/clickhouse/config) PRIMARY KEY (config_key);创建时需要指定一个Keeper路径路径不能冲突表数据直接写入ClickHouse Keeper的日志存储。它对INSERT、UPDATE、DELETE操作的支持比MergeTree友好得多按主键做等值点查也非常快。适合放配置项、小维表、状态标记这类几百到几万行的轻量数据。我实测下来有个心得KeeperMap适合的是“小但热”的数据。你用Flink同步MySQL如果目标表是几百万行的大维表KeeperMap会非常吃力毕竟底层要写Keeper日志这时候更应该考虑列存表加去重逻辑。而像商品状态、用户标签、费率配置这类频繁更新但总量很小的数据KeeperMap体验很好。另外需要注意使用KeeperMap的前提是你已经部署并配置了ClickHouse Keeper或者自托管ZooKeeper兼容模式如果只是单机测试版得先把Keeper组件跑起来。4.3 Memory和File引擎临时行存与行式导出除了上面两个重点引擎还有两个经常被忽略的行存选项。Memory引擎本质上就是把数据放在内存里按行组织读写极快但服务重启数据就清空。它适合做临时缓存的中间层比如把Flink同步过来的热数据先落到Memory表供应用点查再异步刷到MergeTree列存表做持久化。用它的好处是零序列化开销延迟极低但不适合做正式存储。File引擎的灵活性容易被低估。你可以这样建一张表CREATE TABLE export_rows ( id UInt64, name String ) ENGINE File(JSONEachRow);这张表查出来的数据会出现在服务端数据目录的data/default/export_rows/文件夹下每行是一个JSON对象。这种行式文件格式适合做数据传输的中间态比如给下游系统提供行式快照或者调试时输出方便人读的数据。它并不适合高频写入和高并发但在数据交换场景里很有用。4.4 实操对比表为了让你快速判断适合哪个方案我把这几个行存能力放在一起对比方案存储介质能否UPDATE/DELETE数据规模上限重启后数据典型用途JOIN引擎内存磁盘可以取决于内存保留重启加载维表JOIN、键值匹配KeeperMapKeeper存储可以万级到百万级保留配置、状态、热数据点查Memory内存可以内存上限丢失临时缓存、热数据中转File(JSONEachRow)磁盘文件不可以文件大小保留行式文件导出、数据交换5. 遇到“行存需求”怎么选型从Flink同步场景说起5.1 先判断需求再决定方案每次有人问我ClickHouse行存选型我都会先反问三个问题你的点查QPS是多少更新频率有多高分析查询的占比有多大如果分析查询占比90%以上点查只是偶尔出现那么优先优化列存的查询效率就够了不必引入行存。比如给MergeTree表设计合理的主键顺序配合分区裁剪和稀疏索引很多“点查慢”的问题其实能缓解。又或者建一个投影Projection或跳数索引避免对非主键列做全扫描。如果点查和更新频率都很高比如每秒要处理几千个按ID查询和更新的请求这时候列存表很难扛住你需要引入真正的行存方案。具体用哪种要看你手里数据的特点总量小、更新频繁的用KeeperMap维表类、需要JOIN的用JOIN引擎可以容忍数据丢失的中间缓存用Memory。5.2 三种常见组合方案第一种是“列存为主行存为辅”的双引擎方案。比如用Flink同步MySQL订单数据核心明细表用MergeTree列存负责跑聚合报表同时把订单状态、最新修改时间这类高频更新的小表同步到KeeperMap负责在线点查。两边各干各的活互不干扰。这种方案在资源上有一点冗余但是架构上最清晰。第二种是“单表列存轻量级更新”方案。如果你的业务更新不是特别频繁可以通过ReplacingMergeTree或AggregatingMergeTree配合Flink的upsert语义按主键去重。ClickHouse 22.x以后还开放了轻量级DELETE和UPDATE能力对低频小批量的修改够用。这个方案没有引入新引擎但要注意Mutation是异步重写part不能期望像MySQL那样秒级生效。第三种是“ClickHouse外部存储”方案。当ClickHouse本身的行存能力满足不了业务时可以把高并发点查和高频更新放到外部比如Redis配合MySQLClickHouse只负责分析和报表。这种方案看起来“绕了一圈”但在一些生产环境里反而最稳定、最好维护。我见过有团队把所有点查都压到ClickHouse上最后发现不如在Redis里缓存一层来得简单。5.3 与Doris选型的一点对比很多人在“Doris和ClickHouse选型”这个问题上纠结其实行存能力就是两者差异的一个缩影。Doris的主键模型Unique Key在更新语义上比ClickHouse更接近传统OLTP支持Merge-on-Write高频更新场景下的实时一致性更好ClickHouse则是在分析性能、生态成熟度上更有优势行存能力更多是“补充”。我的个人倾向是如果这张表既要支持高并发点查、又要高频更新、还要做分析那Doris可能更合适如果分析为主点查和更新是边缘场景那ClickHouse配合上面说的行存方案完全够用。选型不是看谁功能全而是看你的核心矛盾是什么。别因为一个边缘需求推翻一个本来合适的架构。6. 常见问题排查与避坑实录6.1 JOIN引擎内存爆掉病状JOIN引擎表数据量一涨ClickHouse内存直线上升最后OOM。原因很简单JOIN引擎的右表全量加载在内存里哈希表的结构开销远高于普通数组几百万行维表就可能吃掉几个GB内存。排查思路先看system.tables里JOIN表的total_rows估算内存占用再看服务器的可用内存留足操作系统和查询执行的内存余量。如果维表实在太大建议换KeeperMap或者拆成多个小维表按需加载再或者把这个维表放到外部存储Redis里用。实操心得JOIN引擎适合的维表规模在几十万行以内超过这个量级别硬扛。另外JOIN引擎的hash table在并发写入时会有锁竞争Flink同步频率高的话写入吞吐也会成为瓶颈。6.2 KeeperMap重启丢数据病状ClickHouse Keeper或节点重启后KeeperMap表数据为空或部分丢失。这个问题排查起来要分两层看。第一层是ClickHouse Keeper本身的持久化配置。KeeperMap的数据保存在Keeper的日志和快照里如果Keeper组件的日志目录和快照目录没配置好或者数据没同步到多数节点重启后确实可能丢数据。我用KeeperMap之前吃了这个亏本地测试环境Keeper配置是默认的重启ClickHouse后表还在但数据全没了就是因为Keeper快照没落地到磁盘。第二层是表结构问题。KeeperMap表在创建后如果有结构变更或者路径冲突也可能导致数据异常。建议生产环境给KeeperMap单独规划路径前缀别和Keeper自身的配置混在一起同时把Keeper快照和日志目录放到持久化磁盘定期检查Keeper集群的健康状态。6.3 老版本比如21.8到底行不行不少朋友用的是21.8.15.7这种版本有些还是在国产操作系统比如银河麒麟上离线部署的没法轻易升级。这种情况下KeeperMap这种22.6才有的能力肯定是用不了的但不代表完全没有行存可用。21.8版本里你能用的行存方案包括JOIN引擎做维表关联和哈希点查、Memory引擎做临时缓存、File引擎做行式文件导出、Compact存储模式小part的类行存布局。如果你在21.8上感觉“完全不支持行存”大概率是只盯着MergeTree了。把JOIN引擎用起来很多点查和维表关联问题都能解决。如果业务确实需要KeeperMap这类新能力那就得评估升级路径了。离线环境升级ClickHouse本身不复杂但要提前验证你用的函数、引擎、DDL语法在目标版本上是否兼容。我见过因为一个小函数在新版本里改了签名导致整条同步链路跑不起来的案例升级前一定要拿生产全量DDL过一遍兼容性测试。6.4 把“能更新”当成“行存”的误区还有一种常见误区是把“能更新”等同于“行存”。ClickHouse在较新版本里支持了轻量级UPDATE和DELETE有人就以为这就是行存版本了结果发现更新一多性能暴跌。实际上轻量级更新依然基于Mutation机制异步重写part底层还是列存结构它对“低频小批量”的容忍度还行但绝对撑不起高频点查更新的OLTP负载。判断你是否真的需要行存最简单的标准就一条你的查询是不是大量按主键等值取回完整记录并且更新要求秒级可见如果是那才考虑KeeperMap或外部存储如果不是列存加索引优化足够。我在这个踩坑过程中最大的体会是ClickHouse的行存能力不是没有而是被分布式地分散在多个引擎和模式里需要你主动去组合。不要因为默认列存慢了点查就全盘否定它也别指望有个“一键行存”能解决所有问题。实际落地时我建议采用“热行存、冷列存”的混合分层策略热数据放KeeperMap或Memory迎接点查和更新冷数据沉淀到MergeTree列存表做分析和历史保留中间用Flink或定时任务串起来。这个思路我用了两年多既保住了分析性能也接住了在线查询的活是ClickHouse在“行存需求”面前最务实的解法。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

游戏引擎原理与实践:从渲染管线到场景管理的3A级设计逻辑 2026/10/2 15:41:31

游戏引擎原理与实践:从渲染管线到场景管理的3A级设计逻辑

做游戏引擎相关工作这么多年,经常被问到一个问题:3A游戏到底“大”在哪?画面好?动捕细腻?还是玩法设计精巧?我的看法是,3A游戏最核心的底气,来自一套成熟、稳定、可扩展的游戏引擎。…

阅读更多 →
Jev决策模型验证:分类聚合与Transformer架构实操指南 2026/10/2 15:41:31

Jev决策模型验证:分类聚合与Transformer架构实操指南

1. 决策模型验证为什么突然成了热门话题 最近一段时间,TypeSafe AI 发布的 Jev 决策模型验证方案在技术圈里讨论度很高。我最早注意到这个话题,是因为好几个做数据系统和 AI 应用的朋友都在转发相关的验证结果。仔细看下来,核心观点其实很明确…

阅读更多 →
AI短剧出海流水线实战:从剧本到成片的批量生产与算力优化 2026/10/2 15:41:31

AI短剧出海流水线实战:从剧本到成片的批量生产与算力优化

1. AI短剧出海的生产力困局与破局逻辑1.1 从“拍一部”到“跑一批”到底变了什么传统短剧出海,本质上还是影视工业那套逻辑:先定剧本,再找演员,然后租场地、布灯光、拍摄、剪辑、配音、字幕、投流。一部80到100集的竖屏短剧&#…

阅读更多 →
FDE模式实战:AI Agent前线共创与ADP Skill落地指南 2026/10/2 15:41:31

FDE模式实战:AI Agent前线共创与ADP Skill落地指南

1. 从“前线共创”说起:FDE 模式到底在解决什么问题第一次听到 FDE 这个词,是在一个做企业数字化交付的朋友群里。有人甩了张截图,说他们团队新设了“FDE 工程师”岗位,底下立刻有人问:这是不是高级售前换了个马甲&…

阅读更多 →
工业Agent不碰实时控制:它的正确位置在决策辅助 2026/10/2 15:41:30

工业Agent不碰实时控制:它的正确位置在决策辅助

最近“工业Agent”这个词真的太火了,动不动就刷到“大模型赋能工业”“Agent接管产线”的宣传。说实话,我第一反应是兴奋的,干了这么多年自动化,终于看到AI圈的人开始认真聊工业场景了。但紧接着,心里又冒出一丝不安。…

阅读更多 →
CISSP备考资料合集:版本鉴别、解压排错与高效复习指南 2026/10/2 15:41:21

CISSP备考资料合集:版本鉴别、解压排错与高效复习指南

简介:CISSP认证备考人群可关注这份集合型资料包,覆盖官方第八版中文学习指南、历年真题、完整培训讲义及高分考生复习经验。资源以教程指南、习题试卷、培训讲义和复习文档为主,压缩包大小752.16MB,整体按知识模块整理&#xff0c…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉