IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> clickhouse -> 正文阅读

[大数据]clickhouse

安装clickHouse

取消打开文件数和线程数的限制

[root@hadoop103 ~]# vim /etc/security/limits.conf

在文件末尾添加

* soft nofile 65536

* hard nofile 65536

* soft nproc 131072

* hard nproc 131072

注:nofile 文件数 nproc进程数

[root@hadoop103 ~]# vim /etc/security/limits.d/20-nproc.conf

在文件末尾添加

* soft nofile 65536

* hard nofile 65536

* soft nproc 131072

* soft nproc 131072

分发

[root@hadoop103 ~]# xsync /etc/security/limits.d/20-nproc.conf

[root@hadoop103 ~]# xsync /etc/security/limits.conf

安装依赖

[root@hadoop103 ~]# xcall yum install -y libtool

[root@hadoop103 ~]# xcall yum install -y unixODBC

取消selinux(内核安全系统)

[root@hadoop103 ~]# vim /etc/selinux/config

修改为

SELINUX=disabled

[root@hadoop103 ~]# xsync /etc/selinux/config

下载clickhouse

官网:https://clickhouse.tech/

下载地址:http://repo.red-soft.biz/repos/clickhouse/stable/el7/

特别注意的版本

20.5

20.6.3

[root@hadoop103 ~]# mkdir /opt/soft/clickhouse

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hBMSiL0f-1628409844352)(C:\Users\徐高\AppData\Roaming\Typora\typora-user-images\image-20210802210644397.png)]

上传到clickhouse目录下

[root@hadoop103 clickhouse]# rpm -ivh *.rpm

其它机器也这样安装

ClickHouse各文件目录

? bin/ ===> /usr/bin/
? conf/ ===> /etc/clickhouse-server/
? lib/ ===> /var/lib/clickhouse
? log/ ===> /var/log/clickhouse-server

修改配置文件

[root@hadoop103 ~]# vim /etc/clickhouse-server/config.xml

把 <listen_host>::</listen_host>的注释打开,这样的话才能让 ClickHouse 被除本 机以外的服务器访问

[root@hadoop103 ~]# xsync /etc/clickhouse-server/config.xml

启动命令

[root@hadoop103 ~]# clickhouse start

连接server

clickhouse-client -m

数据类型

整型

固定长度的整型,包括有符号整型或无符号整型。

整型范围(-2n-1~2n-1-1):

Int8 - [-128 : 127]

Int16 - [-32768 : 32767]

Int32 - [-2147483648 : 2147483647]

Int64 - [-9223372036854775808 : 9223372036854775807]

无符号整型范围(0~2n-1):

UInt8 - [0 : 255]

UInt16 - [0 : 65535]

UInt32 - [0 : 4294967295]

UInt64 - [0 : 18446744073709551615]

使用场景: 个数、数量、也可以存储型 id。

浮点型

Float32 - float

Float64 – double

建议尽可能以整数形式存储数据。例如,将固定精度的数字转换为整数值,如时间用毫秒为单位表示,因为浮点型进行计算时可能引起四舍五入的误差。

布尔型

没有单独的类型来存储布尔值。可以使用 UInt8 类型,取值限制为 0 或 1。

Decimal 型

有符号的浮点数,可在加、减和乘法运算过程中保持精度。对于除法,最低有效数字会 被丢弃(不舍入)。

有三种声明:

? Decimal32(s),相当于 Decimal(9-s,s),有效位数为 1~9

? Decimal64(s),相当于 Decimal(18-s,s),有效位数为 1~18

? Decimal128(s),相当于 Decimal(38-s,s),有效位数为 1~38

s 标识小数位

使用场景: 一般金额字段、汇率、利率等字段为了保证小数点精度,都使用 Decimal 进行存储。

字符串

String 字符串可以任意长度的。它可以包含任意的字节集,包含空字节。 FixedString(N) 固定长度 N 的字符串,N 必须是严格的正自然数。当服务端读取长度小于 N 的字符 串时候,通过在字符串末尾添加空字节来达到 N 字节长度。 当服务端读取长度大于 N 的 字符串时候,将返回错误消息。

与 String 相比,极少会使用 FixedString,因为使用起来不是很方便。

使用场景:名称、文字描述、字符型编码。 固定长度的可以保存一些定长的内容,比 如一些编码,性别等但是考虑到一定的变化风险,带来收益不够明显,所以定长字符串使用 意义有限。

枚举类型

包括 Enum8 和 Enum16 类型。Enum 保存 ‘string’= integer 的对应关系。 Enum8 用 ‘String’= Int8 对描述。 Enum16 用 ‘String’= Int16 对描述。

1)用法演示 创建一个带有一个枚举 Enum8(‘hello’ = 1, ‘world’ = 2) 类型的列 CREATE TABLE t_enum ( x Enum8(‘hello’ = 1, ‘world’ = 2) ) ENGINE = TinyLog;

2)这个 x 列只能存储类型定义中列出的值:‘hello’或’world’

hadoop102 😃 INSERT INTO t_enum VALUES (‘hello’), (‘world’), (‘hello’);

3)如果尝试保存任何其他值,ClickHouse 抛出异常

hadoop102 😃 insert into t_enum values(‘a’)

4)如果需要看到对应行的数值,则必须将 Enum 值转换为整数类型

hadoop102 😃 SELECT CAST(x, ‘Int8’) FROM t_enum;

使用场景:对一些状态、类型的字段算是一种空间优化,也算是一种数据约束。但是实 际使用中往往因为一些数据内容的变化增加一定的维护成本,甚至是数据丢失问题。所以谨 慎使用。

时间类型

目前 ClickHouse 有三种时间类型

? Date 接受年-月-日的字符串比如 ‘2019-12-16’

? Datetime 接受年-月-日 时:分:秒的字符串比如 ‘2019-12-16 20:50:10’

? Datetime64 接受年-月-日 时:分:秒.亚秒的字符串比如‘2019-12-16 20:50:10.66’

日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。 还有很多数据结构,可以参考官方文档:https://clickhouse.yandex/docs/zh/data_types/

数组

Array(T):由 T 类型元素组成的数组。

T 可以是任意类型,包含数组类型。 但不推荐使用多维数组,ClickHouse 对多维数组 的支持有限。例如,不能在 MergeTree 表中存储多维数组。

(1)创建数组方式 1,使用 array 函数 array(T)

hadoop102 😃 SELECT array(1, 2) AS x, toTypeName(x)

(2)创建数组方式 2:使用方括号 []

hadoop102 😃 SELECT [1, 2] AS x, toTypeName(x);

表引擎

表引擎的使用

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

包括:

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

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

? 并发数据访问。

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

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

? 数据复制参数。

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

特别注意:引擎的名称大小写敏感

TinyLog

以列文件的形式保存在磁盘上,不支持索引,没有并发控制。一般保存少量数据的小表, 生产环境上作用有限。可以用于平时练习测试用。

如: create table t_tinylog ( id String, name String) engine=TinyLog;

Memory

内存引擎,数据以未压缩的原始形式直接保存在内存当中,服务器重启数据就会消失。 读写操作不会相互阻塞,不支持索引。简单查询下有非常非常高的性能表现(超过 10G/s)。

一般用到它的地方不多,除了用来测试,就是在需要非常高的性能,同时数据量又不太 大(上限大概 1 亿行)的场景。

MergeTree

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

1)建表语句

create table t_order_mt( id UInt32,
sku_id String, 
total_amount Decimal(16,2), 
create_time Datetime ) 
engine =MergeTree
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id,sku_id);

engine引擎

partition分区

order by 排序

primary key 主键

2)插入数据

insert into t_order_mt values 
(101,'sku_001',1000.00,'2020-06-01 12:00:00') ,
(102,'sku_002',2000.00,'2020-06-01 11:00:00'), (102,'sku_004',2500.00,'2020-06-01 12:00:00'), (102,'sku_002',2000.00,'2020-06-01 13:00:00'), (102,'sku_002',12000.00,'2020-06-01 13:00:00'), (102,'sku_002',600.00,'2020-06-02 12:00:00');

partition by 分区(可选)

1)作用

分区的目的主要是降低扫描的范围,优化查询速度

2)如果不填 只会使用一个分区。

3)分区目录 MergeTree 是以列文件+索引文件+表定义文件组成的,但是如果设定了分区那么这些文 件就会保存到不同的分区目录中。

4)并行 分区后,面对涉及跨分区的查询统计,ClickHouse 会以分区为单位并行处理。

5)数据写入与分区合并 任何一个批次的数据写入都会产生一个临时分区,不会纳入任何一个已有的分区。写入 后的某个时刻(大概 10-15 分钟后),ClickHouse 会自动执行合并操作(等不及也可以手动 通过 optimize 执行),把临时分区的数据,合并到已有分区中。

optimize table xxxx final;

例如

insert into t_order_mt values
(101,'sku_001',1000.00,'2020-06-01 12:00:00') ,
(102,'sku_002',2000.00,'2020-06-01 11:00:00'),
(102,'sku_004',2500.00,'2020-06-01 12:00:00'),
(102,'sku_002',2000.00,'2020-06-01 13:00:00'),
(102,'sku_002',12000.00,'2020-06-01 13:00:00'),
(102,'sku_002',600.00,'2020-06-02 12:00:00');
image-20210803183839160

并未分区

执行

hadoop103 😃 optimize table t_order_mt final;

手动合并分区

image-20210803184004394

也可以指定某个分区合并,语法如下

optimize table t_order_mt partition ‘20200621’ final;

primary key 主键(可选)

ClickHouse 中的主键,和其他数据库不太一样,它只提供了数据的一级索引,但是却不 是唯一约束。这就意味着是可以存在相同 primary key 的数据的。

主键的设定主要依据是查询语句中的 where 条件。

根据条件通过对主键进行某种形式的二分查找,能够定位到对应的

index granularity,避 免了全表扫描。 index granularity: 直接翻译的话就是索引粒度,指在稀疏索引中两个相邻索引对应数 据的间隔。ClickHouse 中的 MergeTree 默认是 8192。官方不建议修改这个值,除非该列存在 大量重复值,比如在一个分区中几万行才有一个不同数据。

稀疏索引:

稀疏索引的好处就是可以用很少的索引数据,定位更多的数据,代价就是只能定位到索引粒度的第一行,然后再进行进行一点扫描。

order by(必选)

order by 设定了分区内的数据按照哪些字段顺序进行有序保存。

order by 是 MergeTree 中唯一一个必填项,甚至比 primary key 还重要,因为当用户不 设置主键的情况,很多处理会依照 order by 的字段进行处理(比如后面会讲的去重和汇总)。

要求:主键必须是 order by 字段的前缀字段。

比如 order by 字段是 (id,sku_id) 那么主键必须是 id 或者(id,sku_id)

二级索引

create table t_order_mt2(
 id UInt32,
 sku_id String,
 total_amount Decimal(16,2),
 create_time Datetime,
INDEX a total_amount TYPE minmax GRANULARITY 5
)
engine =MergeTree
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id, sku_id);

其中 GRANULARITY N 是设定二级索引对于一级索引粒度的粒度。

insert into t_order_mt2 values
(101,'sku_001',1000.00,'2020-06-01 12:00:00') ,
(102,'sku_002',2000.00,'2020-06-01 11:00:00'),
(102,'sku_004',2500.00,'2020-06-01 12:00:00'),
(102,'sku_002',2000.00,'2020-06-01 13:00:00'),
(102,'sku_002',12000.00,'2020-06-01 13:00:00'),
(102,'sku_002',600.00,'2020-06-02 12:00:00');

使用下面语句进行测试,可以看出二级索引能够为非主键字段的查询发挥作用。

[root@hadoop103 ~]# clickhouse-client --send_logs_level=trace <<<

‘select from test.t_order_mt2 where total_amount > toDecimal32(900., 2)’;

数据 TTL

TTL 即 Time To Live,MergeTree 提供了可以管理数据表或者列的生命周期的功能。

1)列级别 TTL

(1)创建测试表

create table t_order_mt3(
 id UInt32, 
sku_id String, 
total_amount Decimal(16,2) TTL create_time+interval 10 SECOND, 
create_time Datetime  ) engine =MergeTree 
partition by toYYYYMMDD(create_time) 
primary key (id) 
order by (id, sku_id); 

(2)插入数据(注意:根据实际时间改变)

 insert into t_order_mt3 values
 (106,'sku_001',1000.00,'2021-08-03 19:40:00'),
 (107,'sku_002',2000.00,'2021-08-03 19:40:00'),
 (110,'sku_003',600.00,'2021-08-03 19:40:00'); 

(3)手动合并,查看效果 到期后,指定的字段数据归 0

2)表级 TTL

下面的这条语句是数据会在 create_time 之后 10 秒丢失

alter table t_order_mt3 MODIFY TTL create_time + INTERVAL 10 SECOND;

涉及判断的字段必须是 Date 或者 Datetime 类型,推荐使用分区的日期字段。

能够使用的时间周期:

-SECOND

-MINUTE

-HOUR

-DAY

-WEEK

-MONTH

-QUARTER

-YEAR

ReplacingMergeTree

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

1)去重时机 数据的去重只会在合并的过程中出现。合并会在未知的时间在后台进行,所以你无法预 先作出计划。有一些数据可能仍未被处理。

2)去重范围 如果表经过了分区,去重只会在分区内部进行去重,不能执行跨分区的去重。 所以 ReplacingMergeTree 能力有限, ReplacingMergeTree 适用于在后台清除重复的数 据以节省空间,但是它不保证没有重复的数据出现。

3)案例演示

(1)创建表

create table t_order_rmt( id UInt32, sku_id String, total_amount Decimal(16,2), create_time Datetime  )engine =ReplacingMergeTree(create_time)partition by toYYYYMMDD(create_time) primary key (id)order by (id, sku_id);

ReplacingMergeTree() 填入的参数为版本字段,重复数据保留版本字段值最大的。

如果不填版本字段,默认按照插入顺序保留最后一条。

(2)向表中插入数据

 insert into t_order_rmt values (101,'sku_001',1000.00,'2020-06-01 12:00:00') ,(102,'sku_002',2000.00,'2020-06-01 11:00:00'), (102,'sku_004',2500.00,'2020-06-01 12:00:00'),(102,'sku_002',2000.00,'2020-06-01 13:00:00'),(102,'sku_002',12000.00,'2020-06-01 13:00:00'),(102,'sku_002',600.00,'2020-06-02 12:00:00');

4)通过测试得到结论

? 实际上是使用 order by 字段作为唯一键

? 去重不能跨分区

? 只有同一批插入(新版本)或合并分区时才会进行去重

? 认定重复的数据保留,版本字段值最大的

? 如果版本字段相同则按插入顺序保留最后一笔

SummingMergeTree

对于不查询明细,只关心以维度进行汇总聚合结果的场景。如果只使用普通的MergeTree 的话,无论是存储空间的开销,还是查询时临时聚合的开销都比较大。 ClickHouse 为了这种场景,提供了一种能够“预聚合”的引擎 SummingMergeTree

1)案例演示

(1)创建表

create table t_order_smt( id UInt32,sku_id String, total_amount Decimal(16,2) ,create_time Datetime  ) engine =SummingMergeTree(total_amount)partition by toYYYYMMDD(create_time)primary key (id) order by (id,sku_id );

(2)插入数据

 insert into t_order_smt values  (101,'sku_001',1000.00,'2020-06-01 12:00:00'),  (102,'sku_002',2000.00,'2020-06-01 11:00:00'),  (102,'sku_004',2500.00,'2020-06-01 12:00:00'),  (102,'sku_002',2000.00,'2020-06-01 13:00:00'),  (102,'sku_002',12000.00,'2020-06-01 13:00:00'),  (102,'sku_002',600.00,'2020-06-02 12:00:00');

结论

? 以 SummingMergeTree()中指定的列作为汇总数据列

? 可以填写多列必须数字列,如果不填,以所有非维度列且为数字列的字段为汇总数 据列

? 以 order by 的列为准,作为维度列

? 其他的列按插入顺序保留第一行

? 不在一个分区的数据不会被聚合

? 只有在同一批次插入(新版本)或分片合并时才会进行聚合

sql操作

mysql的语句都适用

副本

副本的目的主要是保障数据的高可用性,即使一台 ClickHouse 节点宕机,那么也可以从 其他服务器获得相同的数据。

配置

(1)启动 zookeeper 集群

(2)在 hadoop103 的/etc/clickhouse-server/config.d 目录下创建一个名为 metrika.xml 的配置文件,

内容如下:

注:也可以不创建外部文件,直接在 config.xml 中指定

<?xml version="1.0"?><yandex><zookeeper-servers> <node index="1"> <host>hadoop102</host> <port>2181</port> </node> <node index="2"> <host>hadoop103</host> <port>2181</port> </node> <node index="3"> <host>hadoop104</host> <port>2181</port> </node></zookeeper-servers></yandex>

[root@hadoop103 config.d]# chown clickhouse:clickhouse metrika.xml

修改文件的归属

(3)同步到 hadoop103 和 hadoop104 上

(4)在 hadoop103 的/etc/clickhouse-server/config.xml 中增加(720行)

<zookeeper incl="zookeeper-servers" optional="true" /><include_from>/etc/clickhouse-server/config.d/metrika.xml</include_from>

(5)同步到 hadoop102 和 hadoop104 上

(6)在 hadoop102 和 hadoop103 上分别建表 副本只能同步数据,不能同步表结构,所以我们需要在每台机器上自己手动建表

①hadoop102

create table t_order_rep2 ( id UInt32, sku_id String, total_amount Decimal(16,2),create_time Datetime ) engine =ReplicatedMergeTree('/clickhouse/table/01/t_order_rep','rep_102') partition by toYYYYMMDD(create_time) primary key (id) order by (id,sku_id); 

②hadoop103

create table t_order_rep2 ( id UInt32, sku_id String, total_amount Decimal(16,2), create_time Datetime ) engine =ReplicatedMergeTree('/clickhouse/table/01/t_order_rep','rep_103') partition by toYYYYMMDD(create_time) primary key (id) order by (id,sku_id);

③参数解释 ReplicatedMergeTree 中, 第一个参数是分片的 zk_path 一般按照:/clickhouse/table/{shard}/{table_name} 的格式写,如果只有一个分片就写 01 即可。

(7)在 hadoop102 上执行 insert 语句

insert into t_order_rep2 values(101,'sku_001',1000.00,'2020-06-01 12:00:00'), (102,'sku_002',2000.00,'2020-06-01 12:00:00'), (103,'sku_004',2500.00,'2020-06-01 12:00:00'), (104,'sku_002',2000.00,'2020-06-01 12:00:00'), (105,'sku_003',600.00,'2020-06-02 12:00:00');

(8)在 hadoop103 上执行 select,可以查询出结果,说明副本配置正确

集群分片

副本虽然能够提高数据的可用性,降低丢失风险,但是每台服务器实际上必须容纳全量 数据,对数据的横向扩容没有解决。

要解决数据水平切分的问题,需要引入分片的概念。通过分片把一份完整的数据进行切 分,不同的分片分布到不同的节点上,再通过 Distributed 表引擎把数据拼接起来一同使用。

Distributed 表引擎本身不存储数据,有点类似于 MyCat 之于 MySql,成为一种中间件, 通过分布式逻辑表来写入、分发、路由来操作多台节点不同分片的分布式数据。

集群写入流程

集群读取流程

3 分片 2 副本共 6 个节点集群配置(参考)

配置的位置还是在之前的/etc/clickhouse-server/config.d/metrika.xml,

<yandex><remote_servers><gmall_cluster> <!-- 集群名称--> <shard> <!--集群的第一个分片--><internal_replication>true</internal_replication><!--该分片的第一个副本--> <replica>  <host>hadoop101</host> <port>9000</port> </replica> <!--该分片的第二个副本--> <replica>  <host>hadoop102</host> <port>9000</port> </replica></shard> <shard> <!--集群的第二个分片--> <internal_replication>true</internal_replication> <replica> <!--该分片的第一个副本--> <host>hadoop103</host> <port>9000</port> </replica> <replica> <!--该分片的第二个副本--> <host>hadoop104</host> <port>9000</port> </replica> </shard> <shard> <!--集群的第三个分片--> <internal_replication>true</internal_replication> <replica> <!--该分片的第一个副本--> <host>hadoop105</host> <port>9000</port> </replica> <replica> <!--该分片的第二个副本--> <host>hadoop106</host> <port>9000</port> </replica> </shard></gmall_cluster></remote_servers></yandex>

配置三节点版本集群及副本

集群及副本规划(2 个分片,只有第一个分片有副本)

配置步骤

1)在 hadoop103 的/etc/clickhouse-server/config.d 目录下创建 metrika-shard.xml 文件

<?xml version="1.0"?><yandex><remote_servers><gmall_cluster> <!-- 集群名称--> <shard> <!--集群的第一个分片--><internal_replication>true</internal_replication> <replica> <!--该分片的第一个副本--> <host>hadoop102</host> <port>9000</port> </replica> <replica> <!--该分片的第二个副本--> <host>hadoop103</host> <port>9000</port> </replica></shard><shard> <!--集群的第二个分片--> <internal_replication>true</internal_replication> <replica> <!--该分片的第一个副本--> <host>hadoop104</host> <port>9000</port> </replica></shard></gmall_cluster></remote_servers><zookeeper-servers><node index="1"><host>hadoop102</host><port>2181</port></node><node index="2"><host>hadoop103</host> <port>2181</port></node><node index="3"> <host>hadoop104</host> <port>2181</port></node></zookeeper-servers><macros><shard>01</shard> <!--不同机器放的分片数不一样--><replica>rep_1_2</replica> <!--不同机器放的副本数不一样--></macros></yandex>

打开/etc/clickhouse-server/config.xml

image-20210806100630261

改为image-20210806100716650

2)将 hadoop103 的 metrika-shard.xml 同步到 102 和 104 sudo

xsync /etc/clickhouse-server/config.d/metrika-shard.xml

xsync /etc/clickhouse-server/config.xml

3)修改 102 和 104 中 metrika-shard.xml 宏的配置

hadoop102

01 rep_1_1

hadoop104

02 rep_2_1

4)重启三台服务器上的 ClickHouse 服务

5)在 hadoop103 上执行建表语句

? 会自动同步到 hadoop103 和 hadoop104 上

? 集群名字要和配置文件中的一致

? 分片和副本名称从配置文件的宏定义中获取

create table st_order_mt on cluster gmall_cluster ( id UInt32, sku_id String, total_amount Decimal(16,2),create_time Datetime ) engine  =ReplicatedMergeTree('/clickhouse/tables/{shard}/st_order_mt','{replica}') partition by toYYYYMMDD(create_time) primary key (id) order by (id,sku_id);

6)在hadoop103上创建Distribute 分布式表

create table st_order_mt_all2 on cluster gmall_cluster ( id UInt32,sku_id String, total_amount Decimal(16,2), create_time Datetime )engine = Distributed(gmall_cluster,default,st_order_mt,hiveHash(sku_id));

参数含义: Distributed(集群名称,库名,本地表名,分片键) 分片键必须是整型数字,所以用 hiveHash 函数转换,也可以 rand()

7)在 hadoop103 上插入测试数据

insert into st_order_mt_all2 values(201,'sku_001',1000.00,'2020-06-01 12:00:00') ,(202,'sku_002',2000.00,'2020-06-01 12:00:00'),(203,'sku_004',2500.00,'2020-06-01 12:00:00'),(204,'sku_002',2000.00,'2020-06-01 12:00:00'),(205,'sku_003',600.00,'2020-06-02 12:00:00');

8)查询

(1)分布式表 SELECT * FROM st_order_mt_all;

(2)本地表 select * from st_order_mt;

Explain 查看执行计划

基本语法

EXPLAIN [AST | SYNTAX | PLAN | PIPELINE] [setting = value, …] SELECT … [FORMAT …]

? PLAN:用于查看执行计划,默认值。

? header 打印计划中各个步骤的 head 说明,默认关闭,默认值 0;

? description 打印计划中各个步骤的描述,默认开启,默认值 1;

? actions 打印计划中各个步骤的详细信息,默认关闭,默认值 0。

? AST :用于查看语法树;

? SYNTAX:用于优化语法;

? PIPELINE:用于查看 PIPELINE 计划。

? header 打印计划中各个步骤的 head 说明,默认关闭;

? graph 用 DOT 图形语言描述管道图,默认关闭,需要查看相关的图形需要配合 graphviz 查看;

? actions 如果开启了 graph,紧凑打印打,默认开启。

建表优化

建表时能用数值型或日期时间型表示的字段就不要用字符串,全 String 类型在以 Hive 为中心的数仓建设中常见,但 ClickHouse 环境不应受此影响。

虽然 ClickHouse 底层将 DateTime 存储为时间戳 Long 类型,但不建议存储 Long 类型, 因为 DateTime 不需要经过函数转换处理,执行效率高、可读性好。

尽量避免使用null,会影响性能

写入和删除优化

(1)尽量不要执行单条或小批量删除和插入操作,这样会产生小分区文件,给后台 Merge 任务带来巨大压力

(2)不要一次写入太多分区,或数据写入太快,数据写入太快会导致 Merge 速度跟不 上而报错,一般建议每秒钟发起 2-3 次写入操作,每次操作写入 2w~5w 条数据(依服务器 性能而定)

常见配置

配置描述
background_pool_size后台线程池的大小,merge 线程就是在该线程池中执行,该线程池 不仅仅是给 merge 线程用的,默认值 16,允许的前提下建议改成 c pu 个数的 2 倍(线程数)。
background_schedule_pool_size执行后台任务(复制表、Kafka 流、DNS 缓存更新)的线程数。默 认 128,建议改成 cpu 个数的 2 倍(线程数)。
background_distributed_schedule_ pool_size设置为分布式发送执行后台任务的线程数,默认 16,建议改成 cpu 个数的 2 倍(线程数)。
max_concurrent_queries最大并发处理的请求数(包含 select,insert 等),默认值 100,推荐 1 50(不够再加)~300。
max_threads最大并发处理的请求数(包含 select,insert 等),默认值 100,推荐 1 50(不够再加)~300。
max_threads设置单个查询所能使用的最大 cpu 个数,默认是 cpu 核数
max_memory_usage此参数在 users.xml 中,表示单次 Query 占用内存最大值,该值可 以设置的比较大,这样可以提升集群查询的上限。 保留一点给 OS,比如 128G 内存的机器,设置为 100GB。
max_bytes_before_external_group_ by一般按照 max_memory_usage 的一半设置内存,当 group 使用内 存超过阈值后会刷新到磁盘进行。 因为 clickhouse 聚合分两个阶段:查询并及建立中间数据、合并中 间数据,结合上一项,建议 50GB。
max_bytes_before_external_sort当 order by 已使用 max_bytes_before_external_sort 内存就进行 溢写磁盘(基于磁盘排序),如果不设置该值,那么当内存不够时直接 抛错,设置了该值 order by 可以正常完成,但是速度相对存内存来 说肯定要慢点(实测慢的非常多,无法接受)。
max_table_size_to_drop此参数在 config.xml 中,应用于需要删除表或分区的情况,默认是 50GB,意思是如果删除 50GB 以上的分区表会失败。建议修改为 0, 这样不管多大的分区表都可以删除。

ClickHouse 语法优化规则

ClickHouse 的 SQL 优化规则是基于 RBO(Rule Based Optimization),下面是一些优化规则

准备测试用表

1)上传官方的数据集

将 visits_v1.tar 和 hits_v1.tar 上传到虚拟机,解压到 clickhouse 数据路径下

// 解压到 clickhouse 数据路径

sudo tar -xvf hits_v1.tar -C /var/lib/clickhouse

sudo tar -xvf visits_v1.tar -C /var/lib/clickhouse

//修改所属用户

chown -R clickhouse:clickhouse /var/lib/clickhouse/data/datasets

chown -R clickhouse:clickhouse /var/lib/clickhouse/metadata/datasets

2)重启 clickhouse-server

3)执行查询

clickhouse-client --query “SELECT COUNT(*) FROM datasets.hits_v1”

clickhouse-client --query “SELECT COUNT(*) FROM datasets.visits_v1”

注意:官方的 tar 包,包含了建库、建表语句、数据内容,这种方式不需要手动建库、建表,最方便。 hits_v1 表有 130 多个字段,880 多万条数据

visits_v1 表有 180 多个字段,160 多万条数据

COUNT 优化

在调用 count 函数时,如果使用的是 count() 或者 count(*),且没有 where 条件,则 会直接使用 system.tables 的 total_rows,例如:

EXPLAIN SELECT count()FROM datasets.hits_v1;

消除子查询重复字段

下面语句子查询中有两个重复的 id 字段,会被去重:

EXPLAIN SYNTAX SELECT  a.UserID, b.VisitID, a.URL, b.UserID FROM hits_v1 AS a  LEFT JOIN (  SELECT  UserID,  UserID as HaHa,  VisitID  FROM visits_v1) AS b  USING (UserID) limit 3;

返回优化语句:

SELECT  UserID, VisitID, URL, b.UserIDFROM hits_v1 AS aALL LEFT JOIN ( SELECT  UserID, VisitID FROM visits_v1) AS b USING (UserID)LIMIT 3

谓词下推

当 group by 有 having 子句,但是没有 with cube、with rollup 或者 with totals 修饰的时 候,having 过滤会下推到 where 提前过滤。例如下面的查询,HAVING name 变成了 WHERE name,在 group by 之前过滤:

EXPLAIN SYNTAX SELECT UserID FROM hits_v1 GROUP BY UserID HAVING UserID =  '8585742290196126178'; //返回优化语句 SELECT UserID FROM hits_v1 WHERE UserID = \'8585742290196126178\' GROUP BY UserID

子查询也支持谓词下推:

EXPLAIN SYNTAXSELECT *FROM ( SELECT UserID FROM visits_v1)WHERE UserID = '8585742290196126178'//返回优化后的语句SELECT UserIDFROM ( SELECT UserID FROM visits_v1 WHERE UserID = \'8585742290196126178\')WHERE UserID = \'8585742290196126178\'

聚合计算外推

聚合函数内的计算,会外推,例如:

EXPLAIN SYNTAXSELECT sum(UserID * 2)FROM visits_v1//返回优化后的语句SELECT sum(UserID) * 2FROM visits_v1
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:18:18  更:2021-08-09 10:19:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 18:46:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码