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 应该如何设计才会更好,最终做到点击响应延迟尽量小。
1
nbabook 2016-10-31 12:47:25 +08:00
以我最近的经验来讲, hadoop 的计算时间可能会比你现在的计算时间还要长。。。
|
2
Zuckonit 2016-10-31 12:50:09 +08:00
每天一千万。总量大概维持到多少?
|
3
funky 2016-10-31 12:54:27 +08:00
持续关注,面临一样的问题
|
4
bsidb 2016-10-31 13:07:06 +08:00 via Android
用 Spark?性能会比 Hadoop 好。
如果这个查询频繁使用,可以考虑离线预计算然后在线查询。 |
5
bsidb 2016-10-31 13:08:42 +08:00 via Android
离线预计算的话, Apache Kylin 是做这个的。
|
6
reus 2016-10-31 13:24:32 +08:00
count 运算可以按日切分,所以昨天和更早的可以汇总到一张表,每日的数据计算一次就可以重复使用了
|
7
enjoyhot OP |
9
enjoyhot OP @reus 我也希望离线计算能用到这种方案,但是 count 是与 distinct 关联在一起的,单纯保存 count 就把 distinct 的信息忽略了。
|
10
wmttom 2016-10-31 16:06:19 +08:00 1
一千万条用 elasticsearch 吧,能满足线上查询,就是查询的 DSL 得改下,不能用 SQL 。离线计算可以用 spark 直接读 es 当做 rdd 处理, es 官方有工具。
一般统计查询类的需求分两种,一种是可离线计算的,固定维度,固定时间范围的,或者可由这类线性叠加能得到的,都可以离线计算(比如一周 pv 就是每天 pv 之和),存 Hive 按照天的分区表, spark 跑数据存 MySQL 或者 HBASE ,用来直接显示; 另一种不固定维度,或者需要去重的。需求方如果可以接受固定时间范围,这样也可以离线算,比如月活没法用日活叠加,但是可以只提供自然月的月活,这类也可以离线跑。 最不好搞的就是任意维度任意范围,这种只能及时算,可以用 Impala 直接读 Hive 的分区表来实时查询结果,或者用 elasticsearch 当做实时分析引擎来出,可以根据数据集的大小和集群的资源限制这类查询的最大范围。 |
11
cswanghan 2016-10-31 16:12:35 +08:00
赞同 @wmttom 对于统计需求分类的解法。
另外对于这种在线动态查询,可以尝试引导业务方接受有限制的在线动态查询(数据预处理好,月粒度,周粒度,天粒度统计数据,在线直接插),对于动态查询如果非要在线查要接受现有条件下相应慢的情况。 工作中,有些问题是靠工程解的,有些问题是靠沟通解的。 |
12
bsidb 2016-10-31 16:42:11 +08:00 via Android
如果 b 是和时间有紧密相关性的,那么可以分时段累加。
|
13
billowqiu 2016-10-31 16:52:35 +08:00
"工作中,有些问题是靠工程解的,有些问题是靠沟通解的"
不能同意更多啊 |
14
Zuckonit 2016-10-31 17:20:26 +08:00
单位都是天了,应该不是实时性要求高的需求了。把能选的时间固化下来,提前计算。
|
15
menc 2016-10-31 17:54:09 +08:00
@nbabook 说了 hadoop 是离线计算,刷到 database 里面的,离线计算多长时间都无所谓的了,两分钟五分钟又能如何。
|
16
nbabook 2016-10-31 19:03:49 +08:00 1
@menc 我只是看他说了 40s 的耗时,才会说 hadoop 的离线计算时间问题。
单纯从离线计算的角度而言,我所做的项目大部分是采用 hive+spark+mysql 的方式,按小时、天进行统计计算,然后将结果存储 mysql 供界面显示。 mapreduce 的方式始终是将任务 map 到多台机器上,然后在 reduce 回来,他的执行效率是数据越大越有优势。 但是,如果 time1 和 time2 的随机性非常大,而分时间段统计数据又不能进行简单叠加的话,这个模式基本没有意义,不可能将所有可能的选项都计算好。 |
17
menc 2016-10-31 19:26:16 +08:00
@nbabook
单位是天,每天一千万,没有比天更小的单位,意思就是千万以上的数量级。这个数量级已经比较合适 hadoop 来做离线计算了。 然后, hadoop 调优不是你想的那样。 我们现在从千万到上亿的任务都是 hadoop 来做, hadoop 的运行是很稳定的一件事情,调优也是很稳定的一件事情。 |
18
kylefeng 2016-10-31 19:53:07 +08:00
先和业务上沟通下吧,是不是有索引列做成查询表单的必填项,你这种统计查询很容易全表扫了。除非用上面几位同学的方案离线计算后数据流回展示、查询用的 MySQL 表。
|
19
ebony0319 2016-10-31 23:20:55 +08:00 via Android
你现在的瓶颈是卡在查还是插,索引是一个双刃剑。要想查得更快,就要建立索引。但是要想插得更快。最好把索引去掉。因为索引他会去查是否有重复值。
|
20
liprais 2016-10-31 23:28:04 +08:00 1
用 phoenix 查询 hbase 就行了
|
22
Actrace 2016-11-01 08:54:41 +08:00 1
一般来说瓶颈可能在数据库的计算那块,即出数据。
但是楼主没有给多少业务过程的耗时数据,所以也就无从考量了。 |
23
enjoyhot OP @wmttom 感谢回答。对 elasticsearch 不了解,不过似乎是搜索引擎方面的,“存 Hive 按照天的分区表, spark 跑数据存 MySQL 或者 HBASE ”是指利用 spark 调用 hive 进行 mapreduce 操作存入数据库吗。对于第二种需求,根据其它人的评论,我觉得应该属于大多人的做法,准备尝试。
|
24
enjoyhot OP @ebony0319 有尝试索引的方式,但免不了的全表扫描是硬伤,所以感觉还是修改业务,采取离线计算,再统计展示好一些。
|
25
enjoyhot OP @liprais 目前就是用这种方法,根据官网 http://phoenix.apache.org/performance.html 性能对比,感觉略吊,所以试了一试。
|
26
wmttom 2016-11-01 21:01:45 +08:00
@enjoyhot 这里说的 Hive 意思主要是指用 Hive 作为 SQL on Hadoop 的 metadata ,本质上所有的 Hive 表都是 HDFS 上的文件, Impala 、 Spark df 可以共享 Hive 的 metadata 来把 HDFS 文件当做建好的表跑 SQL 。需求并不是非常复杂的话可以纯 SQL 搞定,比如每一个任务都是一个 Hive 的 SQL ,从一个 Hive 表生成另一个 Hive 表,然后用 sqoop 之类的工具把这张结果 Hive 表导入 MySQL 供数据后台查询。复杂的需求可以通过 Hive UDF 之类的搞定,也可以去写 spark 任务, mapreduce 写起来会比较繁琐, spark rdd 的接口相对简单些。
elasticsearch 自己给自己的定义除了搜索,还有数据分析引擎。很适合做数据量不是非常大情况下的实时全维度数据分析,说白了任意维度数据分析需要所有字段都带索引, es 又封装好了常用统计方法,用起来正合适。一个搞过的实践是当日数据使用 es 实时分析,之前数据离线处理,因为一般离线处理都在凌晨跑,看不到当日数据。 |