涨姿势 | 一文读懂备受大厂青睐的ClickHouse高性能列存核心原理

简介: 本文尝试解读ClickHouse存储层的设计与实现,剖析它的性能奥妙

作者:和君

 

 

 


引言

 

ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域。目前国内各个大厂纷纷跟进大规模使用:

 

  • 今日头条内部用ClickHouse来做用户行为分析,内部一共几千个ClickHouse节点,单集群最大1200节点,总数据量几十PB,日增原始数据300TB左右。
  • 腾讯内部用ClickHouse做游戏数据分析,并且为之建立了一整套监控运维体系。
  • 携程内部从18年7月份开始接入试用,目前80%的业务都跑在ClickHouse上。每天数据增量十多亿,近百万次查询请求。
  • 快手内部也在使用ClickHouse,存储总量大约10PB, 每天新增200TB, 90%查询小于3S。
  • 阿里内部专门孵化了相应的云数据库ClickHouse,并且在包括手机淘宝流量分析在内的众多业务被广泛使用。

 

在国外,Yandex内部有数百节点用于做用户点击行为分析,CloudFlare、Spotify等头部公司也在使用。

 

在开源的短短几年时间内,ClickHouse就俘获了诸多大厂的“芳心”,并且在Github上的活跃度超越了众多老牌的经典开源项目,如Presto、Druid、Impala、Geenplum等;其受欢迎程度和社区火热程度可见一斑。

 

而这些现象背后的重要原因之一就是它的极致性能,极大地加速了业务开发速度,本文尝试解读ClickHouse存储层的设计与实现,剖析它的性能奥妙。

 

 

 

ClickHouse的组件架构

 

下图是一个典型的ClickHouse集群部署结构图,符合经典的share-nothing架构。

 

1.png

 

整个集群分为多个shard(分片),不同shard之间数据彼此隔离;在一个shard内部,可配置一个或多个replica(副本),互为副本的2个replica之间通过专有复制协议保持最终一致性。

 

ClickHouse根据表引擎将表分为本地表和分布式表,两种表在建表时都需要在所有节点上分别建立。其中本地表只负责当前所在server上的写入、查询请求;而分布式表则会按照特定规则,将写入请求和查询请求进行拆解,分发给所有server,并且最终汇总请求结果。

 

 

 

 

ClickHouse写入链路

 

ClickHouse提供2种写入方法,1)写本地表;2)写分布式表。

 

写本地表方式,需要业务层感知底层所有server的IP,并且自行处理数据的分片操作。由于每个节点都可以分别直接写入,这种方式使得集群的整体写入能力与节点数完全成正比,提供了非常高的吞吐能力和定制灵活性。但是相对而言,也增加了业务层的依赖,引入了更多复杂性,尤其是节点failover容错处理、扩缩容数据re-balance、写入和查询需要分别使用不同表引擎等都要在业务上自行处理。

 

而写分布式表则相对简单,业务层只需要将数据写入单一endpoint及单一一张分布式表即可,不需要感知底层server拓扑结构等实现细节。写分布式表也有很好的性能表现,在不需要极高写入吞吐能力的业务场景中,建议直接写入分布式表降低业务复杂度。

 

以下阐述分布式表的写入实现原理。

 

ClickHouse使用Block作为数据处理的核心抽象,表示在内存中的多个列的数据,其中列的数据在内存中也采用列存格式进行存储。示意图如下:其中header部分包含block相关元信息,而id UInt8、name String、_date Date则是三个不同类型列的数据表示。

 

2.png

 

在Block之上,封装了能够进行流式IO的stream接口,分别是IBlockInputStream、IBlockOutputStream,接口的不同对应实现不同功能。

 

当收到INSERT INTO请求时,ClickHouse会构造一个完整的stream pipeline,每一个stream实现相应的逻辑:

 

InputStreamFromASTInsertQuery        #将insert into请求封装为InputStream作为数据源
-> CountingBlockOutputStream         #统计写入block count
-> SquashingBlockOutputStream        #积攒写入block,直到达到特定内存阈值,提升写入吞吐
-> AddingDefaultBlockOutputStream    #用default值补全缺失列
-> CheckConstraintsBlockOutputStream #检查各种限制约束是否满足
-> PushingToViewsBlockOutputStream   #如有物化视图,则将数据写入到物化视图中
-> DistributedBlockOutputStream      #将block写入到分布式表中

注:*左右滑动阅览

 

在以上过程中,ClickHouse非常注重细节优化,处处为性能考虑。在SQL解析时,ClickHouse并不会一次性将完整的INSERT INTO table(cols) values(rows)解析完毕,而是先读取insert into table(cols)这些短小的头部信息来构建block结构,values部分的大量数据则采用流式解析,降低内存开销。在多个stream之间传递block时,实现了copy-on-write机制,尽最大可能减少内存拷贝。在内存中采用列存存储结构,为后续在磁盘上直接落盘为列存格式做好准备。

 

SquashingBlockOutputStream将客户端的若干小写,转化为大batch,提升写盘吞吐、降低写入放大、加速数据Compaction。

 

默认情况下,分布式表写入是异步转发的。DistributedBlockOutputStream将Block按照建表DDL中指定的规则(如hash或random)切分为多个分片,每个分片对应本地的一个子目录,将对应数据落盘为子目录下的.bin文件,写入完成后就返回client成功。随后分布式表的后台线程,扫描这些文件夹并将.bin文件推送给相应的分片server。.bin文件的存储格式示意如下:

 

3.png

 

 

ClickHouse存储格式

 

ClickHouse采用列存格式作为单机存储,并且采用了类LSM tree的结构来进行组织与合并。一张MergeTree本地表,从磁盘文件构成如下图所示。

 

4.png

 

本地表的数据被划分为多个Data PART,每个Data PART对应一个磁盘目录。Data PART在落盘后,就是immutable的,不再变化。ClickHouse后台会调度MergerThread将多个小的Data PART不断合并起来,形成更大的Data PART,从而获得更高的压缩率、更快的查询速度。当每次向本地表中进行一次insert请求时,就会产生一个新的Data PART,也即新增一个目录。如果insert的batch size太小,且insert频率很高,可能会导致目录数过多进而耗尽inode,也会降低后台数据合并的性能,这也是为什么ClickHouse推荐使用大batch进行写入且每秒不超过1次的原因。

 

在Data PART内部存储着各个列的数据,由于采用了列存格式,所以不同列使用完全独立的物理文件。每个列至少有2个文件构成,分别是.bin 和 .mrk文件。其中.bin是数据文件,保存着实际的data;而.mrk是元数据文件,保存着数据的metadata。此外,ClickHouse还支持primary index、skip index等索引机制,所以也可能存在着对应的pk.idx,skip_idx.idx文件。

 

在数据写入过程中,数据被按照index_granularity切分为多个颗粒(granularity),默认值为8192行对应一个颗粒。多个颗粒在内存buffer中积攒到了一定大小(由参数min_compress_block_size控制,默认64KB),会触发数据的压缩、落盘等操作,形成一个block。每个颗粒会对应一个mark,该mark主要存储着2项信息:1)当前block在压缩后的物理文件中的offset,2)当前granularity在解压后block中的offset。所以Block是ClickHouse与磁盘进行IO交互、压缩/解压缩的最小单位,而granularity是ClickHouse在内存中进行数据扫描的最小单位。

 

如果有ORDER BY key或Primary key,则ClickHouse在Block数据落盘前,会将数据按照ORDER BY key进行排序。主键索引pk.idx中存储着每个mark对应的第一行数据,也即在每个颗粒中各个列的最小值。

 

当存在其他类型的稀疏索引时,会额外增加一个<col>_<type>.idx文件,用来记录对应颗粒的统计信息。比如:

 

  • minmax会记录各个颗粒的最小、最大值;
  • set会记录各个颗粒中的distinct值;
  • bloomfilter会使用近似算法记录对应颗粒中,某个值是否存在;

 

5.png

 

在查找时,如果query包含主键索引条件,则首先在pk.idx中进行二分查找,找到符合条件的颗粒mark,并从mark文件中获取block offset、granularity offset等元数据信息,进而将数据从磁盘读入内存进行查找操作。类似的,如果条件命中skip index,则借助于index中的minmax、set等信心,定位出符合条件的颗粒mark,进而执行IO操作。借助于mark文件,ClickHouse在定位出符合条件的颗粒之后,可以将颗粒平均分派给多个线程进行并行处理,最大化利用磁盘的IO吞吐和CPU的多核处理能力。

 

总结

 

本文主要从整体架构、写入链路、存储格式等几个方面介绍了ClickHouse存储层的设计,ClickHouse巧妙地结合了列式存储、稀疏索引、多核并行扫描等技术,最大化压榨硬件能力,在OLAP场景中性能优势非常明显。

原文链接

本文为阿里云原创内容,未经允许不得转载。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

xp正版验证补丁_实操web漏洞验证——IIS HTTP.sys 整数溢出漏洞

一、漏洞描述Http.sys 是一个位于 Windows 操作系统核心组件&#xff0c;能够让任何应用程序通过它提供的接口&#xff0c;以 Http 协议进行信息通讯。微软在 Windows 2003 Server 里引进了新的 HTTP API 和内核模式驱动 Http.sys&#xff0c;目的是使基于 Http 服务的程序更有…

普通公司编程水平与BAT大厂相比,差距到底有多大?

前言BAT的牛人多&#xff0c;普通人也多&#xff0c;虽然他们不是每个人都能达到令人仰望的技术水平&#xff0c;但毕竟平台高&#xff0c;所以眼光会变得宽阔&#xff1b;代码要求更为严格&#xff0c;所以普通的程序员也会被逼变得更优秀&#xff1b;身边的牛人多&#xff0c…

mindi linux 使用教程,Linux使用入门教程之tuned

tuned是RHEL6推出的调优工具&#xff0c;可以简单、动态的调整系统。默认的tuned软件包包含9个调优配置文件&#xff0c;对laptop、desktop、server系统的省电策略、磁盘调度算法、缓存、内存脏页回写等等的调节。tuned包安装后有两个服务&#xff0c;tuned和ktune&#xff0c;…

货运物流移动端解决方案:为货运物流行业打造高性能、高粘性的“双端”触点

简介&#xff1a; 在业务碎片化的情景下&#xff0c;怎么通过平台做整合&#xff0c;建立你的专业化运维池&#xff1f; 从 2020 年发展网络货运以来&#xff0c;在互联网和大数据的协作下&#xff0c;传统的物流企业逐渐转向信息化模式&#xff0c;在政策的不断推动下&#xf…

互联网泛娱乐直播安全的解决之道

简介&#xff1a; 阿里云的CDN和视频云产品在直播安全场景下有广泛的应用&#xff0c;阿里巴巴集团的淘宝、优酷等业务的直播正是基于这些产品底层能力&#xff0c;构建了强大的直播安全体系。这个基于阿里巴巴集团自身业务实践打磨出来的架构设计&#xff0c;也被众多上云客户…

wps office2019PC版和Mac版_学用系列WPS教育版的“十八般武艺”

相信不少朋友都在使用wps进行办公学习&#xff0c;但相信不少教师学生肯定不知道其实WPS还很用心提供教育版&#xff0c;里面有不少实用且好用的学习工具可以让我们的学习如虎添翼。今天胖胖老师就为大家介绍一下新版本WPS教育版的“十八般武艺”&#xff0c;欢迎大家一起来尝鲜…

只因“薪水过高”!被欠薪三个月后遭解雇,程序员删库反击

译者 | 弯月 责编 | 王晓曼出品 | 程序人生 &#xff08;ID&#xff1a;coder _life&#xff09;非技术出身的公司创始人往往并不了解开发人员的价值。如果他们的产品是科技产品&#xff0c;那么开发人员就是公司的燃料。我从一位同事那里听到了这个故事。故事的主人公叫做小…

linux模拟内存数据落盘,Linux:保证数据安全落盘

背景在很多IO场景中&#xff0c;我们经常需要确保数据已经安全的写到磁盘上&#xff0c;以便在系统宕机重启之后还能读到这些数据。但是我们都知道&#xff0c;linux系统的IO路径还是很复杂的&#xff0c;分为很多层&#xff0c;每一层都可能会有buffer来加速IO读写。同时&…

阿里云高级技术专家周哲:阿里云边缘云原生应用实践

简介&#xff1a; 为什么需要边缘云原生&#xff1f;边缘云原生的技术特性和优势是什么&#xff1f;它可以为行业提供哪些关键能力&#xff1f;又有哪些场景适合边缘云原生呢&#xff1f;在MEC全球应用开发者大会的“MEC开放论坛”上&#xff0c;阿里云高级技术专家周哲进行了《…

dataframe 如何选中某列的一行_PySpark和SparkSQL基础:如何利用Python编程执行Spark(附代码)

作者&#xff1a;Pinar Ersoy翻译&#xff1a;孙韬淳校对&#xff1a;陈振东本文约2500字&#xff0c;建议阅读10分钟本文通过介绍Apache Spark在Python中的应用来讲解如何利用PySpark包执行常用函数来进行数据处理工作。Apache Spark是一个对开发者提供完备的库和API的集群计算…

重磅官宣:Nacos2.0 发布,性能提升 10 倍

简介&#xff1a; 继 Nacos 1.0 发布以来&#xff0c;Nacos 迅速被成千上万家企业采用&#xff0c;并构建起强大的生态。但是随着用户深入使用&#xff0c;逐渐暴露一些性能问题&#xff0c;因此我们启动了 Nacos 2.0 的隔代产品设计&#xff0c;时隔半年我们终于将其全部实现&…

deepin linux 2014 硬盘安装教程,Linux Deepin的硬盘安装

于是装了&#xff0c;问题来了&#xff0c;即使执行了sudo umount -l /cdrom&#xff0c;也不能直接把原来的个人文件分区挂成/home&#xff0c;因为liveCD的内容还放在这个上面(想不通&#xff0c;我只是挂载&#xff0c;又不格式化&#xff0c;怎么就行了&#xff1f;新氧好像…

一站式云原生智能告警运维平台——SLS新版告警发布!

简介&#xff1a; 本文介绍什么是云原生可观测性需求以及告警限制&#xff0c;介绍一站式云原生智能告警运维平台——SLS新版告警。 前言 本篇是SLS新版告警系列宣传与培训的第一篇&#xff0c;后续我们会推出20系列直播与实战培训视频&#xff0c;敬请关注。 系列目录&#…

ansible 修改文件变量_基于ansible的批量配置生成

背景网络运维&#xff0c;我们有很多时间是在准备配置的路上&#xff0c;咱们之前也讲过&#xff0c;从脑海中或者是从自己的宝藏笔记中找出模板&#xff0c;一顿操作猛如虎&#xff0c;Ctrl C Ctrl V。这个过程是十分危险的&#xff0c;因为人不是机器&#xff0c;肯定会出错&…

Fluid — 云原生环境下的高效“数据物流系统”

简介&#xff1a; 为了解决大数据、AI 等数据密集型应用在云原生计算存储分离场景下&#xff0c;存在的数据访问延时高、联合分析难、多维管理杂等痛点问题&#xff0c;南京大学 PASALab、阿里巴巴、Alluxio 在 2020 年 9 月份联合发起了开源项目 Fluid。Fluid 本质上是一个云原…

普通大学生的 Java 开发能力到什么水平才能进大厂?

对于刚开始接触编程的同学来说&#xff0c;选择一门合适的编程语言非常重要。Java一直以来都是被广泛使用的语言&#xff0c;其服务端开发占比90%&#xff0c;83次在TIOBE排行第一&#xff0c;是很多程序员的首选语言。在发展前景方面&#xff0c;Java的就业范围很广&#xff0…

delphi7 如何判定dbgrid两行重复_教你如何在服装上加入好看的毛线刺绣花边

有时候一件旧衣服我们给它添加一些新的元素&#xff0c;会产生意外惊喜的效果。今天&#xff0c;我们就来学学如何用毛线在衣服上刺绣花边&#xff0c;让衣服变得更加漂亮的方法吧&#xff01;在本教程中&#xff0c;我们使用了一些零头羊毛线&#xff0c;11号木针和用于刺绣的…

阿里的 RocketMQ 如何让双十一峰值之下 0 故障?

简介&#xff1a; 2020 年双十一交易峰值达到 58.3 W 笔/秒&#xff0c;消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳。 作者 | 愈安 来源 | 阿里巴巴云原生公众号 2020 年双十一交易峰值达到 58.3 W 笔/秒&#xff0c;消息中间件 Roc…

英特尔携手谷歌云加速最新虚拟机;谷歌云平台下调抽成比例;Hitachi Vantara推出全新云成本优化服务...

NEWS新闻回顾GitLab 将上市随着收入持续增长和亏损扩大&#xff0c;DevOps 宠儿 GitLab 终于申请了首次公开募股 (IPO)。GitLab 一直致力于成为开发人员的一站式商店&#xff0c;与 GitHub&#xff08;2018 年被微软以 75 亿美元高价收购&#xff09;和其他 DevOps 公司竞争。在…

eq linux_音乐家和音乐爱好者的开放硬件 | Linux 中国

从 3D 打印乐器到无线播放声音的设备&#xff0c;有很多通过开放硬件项目来奏乐的方法。-- Michael Weinberg这个世界到处都是很棒的开源音乐播放器&#xff0c;但为什么只是将开源用在播放音乐上呢&#xff1f;你还可以使用开源硬件奏乐。本文中描述的所有工具都是经过了开源硬…