定义
高性能的OLAP的列式数据库
优势
- 数据压缩比率大
- 单表读写能力强
- 多数据引擎,选择性多
- 支持高可用
劣势
- 不适合高qps
- 表连接性能低
- 自定义函数开发难度高
- 删改能力弱
数据库排名
排名44,不算靠前,但在OALP领域里,还算不错
性能测试
我使用我的笔记本电脑的虚拟机测试的资源如下
写能力测试
读能力测试
系统负载高,性能稍微低一些,其中UserBea表一共有35168911条数据,而CityRecord表有1156831条数据
select t.day,t.visit_num,t2.sale_num from
(select day,count(day) as visit_num from(
select toDate(times) as day from UserBea where item_id=1
)t
group by day ) t left join (
select day,count(day) as sale_num from(
select toDate(times) as day from CityRecord where item_id=1
)group by day)t2
ON t2.day=t.day
ck读写性能强劲的来源
- 高效利用cpu的并行处理的(MMP架构)
- 高效紧凑的列式数据压缩
- 向量化计算
数据引擎介绍
clickhouse支持多种数据引擎,如可以从mysql和hdfs读取数据,以下一一介绍
Megre Tree
Megre Tree是使用最多的数据引擎,是clickhouse的最重要的引擎
写入特点
- 数据以数据段的形式批次写入
- 数据段不可更改
- 数据段定期合并
建表语法
create table t_order_mt(
id type,
name type
) engine =MergeTree
partition by name
primary key (id)
order by (id);
sample by inthash32(id)
setting index_granularity=8192
- partition by 按字段分区,可提升索引效率
- primary key 唯一主键索引,可以不添加,默认为order by 的字段作为索引
- order by 在数据字段指定的字段排序按照排序
- sample by 采样方法
- setting index_granularity 指定稀疏索引,相比之前的全部指定全部索引,采取建立少量的索引,用来 索引一定范围字段,可以减少查找索引的时间
TTL
ttl可以设定非主键列或者表的存活时间,设定格式为
指定列
#后续添加
alter table t_order_mt modify column name type ttl create_time + interval 1 day/second/minute
## 或者建表时候指定ttl时间
name ttl create_time + interval 1 day/second/minute
指定表
create table t_order_mt(
id type,
name type
) engine =MergeTree
partition by name
primary key (id)
order by (id);
sample by inthash32(id)
setting index_granularity=8192
ttl create_time + interval 1 day/second/minute
LSM树
clickhouse使用LSM结构来查询保存数据
写入方式
Megre Tree 使用LSM tree结构保存数据。LSM树存储原理是使用多个层次的树,最上层次的树,数据最少,数据版本也是最新,每次都会写到最少一层,达到一层次后,才进行合并
数据合并方式
数据合并方式是以上一层直接覆盖下一层的相同的key,合并的层能保证全局有序
ReplacingMergeTree
ReplaingMergeTree可以保证主键唯一,避免重复数据,但需要注意的是:
- 只能保证分区内是唯一的
- order by的字段比primary key权重更高
- 只能在表合并后,才能去除重复数据(按照版本号,key等标志)
#合并表
optimize table a final
SummingMerge Tree
只能查询聚合结果
AggregatingMerge Tree
类似数据立方体的概念,会预先将数据聚合成为一个cube,是一个聚合的统计的概念,统计一下表数据,字段结构如下
create table item_agg(
item_id Int64,
day Date,
num AggregateFunction(sum,Int32),
price AggregateFunction(sum,Int32)
)engine=AggregatingMergeTree()
partition by day
order by item_id
注意:
- 聚合是使用order by 字段
- 合并分区才会发生聚合计算
- 建议和物理视图搭配使用
- 由于保存的结果为二级制,需要相应的查询语法
select item_id,day,sumMerge(num) from item_agg group by item_id,day ;
VersionedCollapsingMergeTree
这两个引擎是用在数据修改方面,可以直接插入新的数据,可以根据版本号,保留最新版本的数据,但必须在一个分区内。
HDFS
hdfs引擎可以直接查询hdfs上的数据,建表的格式如下
create table item_agg(
item_id Int64,
day Date,
num AggregateFunction(sum,Int32),
price AggregateFunction(sum,Int32)
)engine=HDFS('hdfs://host:9000/hive','csv')
Mysql引擎
create table t1
(
id Int32,
name String,
createDate DateTime
)
engine = MySQL('localhost:3306', 'demo', 'mysql_engine', 'root', '123456');
kafka引擎
建议使用kafka引擎消费kafka数据,在使用物化视图查询写入另外的表
create table t1
(
id Int32,
name String,
createDate DateTime
)ENGINE = Kafka()
SETTINGS kafka_broker_list = 'hadoop103:9092',
kafka_topic_list = 'userkafka',
kafka_group_name = 'consumer-group',
kafka_format = 'JSONEachRow',
kafka_skip_broken_messages = 1,
kafka_num_consumers = 2
参数说明:
- kafka_skip_broken_message:解析错误跳过的条数
- kafka_num_consumers :消费的线程数
Buffer
内存型引擎,重新将直接丢失数据
物化视图
视图是数据预聚合结果的查询,性能较高,但对源表写入不友好,需要消耗太多资源处理视图的触发器
定义
下面是物化视图的维基百科的介绍
In computing, a materialized view is a database object that contains the results of a query. For example, it may be a local copy of data located remotely, or may be a subset of the rows and/or columns of a table or join result, or may be a summary using an aggregate function.
The process of setting up a materialized view is sometimes called materialization. This is a form of caching the results of a query, similar to memoization of the value of a function in functional languages, and it is sometimes described as a form of precomputation. As with other forms of precomputation, database users typically use materialized views for performance reasons, i.e. as a form of optimization.
总结如下:物化视图是先先建立规则并优化的查询的缓存 场景如下: 为了不断更新源表的聚合记录可以使用视图,将新的记录写入
CREATE MATERIALIZED VIEW agg_mv engine=AggregatingMergeTree()
partition by day
order by (item_id,day) POPULATE as
select item_id , day, sumState(toInt32(1)) as num ,sumState(toInt32(price)) as price from(
select item_id ,toDate(times) as day, 1 as num ,price
from CityRecord
)
group by item_id,day
更新策略
1.物化视图创建好之后,若源表被写入新数据则物化视图也会同步更新 2.POPULATE 关键字决定了物化视图的更新策略: 若有POPULATE 则在创建视图的过程会将源表已经存在的数据一并导入,类似于 create table ... as 若无POPULATE 则物化视图在创建之后没有数据,只会在创建只有同步之后写入源表的数据. clickhouse 官方并不推荐使用populated,因为在创建物化视图的过程中同时写入的数据不能被插入物化视图。 3.物化视图不支持同步删除,若源表的数据不存在(删除了)则物化视图的数据仍然保留
4.物化视图是野种特殊的数据表,可以用show tables 查看