行式储存与clickhouse | 青训营笔记

211 阅读9分钟

这是我参与「第五届青训营」伴学笔记创作活动的第 16 天

数据库类型

  • 关系数据库:

    关系型数据库是把数据以表的形式进行储存,然后再各个表之间建立关系,通过这些表之间的关系来操作不同表之间的数据。

  • 非关系数据库:

    NoSQL或非关系数据库,支持存储和操作非结构化及半结构化数 据。相比于关系型数据库,NoSQL没有固定的表结构,且数据之间不存在表与表之 间的关系,数据之间可以是独立的。

  • 单机数据库:在一台计算机上完成数据的存储和查询的数据库系统。

  • 分布式数据库:分布式数据库由位于不同站点的两个或多个文件组成。数据库可以存储在多台计算机上,位于同一个物理位置,或分散在不同的网络上。

  • OLTP数据库: OLTP (Online transactional processing)数据库是一种高速分析数据库,专为多个用户执行大量事务而设计。

  • OLAP数据库: OLAP (Online analytical processing)数据库旨在同时分析多个数据维度,帮助团队更好地理解其数据中的复杂关系

存储方式

行式储存

行式储存**(Row-based Storage)**则是将数据按照行存储,每一行数据都包含所有的列。这种方式适用于需要频繁更新和插入数据的场景,例如 OLTP(Online Transaction Processing)系统。在行式储存中,一次查询会返回整行数据,这样可以方便地进行修改和更新操作。但是由于每个行的数据类型不一定相同,数据的压缩比率较低,同时每次查询需要读取整行数据,对于大规模数据处理时查询效率较低。

image-20230227214052366

列式储存

列式储存(Columnar Storage)是将数据按照列存储,而不是按照行存储。这种方式适用于数据仓库等大规模数据处理场景,因为这些场景下通常需要对大量的数据进行聚合操作,例如 SUM、COUNT、AVG 等。在列式储存中,所有的值都按照类型存储在一起,这样可以提高数据压缩比率查询性能。同时,由于只需要读取需要的列,而不是整行,所以可以大大减少 I/O 操作,从而提高查询效率。

image-20230227214104818

列式储存为什么拥有更好的压缩比率与查询性能呢?

  1. 数据压缩比率更高

    在行式存储中,每一行的数据类型都不一定相同,因此无法利用相邻的数据之间的重复性,从而影响了数据的压缩比率。而在列式存储中,每个列的数据类型都是相同的,可以通过列存储的方式来提高数据的压缩比率。列式存储可以采用各种压缩算法,例如字典编码、位图压缩、Run-Length Encoding 等,这些算法都可以充分利用相邻的数据之间的重复性,从而提高数据的压缩比率。

  2. 查询性能更高

    在行式存储中,一次查询需要读取整行数据,包括不需要的列,从而浪费了大量的 I/O 操作。而在列式存储中,一次查询只需要读取需要的列,可以大大减少 I/O 操作,从而提高查询性能。此外,由于列式存储中相同类型的数据都在一起存储,可以更方便地使用向量化操作,例如 SSE、AVX 等,从而进一步提高查询性能。

数据压缩

  • LZ4

    image-20230227214323487

    (5,4) 代表向前5个byte,匹配到的内容长度有4,即"bcde"是一 个重复,重复项越多压缩率越高

  • Run-length encoding

    image-20230227214439564

    压缩重复数据,可以在压缩数据上进行计算

  • Delta encoding

    image-20230227214518720

    将数据存储为连续数据之间的差异,而不是直接存储数据本身

    特定算子也能直接在压缩数据上计算

延迟物化

在数据库中,物化(Materialization)通常指将视图、查询结果、计算结果等虚拟数据结构转化为实际存储的过程。物化可以将虚拟的数据结构转化为实际存储的表或者文件,从而提高查询性能和降低计算开销。物化也是一种常见的查询优化技术,可以在查询时预先计算和存储结果,从而避免重复的计算和减少磁盘 I/O 操作。

在数据库中,物化可以分为两种类型:

  1. 预先物化(Pre-Materialization):在查询之前预先计算和存储查询结果。预先物化可以提高查询性能,但会增加存储开销和降低更新和插入的性能。
  2. 延迟物化(Late Materialization):尽可能地推迟计算和存储决策,直到查询真正需要这些数据时才进行计算和存储。延迟物化可以减少存储空间和提高查询性能,但也会带来一些负面影响,例如增加查询时的计算量和降低更新和插入的性能。

常见的物化对象包括物化视图、物化查询结果、物化计算结果等。物化视图是指将虚拟视图转化为实际存储的表或者文件,可以加速查询操作。物化查询结果是指将查询语句的结果存储在表或者文件中,可以避免在每次查询时都进行计算,提高查询性能。物化计算结果是指将计算结果存储在表或者文件中,例如聚合函数的计算结果,可以避免在每次查询时都进行计算,提高查询性能。

在列式存储中,延迟物化的主要方式是使用列存储的优势,即只读取需要的列。在查询时,只需要读取需要的列,而不是全部列,可以减少磁盘 I/O 操作和 CPU 计算,从而提高查询性能。如果查询需要的列是从多个列计算得出的,则可以使用延迟物化的技术,在查询需要这些计算结果的时候才进行计算和存储。

具体而言,列式存储可以使用计算列(Computed Column)和虚拟列(Virtual Column)的方式来实现延迟物化。

计算列是一种新的列,可以根据公式或者表达式从现有的列中计算出来,并在查询时进行计算。虚拟列是一种不存储实际数据的列,仅仅是一些基于现有的列计算的中间结果,可以在查询时动态生成。这两种列的共同点是只有在查询时才进行计算和存储,可以避免在存储过程中冗余的计算和存储。

对比

image-20230227215533579

clickhouse

ClickHouse是一个开源的分布式列式数据库管理系统,用于在线分析处理(OLAP)和商业智能(BI)应用。它支持海量数据的高效存储和快速查询,并提供了实时数据的处理能力。

ClickHouse采用列式存储的方式,可以提供高度压缩和高效的数据扫描。它支持高并发查询和多种查询语言(例如SQL、Graphite、PromQL等),并可以与多种数据源进行集成。

ClickHouse的特点包括:

  1. 高性能:支持并发查询和高效数据扫描,可处理海量数据的快速查询。
  2. 高可用性:支持分布式架构和故障转移,可以保证数据的高可用性。
  3. 高度压缩:采用列式存储和基于字典的压缩算法,可以实现高度压缩和低存储成本。
  4. 多种查询语言:支持SQL、Graphite、PromQL等多种查询语言,便于不同的应用场景。
  5. 灵活的数据模型:支持多种数据类型和索引,可以满足不同的数据存储需求。

ClickHouse适用于需要处理大量数据并需要快速查询的场景,例如Web分析、日志分析、实时数据分析、物联网等。它已被广泛应用于多个领域,例如金融、电商、广告等

集群架构

ClickHouse的集群架构是基于分布式的共享-nothing架构,它可以横向扩展到数百或数千台机器。 ClickHouse集群由多个节点组成,其中每个节点都是独立的、自治的,它们通过网络互相通信,共同协作完成数据存储和查询操作。ClickHouse集群中有以下几种类型的节点:

  1. Shard节点(分片节点):负责存储数据的节点,每个Shard节点存储部分数据,数据被划分成多个分片进行存储。每个分片在一个Shard节点上存储,多个分片可以在同一个Shard节点上存储,也可以在不同的Shard节点上存储。
  2. Replica节点(副本节点):用于提高数据的可用性和冗余性。每个Shard节点可以有多个Replica节点,它们存储相同的数据。如果某个Replica节点失效,其他Replica节点可以自动接管工作,从而保证数据的可用性。
  3. Aggregator节点(聚合节点):负责接收和处理查询请求。当用户发送查询请求时,请求会被发送到一个或多个Aggregator节点,Aggregator节点会协调Shard节点和Replica节点,执行查询操作,并返回结果给用户。

ClickHouse集群的架构可以分为两种模式:

  1. Replicated模式:在这种模式下,每个Shard节点都有多个Replica节点,用于提高数据的可用性和冗余性。每个Replica节点都存储相同的数据,并且可以接收查询请求。在查询时,每个Aggregator节点都可以直接发送查询请求到任意一个Replica节点,Replica节点会返回结果给Aggregator节点,最终结果会在Aggregator节点上汇总并返回给用户。
  2. Distributed模式:在这种模式下,每个Shard节点都是独立的,没有副本节点。当用户发送查询请求时,Aggregator节点会将请求发送到所有的Shard节点上进行查询操作,并将结果汇总返回给用户。在这种模式下,查询的性能和可用性都依赖于Shard节点的数量和性能。

ClickHouse的集群架构可以根据应用需求进行灵活配置,可以通过添加或删除节点来实现横向扩展和收缩,以满足不同的数据处理和查询需求。