› 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 · Oct 31, 2016 · 16975 views
    This topic created in 3627 days ago, the information mentioned may be changed or developed.

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

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

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

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