• 第二章 ClickHouse架构设计


    一、核心特性

    1. MPP架构

    2. 完备的DBMS功能

    • DDL
    • DML
    • 权限控制
    • 数据备份和恢复
    • 分布式管理

    3. 列式存储和数据压缩

            同一个列的数据类型相同,相似度较高,相比行式存储压缩效率更高。

    4. 向量化执行引擎

            向量化执行,就是利用寄存器硬件层面的特性,为上层应用程序的性能带来指数级的提升。为了实现向量化执行,需要利用CPU的SIMD(Single Instruction Multiple Data,即单挑指令操作多条数据)命令,它通过数据并行来提高性能,原理就是CPU寄存器层面实现数据的并行操作。

    5. 支持sql查询

            使用关系型模型描述数据,类似传统数据库概念,如数据库、表、视图、函数等。

    6. 支持多种表引擎(类似MySql)

            将存储引擎部分进行抽象,把存储引擎作为一层独立的接口,与MySql类似。

            目前有合并树、内存、日志、接口、外部存储和其他 6大类20多种表引擎,可以根据实际场景进行选择

    7. 多线程、分布式

            向量化执行是通过数据级并行的方式提升性能,多线程处理是通过线程并行的方式实现性能提升。

            ClickHouse在数据存取方面,既支持分区(纵向扩展,增加分区,利用多线程技术),也支持分片(横向扩展,增加节点,利用分布式技术)。

    8. 多主架构

            Hadoop生态系统技术都采用了Master-Slave主从架构,而ClickHouse则采用Multi-Master多主架构,集群中每个节点角色对等,客户端访问任意一个节点都能达到相同的效果。

    9. 支持实时查询

            即使是复杂查询的场景,也能做到极快响应,且无需对数据进行预加工处理,ClickHouse优势明显:

    • 商用软件价格昂贵
    • SparkSQL和Hive无法保障90%的查询在1秒内返回,海量数据的复杂查询可能需要分钟级别的响应时间
    • Elasticsearch在处理亿级数据聚合时,会显得力不从心       

     10. 支持分布式查询

    • 支持分片
    • 分片依赖集群,每个集群由1个或多个分片组成,每个分片对应ClickHouse的1台服务器节点,分片的数量取决于节点数量
    • 提供了本地表(Local Table)和分布式表(Distribute Table)概念
      • 一张本地表相当于一份数据分片
      • 分布式表本身不存储数据,它是本地表的访问代理,借助分布式表,能够代理访问多个数据分片,从而实现分布式查询

    二、架构设计

    2.1 Column与Field

            Column和Field是ClickHouse数据最基础的映射单元。ClickHouse按列存储数据,内存中一列数据由一个Column对象表示。大多数情况下,ClickHouse都会以整列的方式操作数据,如果操作某列具体的数值,则需要使用Field对象,即Field对象代表一个值。

            Column对象采用泛华设计思路,对象分为接口和实现两部分。接口定义对数据进行各种运算的方法;在IColumn接口对象中,定义了对数据进行各种关系运算的方法,如插入数据、分页、过滤等。

            Field对象使用聚合的设计模式,在Field对象内部聚合了Null、UInt64、String和Array等13种数据类型及相应的处理逻辑。

    2.2 DataType

            DataType负责数据的序列化和反序列化,但是不负责数据的读取,数据通过Column和Field对象读取。IDataType接口定义的方法,及相应的接口对象,其中序列化和反序列化接口成对出现,可以覆盖二进制、文本、JSON、XML、CSV、Protobuf等多种格式类型。

    2.3 Block与Block流

            虽然Column和Field组成了数据的基本映射单元,但是实际操作中,还缺少了一些必要信息,如数据的类型和列名称,于是ClockHouse设计了Block对象,Block对象可以看作是数据表的子集。

            Block对象的本质是由数据对象(Column)、数据类型(DataType)和列名称组成,Column提供数据的读取能力,DataType提供数据的序列化和反序列化的能力,Block在他们的基础上做进一步的抽象和封装,仅通过Block对象就可以完成一系列的操作。

            Block流基于Block,其操作有两组顶层接口:

    • IBlockInputStream - 负责数据的读取和关系运算,大致分为三类:
      • 用于处理定义的DDL操作
      • 处理关系运算的操作,如limit、join、Agg等
      • 支持不同表引擎,如BlockInputStream、MergeTreeBaseSelectBlockInputStream等
    • IBlockOutputStream - 负责将数据输出到下一环节,最终将数据写入目的地                

    2.4 Table

            底层设计中并没有所谓的Table对象,它直接使用IStorage接口指代数据表。

            IStorage接口定义了DDL、read、write方法,分别负责数据的定义、查询和写入。在数据查询时,IStorage负责根据AST(抽象语法树)查询语句的要求,返回指定列的原始数据,然后交给Interpreter做进一步处理。

            表引擎是ClickHouse的一个显著特性,IStorage接口指代数据表,因此不同的表引擎对应的有不同的IStorage子类实现,如IStorageSystemOneBlock、StorageMergeTree等。

    2.5 Parser与Interpreter

            Parser - 分析器,负责创建AST抽象语法树对象;

    • 不同的sql会由不同的Parser实现类解析,如负责解析DDL的ParserRenameQuery、ParserDropQuery,腐恶解析INSERT的ParserInsertQuery等。                        

            Interpreter - 解释器,负责解释AST,并创建下一步查询的执行管道。

    • 类似Service服务层,祈祷串联整个查询过程的作用,根据解释器类型聚合相应资源,解析AST对象,执行业务逻辑,最终返回IBlock对象,一线程的形式建立起一个查询执行管道。

            它们与IStorage一起串联整个数据查询过程。IStorage负责根据AST的指示要求,返回指定的原始数据,通过Block对象完成一系列的操作。

    2.6 Functions与Aggregate Functions

            ClickHouse主要提供两类函数:普通函数和聚合函数。

            普通函数由IFunction接口定义,主要做一些数据转换之类的操作;

            聚合函数由IAggregateFunction接口定义,聚合函数有状态,而且其状态支持序列化和反序列化,能够在分布式节点之间传输,从而实现增量运算。

  • 相关阅读:
    湖仓一体电商项目(十九):业务实现之编写写入DWS层业务代码
    【Java核心技术12】面向对象编程(OOP):深入理解类与对象
    idea 实用小技巧分享
    曲线救国|基于函数计算FC3.0部署AI数字绘画stable-diffusion
    我的创作纪念日
    【Java面试宝典】线程安全问题|线程死锁的出现|线程安全的集合类
    数据结构与算法基础-学习-05-线性表之链式表-删除元素、头插法创建单链表、尾插法创建单链表等实现
    spring boot自定义配置时在yml文件输入有提示
    FPGA HLS 卷积单元 数据类型&hls优化&约束设置
    矩阵键盘的扫描原理与基础应用
  • 原文地址:https://blog.csdn.net/u014051010/article/details/126235998