日均数据量千万级,MySQL、TiDB两种存储方案的落地对比
http://mp.weixin.qq.com/s?__biz=MzIzNjUxMzk2NQ==&mid=2247484743&idx=1&sn=04337e020d268a951139ea1b36e74854&chksm=e8d7fa85dfa07393964671f307159a0a6eb13598b242e0b2a674b33d6b672d10383cc9ceb9df&mpshare=1&scene=23&srcid=0309zXCe6mDBWQ272CKCfpVq#rd
背景介绍
盖娅广告匹配系统(GaeaAD)用于支撑盖娅互娱全平台实时广告投放系统,需要将广告数据和游戏 SDK 上报的信息进行近实时匹配,本质上来说需要实时的根据各个渠道的广告投放与相应渠道带来的游戏玩家数据进行计算,实现广告转化效果分钟级别的展现及优化。
初期的MysQL存储
在系统设计之初,基于对数据量的预估以及简化实现方案考虑,我们选用了高可用的 MySQL RDS 存储方案,当时的匹配逻辑主要通过 SQL 语句来实现,包含了很多联表查询和聚合操作。当数据量在千万级别左右,系统运行良好,基本响应还在一分钟内。
遭遇瓶颈,寻找解决方案
然而随着业务的发展,越来越多游戏的接入,盖娅广告系统系统接收数据很快突破千万/日,高峰期每次参与匹配的数据量更是需要翻几个番,数据库成为了业务的瓶颈。由于此时,整个技术架构出现了一些问题:
1.单次匹配耗时已从原本的 10 秒左右增加到 2 分钟以上,最慢的聚合查询甚至达到 20 分钟,时效性受到严重挑战。而且 MySQL 的问题是查询的时间随着数据量的增长而增长,以至于数据量越大的情况下查询越慢。
2.随着历史数据的积累,单表数据很快达到亿级别,此时单表的读写压力已经接近极限。
3.由于第一点提到的查询性能问题以及单机的容量限制,需要定时删除数据,对于一些时间跨度较长的业务查询需求没法满足。
根据数据量的增长情况来看,分布式数据库会是很好的解决方案。首先考虑的是业务的垂直及水平拆分或者基于 MySQL 的数据库中间件方案和一些主流的 NoSQL 方案。
但是仔细评估后,最先排除掉的是业务水平拆分的方案,因为业务逻辑中包含大量的关联查询和子查询,如果拆表后这些查询逻辑就没有办法透明的兼容,而且是比较核心的业务系统,时间精力的关系也不允许整体做大的重构。中间件的问题和分库分表的问题类似,虽然解决了大容量存储和实时写入的问题,但是查询的灵活度受限,而且多个 MySQL 实例的维护成本也需要考虑。
第二个方案就是采用 NoSQL,因为此系统需要接收业务端并发的实时写入和实时查询,所以使用类似 Greenplum,Hive 或者 SparkSQL 这样的系统不太合适,因为这几个系统并不是针对实时写入设计的, MongoDB 的问题是文档型的查询访问接口对业务的修改太大,而且 MongoDB 是否能满足在这么大数据量下高效的聚合分析可能是一个问题。
所以很明显,我们当时的诉求就是能有一款数据库既能像 MySQL 一样便于使用,最好能让业务几乎不用做任何修改,又能满足分布式的存储需求,还要保证很高的复杂查询性能。
当时调研了一下社区的分布式数据库解决方案,找到了 TiDB 这个项目,因为协议层兼容 MySQL,而且对于复杂查询的支持不错,业务代码完全不用修改直接就能使用,使迁移使用成本降到极低。
技术转身,使用TiDB
在部署测试的过程中,我们使用 TiDB 提供的 Syncer 工具将 TiDB 作为 MySQL Slave 接在原业务的 MySQL 主库后边观察,确保读写的兼容性以及稳定性,经过一段时间观察后,确认读写没有任何问题,业务层的读请求切换至 TiDB,随后把写的流量也切换至 TiDB 集群,完成平滑的上线。
GaeaAD 系统从 2016年10月上线以来,已经稳定运行了一季度多,结合实际的使用体验,我们总结了 TiDB 带来的收益,主要有以下几点:
用 3 个节点组成的 TiDB 集群替换了原先的高可用 MySQL RDS 后,同样数据量级下,单次匹配平均耗时从 2 分钟以上降到了 30 秒左右,后续随着 TiDB 工程师的持续优化,达到了10 秒左右。另外,我们发现,TiDB 在数据规模越大的情况下,对比 MySQL 的优势就越明显,应该是 TiDB 自研的分布式 SQL 优化器带来的优势。不过在数据量比较轻量的情况下,因内部通信成本,优势相比 MySQL 并不明显。
(图为 TiDB 与 MySQL 在不同数据量下的查询时间对比)
TiDB 支持自动 Sharding,业务端不用切表操作,TiDB 也不需要像传统的数据库中间件产品设定 Sharding key 或者分区表什么的,底层的存储会自动根据数据的分布,均匀的分散在集群中,存储空间和性能可以通过增加机器实现快速的水平扩展,极大地降低了运维成本。
TiDB 支持在线不中断的滚动升级,至今直接在线升级已有 10 余次左右,没出现过一起导致线上服务中断的情况,在可用性上体验不错。
TiDB 支持和 MySQL 的互备,这个功能很好的解决了我们业务迁移时候的过渡问题。
当前我们正在着手把 storm 集群上的 BI 系统的实时计算业务的数据存储系统从 MongoDB 替换成 TiDB(因 MongoDB 的使用门槛相对较高,运维成本大,查询方式不如传统的 SQL 灵活),后续也计划把实时性要求高、数据存储量大且存储周期较长的业务都迁移到 TiDB 上来,看上去是一个比较合适的场景。
TiDB组的点评
盖娅的业务使用了 TiDB 如下的优化:
支持更多表达式下推,充分利用 TiKV 多实例的计算资源,加快计算速度;同时也尽可能将不需要用到的数据过滤掉,减小网络传输。
TiDB 默认支持 HashJoin,将算子尽可能并行化,能够利用整个集群的计算资源。
TiDB 采用流水线的方式读取数据,并且优化过 IndexScan 算子,降低整个流程的启动时间。
日均数据量千万级,MySQL、TiDB两种存储方案的落地对比的更多相关文章
- Mysql的两种存储引擎以及区别
一.Mysql的两种存储引擎 1.MyISAM: ①不支持事务,但是整个操作是原子性的(事务具备四种特性:原子性.一致性.隔离性.持久性) ②不支持外键,支持表锁,每次所住的是整张表 MyIS ...
- MySQL 的两种存储引擎
MyISAM 是MySQL的默认数据库引擎(5.5以后默认是InnoDB)性能极佳,但不支持事务处理. InnoDB 是MySQL的数据库常用的数据引擎. MyISAM 和 InnoDB 两者之间有明 ...
- MySQL 快速删除大量数据(千万级别)的几种实践方案
笔者最近工作中遇见一个性能瓶颈问题,MySQL表,每天大概新增776万条记录,存储周期为7天,超过7天的数据需要在新增记录前老化.连续运行9天以后,删除一天的数据大概需要3个半小时(环境:128G, ...
- mysql的两种存储引擎
MySQL 有多种存储引擎,目前常用的是 MyISAM 和 InnoDB 这两个引擎,除了这两个引擎以为还有许多其他引擎,有官方的,也有一些公司自己研发的.这篇文章主要简单概述一下常用常见的 MySQ ...
- MYSQL的两种存储引擎区别
Innodb引擎 Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别.该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL ...
- MySQL的两种存储引擎storage engine特点和对比
MyISAM 优点:快速读取数据, 占用空间小 缺点:不支持事务,外键 (表级别锁) InnoDB 优点:支持事务,外键; 高性能(CPU效率高) 缺点: 慢,占空间 (行级别锁)
- Mysql有两种存储引擎:InnoDB与Myisam
http://www.cnblogs.com/kevingrace/p/5685355.html
- 千万级MySQL数据库建立索引,提高性能的秘诀
实践中如何优化MySQL 实践中,MySQL的优化主要涉及SQL语句及索引的优化.数据表结构的优化.系统配置的优化和硬件的优化四个方面,如下图所示: SQL语句及索引的优化 SQL语句的优化 SQL语 ...
- MySQL两种存储引擎: MyISAM和InnoDB
MySQL两种存储引擎: MyISAM和InnoDB 简单总结 MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM(Indexed Sequential Access Me ...
随机推荐
- destoon分页
<?php //控制分页//分页$pagesize=4;$pagesql="SELECT COUNT(*) AS num FROM `{$DT_PRE}` company"; ...
- 安利一个神器:Tmux
对于程序员来说,一个好用且高效的软件工具就如同加持了神技的游戏角色.下面就给大家介绍一个神器 Tmux 以及个人的使用总结. 一.我所认识的 Tmux 在工作中,我把 tmux 当作终端会话管理器来使 ...
- Android 基础:常用布局 介绍 & 使用(附 属性查询)
Android 基础:常用布局 介绍 & 使用(附 属性查询) 前言 在 Android开发中,绘制UI时常需各种布局 今天,我将全面介绍Android开发中最常用的五大布局 含 Andr ...
- javascript对象的标签
[[proto]]标签 [[class]]标签 [[class]] 标签,代表这对象是哪个类型的.在js中不能直接访问到.可以通过Object.prototype.toString.call(obj) ...
- python 之pulp 线性规划介绍及举例
pulp http://pythonhosted.org/PuLP/main/basic_python_coding.html 供水问题 1问题 供水公司有三个水库分别为A,B,C向四个小区甲乙丙丁供 ...
- linkin大话数据结构--Google commons工具类
package tz.web.dao.bean; import java.util.Arrays; import java.util.Collection; import java.util.List ...
- Java8内存模型—永久代(PermGen)和元空间(Metaspace)(转)
Java8内存模型—永久代(PermGen)和元空间(Metaspace) 查看原文点击传送门:http://www.cnblogs.com/paddix/p/5309550.html 提示:本文做了 ...
- join on用法
内连接和外连接 内连接用于返回满足连接条件的记录:而外连接则是内连接的扩展,它不仅会满足连接条件的记录,而且还会返回不满足连接条件的记录 内连接 内连接查询返回满足条件的所有记录,默认情况下没有指定任 ...
- CSS 自动隐藏文字并添加省略号
.cut { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; -o-text-overflow:ellipsis; -icab ...
- 一步一步从原理跟我学邮件收取及发送 9.多行结果与socket的阻塞
前几篇的文章发表后,有网友留言说没有涉及到阻塞的问题吗?在 socket 的编程当中,这确实是个很重要的问题.结合目前我们文章的内容进度,我们来看看为什么说阻塞概念很重要. 接着上篇的内容,当我们发送 ...