分享嘉宾:墨淄 阿里云数据库事业部 编辑整理:猫哥 出品平台:大数据猫 目录
我们是OLAP监控诊断团队的,我们这边收集了海量的SQL审计数据,我们的用户经常提出这样的需求:
我们的数据规模:
为什么会选择ClickHouse,主要从这几点出发吧:
在进行经验分享之前,先简单介绍一下我们整个的OLAP监控诊断系统架构,这样可以让大家知道ClickHouse在我们整个系统架构中扮演者什么样的角色和作用,我们整个架构分为两个链路。
后面我们会提供一个服务层,然后到用户那里去,其中主要包括:用户画像、监控指标、SQL审计、诊断分析等。细心的同学可能会看到,我们这个架构上有一块属于离线的分析,那为什么我们会用离线的分析呢?上面我们也说了,ClickHouse做简单的Join还是可以的,如果我们做复杂的任务计算的话,ClickHouse可能会把我们的系统资源打满,会影响整个ClickHouse的稳定性。一开始的我们会把大的任务放到凌晨1-2点开始执行,后来发现这种方式不太可行,因为随着业务的接入,任务也越来越多,所以我们后来加入了离线分析这块。 这个就是ClickHouse在我们这个整个监控诊断系统架构扮演的角色。 在进入经验分享之前我还想让大家先了解一下ClickHouse的整个架构,尽管好多同学都已经非常了解整个ClickHouse的架构了,我还想多说一下,因为后边讲的优化点,都是需要先了解ClickHouse架构,才知道如何去优化,尤其是ClickHouse的存储结构。
ClickHouse经验分享,我们今天主要分享两个部分:
对于ClickHouse我们这块的优化主要有三点:
下面我们再来讲一下写入的优化,我们每次batch insert之后都会产生一个MergeDataPart,然后MergeDataPart再去异步合并成一个总的MergeDataPart,这会出现一个问题,当我们写入特别快,Merge又来不及Merge,那就会产生too many parts异常,这也是我们一开始使用clickhoue不太清楚底层写入的机制,导致不断的有这种异常出现,所以我在分享之前,先去给大家回顾一下ClickHouse的存储结构还有他的存储机制。我们客户端写入尽量进行批次写入,防止MergeDataPart过多,导致后台频繁merge影响性能或者报too many parts异常。 ClickHouse JDBCDriver流式写入,通过buffer表索引缓存,超过一定时间或者数据量落盘,这样会减少客户端的内存压力。 当然我们每次都是大量的数据积累批次写入,带来的影响就是数据的时效性差,对实时可见的场景不太友好,这个需要根据你的业务写入量和场景去平衡一下,到底是要积累更多的批数据写入,还是更实时的可见。 在merge的时候,我们为了提高merge的性能可以在后台配置一下:
整体的思路:
方案1:如果我们按照logic_ins_id做分区,我们会按照logic_ins_id做主键索引,如果 我们的查询sql没有包含logic_ins_id,我们传入的是processid,这会出现命中不了主键索引,从而扫码全部本地索引数据,这对查询性能带来很大的影响。 方案2:我们需要做一个映射表,记录pricessid和logic_ins_id的映射关系,这样我们在查询的时候,先通过pricessid查询出来logic_ins_id,然后再通过logic_ins_id命中主键索引,从而避免全表扫码,提高查询效率,我们这整个优化下来,查询时间降低到秒级和毫秒级以内,大家看完这个方案,可能会联想到二级索引,是的,我们有一个映射表,来充当二级索引的作用。 这个是我们业务场景的效果,整个页面的查询都是毫秒级返回。 用户画像的查询,如果放在ClickHouse做比较复杂,查询时间会在30分钟左右,我们通过把用户画像的SQL放在了Spark内计算,计算完结果写入ClickHouse中,也可以加速ClickHouse查询的速度。
今天的内容大体就到这了,感谢🙏大家。 |
|