clickhouse啊, 你很快嘛

是什么

从使用角度来看是一个分析型数据库

从实现角度来看是一个列式数据库系统

分析型数据库和事务型数据库

字面意思是为了分析数据的数据库, 特点是需要存储的数据非常多

但是对数据的一致性没有要求, 因为分析数据后看的是趋势, 小部分数据的错误不影响总体的趋势

相对应的是事务型数据库

事务是什么

简单来说, 是不可分离的多个动作

讲到事务就不得不讲讲事务四个特性

原子性, 要么都成功, 要么都失败
一致性, 同一个事务中, 多次查询的数据要一致
隔离性, 每个事务要尽可能的不影响其他事务
持久性, 写入后不能丢失数据

事务性数据库对一致性要求很高

分析型数据库对海量数据要求很高

分析型的数据库一般没有一致性, 隔离性, 原子性, 但是肯定会有持久性

什么是列式数据库

比如有三条记录

1
2
3
1,clickhouse,database
2,mysql,database
3,nginx,web

如果我们按照每行进行存储, 那就是行式数据库

比如这样存储:

1
1,clickhouse,database|2,mysql,database|3,nginx,web

而我们在分析数据的时候经常会选取几列的数据进行统计分析

如果是行式存储的话, 会将整条的数据也一并读取出来(核心思想是减少

1
1,2,3|clickhouse,mysql,nginx|database,database,web

而如果是列式数据库, 则只会读取相关列的数据

通常随着数据的增大, 磁盘的 IO 会首先出现瓶颈.

采用列式数据库能够的大量减少读取的数据

并且在因为每列的数据类型都是相同的, 所以每列都能压缩数据, 减少存储大小

因为总数据量的减少, 所以在磁盘 IO 又进一步的降低了.

但是涉及到压缩和解压, 导致相比于其他数据库会使用更多的 CPU 资源

所以, clickhouse大部分情况下都是CPU先跑满, 而磁盘IO方面不会成为瓶颈

分布式数据库?

这样说可能不对劲, 因为 clickhouse 的分布式是体现在 table 层的.

打个比方, 我们有 10 万条数据, 两个节点, 不考虑双副本的情况下(高可用)

将 5 万条数据存入节点 1, 另 5 万条数据存入节点 2

这个存储数据的东西叫做本地表, 是保存了实实在在的数据

另外通过创建分布式表将本地表关联起来, 从而实现分片的效果

我们查询数据的时候直接实用分布式表名, 分布式表会自动帮我们去每个本地表上查询数据

然后在进行聚合汇总

那我们写数据的时候也写入分布式表吗?

分片和负载均衡

clickhouse 分片和其他分布式集群有点不太一样.

我们确实可以将数据写入分布式表

但是规模(日千亿级别, 百 M/s)上来了后不太推荐这种做法

主要是数据性能和数据一致性的问题.

本机的分布式表收到请求后会将数据存放在临时文件

然后再尝试将数据写入相应的分片, 造成了写放大

推荐写入数据的方式是, 通过负载均衡将数据写入不同的分片

从逻辑上来说, 每个分片是相互独立的数据

具体的数据分布情况要看负载均衡的调度策略, 以及每次写入 batch 的大小

这个需要在业务使用中多加注意

总结

非常适合用来做用户行为分析

大部分应用的瓶颈都在 IO 上, clickhouse 的架构设计避开了这点

最大限度的利用了多核的优势, 比如从磁盘读取数据后的并行解压, 以及数据分片的使用

但是在查询使用过程中需要做一些兼容.

一个大胆的想法

既然 clickhouse 能够存储大量的数据并且把数据压缩起来.

是不是可以将游戏通信中的数据存入 clickhouse 中.

这样可以分析游戏中的热点请求以及, 帮助游戏排查业务Bug