简介

ClickHouse是"战斗民族"俄罗斯搜索巨头Yandex公司开源的一个极具"战斗力"的实时数据分析数据库,是面向 OLAP 的分布式列式DBMS,圈内人戏称为"喀秋莎数据库"。ClickHouse简称"CH",但在中文社区里大家更偏爱"CK",反馈是因为有"AK"的感觉!与Hadoop、Spark这些巨无霸组件相比,ClickHouse很轻量级,且不依赖于其他组件。

  1. 下载仓库:https://repo.yandex.ru/clickhouse
  2. 中文文档:https://clickhouse.yandex/docs/zh/

通过实践应用,ClickHouse完美解决了MySQL的查询瓶颈,20亿行以下的数据量级查询,90%都可以在亚秒(1秒内)给到结果,并深受腾讯、快手、今日头条、携程等一线大厂的青睐。ClickHouse特点鲜明: ROLAP、在线实时查询、完整的DBMS、列式存储、不需要任何数据预处理、支持批量更新、具有非常完善的SQL支持和函数、支持高可用、不依赖Hadoop复杂生态、开箱即用……当然,还有最重要的一点就是查询速度变态快!1亿数据: ClickHouse比Vertica快5倍,比Hive快279倍,比MySQL快801倍!

适用场景

适用场景从社区分享的案例看主要有以下几类:日志数据的行为分析,标签画像的分析,数据集市层分析;还可作为存储引擎集成在了产品内部,应用于知识图谱作为本体数据存储,及标签数据的存储引擎等。
一般使用方式场景建议:
 绝大多数请求都是用于读访问
 表很"宽",即表中包含大量的列
 在处理单个查询时需要高吞吐量
 每次查询中大多数场景查询一个大表
 查询结果显著小于数据源,即数据有过滤或聚合

性能测试对比

性能测试对比如下图:

Clickhouse优缺点及性能情况

优点:

1,为了高效的使用CPU,数据不仅仅按列存储,同时还按向量进行处理;

2,数据压缩空间大,减少IO;处理单查询高吞吐量每台服务器每秒最多数十亿行;

3,索引非B树结构,不需要满足最左原则;只要过滤条件在索引列中包含即可;即使在使用的数据不在索引中,由于各种并行处理机制ClickHouse全表扫描的速度也很快;

4,写入速度非常快,50-200M/s,对于大量的数据更新非常适用。

缺点:

1,不支持事务,不支持真正的删除/更新;

2,不支持高并发,官方建议qps为100,可以通过修改配置文件增加连接数,但是在服务器足够好的情况下;

3,SQL满足日常使用80%以上的语法,join写法比较特殊;最新版已支持类似SQL的join,但性能不好;

4,尽量做1000条以上批量的写入,避免逐行insert或小批量的insert,update,delete操作,因为ClickHouse底层会不断的做异步的数据合并,会影响查询性能,这个在做实时数据写入的时候要尽量避开;

5,Clickhouse快是因为采用了并行处理机制,即使一个查询,也会用服务器一半的CPU去执行,所以ClickHouse不能支持高并发的使用场景,默认单查询使用CPU核数为服务器核数的一半,安装时会自动识别服务器核数,可以通过配置文件修改该参数。

数据迁移:从 MySQL 到 ClickHouse

ClickHouse 支持 MySQL 大多数语法,迁移成本低,数据迁移需要从 mysql 导入 clickhouse, 总结方案如下,clickhouse 自身支持的三种方式。

create table engin mysql

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],...INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);

注意,实际数据存储在远端 mysql 数据库中,可以理解成外表。可以通过在 mysql 增删数据进行验证。

insert into select from

-- 先建表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = engine
-- 导入数据
INSERT INTO [db.]table [(c1, c2, c3)] select 列或者* from mysql('host:port', 'db', 'table_name', 'user', 'password')

可以自定义列类型,列数,使用 clickhouse 函数对数据进行处理

create table as select from

CREATE TABLE IF NOT EXISTS `article_clientuser_sum` ENGINE =Log AS
SELECT * FROM mysql('host:port', 'db', 'article_clientuser_sum', 'user', 'password')CREATE TABLE IF NOT EXISTS `article_clientuser_sum` ENGINE =MergeTree() PARTITION BY toYYYYMMDD(rectime) ORDER BY id AS
SELECT * FROM mysql('host:port', 'db', 'article_clientuser_sum', 'user', 'password')

可以理解成 create table 和 insert into select 的组合。PARTITION BY分区键,不声明分区键,则会默认生成一个名为all的分区

建表语句

Clickhouse 中最强大的表引擎当属MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎。MergeTree引擎系列的基本理念如下。当你有巨量数据要插入到表中,你要高效地一批批写入数据片段,并希望这些数据片段在后台按照一定规则合并。相比在插入时不断修改(重写)数据进存储,这种策略会高效很多。Mergetree在写入数据时,数据总会以数据片段的形式写入磁盘,为了避免片段过多,ClickHouse会通过后台线程,定期合并这些数据片段,属于相同分区的数据片段会被合并成一个新的片段,正式合并树名称的由来。

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]

主要参数:

PARTITION BY

分区键,不声明分区键,则会默认生成一个名为all的分区。

ORDER BY

必填,排序键,默认情况下主键与排序键相同。

PRIMARY KEY

会根据主键字段生成一级索引,用于加速查询,可不声明,默认是ORDER BY定义的字段。

SAMPLE BY

抽样表达式,声明数据以何种标准进行采样,如果使用此配置,必须子主键的配置中也声明同样的表达式。
ORDER BY (CounterID,intHash32(UserID))
SAMPLE BY intHash32(UserID)

SETTINGS

index_granularity:索引粒度,默认8192,也就每隔8192行才生成一条索引
enable_mixed_granularity_parts:是否开启自适应索引间隔功能,默认开启
index_granularity_bytes:索引粒度,根据每一批次写入数据的大小,动态划分间隔大小,默认10M(10*1024*1024)

CREATE TABLE user
(`id`          UInt64, --UInt8,UInt16,UInt32,UInt64,Int8,Int16,Int32,Int64`name`        String,`password`    String,`telephone`   String,`create_time` DateTime DEFAULT now(),`create_day`  Date     DEFAULT CAST(now(), 'Date')
) ENGINE = MergeTree(create_day, intHash32(id), 8192)

布尔值:没有单独的类型来存储布尔值。可以使用 UInt8 类型,取值限制为 0 或 1。
固定字符串:固定长度 N 的字符串(N 必须是严格的正自然数)。SHA256使用FixedString(32)

CREATE TABLE test.part
(`ID` String,`URL` String,`age` UInt8 DEFAULT 0,`EventTime` Date
)
ENGINE = MergeTree()PARTITION BY toYYYYMMDD(EventTime)ORDER BY IDSETTINGS index_granularity = 8192

存储结构

查看目录结构

[root@test 20200801_12_12_0]# ll
总用量 56
-rw-r----- 1 clickhouse clickhouse  29 8月  18 15:56 age.bin
-rw-r----- 1 clickhouse clickhouse  48 8月  18 15:56 age.mrk2
-rw-r----- 1 clickhouse clickhouse 456 8月  18 15:56 checksums.txt
-rw-r----- 1 clickhouse clickhouse  91 8月  18 15:56 columns.txt
-rw-r----- 1 clickhouse clickhouse   1 8月  18 15:56 count.txt
-rw-r----- 1 clickhouse clickhouse  32 8月  18 15:56 EventTime.bin
-rw-r----- 1 clickhouse clickhouse  48 8月  18 15:56 EventTime.mrk2
-rw-r----- 1 clickhouse clickhouse  42 8月  18 15:56 ID.bin
-rw-r----- 1 clickhouse clickhouse  48 8月  18 15:56 ID.mrk2
-rw-r----- 1 clickhouse clickhouse   4 8月  18 15:56 minmax_EventTime.idx
-rw-r----- 1 clickhouse clickhouse   4 8月  18 15:56 partition.dat
-rw-r----- 1 clickhouse clickhouse  10 8月  18 15:56 primary.idx
-rw-r----- 1 clickhouse clickhouse  49 8月  18 15:56 URL.bin
-rw-r----- 1 clickhouse clickhouse  48 8月  18 15:56 URL.mrk2
[root@test 20200801_12_12_0]# pwd
/var/lib/clickhouse/data/test/part_v1/20200801_12_12_0

目录层次:数据库名 > 数据表名 > 分区目录 > 分区下具体文件
20200801_12_12_0是分区名

.txt是明文存储,.bin/.dex/.mrk二进制存储

  • partition.dat: 分区信息
  • checksum.txt: 数据校验信息
  • columns.txt: 列信息
  • count.txt: 计数信息
  • primary.idx: 一级索引信息,用于存储稀疏索引信息
  • [column].bin: 存储某一列的信息,默认使用lz4压缩算法存储
  • [column].mrk: 列字段标记问题,保存.bin文件中数据的偏移量信息
  • [column].mrk2: 如果定义了自适应索引,则会出现该文件,作用和.mrk文件一样
  • partition.dat、minmax_[column].idx: 定义了分区键,会出现这二个文件,partition存储当前分区下分区表达式最终生成的值,minmax_[column].idx记录当前分区下对应原始数据的最小最大值
  • skp_idx_[Column].idx与skp_idx_[Column].mrk: 二级索引信息

数据分区

数据的分区规则

分区规则由分区ID决定,,分区ID生成规则有四种逻辑

  • 不指定分区键:没有定义PARTITION BY,分区ID默认all
  • 使用整型:直接按该整型的字符串形式输出,做为分区ID
  • 使用日期类型:分区键时日期类型,或者可以转化成日期类型,比如用today转化,YYYYMMDD格式按天分区,YYYYMM按月分区等
  • 使用其他类型:String、Float类型等,通过128位的Hash算法取其Hash值作为分区ID

数据进行分区存储,在查询时可以快速定位数据位置

分区目录的命名规则

分区命名规则,对于20200801_1_1_0
PartitionID_MinBlockNum_MaxBlockNum_Level

  • PartitionID: 分区ID,20200801就是分区ID
  • MinBlockNum、MaxBlockNum: 最小分区块编号和最大分区块编号,BlockNum是整型的自增长编号,从1开始,新创建一个分区目录时,会+1,新创建的分区MinBlockNum=MaxBlockNum
  • Level:合并的层级,被合并的次数

分区目录的合并过程

每次数据insert写入,都会生成新的分区目录,在之后的某个时刻(写入后的10-15分钟,也可以手动执行optimize强制合并)会通过后台任务再将属于相同分区的多个目录合并成一个新的目录,已经存在的目录通过后台任务删除(默认8分钟)。

合并之后新目录名规则:

  • MinBlockNum:取同一分区内所有目录中最小的MinBlockNum值
  • MaxBlockNum:取同一分区内所有目录中最大的MaxBlockNum值
  • Level:取同以分区内最大Level值并+1

一级索引

一级索引也就是主键索引,通过PRIMARY KEY/ORDER BY定义
会写入primary.idx文件中

稀疏索引和稠密索引的区别

稀疏索引使用一个索引标记一大段时间,减少了索引的数据量,使得primary.idx可以常驻内存,加速数据查询

数据索引的生成过程

PARTITION BYtoYYYYMM(EventDate)),所以2014年3月份的数据最终会被划分到同一个分区目录内。使用CounterID作为主键(ORDER BY CounterID),每间隔8192行会生成一个主键索引保存到primary.idx文件中

压缩数据块

数据标记的生成规则

数据标记是衔接一级索引和数据的桥梁

数据标记和索引区间是对齐的,均按照index_granularity的粒度间隔。只需简单通过索引区间的下标编号就可以直接找到对应的数据标记。每一个列字段[Column].bin文件都有一个与之对应的[Column].mrk数据标记文件,用于记录数据在.bin文件中的偏移量信息

一行标记数据使用一个元组表示,元组内包含两个整型数值的偏移量信息。对应的.bin压缩文件中,压缩数据块的起始偏移量;以及将该数据压缩块解压后,其未压缩数据的起始偏移量
每一行标记数据都表示了一个片段的数据(默认8192行)在.bin压缩文件中的读取位置信息。标记数据与一级索引数据不同,它并不能常驻内存,而是使用LRU(最近最少使用)缓存策略加快其取用速度。

分区、索引、标记和压缩数据的协同总结

写入过程

首先生成分区目录,属于相同分区的目录会依照规则合并到一起
紧接着按照index_granularity索引粒度,会分别生成primary.idx一级索引(如果声明了二级索引,还会创建二级索引文件)、每一个列字段的.mrk数据标记和.bin压缩数据文件

查询过程

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

如果一条查询语句用不到索引会进行分区目标扫描,虽不能缩小数据范围,但是MergeTree仍然能够借助数据标记,以多线程的形式同时读取多个压缩数据块,以提升性能

数据标记和压缩数据块的对应关系

每个压缩数据块的体积都被严格控制在64KB~1MB。而一个间隔(index_granularity)的数据,又只会产生一行数据标记,根据一个间隔内数据的实际字节大小,数据标记和压缩数据块之间会产生三种不同的对应关系

多对一

多个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size小于64KB时,会出现这种对应关系。

一对一

一个数据标记对应一个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size大于64KB小于1M时,会出现这种对应关系。

一对多

一个数据标记对应多个压缩数据块,当一个间隔(index_granularity)内的数据未压缩大小size大于1M时,会出现这种对应关系。

二级索引

二级索引又称跳数索引,由数据的聚合信息构建而成,根据索引类型的不同,其聚合信息的内容也不同。
需要在CREATE语句内定义,定义了跳数索引会额外生成相应的索引文件后标记文件
skp_idx_[Column].idx和skp_idx_[Column].mrk

批量写入

INSERT INTO user (id,name,password,telephone) VALUES (1,'张三','123','15466668888'),(2,'李四','234','15366668888'),(3,'王五','345','15266668888');

Json数据插入

INSERT INTO database.table_name FORMAT JSONEachRow{"id":"1", "name":"test", "age":"11", "flag":"1"}

Ubuntu/Debian安装

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv E0C56BD4    # optional
sudo apt-add-repository "deb http://repo.yandex.ru/clickhouse/deb/stable/ main/"
sudo apt-get update
sudo apt-get install clickhouse-server-common clickhouse-client -y
sudo service clickhouse-server start
clickhouse-client#用户密码访问
clickhouse-client -u default --passwordtail -f /var/log/clickhouse-server/clickhouse-server.log

使用/etc/clickhouse-server/config.xml作为配置文件,也可以手动启动,指定配置文件:

DB::NetException: Connection refused (localhost:9000, ::1

使用clickhouse-client命令默认连接的是9000端口,所以在连接的时候需要指定端口(或者修改tcp_port),clickhouse-client --port 80

开启远程访问/etc/clickhouse-server/config.xml去掉注释

<listen_host>::</listen_host>

DB::Exception: Effective user of the process (root) does not match the owner of the data (clickhouse). Run under 'sudo -u clickhouse'

sudo -u clickhouse clickhouse-server --config-file=/etc/clickhouse-server/config.xml

进入到clickhouse客户端,与MySQL客户端类似,show databases、show tables等,简单试下

localhost :) show databasesSHOW DATABASES┌─name────┐
│ default │
│ system  │
└─────────┘2 rows in set. Elapsed: 0.030 sec.

JAVA其实 Mybatis 还可以操作 ClickHouse,这里用 Druid 进行连接管理

<dependency><groupId>ru.yandex.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.1.40</version>
</dependency>

注意事项:clickhouse的http访问默认端口是8123,tcp默认端口是9000。所有jdbc连接ck的端口是8123。9009端口,用于集群复制数据。用户名默认default,密码为空,可以在/etc/clickhouse-server/users.xml修改

root@PC-202003221735:/# echo -n "0rb!t" | sha256sum | tr -d '-'
echo -n "0rbtail -f /data/www/html/a.txt " | sha256sum | tr -d '-'
817729d06941a2fb974367c82e52f77ecc8b8284add6f103ca756aa096ead8e6<!--
<password>0rb!t</password>
-->
<password_sha256_hex>817729d06941a2fb974367c82e52f77ecc8b8284add6f103ca756aa096ead8e6</password_sha256_hex>

php

composer require smi2/phpclickhouse

aaa

【CK】ClickHouse入门相关推荐

  1. ClickHouse入门技术分享PPT之一

    今天为小伙伴们做了ClickHouse入门的技术分享(确实好用),把做的PPT贴在下面当做今日份吧. 多图预警~ 紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布丁紫薯布 ...

  2. 《ClickHouse入门、实战与进阶》的创作之路

    写作不是思考的记录,写作就是思考本身. --理查德·费曼 目录 写作的重要性 写作之路 OLAP技术对于企业决策者.数据分析师等至关重要 分享一些经验 最后 写作的重要性 本文开头借用了费曼的名言来表 ...

  3. ClickHouse入门

    1 什么是ClickHouse ​ ClickHouse 是俄罗斯的Yandex于2016年开源的列式存储数据库(DBMS),他的优势就是快,每秒处理的数据量特别大,主要用于在线分析处理查询(OLAP ...

  4. Clickhouse入门学习、单机、集群安装部署

    参考:https://blog.csdn.net/qq_37933018/article/details/108019566 Clickhouse官网:https://clickhouse.tech/ ...

  5. ClickHouse入门基础教程

    问题导读: 1. ClickHouse是什么? 2. ClickHouse有哪些特性? 3. ClickHouse的使用场景有哪些? 一.what is clickhouse? clickhouse ...

  6. ClickHouse入门到精通

    一 clickhouse-简介 ​ ClickHouse是俄罗斯的Yandex于2016年开源的一个用于联机分析(OLAP:Online Analytical Processing)的列式数据库管理系 ...

  7. clickhouse入门与安装

    单机版安装 下载如下四个安装包 -rw-r--r--. 1 root root 76140 1月 8 16:47 clickhouse-client-20.5.2.7-2.noarch.rpm -rw ...

  8. [Clickhouse 入门到精通]-单机安装部署

    Clickhouse官网:ClickHouse - Fast Open-Source OLAP DBMS Clickhouse中文官网:什么是ClickHouse? | ClickHouse Docs ...

  9. ClickHouse入门教程

    文章目录 一.介绍 1.1 什么是ck 1.2 OLAP 场景的关键属性 1.3 列式存储和行式存储的区别 二.安装&卸载 2.1 安装 2.2 卸载 2.3 相关的文件夹 三. SQL语句 ...

最新文章

  1. 监控Oracle性能的SQL
  2. 《非暴力沟通》- 笔记
  3. .net core orm框架_轻量级高性能PHP框架ycroute
  4. python不完全支持面向对象程序设计_Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】...
  5. CentOS6.5与XP双系统安装
  6. k-means 聚类算法
  7. 李宏毅-《深度学习人类语言处理》国语版(2020)视频课程及ppt分享
  8. python解密m3u8播放_Python3 通过m3u8连接获取完整媒体文件(附全网视频VIP观看方法)...
  9. Windows下IIS中不能添加网站
  10. 金山云android连麦源代码,Android-SDK开发指南
  11. 土豆聊天poeato Chat注册账号时提示网络刺错误怎么解决
  12. 4.JUC-共享模型之无锁
  13. 面试求职:数据库常见面试题(数据库优化思路)
  14. [渝粤教育] 内蒙古大学 微生物学 参考 资料
  15. Excel表格将多个单元格内容合并到一个单元格中_工作中使用记录_2021-03-29
  16. 【解决方案】logging: 中文log乱码
  17. eclipes error
  18. LeetCode刷题1894-中等-找到需要补充粉笔的学生编号
  19. 网络信息安全管理要素和安全风险评估
  20. GridView控件 Image控件 与图片的二进制数据库存储和显示

热门文章

  1. 正则表达式常用操作符
  2. python爬虫网易云音乐评论最多的歌_Python爬虫44万条数据揭秘:如何成为网易云音乐评论区的网红段子手?...
  3. Antd给表格一个斜线分隔
  4. 公司注册不满一年如何名称变更
  5. Z字型变幻,整数反转
  6. 【C语言编程4】输入年份输出全年日历
  7. ../,./,/的区别
  8. HDMI协议解析-从软硬件角度分析
  9. 电脑有网但打不开网页怎么办?
  10. 工艺角,PVT, TT,SS,FF,FS,SF