大数据之ClickHouse

大数据之ClickHouse

简介

  • ClickHouse是一种列式数据库管理系统,专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统,最初由俄罗斯搜索引擎公司Yandex开发,用于满足大规模数据分析和报告的需求。

特点

  • 开源的列式存储数据库管理系统,支持线性扩展,简单方便,高可靠性
  • 容错跑分快:可处理的数据级别达到10亿级别
  • 功能多:支持数据统计分析各种场景,支持类SQL查询,异地复制部署

优点

  • 真正的面向列的DBMS,不是一个单一的数据库,它允许在运行时创建表和数据库、加载数据和运行查询,而无需重新配置和重新启动服务器
  • 使用数据压缩,提高了性能
  • 磁盘存储数据
  • 多核并行处理:多核多节点并行化大型查询
  • 在多个服务器上分布式处理:数据可以驻留在不同的分片上,每个分片都可以用于容错的一组副本,查询会在所有分片上进行处理
  • SQL支持:基本语法跟SQL语法兼容
  • 向量化引擎:数据不仅按列式存储,而且由矢量-列的部分进行处理,这使得开发者能够实现高CPU性能
  • 实时数据更新:为了快速执行对主键范围的查询,数据使用合并数(MergeTree)进行递增排序
  • 支持近似计算
  • 数据复制和对数据完整性的支持:使用异步多主复制,写入任何可用的副本后,数据将分发到所有剩余的副本。系统在不同的副本上保持相同的数据,数据在失败后自动恢复

缺点

  • 没有完整的事务支持,不支持Transaction
  • 缺少完整Update/Delete操作,缺少高频率、低延迟的修改或删除已存在数据的能力,仅用于批量删除或修改数据
  • 聚合结果必须小于一台机器的内存大小
  • 支持有限操作系统
  • 不适合Key-value存储,不支持Blob等文档型数据库

系统架构

  • ClickHouse是一个真正的列式数据库管理系统。在ClickHouse中,数据始终是按列存储的,包括矢量执行的过程。

Column与Field

  • Column和Field是ClickHouse数据最基础的映射单元。内存中的一列数据由一个Column对象表示。
  • Column对象分为接口和实现两部分,在IColumn接口对象中,定义了对数据进行各种关系运算的方法。
  • ClickHouse是以整列的方式操作数据,如果需要操作单个具体的数值,也就是单列中的一行数据时,则需要使用Field对象,Field对象代表一个单值。
  • Column对象使用的是泛化设计思路,Field对象使用的是聚合的设计思路。

数据类型DataType

  • IDataType负责序列化和反序列化:读写二进制或文本形式的列或单个值构成的块。直接与表的数据类型相对应
  • IDataTypeIColumn之间的关联并不大。不同的数据类型在内存中能够用相同的IColumn实现来表示。
  • IDataType仅存储元数据。
  • 数据的序列化和反序列化工作由DataType负责。IDataType接口定义了许多正反序列化的方法,它们成对出现。IDataType使用的是泛化的设计模式,具体方法的实现逻辑由对应数据类型的实例承载。
  • DataType虽然负责序列化相关工作,但它并不直接负责数据的读取,而是转由从Column或Field对象获取。

块Block

  • Block是表示内存中表的子集的容器,是由IColumnIDataType列名构成的集合
  • ClickHouse内部的数据操作是面向Block对象进行的,并且采用了流的形式。

块流BlockStreams

  • 块流用来处理数据,它可以从某个地方读取数据,执行数据转换,或将数据写到某个地方

  • Block流操作的两组顶层接口:

    • IBlockInputStream负责数据的读取和关系运算, IBlockInputStream 具有 read 方法,其能够在数据可用时获取下一个块。
    • IBlockOutputStream负责将数据输出到下一环节。 IBlockOutputStream 具有 write 方法,其能够将块写到某处。
  • IBlockInputStream接口的实现类大致可以分为三类:

    • 第一类用于处理数据定义的DDL操作
    • 第二类用于处理关系运算的相关操作
    • 第三类则是与表引擎呼应,每一种表引擎都拥有与之对应的BlockInputStream实现

Formats格式

  • 数据格式同块流一起实现。用于向客户端输出数据的展示格式

数据读写I/O

  • ReadBufferWriteBuffer两个抽象类来面向字节输入输出
  • 它们是由一个连续的缓冲区和指向缓冲区中某个位置的一个指针组成,它们用于处理文件、文件描述符和网络套接字,也用于实现压缩等。

数据表Table

  • 表由IStorage接口表示。该接口的不同实现对应不同的表引擎。
  • 表引擎是ClickHouse的一个显著特性,不同的表引擎由不同的子类实现。
  • 表的read方法能够返回多个IBlockInputStream对象以允许并行处理数据。多个块输入流能够从一个表中并行读取。
  • AST查询被传递给read方法,表引擎可以使用它来判断是否能够使用索引,从而从表中读取更少的数据。

解析器Parser

  • 查询由一个手写递归下降解析器解析。
  • 解析器创建AST

解释器Interpreter

  • 解释器负责从AST创建查询执行流水线。
  • 查询执行流水线由块输入或输出流组成。
  • Parser分析器可以将一条SQL语句以递归下降的方法解析成AST语法树的形式。不同的SQL语句,会经由不同的Parser实现类解析。

函数Functions

  • ClickHouse主要提供两类函数

    • 普通函数Functions

      • 不会改变行数,它们的执行看起来就像是独立地处理每一行数据。
      • 实际上,函数不会作用于一个单独的行上,而是作用在以Block为单位的数据上,以实现向量查询执行。
      • 普通函数采用向量化的方式直接作用于一整列数据。
    • 聚合函数Aggregate Functions

      • 聚合函数是状态函数,它们将传入的值激活到某个状态,并允许你从该状态获取结果。
      • 聚合状态可以被序列化和反序列化,以在分布式查询执行期间通过网络传递或者在内存不够的时候将其写到硬盘。

Cluster与Replication

  • ClickHouse的集群由分片(Shard)组成,而每个分片又通过副本(Replica)组成。
  • ClickHouse的1个节点只能拥有1个分片,也就是说如果要实现1分片、1副本,则至少需要部署2个服务节点。
  • 分片只是一个逻辑概念,其物理承载还是由副本承担的。

MergeTree

  • ClickHouse拥有非常庞大的表引擎体系,其共拥有合并树、外部存储、内存、文件、接口和其他6大类20多种表引擎。
  • 合并树家族自身也拥有多种表引擎的变种。其中MergeTree作为家族中最基础的表引擎,提供了主键索引、数据分区、数据副本和数据采样等基本能力,而家族中其他的表引擎则在MergeTree的基础之上各有所长。

创建与存储

  • MergeTree在写入一批数据时,数据总会以数据片段的形式写入磁盘,且数据片段不可修改。
  • 为了避免片段过多,ClickHouse会通过后台线程,定期合并这些数据片段,属于相同分区的数据片段会被合并成一个新的片段。
  • 这种数据片段往复合并的特点,也正式合并树名称的由来。
  • MergeTree表引擎中的数据是拥有物理存储的,数据会按照分区目录的形式保存到磁盘之上

数据分区

数据分区规则

  • MergeTree数据分区的规则由分区ID决定,而具体到每个数据分区所对应的ID,则是由分区键的取值决定的。

  • 分区键支持使用任何一个或一组字段表达式声明。

  • 分区ID的生成逻辑有四种规则:

    • 不指定分区键:如果不适用分区键,则分区ID默认取名为all,所有的数据都会被写入这个all分区。
    • 使用整型:如果分区键取值属于整型,且无法转换为日期类型YYYYMMDD格式,则直接按照该整型的字符形式输出,作为分区ID的取值。
    • 使用日期类型:如果分区键取值属于日期类型,或者是能够转换为YYYYMMDD格式的整型,则使用按照YYYYMMDD进行格式化后的字符形式输出,并作为分区ID的取值。
    • 使用其他类型:如果分区键取值既不属于整型,也不属于日期类型,则通过128位Hash算法取其Hash值作为分区ID的取值。

分区目录命名

  • 一个完整分区目录的命名公式

  • 在这里插入图片描述

    • 201905表示分区目录的ID
    • 1_1分别表示最小的数据块编号与最大的数据块编号
    • 而最后的_0则表示目前合并的层级
    • PartitionID:分区ID
    • MinBlockNum和MaxBlockNum:最小数据块编号与最大数据块编号
    • Level:合并的层级,可以理解为某个分区被合并过的次数,或者这个分区的年龄。数值越高表示年龄越大

分区目录合并

  • 首先,MergeTree的分区目录并不是在数据表被创建之后就存在的,而是在数据写入过程中被创建的,也就是说,如果一张数据表没有任何数据,那么也不会有任何分区目录存在。

  • 其次,它的分区目录在建立之后也并不是一成不变的。

    • 在其他某些数据库的设计中,追加数据后目录自身不会发生变化,只是在相同分区目录中追加新的数据文件。而MergeTree完全不同,伴随着每一批数据的写入,MergeTree都会生成一批新的分区目录。
    • 即便不同批次写入的数据属于相同分区,也会生成不同的分区目录。
    • 之后,ClickHouse会通过后台任务再将属于相同分区的多个目录合并成一个新的目录。
    • 已经存在的旧分区目录并不会立即被删除,而是在之后的某个时刻通过后台任务被删除(默认8分钟)。

一级索引

  • 稠密索引中每一行索引标记都会对应到一行具体的数据记录。
  • 稀疏索引中每一行索引标记对应的是一段数据,而不是一行。
  • 稀疏索引的优势在于它仅需使用少量的索引标记就能够记录大量数据的区间位置信息,且数据量越大优势越明显。

索引查询过程

  • MarkRange在ClickHouse中是用于定义标记区间的对象。

  • MergeTree按照index_granularity的间隔粒度,将一段完整的数据划分成了多个小的间隔数据段,一个具体的数据段即是一个MarkRange。

  • MarkRange与索引编号对应,使用start和end两个属性表示其区间范围。

  • 通过与start及end对应的索引编号的取值,即能够得到它所对应的数值区间。而数值区间表示了此MarkRange包含的数据范围。

  • 查询步骤

    • 生成查询条件区间:首先,将查询条件转换为条件区间。

    • 递归交集判断:以递归的形式,一次对MarkRange的数值区间与条件区间做交集判断。

      • 如果不存在交集,则直接通过剪枝算法优化此整段MarkRange。
      • 如果存在交集,且MarkRange步长大于8(end-start),则将此区间进一步拆分成8个子区间,并重复此规则,继续做递归交集判断。
      • 如果存在交集,且MarkRange不可再分解(步长小于8),则记录MarkRange并返回。
    • 合并MarkRange区间:将最终匹配的MarkRange聚在一起,合并它们的范围。

二级索引

  • 二级索引又称跳数索引,由数据的聚合信息构建而成。
  • 根据索引类型的不同,其聚合信息的内容也不同。跳数索引的目的与一级索引一样,也是帮助查询时减少数据扫描的范围。

粒度

  • 首先,按照index_granularity粒度间隔将数据划分成n段,总共有[0,n-1]个区间
  • 接着,根据索引定义时声明的表达式,从0区间开始,一次按index_granularity粒度从数据中获取聚合信息,每次向前移动1步,聚合信息逐步累加。
  • 最后,当移动granularity次区间时,则汇总并生成一行跳数索引数据。

分类

  • minmax:记录了一段数据内的最小和最大极值,其索引的作用是能够快速跳过无用的数据区间。
  • set:直接记录了声明字段或表达式的取值,其完整形式为set(max_rows),其中max_rows是一个阈值,表示在一个index_granularity内,索引最多记录的数据行数。
  • ngrambf_v1:记录的是数据短语的布隆表过滤器,只支持String和FixedString数据类型。
  • tokenbf_v1:是ngrambf_v1的升级版,同样也是一种布隆过滤器索引,会自动按照非字符的、数字的字符串分割token。

数据存储

列式存储

  • 在MergeTree,数据按列存储。而具体到每个列字段,数据也是独立存储的,每个列字段都拥有一个与之对应的.bin数据文件。这些.bin文件也是最终承载着数据的物理存储。

  • 数据文件以分区目录的形式被组织存放,所以在.bin文件中只会保存当前分区片段内的这一部分数据。

  • 优势:

    • 可以更好地进行数据压缩
    • 能够最小化数据扫描的范围
  • 存储方式

    • 首先,数据是经过压缩的,默认使用LZ4算法
    • 其次,数据会事先依照ORDER BY的声明排序
    • 最后,数据是以压缩数据块的形式被组织并写入.bin文件中的

数据压缩

  • 一个压缩数据块由头信息和压缩数据两部分组成。

    • 头信息固定使用9位字节表示,具体由1个UInt8(1字节)整型和2个UInt32(4字节)整型组成,分别代表使用的压缩算法类型、压缩后的数据大小和压缩前的数据大小
    • 每个压缩数据块的体积,按照其压缩前的数据字节大小,都被严格控制在64KB~1MB
    • 一个压缩数据块最终的大小,和一个间隔(index_granularity)内数据的实际大小相关
  • 数据写入过程

    • MergeTree在数据具体的写入过程中,会依照索引粒度(默认情况下,每次取8192行),按批次获取数据并进行处理
    • 单个批次数据size<64KB :如果单个批次数据小于64KB,则继续获取下一批数据,直至累积到size>=64KB时,生成下一个压缩数据块
    • 单个批次数据64KB<=size<=1MB :如果单个批次数据大小恰好在64KB与1MB之间,则直接生成下一个压缩数据块
    • 单个批次数据size>1MB :如果单个批次数据直接超过1MB,则首先按照1MB大小截断并生成下一个压缩数据块。剩余数据继续依照上述规则执行
  • 优势:

    • 其一,虽然数据被压缩后能够有效减少数据大小,降低存储空间并加速数据传输效率,但数据的压缩和解压动作,其本身也会带来额外的性能损耗。所以需要控制被压缩数据的大小,以求在性能损耗和压缩率之间寻求一种平衡。
    • 其二,在具体读取某一列数据时(.bin文件),首先需要将压缩数据加载到内存并解压,这样才能进行后续的数据处理。通过压缩数据块,可以在不读取整个.bin文件的情况下将读取粒度降低到压缩数据块级别,从而进一步缩小数据读取的范围。

数据读写流程

写入数据

  • 数据写入的第一步是生成分区目录,伴随着每一批数据的写入,都会生成一个新的分区目录。在后续的某一时刻,属于相同分区的目录会依照规则合并到一起;接着,按照index_granularity索引粒度,会分别生成primary.idx一级索引、每一个列字段的.mrk数据标记和.bin压缩数据文件。

查询数据

  • 数据查询的本质,可以看作一个不断减小数据范围的过程。在最理想的情况下,MergeTree首先可以依次借助分区索引、一级索引和二级索引,将数据扫描范围缩至最小。然后再借助数据标记,将需要解压与计算的数据范围缩至最小。

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

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

相关文章

elementUI 下拉框加提示文案

效果如下&#xff1a; 展示文案在最下面&#xff0c;跟选项有个分割线 <el-select v-model"value" placeholder"请选择" clearable popper-class"addNotice" class"addNoticeS" visible-change"(v) >selectNotice(v,展示…

Testng测试框架(7)--测试运行

忽略测试 TestNG可以让你忽略类、特殊包、包及其子中的所有Test方法。 当在测试方法级别使用Ignore 注解&#xff0c;在功能上与Test(enabledfalse).一样。 以下例子将忽略类中所有tests。 import org.testng.annotations.Ignore; import org.testng.annotations.Test; Ign…

秦朗丢寒假作业系摆拍 博主被处罚

大家好&#xff01; 我是老洪&#xff0c;刚看到秦朗丢寒假作业系摆拍博主被处罚。 据央视财经媒体报道&#xff0c;近期&#xff0c;“秦朗丢寒假作业”事件被证实为自导自编的摆拍视频。 图片来源央视财经公众号截图 该博主与同事薛某&#xff0c;为了吸引更多的粉丝和流量&a…

基于SSM的旅游管理系统论文

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对旅游信息管理混乱&#xff0c;出错率高&#xff0c;信息安全性差&am…

解决cmd输入py文件路径不能执行,使用anaconda prompt 能执行

究其原因&#xff0c;是因为没有配置环境&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 第一步&#xff1a;配置环境变量 操作步骤如下&#xff1a; 1、右击此电脑 ---->属性 2、高级系统设置 3、点击环境变量 4、选择 …

代码随想录--数组--长度最小的子数组

题目 给定一个含有 n 个正整数的数组和一个正整数 s &#xff0c;找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组&#xff0c;并返回其长度。如果不存在符合条件的子数组&#xff0c;返回 0。 示例&#xff1a; 输入&#xff1a;s 7, nums [2,3,1,2,4,3] 输出&#…

[BT]BUUCTF刷题第16天(4.12)

第16天 Web [MRCTF2020]Ezpop 打开网站就是一段泄露的源代码&#xff1a; <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack…

文件名乱码危机:数据恢复全攻略

在数字化时代的浪潮中&#xff0c;电脑文件成为我们日常生活和工作中不可或缺的一部分。然而&#xff0c;有时我们会突然遭遇一个令人头疼的问题&#xff1a;原本清晰易读的文件名突然变成了乱码。这些乱码文件名不仅让我们无法准确识别文件内容&#xff0c;更可能意味着数据丢…

时间序列分析 # 平稳性检验和ARMA模型的识别与定阶 #R语言

掌握单位根检验的原理并能解读结果&#xff1b;掌握利用序列的自相关图和偏自相关图识别模型并进行初步定阶。 原始数据在文末&#xff01;&#xff01;&#xff01; 练习1、根据某1971年9月-1993年6月澳大利亚季度常住人口变动&#xff08;单位&#xff1a;千人&#xff09;的…

一个开源跨平台嵌入式USB设备协议:TinyUSB

概述 TinyUSB 是一个用于嵌入式系统的开源跨平台 USB 主机/设备堆栈&#xff0c;设计为内存安全&#xff0c;无需动态分配&#xff0c;线程安全&#xff0c;所有中断事件都被推迟&#xff0c;然后在非 ISR 任务函数中处理。查看在线文档以获取更多详细信息。 源码链接&#xff…

Redis从入门到精通(十五)Redis分布式缓存(三)Redis分片集群的搭建和原理分析

文章目录 前言5.4 分片集群5.4.1 搭建分片集群5.4.2 散列插槽5.4.3 集群伸缩5.4.3.1 需求分析5.4.3.2 创建新的Redis实例5.4.3.3 添加新节点到Redis集群5.4.3.4 转移插槽 5.4.4 故障转移5.4.4.1 自动故障转移5.4.4.2 手动故障转移 5.4.5 RedisTemplate 5.5 小结 前言 Redis分布…

kali工具----枚举工具

一、枚举工具 枚举是一类程序&#xff0c;它允许用户从一个网络中收集某一类的所有相关信息。本节将介绍DNS枚举和SNMP枚举技术。DNS枚举可以收集本地所有DNS服务和相关条目。DNS枚举可以帮助用户收集目标组织的关键信息&#xff0c;如用户名、计算机名和IP地址等&#xff0c;…

【Qt】界面优化

目录 一、QSS 1.1 基本语法 1.2 QSS设置方法 1.2.1 指定控件样式设置 1.2.2 全局样式设置 1.2.3 从文件加载样式表 1.2.4 使用Qt Designer编辑样式 1.3 选择器 1.3.1 介绍 1.3.2 子控件选择器 1.3.3 伪类选择器 1.4 样式属性(盒模型) 1.5 代码示例(登录界面) 二、…

OSCP靶场--Banzai

OSCP靶场–Banzai 考点(ftp爆破 webshell上传web1访问403web2可以访问webshell反弹mysql udf提权) 1.nmap扫描 ## nmap扫描一定要使用 -p- 否则容易扫不全端口 ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC 192.168.158.56 -Pn -p- --min-rate 2500Starting Nmap 7.…

机器学习前导——PyCharm PyTorch Python3 机器学习

机器学习前导——PyCharm & pytorch & Python3 & 机器学习 文章目录 前言PyCharmPyTorchPython3机器学习联系 前言 这学期选了《机器学习》&#xff0c;第一次接触&#xff0c;对一些专有名词很陌生。 PyCharm PyCharm是一款由JetBrains开发的软件&#xff0c…

STM32 串口接收定长,不定长数据

本文为大家介绍如何使用 串口 接收定长 和 不定长 的数据。 文章目录 前言一、串口接收定长数据1. 函数介绍2.代码实现 二、串口接收不定长数据1.函数介绍2. 代码实现 三&#xff0c;两者回调函数的区别比较四&#xff0c;空闲中断的介绍总结 前言 一、串口接收定长数据 1. 函…

SpringBoot3 + Vue3 + Uniapp + uView + Elenment 实现动态二级分类以及二级分类的管理

SpringBoot3 Vue3 Uniapp uView Elenment 实现动态二级分类以及二级分类的管理 1. 效果展示1.1 前端显示效果1.2 后台管理一级分类1.3 后台管理二级分类 2. 后端代码2.1 GoodsCategoryController.java2.2.1 GoodsCategoryMapper.java2.2.2 GoodsCategorySonMapper.java2.3.…

Zookeeper的集群搭建和ZAB协议详解

Zookeeper的集群搭建 1&#xff09;zk集群中的角色 Zookeeper集群中的节点有三个角色&#xff1a; Leader&#xff1a;处理集群的所有事务请求&#xff0c;集群中只有一个LeaderFollwoer&#xff1a;只能处理读请求&#xff0c;参与Leader选举Observer&#xff1a;只能处理读…

数仓维度建模

维度建模 数仓建模方法1. 范式建模法&#xff08;Third Normal Form&#xff0c;3NF&#xff09;2. 维度建模法&#xff08;Dimensional Modeling&#xff09;3. 实体建模法&#xff08;Entity Modeling&#xff09; 维度建模1. 事实表事实表种类事务事实表周期快照事实表累计快…

强大的数据分析计算软件:Stata 15 for Mac 激活版

Stata 15 for Mac是一款高级统计分析软件&#xff0c;具有强大的数据管理和数据提取工具。以下是其功能和特点的详细介绍&#xff1a; 软件下载&#xff1a;Stata 15 for Mac 激活版版下载 数据管理&#xff1a;Stata 15 for Mac支持多种数据库、数据格式和计算机语言&#xff…