请教关于大数据量(每天约 1000 万)的统计操作优化方法。

2016-10-31 11:56:52 +08:00
 enjoyhot

mysql 示例: select a,count(distinct b) as num from table where c between time1 and time2 group by a order by num desc limit N;

要做的是线上事务处理,一般 time1 和 time2 是自由选择,单位是天,考虑到了数据量增长快,时间阔度的自由选择将导致查询越来越慢。

目前采用 phoenix+hbase 的方式查询,用一天的数据做测试,效果不是很好,约( 40s ),请教有什么好的方法,提高在线查询的效率。

目前想到方案有: hbase 继续保持原数据,利用 hadoop 等工具离线统计最终需要的信息,将统计信息保存到 mysql 或 hbase 中,再由 web 查询。不知道这种方法是否可行?如果可行, mysql 或 hbase 应该如何设计才会更好,最终做到点击响应延迟尽量小。

15405 次点击
所在节点    MySQL
26 条回复
nbabook
2016-10-31 12:47:25 +08:00
以我最近的经验来讲, hadoop 的计算时间可能会比你现在的计算时间还要长。。。
Zuckonit
2016-10-31 12:50:09 +08:00
每天一千万。总量大概维持到多少?
funky
2016-10-31 12:54:27 +08:00
持续关注,面临一样的问题
bsidb
2016-10-31 13:07:06 +08:00
用 Spark?性能会比 Hadoop 好。
如果这个查询频繁使用,可以考虑离线预计算然后在线查询。
bsidb
2016-10-31 13:08:42 +08:00
离线预计算的话, Apache Kylin 是做这个的。
reus
2016-10-31 13:24:32 +08:00
count 运算可以按日切分,所以昨天和更早的可以汇总到一张表,每日的数据计算一次就可以重复使用了
enjoyhot
2016-10-31 14:50:08 +08:00
@nbabook 嗯嗯,是的,我用开始用 spark ,觉得时间是不可接受的,而且每次都要提交一个应用。所以考虑离线计算,采取先计算好的方式。

@bsidb Kylin 我再去了解一下。而你说的预计算,有没有预计算的方案推荐,因为 time1 和 time2 是不确定的,导致了预计算的结果保存比较难定。
enjoyhot
2016-10-31 14:51:42 +08:00
@Zuckonit 目前暂不考虑总量的问题,暂时查询跨度订个目标一个月吧。
enjoyhot
2016-10-31 14:54:01 +08:00
@reus 我也希望离线计算能用到这种方案,但是 count 是与 distinct 关联在一起的,单纯保存 count 就把 distinct 的信息忽略了。
wmttom
2016-10-31 16:06:19 +08:00
一千万条用 elasticsearch 吧,能满足线上查询,就是查询的 DSL 得改下,不能用 SQL 。离线计算可以用 spark 直接读 es 当做 rdd 处理, es 官方有工具。
一般统计查询类的需求分两种,一种是可离线计算的,固定维度,固定时间范围的,或者可由这类线性叠加能得到的,都可以离线计算(比如一周 pv 就是每天 pv 之和),存 Hive 按照天的分区表, spark 跑数据存 MySQL 或者 HBASE ,用来直接显示;
另一种不固定维度,或者需要去重的。需求方如果可以接受固定时间范围,这样也可以离线算,比如月活没法用日活叠加,但是可以只提供自然月的月活,这类也可以离线跑。
最不好搞的就是任意维度任意范围,这种只能及时算,可以用 Impala 直接读 Hive 的分区表来实时查询结果,或者用 elasticsearch 当做实时分析引擎来出,可以根据数据集的大小和集群的资源限制这类查询的最大范围。
cswanghan
2016-10-31 16:12:35 +08:00
赞同 @wmttom 对于统计需求分类的解法。

另外对于这种在线动态查询,可以尝试引导业务方接受有限制的在线动态查询(数据预处理好,月粒度,周粒度,天粒度统计数据,在线直接插),对于动态查询如果非要在线查要接受现有条件下相应慢的情况。

工作中,有些问题是靠工程解的,有些问题是靠沟通解的。
bsidb
2016-10-31 16:42:11 +08:00
如果 b 是和时间有紧密相关性的,那么可以分时段累加。
billowqiu
2016-10-31 16:52:35 +08:00
"工作中,有些问题是靠工程解的,有些问题是靠沟通解的"
不能同意更多啊
Zuckonit
2016-10-31 17:20:26 +08:00
单位都是天了,应该不是实时性要求高的需求了。把能选的时间固化下来,提前计算。
menc
2016-10-31 17:54:09 +08:00
@nbabook 说了 hadoop 是离线计算,刷到 database 里面的,离线计算多长时间都无所谓的了,两分钟五分钟又能如何。
nbabook
2016-10-31 19:03:49 +08:00
@menc 我只是看他说了 40s 的耗时,才会说 hadoop 的离线计算时间问题。
单纯从离线计算的角度而言,我所做的项目大部分是采用 hive+spark+mysql 的方式,按小时、天进行统计计算,然后将结果存储 mysql 供界面显示。
mapreduce 的方式始终是将任务 map 到多台机器上,然后在 reduce 回来,他的执行效率是数据越大越有优势。
但是,如果 time1 和 time2 的随机性非常大,而分时间段统计数据又不能进行简单叠加的话,这个模式基本没有意义,不可能将所有可能的选项都计算好。
menc
2016-10-31 19:26:16 +08:00
@nbabook
单位是天,每天一千万,没有比天更小的单位,意思就是千万以上的数量级。这个数量级已经比较合适 hadoop 来做离线计算了。
然后, hadoop 调优不是你想的那样。
我们现在从千万到上亿的任务都是 hadoop 来做, hadoop 的运行是很稳定的一件事情,调优也是很稳定的一件事情。
kylefeng
2016-10-31 19:53:07 +08:00
先和业务上沟通下吧,是不是有索引列做成查询表单的必填项,你这种统计查询很容易全表扫了。除非用上面几位同学的方案离线计算后数据流回展示、查询用的 MySQL 表。
ebony0319
2016-10-31 23:20:55 +08:00
你现在的瓶颈是卡在查还是插,索引是一个双刃剑。要想查得更快,就要建立索引。但是要想插得更快。最好把索引去掉。因为索引他会去查是否有重复值。
liprais
2016-10-31 23:28:04 +08:00
用 phoenix 查询 hbase 就行了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/316742

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX