在使用Impala的过程中,也发现了Impala的不足。
首先是单点问题,即Catalog和StateStored单点问题,虽然Catalog单点挂掉之后,对正在进行中的查询影响并不是很大,但可能拉取不到最新的元数据。
第二个是资源隔离的问题,资源隔离不精确,并且资源不能通过YARN统一资源管理调度,无法实现Impala、Spark、Hive等组件的动态资源共享。
第三个是元数据更新问题,无法感知HDFS操作,每当新的记录/文件被添加到HDFS中的数据目录时,需要手动去刷新元数据。第四个比较重要的点是Impala基于内存计算,速度很快,但存在风险就是内存会溢出,内存溢出就导致任务挂掉。另外Impala的并发能力比较有限,QPS稍高一点,查询性能下降明显。
7. ClickHouse为什么快
2019年后,37手游开始引入ClickHouse。当时ClickHouse是一个比较现象级的产品,非常快。为什么ClickHouse会这么快?
- ClickHouse实现了单机多核并行,还支持分布式计算,支持SIMD指令等,能榨干机器的性能,从而提升查询速度;
- ClickHouse支持多样化的表引擎,包括mergeTree等20多种表引擎,基于不同的业务场景选择不同的表引擎,可以带来性能上的提升;
- ClickHouse的索引机制包括主键索引,稀疏索引,能够提升查询性能;
- ClickHouse的向量化引擎能够在多数据流时,为上层应用的性能带来极大提升;
- ClickHouse是列式存储,自带数据压缩,列式存储更适合OLAP场景,再加上自带的数据压缩的处理速度,能做到百倍级别的性能提升;
- ClickHouse支持多核并行处理,单条SQL的执行会尽可能地利用更多的CPU核数,榨干CPU的资源来提升执行效率;
- ClickHouse还支持多服务的并行处理数据,数据保存在不同的节点不同shard上,查询可以并行地在所有shard上进行处理。
8. ClickHouse在广告自动化投放平台的应用
37手游将ClickHouse应用在广告自动化投放平台来做查询的加速。37手游的广告投放平台需要对媒体广告投放效果进行实时监控(比如在头条或腾讯的媒体上投放广告),广告投放之后就有广告费用消耗,同时也会拉来一些用户注册(即对应的广告效果),根据广告效果来调整自动化投放策略。未引入ClickHouse之前,面临着两个技术挑战:
(1)业务数据的更新频率非常高,因为媒体广告投放时,投放资源时刻在消耗,需要实时拉取。
(2)多表关联的问题:广告投放资源的消耗需要关联上效果数据,还要关联各种各样的广告数据,多表关联的效率就会比较低。
针对这些问题使用了ReplicatedMergeTree表引擎。
- 对于多表关联,根据相同的join key,哈希到同一个节点,以实现local join,以减少计算时数据做shuffle时的消耗;
- 对于频繁更新的问题,将业务业务库MySQL的数据同步到ClickHouse,将Mysql的update/delete/ insert的方式变成clickhouse insert(append),构建历史数据和新增数据的视图,进行优化合并操作,因为历史数据不会发生变化,相对比较好处理;
- 对于T-1或T的新增数据,只有一天的数据,数据量比较小,在进行更新操作时,取最近一条数据,然后两份数据合起来,我们曾考虑过用默认的replace来进行表更新,通过ClickHouse本身的一些机制来做数据合并,但因为业务数据插入的频率高,数据量大,ClickHouse数据合并是异步的,容易出现Merge不过来的现象。当然可以通过一些手段优化,比如optimize、final进行强制合并,但因为optimize不是一个常规操作,不能太频繁;
- 在查询时,使用final来做合并,会影响查询性能,特别是在ClickHouse的早期版本,是单线程的,性能也不行。
因此最终采用了ReplicatedMerge表引擎配合视图的方式。
9. ClickHouse使用心得
在使用ClickHouse过程中有一些心得。
第一个根据应用场景合理选择ClickHouse,避免“让举重运动员参加长跑比赛”(避免让clickhouse干它不擅长*事情),应多做短查询,避免大数据量的合并或频繁更新;数仓中的数据最好构建大宽表,预聚合之后再写入,并且是批量写入Clickhouse。
第二个是建表和索引的优化。
第三个是查询SQL优化,SQL优化的很多策略,无论是列裁剪与分区裁剪,归根结底就是减少查询时的IO,减少网络传输的成本;如果业务上能接受,可以采用数据采样,或者使用simple、limit、uniqComBIned等方式做近似计算来提升性能。
第四个是调整系统参数,比如单次查询的最大执行时间max_execution_time,如果执行某SQL时超过这个时间,在业务上就可能认为该SQL是有问题的,可以做降级操作,停掉该任务;还有单个服务器单次查询的最大内存max_memory_usage、单个服务器所有查询的最大内存max_memory_usage_for_all_queries、合并线程量等参数,需要在具体的业务运行过程中来调整这些参数,来使ClickHouse达到最优性能。
10. ClickHouse使用痛点
在使用ClickHouse过程中,痛点也非常清晰。
从查询性能角度看,ClickHouse的高并发能力不足,多表关联查询性能欠佳。从运维角度看,ClickHouse集群强依赖ZooKeeper,增加了运维复杂度;ClickHouse集群缺乏Resharding机制,集群扩容节点比较麻烦。从数据更新角度看,数据Replacing使用merge-on-read模式,类似MOR的表模式,当多个数据版本存在时,不管是直接取数还是合并后取数,要取最新的一条数据,容易存在性能问题;另外ClickHouse不支持删除数据,需要通过表引擎增加删除标识位或TTL来变相实现数据删除的操作,这样就会拖慢性能。