架构概述
ClickHouse 是一个真正的列式数据库管理系统,数据始终是按列存储的,包括矢量(向量或列块)执行的过程。只要有可能,操作都是基于矢量进行分派的,而不是单个的值,这被称为,矢量化查询执行.
优点
- ClickHouse是一个DBMS(Database Management System,DBMS),而不是一个单一的数据库。ClickHouse允许在运行时创建表和数据库,加载数据和运行查询,而无需重新配置和重新启动服务器。
- 数据压缩空间大,处理单查询高吞吐量每台服务器每秒最多数十亿行,写入速度50-200M/s对于大量的数据更新非常适用。
- 支持大部分SQL(join写法比较特殊;最新版已支持类似SQL的join,但性能不好)
- 支持多核并行处理,在多个服务器上分布式处理,数据可以驻留在不同的分片上
缺点:
- 不支持真正的Update/Delete操作。
- 不支持事务。
- 支持有限操作系统。(目前支持具有x86_64,AArch64或PowerPC64LE CPU架构的Linux,FreeBSD或Mac OS X上运行。对于Windows不支持。)
- 尽量做1000条以上批量的写入,避免逐行insert或小批量的insert,update,delete操作,因为ClickHouse底层会不断的做异步的数据合并,会影响查询性能,这个在做实时数据写入的时候要尽量避开
什么是面向行与面向列的数据库?
面向行的数据库是按行存储,把一条记录的所有属性(列)存储在一起.主要使用在OLTP(事务处理)的场景,如电商场景中加购物车、下单、支付等需要在原地进行大量insert、update、delete操作.主流的数据库有MySQL、PostgreSQL和大多数传统的关系数据库
面向列的数据库是将行分解成多个数据元素,并且储存的数据库元素对应于所有的行。主要应用在数据分析(OLAP)场景.大部分的分析查询都只需要读取某一个(或者几个)表的几列,而不需要像传统以行为导向的数据库那样需要扫描整个表的数据,这两者IO量的差距是非常大的.
和MySQL使用有什么区别?
- MySQL单条SQL是单线程的,只能跑满一个core,ClickHouse相反,有多少CPU,吃多少资源,所以飞快
- MySQL需要大量随机IO,ClickHouse基本是顺序IO,对IO基本没有太高要求,通常情况下ClickHouse的CPU先跑满了,当出现查询波动时需要优先关注CPU消耗.
- ClickHouse因为不支持事务,所以不存在隔离级别。ClickHouse的定位是分析性数据库,而不是严格的关系型数据库
OLAP场景的特点
大宽表,读大量行但是少量列,结果集较小 在OLAP场景中,通常存在一张或是几张多列的大宽表,列数高达数百甚至数千列。对数据分析处理时,选择其中的少数几列作为维度列、其他少数几列作为指标列,然后对全表或某一个较大范围内的数据做聚合计算。这个过程会扫描大量的行数据,但是只用到了其中的少数列。而聚合计算的结果集相比于动辄数十亿的原始数据,也明显小得多。 在分析场景中,删除、更新操作并不是核心需求。ClickHouse没有直接支持delete、update操作,而是变相支持了mutation操作,语法为alter table delete where filter_expr,alter table update col=val where filter_expr。
案例分析
ClickHouse是近年来备受关注的开源列式数据库,主要用于数据分析(OLAP)领域。目前国内社区火热,各个大厂纷纷跟进大规模使用:
- 今日头条内部用ClickHouse来做用户行为分析,内部一共几千个ClickHouse节点,单集群最大1200节点,总数据量几十PB,日增原始数据300TB左右。
- 腾讯内部用ClickHouse做游戏数据分析,并且为之建立了一整套监控运维体系。
- 携程内部从18年7月份开始接入试用,目前80%的业务都跑在ClickHouse上。每天数据增量十多亿,近百万次查询请求。
- 快手内部也在使用ClickHouse,存储总量大约10PB,每天新增200TB, 90%查询小于3S。
- 阿里云也推出了自己的ClickHouse托管产品
安装
- 这里使用RPM安装包
//添加官方存储库
sudo yum install yum-utils
sudo rpm --import https://repo.clickhouse.tech/CLICKHOUSE-KEY.GPG
sudo yum-config-manager --add-repo https://repo.clickhouse.tech/rpm/stable/x86_64
// 运行命令安装:
sudo yum install clickhouse-server clickhouse-client
启动
- 运行如下命令在后台启动服务
sudo /etc/init.d/clickhouse-server start
- 启动服务后,您可以使用命令行客户端连接到它(默认情况下,使用default用户并不携带密码连接到localhost:9000):
clickhouse-client
安装过程中常见问题
- 在ClickHouse安装过程中,clickhouse-server start 命令启动 提示 UNKNOW错误
该问题为config.xml 中的配置的日志路径和数据路径所属用户为非ClickHouse,导致,执行 chown -R clickhouse:clickhouse 日志目录/数据目录 即可解决该问。
- 安装结束后启动客户端报错:Code: 210. DB::NetException: Connection refused (localhost:9000)
该问题为clickhouse 默认端口为9000, 端口被占用了,修改配置文件cd /etc/clickhouse-server/config.xml即可
基本操作
- 创建数据库
// 语法
CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(...)]
// demo
CREATE DATABASE IF NOT EXISTS demo
ClickHouse使用的是原生的数据库引擎Ordinary(在此数据库下可以使用任意类型的表引擎,在绝大多数情况下都只需使用默认的数据库引擎)
- 创建表
// 语法
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2],
...
) ENGINE = engine
// demo
-- 注意首字母大写 -- 建表
CREATE TABLE IF NOT EXISTS user_local
(
id Int32,
name String
) engine = MergeTree
这里需要注意的是(engine)表引擎及其设置,这决定了对此表的查询操作是如何在物理层面执行的所有细节。
表引擎
表引擎(即表的类型)决定了: 数据的存储方式和位置,写到哪里以及从哪里读取数据 支持哪些查询以及如何支持。 并发数据访问。 索引的使用(如果存在)。 是否可以执行多线程请求。 数据复制参数。
所有的表引擎类型详细见: clickhouse.tech/docs/zh/eng…
如果上页中的命令改为engine=Memory, 将创建了一张内存表,即使用Memory引擎。表引擎决定了数据表的特性,也决定了数据将会被如何存储及加载。Memory引擎是ClickHouse最简单的表引擎,数据只会被保存在内存中,在服务重启时数据会丢失。
- 插入数据
// demo
INSERT INTO user_local VALUES(1,'tom'),(2,'jack');
- 查询数据
// demo
select * from user_cluster;
┌─id─┬─name─┐
│ 2 │ jack │
└────┴──────┘
┌─id─┬─name─┐
│ 1 │ tom │
└────┴──────┘
优化
- 关闭虚拟内存,物理内存和虚拟内存的数据交换,会导致查询变慢
- CPU一般在50%左右会出现查询波动,达到70%会出现大范围的查询超时,CPU是最关键的指标,要非常关注。
- 尽量减少JOIN时的左右表的数据量,必要时可以提前对某张表进行聚合操作,减少数据条数。有些时候,先GROUP BY再JOIN比先JOIN再GROUP BY查询时间更短。
- JOIN操作时一定要把数据量小的表放在右边,ClickHouse中无论是Left Join 、Right Join还是Inner Join永远都是拿着右表中的每一条记录到左表中查找该记录是否存在,所以右表必须是小表