总结:ClickHouse

一、介绍

ClickHouse 是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),使用C++语言编写,主要用于在线分析处理查询(OLAP),能够使用SQL查询实时生成分析数据报告。

二、性能

1、写入性能

ClickHouse采用类LSM Tree的结构,数据写入后定期在后台Compaction。通过类LSM tree的结构,ClickHouse在数据导入时全部是顺序append写,写入后数据段不可更改,在后台compaction时也是多个段merge sort后顺序写回磁盘。顺序写的特性,充分利用了磁盘的吞吐能力,即便在HDD上也有着优异的写入性能。

官方公开benchmark测试显示能够达到50MB-200MB/s的写入吞吐能力,按照每行100Byte估算,大约相当于50W-200W条/s的写入速度。

2、读取性能

数据分区与线程级并行

ClickHouse将数据划分为多个partition,每个partition再进一步划分为多个index granularity(索引粒度),然后通过多个CPU核心分别处理其中的一部分来实现并行数据处理。在这种设计下,单条Query就能利用整机所有CPU。极致的并行处理能力,极大的降低了查询延时。

所以,ClickHouse即使对于大量数据的查询也能够化整为零平行处理。但是有一个弊端就是对于单条查询使用多cpu,就不利于同时并发多条查询。所以对于高qps的查询业务,ClickHouse并不是强项。

来源:https://blog.csdn.net/mengxianglong123/article/details/124687953

三、表引擎

1、介绍

表引擎是ClickHouse的一大特色。可以说, 表引擎决定了如何存储表的数据。包括:

  • 数据的存储方式和位置,写到哪里以及从哪里读取数据。

  • 支持哪些查询以及如何支持。

  • 并发数据访问。

  • 索引的使用(如果存在)。

  • 是否可以执行多线程请求。

  • 数据复制参数。

  • 表引擎的使用方式就是必须显式在创建表时定义该表使用的引擎,以及引擎使用的相关参数。

2、MergeTree引擎

  ClickHouse中最强大的表引擎当属MergeTree(合并树)引擎及该系列(MergeTree)中的其他引擎,支持索引和分区,地位可以相当于innodb之于Mysql。 而且基于MergeTree,还衍生除了很多小弟,也是非常有特色的引擎。

3、ReplacingMergeTree引擎

ReplacingMergeTree是MergeTree的一个变种,它存储特性完全继承MergeTree,只是多了一个去重的功能。 尽管MergeTree可以设置主键,但是primary key其实没有唯一约束的功能。如果你想处理掉重复的数据,可以借助这个ReplacingMergeTree。

四、SQL操作

1、查询语句

以下是调用Deepflow的时候实践的一些查询语句。

比较波折的是IPV4类型查询。

-- bj.hubbleloginfo.w.xxx.db  10.xx.xx.46   2987
-- 正常执行sql
select * from flow_log.l4_flow_log_local where `_id` =7213601490089610505; 
-- mysql
-- l7_protocol=60
select protocol , ip4_0 ,nat_real_ip4_0 ,ip4_1 ,nat_real_port_0 ,nat_real_port_1 from flow_log.l4_flow_log_local where nat_real_port_0 =2987 ; 
-- kafka
select protocol , ip4_0 ,nat_real_ip4_0 ,ip4_1 ,nat_real_port_0 ,nat_real_port_1 from flow_log.l4_flow_log_local where nat_real_port_0 =9092 ; 

-- l7_protocol=100表示kafka
select * from flow_log.l4_flow_log_local where nat_real_port_0 =9092 and l7_protocol=100; 

-- l7_protocol=60表示mysql
select * from flow_log.l4_flow_log_local where nat_real_port_0 =2987 and l7_protocol=60; 

-- 
select * from flow_log.l7_flow_log_local where server_port =2987 and l7_protocol=60; 

-- , pod_group_0, pod_group_1, pod_ns_id_0, pod_ns_id_1
select pod_cluster_id_0 ,pod_cluster_id_1, pod_ns_id_0, response_status,pod_group_id_0,pod_group_id_1, pod_group_0 from flow_log.l7_flow_log where server_port =2987 and l7_protocol=60; 

-- 字符串条件查询
SELECT * FROM flow_log.l7_flow_log
WHERE request_type ='PUT' AND response_status IN (0, 2, 3, 4) AND time >= 1679551819 AND time <= 1679552719
LIMIT 1000
-- 查询正常
SELECT * FROM flow_log.l7_flow_log
WHERE request_domain ='venus.cloud.qiyi.domain' 
-- 查询正常
SELECT * FROM flow_log.l7_flow_log
WHERE request_domain ='10.62.36.46:31691' 

SELECT * FROM flow_log.l7_flow_log
WHERE request_domain ='10.62.36.46:31691' 


-- IPv4查询需要转一下
select * from flow_log.l4_flow_log_local where ip4_0 =IPv4StringToNum('10.69.176.46')
-- 如:下面的语句执行失败
select * from flow_log.l4_flow_log_local where ip4_0 ='10.69.176.46'

-- 查看ClickHouse版本  当前版本是22.8.6.71
SELECT version();

五、数据类型

  1. 介绍

ClickHouse提供了许多数据类型,它们可以划分为基础类型、复合类型和特殊类型。其中基础类型使ClickHouse具备了描述数据的基本能力,而另外两种类型则使ClickHouse的数据表达能力更加丰富立体。

CK的字段和Mysql的字段类型有很大差别,比如CK独有的IPv4、IPv6等

可参考:https://www.jianshu.com/p/751640a04929

ClickHouse支持的数据类型,可以从system.data_type_families表中看

写,这个表中存储了 ClickHouse 支持的所有数据类型。

select * from system.data_type_families limit 100;

2、IPV4类型

ClickHouse从1.1版本开始就支持IPv4类型。IPv4类型在ClickHouse中表示为UInt32类型,用于存储IPv4地址的32位整数表示形式。使用IPv4地址作为过滤条件时,将IPv4地址字符串转换为UInt32类型可以提高过滤性能,并减少存储空间。

在ClickHouse中,可以使用IPv4地址的字符串形式或UInt32整数形式进行查询和过滤。例如,以下查询将返回名为example_table的表中IPv4地址为'192.168.0.1'的所有行:

SELECT*FROM example_table WHERE ip_address = IPv4StringToNum('192.168.0.1')

其中,IPv4StringToNum()函数将IPv4地址字符串转换为UInt32整数。

IPv4是与UInt32类型保持二进制兼容的Domain类型,用于存储IPv4地址的值。它提供了更为紧凑的二进制存储的同时支持识别可读性更加友好的输入输出格式。

IPv6是与FixedString(16)类型保持二进制兼容的Domain类型,用于存储IPv6地址的值。它提供了更为紧凑的二进制存储的同时支持识别可读性更加友好的输入输出格式。

3、Int类型

固定长度的整数类型又包括有符号和无符号的整数类型。

  • 有符号整数类型
    | 类型 | 字节 | 范围 |
    | ------ | ------ | ------ |
    | Int8 | 1 | [-2^7 ~2^7-1] |
    | Int16 | 2 | [-2^15 ~ 2^15-1] |
    | Int32 | 4 | [-2^31 ~ 2^31-1] |
    | Int64 | 8 | [-2^63 ~ 2^63-1] |
    | Int128 | 16 | [-2^127 ~ 2^127-1] |
    | Int256 | 32 | [-2^255 ~ 2^255-1] |

  • 无符号类型
    | 类型 | 字节 | 范围 |
    | ------ | ------ | ------ |
    | UInt8 | 1 | [0 ~2^8-1] |
    | UInt16 | 2 | [0 ~ 2^16-1] |
    | UInt32 | 4 | [0 ~ 2^32-1] |
    | UInt64 | 8 | [0 ~ 2^64-1] |
    | UInt256 | 32 | [0 ~ 2^256-1] |

4、字符串类型

字符串类型可以细分为String、FixedString和UUID三类。

String

字符串由String定义,长度不限。因此在使用String的时候无须声明大小。它完全代替了传统意义上数据库的Varchar、Text、CLOB 和BLOB等字符类型。String类型不限定字符集,因为它根本就没有这个概念,所以可以将任意编码的字符串存入其中。

FixedString

固定长度的N字节字符串,通常在在一些明确字符串长度的场景下使用

UUID

UUID是一种数据库常见的主键类型,在ClickHouse中直接把它做为一种数据类型。UUID共有32位,它的格式为8-4-4-4-12,好比:

61f0c404-5cb3-11e7-907b-a6006ad3dba0
-- 当不指定uuid列的值时,填充为0
00000000-0000-0000-0000-000000000000

5、复合类型

ClickHouse提供了数组、元组、枚举和嵌套四类复合类型。

数组类型:

SELECTarray(1,2)AS x,toTypeName(x);-- 结果输出
┌─x─────┬─toTypeName(array(1,2))─┐
│ [1,2] │ Array(UInt8)            │
└───────┴─────────────────────────┘
SELECT[1,2]AS x,toTypeName(x);-- 结果输出
┌─x─────┬─toTypeName([1,2])─┐
│ [1,2] │ Array(UInt8)       │
└───────┴────────────────────┘

Tuple类型:

Tuple(T1, T2, ...),元组,与Array不一样的是,Tuple中每一个元素都有单独的类型,不能在表中存储元组(除了内存表)。它们能够用于临时列分组。在查询中,IN表达式和带特定参数的 lambda 函数能够来对临时列进行分组。

SELECTtuple(1,'a')AS x,toTypeName(x);--结果输出
┌─x───────┬─toTypeName(tuple(1,'a'))─┐
│ (1,'a') │ Tuple(UInt8, String)      │
└─────────┴───────────────────────────┘
-- 建表
CREATETABLEt_tuple(
   c1 Tuple(String,Int8)) engine=TinyLog;-- INSERT数据
INSERTINTO t_tuple VALUES(('jack',20));--查询数据
SELECT *FROM t_tuple;
┌─c1──────────┐
│ ('jack',20) │
└─────────────┘
-- 若是插入数据类型不匹配,会报异常
INSERTINTO t_tuple VALUES(('tom','20'));--Type mismatch inIN or VALUES section. Expected: Int8. Got: String

嵌套Nested:

嵌套类型,顾名思义是一种嵌套表结构。一张数据表,可以定义任意多个嵌套类型字段,但每个字段的嵌套层级只支持一级,即嵌套表内不能继续使用嵌套类型。对于简单场景的层级关系或关联关系,使用嵌套类型也是一种不错的选择。

--创建Nested语句
CREATE TABLE nested_test (
    name String,
    age  UInt8 ,
    dept Nested(
        id UInt8,
        name String
    )) ENGINE = Memory;

枚举类型:

ClickHouse支持枚举类型,这是一种在定义常量时经常会使用的数据类型。ClickHouse提供了Enum8和Enum16两种枚举类型,它们除了取值范围不同之外,别无二致。枚举固定使用(String:Int)Key/Value键值对的形式定义数据,所以Enum8和Enum16分别会对应(String:Int8)和(String:Int16)。

-- 建表
CREATE TABLE t_enum(
    x Enum8('hello' =1,'world' =2))
ENGINE = TinyLog;-- INSERT数据
INSERT INTO t_enum VALUES('hello'),('world'),('hello');-- 若是定义了枚举类型值以后,不能写入其余值的数据
INSERT INTO t_enum values('a')-- 报异常:Unknown element 'a'fortypeEnum8('hello' =1,'world' =2)

六、ClickHouse默认创建哪些数据库?

当您首次安装ClickHouse时,它会自动创建以下系统数据库:

  1. default(必须):默认数据库,用于存储用户创建的所有表(如果没有指定数据库)。

  1. system(必须):系统数据库,用于存储ClickHouse的元数据和系统表。

猜你喜欢

转载自blog.csdn.net/w2009211777/article/details/129736251