OneProxy :: 在MySQL上跑并行查询,可以轻松完成很多实时数据统计的任务!

MySQL数据库不支持Hash Join以及并行查询,PostgreSQL目前的版本也还不支持并行查询,使得大表上的统计查询和复杂的SQL语句不能够及时完成。要么等很长时间,要么再布署一套Oracle或Hadoop/HBase系统来做专门的数据分析,如果要做实时数据分析,就必须建立和维护一套实时数据同步的复杂机制。Oracle和Hadoop体系能够快速处理大量数据的本质还是利用越来越多的CPU核,对数据进行切片后做并行处理。现在通过OneProxy中间件也可以轻松做数据分片了,并且可以打散到不同的MySQL实例中,如果能够并行下发SQL指令,其效果和Oracle/Hadoop一样了,在透明的结果集合并基础之上,平民软件在OneProxy中实现了并行查询机制。

oneproxy_parallel_query

查询语句(SELECT)和更新语句(INSERT/UPDATE/DELETE)都可以进行并行化处理。需要注意的是OnePorxy目前不支持分布式事务,因此无法在事务中使用并行查询功能,并行的更新语句支持需要进行特别的设置才行。在做并行处理时,OnePorxy会先将SQL语句发送到每一个分片上运行,然后将每个分片返回的结果集保存在内存中或一个临时数据库中,到所有的分片都处理完成后,再进行二次汇总处理(比如排序、分组汇总等)后,再返回结果给客户端应用。如果在集群中配置了读写分离等策略,备库也会被利用起来进行并行查询。

下面是在单个MySQL实例上的测试,表“t_bigtable”被OneProxy切分为很多片,第一次跑的是串行扫描,累计需要11秒钟;第二次执行启用了并行扫描,上亿条记录的统计只需要1秒多一点,如果将表打散到更多的MySQL实例中,所需的时间可以线性缩短。

mysql> select  count(*) from t_bigtable;
+-----------+
| count(*)  |
+-----------+
| 115945085 |
+-----------+
1 row in set (11.21 sec)

mysql> select /* parallel */ count(*) from t_bigtable;
+-----------+
| count(*)  |
+-----------+
| 115945085 |
+-----------+
1 row in set (1.36 sec)

下面的SQL可能是在实时数据分析中常用的查询语句,只需要在SQL里加一个“parallel”注释,就可以开启并行查询功能来加速了。

select /* parallel */ distinct col2
   from t_bigtable;
select /* parallel */ col2, count(*)
   from t_bigtable group by col2;
select /* parallel */ col2, count(*), sum(col2)
   from t_bigtable group by col2;
select /* parallel */ col2, count(*), max(id), min(id)
   from t_bigtable group by col2;

当使用内存来缓存各分片返回的结果集时,OneProxy里有一个每个分片的记录数上限设置,默认值是100万行。可以根据OneProxy所在机器的内存,使用“proxy-cache-rows”选项进行调节,需要注意的一点是,如果有太高并发的并行查询请求,也许会出现内存不足的现象,请根据具体的业务特征适当地添加机器内存。