在日常的业务中,我们经常会遇到这样的场景,例如查询最近7天每天的新增用户数,那么这时候的sql样例如下:
SELECT date,count(userid) FROM demo.user WHERE date>="2022-11-03" AND date<="2022-11-09" GROUP BY date ORDER BY date;
这条sql就是统计最近7天每天的新增用户数的,但是如果应用在业务里面,如果每次做计算是不是都会重新计算下,那有没有什么办法优化下整体的业务流程呢?下面介绍下:
在应用层,例如java项目里面,我们可以把当前的结果缓存到redis中去,然后每次都从redis中获取,待redis数据过期或者被重新刷新后,才会展示新的数据。这个方案主要应用在对数据精度要求不高的场景下。
那么试想一下,如果业务场景对数据精度要求非常高,那这个时候是肯定不能在应用层使用redis缓存的,所以只能每次在数据库层去运行这条sql,如果数据量较大的话,执行这条sql的时间还是比较长的,如果在高并发的场景下,数据库很容易就资源耗尽,所以有没有什么其他的办法呢?这就是今天介绍的doris分区缓存。
在doris中自带了分区缓存的功能,就是相当于把一部分的数据结果缓存起来,只查询动态变化的那一部分,例如今天是11月9日,那么11月3日,4日,5日,6日,7日,8日这几天的数据都已经固定了,是不需要再进行重复查询的,只有今天(11月9日的数据是实时变化的),这样子就减少了查询的强度,同时也满足了数据的精度。
在doris中,分区缓存是通过doris的配置文件进行配置的,用户层无需做任何设置,也不需要更改sql。所以对于用户层是无感的。具体的配置只需要配置doris的fe.conf即可,配置项如下:
#开启partitioncache cache_enable_partition_mode=true
配置完毕后把fe重启下即可。
备注:
1、一般在这种聚合场景里面,我们建议把partitioncache给配置上。
2、我们还可以设置具体的缓存行数大小,这样可以避免缓存过多,导致其他的sql语句执行性能变慢。这里这是缓存行数大小的话,主要在fe.conf和be.conf里面进行配置。
fe.conf里面配置的话,添加如下配置项: cache_result_max_row_count=3000 查询结果集放入缓存的最大行数,可以根据实际情况调整,但建议不要设置过大,避免过多占用内存,超过这个大小的结果集不会被缓存。 be.conf里面配置的话,添加如下配置项: cache_max_partition_count=1024 每个SQL对应的最大分区数,如果是按日期分区,能缓存2年多的数据,假如想保留更长时间的缓存,请把这个参数设置得更大,同时修改cache_result_max_row_count的参数 query_cache_max_size_mb=256 query_cache_elasticity_size_mb=128 BE中缓存内存设置,有两个参数query_cache_max_size和query_cache_elasticity_size两部分组成(单位MB),内存超过query_cache_max_size + cache_elasticity_size会开始清理,并把内存控制到query_cache_max_size以下。可以根据BE节点数量,节点内存大小,和缓存命中率来设置这两个参数。
计算方法:
假如缓存10000个Query,每个Query缓存1000行,每行是128个字节,分布在10台BE上,则每个BE需要约128M内存 (10000 1000 128/10)。
还没有评论,来说两句吧...