V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
enjoyhot
V2EX  ›  MySQL

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

  •  2
     
  •   enjoyhot ·
    enjoyhot · 2016-10-31 11:56:52 +08:00 · 15358 次点击
    这是一个创建于 2706 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 应该如何设计才会更好,最终做到点击响应延迟尽量小。

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

    @bsidb Kylin 我再去了解一下。而你说的预计算,有没有预计算的方案推荐,因为 time1 和 time2 是不确定的,导致了预计算的结果保存比较难定。
    enjoyhot
        8
    enjoyhot  
    OP
       2016-10-31 14:51:42 +08:00
    @Zuckonit 目前暂不考虑总量的问题,暂时查询跨度订个目标一个月吧。
    enjoyhot
        9
    enjoyhot  
    OP
       2016-10-31 14:54:01 +08:00
    @reus 我也希望离线计算能用到这种方案,但是 count 是与 distinct 关联在一起的,单纯保存 count 就把 distinct 的信息忽略了。
    wmttom
        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 当做实时分析引擎来出,可以根据数据集的大小和集群的资源限制这类查询的最大范围。
    cswanghan
        11
    cswanghan  
       2016-10-31 16:12:35 +08:00
    赞同 @wmttom 对于统计需求分类的解法。

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

    工作中,有些问题是靠工程解的,有些问题是靠沟通解的。
    bsidb
        12
    bsidb  
       2016-10-31 16:42:11 +08:00 via Android
    如果 b 是和时间有紧密相关性的,那么可以分时段累加。
    billowqiu
        13
    billowqiu  
       2016-10-31 16:52:35 +08:00
    "工作中,有些问题是靠工程解的,有些问题是靠沟通解的"
    不能同意更多啊
    Zuckonit
        14
    Zuckonit  
       2016-10-31 17:20:26 +08:00
    单位都是天了,应该不是实时性要求高的需求了。把能选的时间固化下来,提前计算。
    menc
        15
    menc  
       2016-10-31 17:54:09 +08:00
    @nbabook 说了 hadoop 是离线计算,刷到 database 里面的,离线计算多长时间都无所谓的了,两分钟五分钟又能如何。
    nbabook
        16
    nbabook  
       2016-10-31 19:03:49 +08:00   ❤️ 1
    @menc 我只是看他说了 40s 的耗时,才会说 hadoop 的离线计算时间问题。
    单纯从离线计算的角度而言,我所做的项目大部分是采用 hive+spark+mysql 的方式,按小时、天进行统计计算,然后将结果存储 mysql 供界面显示。
    mapreduce 的方式始终是将任务 map 到多台机器上,然后在 reduce 回来,他的执行效率是数据越大越有优势。
    但是,如果 time1 和 time2 的随机性非常大,而分时间段统计数据又不能进行简单叠加的话,这个模式基本没有意义,不可能将所有可能的选项都计算好。
    menc
        17
    menc  
       2016-10-31 19:26:16 +08:00
    @nbabook
    单位是天,每天一千万,没有比天更小的单位,意思就是千万以上的数量级。这个数量级已经比较合适 hadoop 来做离线计算了。
    然后, hadoop 调优不是你想的那样。
    我们现在从千万到上亿的任务都是 hadoop 来做, hadoop 的运行是很稳定的一件事情,调优也是很稳定的一件事情。
    kylefeng
        18
    kylefeng  
       2016-10-31 19:53:07 +08:00
    先和业务上沟通下吧,是不是有索引列做成查询表单的必填项,你这种统计查询很容易全表扫了。除非用上面几位同学的方案离线计算后数据流回展示、查询用的 MySQL 表。
    ebony0319
        19
    ebony0319  
       2016-10-31 23:20:55 +08:00 via Android
    你现在的瓶颈是卡在查还是插,索引是一个双刃剑。要想查得更快,就要建立索引。但是要想插得更快。最好把索引去掉。因为索引他会去查是否有重复值。
    liprais
        20
    liprais  
       2016-10-31 23:28:04 +08:00   ❤️ 1
    用 phoenix 查询 hbase 就行了
    liprais
        21
    liprais  
       2016-10-31 23:29:44 +08:00
    @liprais 性能不好先做 benchmark 看看瓶颈在哪
    Actrace
        22
    Actrace  
       2016-11-01 08:54:41 +08:00   ❤️ 1
    一般来说瓶颈可能在数据库的计算那块,即出数据。
    但是楼主没有给多少业务过程的耗时数据,所以也就无从考量了。
    enjoyhot
        23
    enjoyhot  
    OP
       2016-11-01 19:38:43 +08:00
    @wmttom 感谢回答。对 elasticsearch 不了解,不过似乎是搜索引擎方面的,“存 Hive 按照天的分区表, spark 跑数据存 MySQL 或者 HBASE ”是指利用 spark 调用 hive 进行 mapreduce 操作存入数据库吗。对于第二种需求,根据其它人的评论,我觉得应该属于大多人的做法,准备尝试。
    enjoyhot
        24
    enjoyhot  
    OP
       2016-11-01 19:42:12 +08:00
    @ebony0319 有尝试索引的方式,但免不了的全表扫描是硬伤,所以感觉还是修改业务,采取离线计算,再统计展示好一些。
    enjoyhot
        25
    enjoyhot  
    OP
       2016-11-01 19:44:20 +08:00
    @liprais 目前就是用这种方法,根据官网 http://phoenix.apache.org/performance.html 性能对比,感觉略吊,所以试了一试。
    wmttom
        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 实时分析,之前数据离线处理,因为一般离线处理都在凌晨跑,看不到当日数据。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2707 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 15:08 · PVG 23:08 · LAX 08:08 · JFK 11:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.