BigData :: 利用OneProxy让MySQL/PostgreSQL具备OLTP和MPP双重功能!

实时数据分析对企业的业务越来越重要,积累的数据越多,越需要对数据做出及时的分析,以尽快发现和充利用数据的价值,谁的计算能力强谁可以以较别人先一步做出决策。

但可能会发现很难直接在现有的业务数据库(正在承担大量业务压力)上做大量数量的实时查询。所以我们会着手布署专门的MPP/OLAP分析系统来胜任这个工作,为了实时地将数据同步到这些分析系统,又会实施一套非常复杂的基于事务日志增量捕捉的TEL机制 (如利用Oracle的日志文件,或MySQL的Binlog日志),再铺设一套消息投递机制(比如MetaQ或Kafka等),然后雇用很多的人来维护这套系统的运行,并且需要采购大量的机器来重复存贮所有的数据,称之为大数据解决方案。它可以工作,但实施和运行的成本却非常地高,下图是从网上找到的一个大数据架构图,相信还有比这个更复杂的。

current_big_data_workflow

不应当投入大量的精力来布署复杂的新系系,然后整天将数据迁来迁去,为什么现有的数据库系统里不做做实时数据统计分析?Oracle 12C中的列存引挚也许是当下最省心的实时数据查询解决方案,直接在一个系统里完成这些工作。

需要独立布署MPP/OLTP分析系统的一个重要原因是,现有的业务系统并不能很好地进行扩展, 需要保证留下足够的资源来处理实时的业务;而大多数MPP/OLAP系统从设计上是面向列存的,不适合用来支持大量的实时小事务,从而导致了不可避免的数据迁移工作。

现在有了新的解决方案来分担一部份实时数据统计任务,OneProxy是面向OLTP设计的高性能分布式数据库中间件,可以非常方便地将业务系充的表进行水平切分,从而均匀地分布到多个数据库节点中,布内置的并行查询功能可以象MPP/OLAP一样做大数据量的实时统计分析。

oneproxy_gp_arch

如上图所示,可以将OneProxy成对地布署以防止单点故障,并且可以布署不同的OneProxy来分别服务于业务系统和数据分析需求,以防相互影响和干扰。我们的一个客户每天需要从许多个传感器上实时接收的10亿条以上的记录,并需要保存半年以上,还要求能很快地统计最近一到三小时的数据(进行分组汇总),并能进行多维护的数据检索。要求系统能有每秒10万条数据的写入能力,并且分组汇总的SQL语句需要能在几秒钟内得到结果,还要求使用SQL语句进行交互,技术上必须成熟稳定易维护。

经过仔细分析后,平民软件给客户推荐了OneProxy的方案,将大表水平拆分成几百张小表,然后均分到多台不同的MySQL实例上,既提升了实时数据接收能力,又加满足了大量数据的实时分析需求,下面是在OneProxy中配置水平分片的一个例子。

[
  {
        "table"   : "t_bigtable",
        "pkey"    : "col2",
        "type"    : "int",
        "method"  : "crc32",
	"partitions": 512,
        "groups": [ "data1", "data2", "data3", "data4" ]
  }
]

然后让应用实时写入数据,发现可以轻松支持20万TPS,如果添加更多的MySQL节点和OneProxy节点,100万TPS也不是大问题,实时数据接收的问题轻松得到解决。随后我们测试了查询能力,目前开源的数据库如MySQL和PostgreSQL都还不支持并行查询,脱离OneProxy中间件的并行查询功能,大数据量分析将非常耗时,而在开启并行查询功能后,响应时间可以线性缩短。

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)

前面的测试来自于单机的实验,通过增加MySQL的节点数,查询时间还可以线性缩短,下面的查询都可以充分地利用到中间件的并行查询功能。MPP/OLAP系统能够飞快地跑统计分析SQL,一方面是因为列存有效压缩了数据的存贮,另一个更重要的原因就是数据切片和并行。

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;

如果担心复杂的分析型查询和业务的SQL语句落在同一个数据库上,而产生相互干扰的情况,可以将分析型查询引到备库上去执行。或者底层使用OneSQL定制版本,其多队列线程池技术可以有效地控制复杂SQL的并发度,留下足够的CPU资源,以保证不会影响到业务的SQL语句。