为什么选择TIDB?
凡事事出有因,选择某类框架也肯定有它存在的原因。所以想先来谈谈我们为什么要选择TIDB。
其实几乎所有公司从传统数据库转向分布式数据库都有个共同的原因,随着业务量的不断增大,RDBMS有瓶颈了,我们也是如此,跑批耗费时间特别长,数据有延迟,给业务带来了很多不便。这时候能怎么办?过去的选择:要不然就是Mysql的分库分表、水平分区等,要不然就是转向HBase等NOSQL数据库,但无论用哪种方式都不完美,Mysql分库分表的弊端就不需多说了,根本没有从本质上解决大数据的问题,它们本身就不是面向分布式而设计的。NOSQL的弊端也有很多,比如它不能严格意义上达到OLTP,它不支持复杂的查询,它的语法跟我们传统SQL语法相差较大,选择它得更改很多业务代码等等。而TIDB正是上述两者的结合体,它结合的Mysql和Nosql的优点,用一个词来形容TIDB就是HTAP (Hybrid Transactional and Analytical Processing)。总而言之,它就是为 OLTP (Online Transactional Processing) 和 OLAP (Online Analytical Processing) 场景提供一站式的解决方案的有力武器。
TIDB优势
前面说到TIDB的优势就是olap+oltp,现在我们再把TIDB的优点给仔细归纳下,但是在说优点前得把TIDB的架构大概阐述一下,因为优点肯定是由架构来实现和决定的。
大概归纳下就是:TIDB主要分为三个组件:PDTIDBTIKV。PD是整个集群的管理模块,作用包括存储集群的元信息、对 TiKV 集群进行调度和负载均衡等。TIDB负责接收 SQL 请求,处理 SQL 相关的逻辑,这就是个计算节点。而TIKV是负责存储的,存储数据的基本单位是 Region。如果熟悉Hadoop生态圈,可以暂时把PD类比为Hadoop的NameNode,TIKV类比为Hadoop的DataNode,TIDB类比为HBase的RegionServer。我认为功能和思路类似,当然具体设计还有很大的不同。
- 水平弹性扩展
这点其实就是NOSQL最大的优势,永远不会随着业务量的扩大而出现瓶颈,加机器就好,轻松应对高并发、海量数据场景。TIDB的水平扩展包括计算能力和存储能力,分别对应TIDB和TIKV节点。 - 高可用
大数据框架比如HadoopHbaseSpark都有这个特性,一切大数据框架没有高可用机制都是不现实的,这也是TIDB的特点之一,TiDB/TiKV/PD 这三个组件都能容忍部分实例失效,不影响整个集群的可用性。TIKV有副本机制,默认保存三副本,某台机器宕机不会出现数据丢失的情况。 - 事务
NOSQL有个弊端就是追求了可扩展性而放弃了强一致性,以牺牲数据的准确性换来高性能。而TIDB创立之初就否定了这种思路,TIDB创始人说:“这是不现实的,相当于本来这个事情是数据库来做,NOSQL却强行交给业务层来做。会给业务带来极大的问题” - 高度兼容mysql语法
这是我们实际使用起来用的最爽的一个特性,业务层完全不需要更改代码,如果你把Mysql换成其他Nosql,要改多少sql语句改多少业务代码?TIDB这项特性给我们带来了极大的便利,可以无缝迁移到TIDB。 - 与Mysql的无缝替换和切换
由于TIDB发展时间不长,几乎所有公司开始使用的时候都会担心稳定性,包括我们自己,确实不敢轻易把核心业务交给TIDB。但是TIDB也非常人性化的考虑到了这一点,你不敢用我,你可以把我当备胎,也就是将 TiDB 集群作为线上 MySQL 的从库,实时同步线上的 MySQL 主库,观察一段时间稳定性兼容性、觉得一切OK之后,再直接替换Mysql,不用修改一行代码。假如有问题也没关系,毕竟是个备胎嘛。另外不仅TiDB 可以做 MySQL 的 slave,MySQL同样可以做 TiDB 的 slave哦! - 完美的监控
其他一些大数据框架,虽然也有自己的监控页面,但确实信息量太少,不够完美,这时候就需要自己改造一些监控。而且觉得TIDB的监控是完美的,至少我想要用到的一切信息它都有(cpu内存存储容量网络节点健康信息QPSTPS等等,非常非常多指标)。而且还非常方便的配置报警机制,邮件、钉钉都可以。
上面六点是我认为TIDB最有优势的几点。顺便另外再补充一下我们实际生产上用到的,觉得不错的功能:
- OOM :可以配置 一条SQL 执行过程中的内存使用阈值 超出这个会取消执行这个操作,并且输出日志
- 慢查询: 可以配置慢查询日志文件以及慢日志的耗时阈值 这样可以有效追踪到慢查询的sql
- 历史数据回溯:TiDB 使用 MVCC 管理版本,当更新/删除数据时,不会做真正的数据删除,只会添加一个新版本数据,所以可以保留历史数据。历史数据不会全部保留,超过一定时间的历史数据会被彻底删除,以减小空间占用以及避免历史版本过多引入的性能开销。
TIDB在生产的应用
应用场景
上图是我们生产中的架构图,目前仅搭建TIDB集群两个月,因此只迁移了部分业务,主要包括以下三方面:
- 直接替换Mysql
我们每日产生的事件数量都非常大,Mysql渐渐已经不能支撑我们的存储和查询,TIDB具有无限扩展的优势,我们不用担心存储问题,且查询速度较mysql提升很多。加上TIDB兼容mysql语法,我们直接无缝将原始业务代码迁移到TIDB,只需要几分钟的时间而已,非常方便。 - 将TIDB用于数据仓库、支撑离线跑批任务。
我们直接把TIDB作为数据仓库用,因为TIDB在OLAP方面表现也很出众。
业务场景:业务人员每日需导出的新客日报以及营销费用分析等报表,由于涉及到的表较大较多,存在着数据延迟和跑批吃力的情况,一个任务可能需要跑二三十分钟,数据中心压力较大,复杂的sql会让数据中心的资源耗尽,有时候不能支撑我们的跑批任务。
做法:使用dumper+loader+syncer 同步mysql的binlog。dump将mysql的数据全部弄到本地服务器上,再用loader将这些文件导入到TIDB中,Syncer把TIDB作为一个Mysql的Slave,实时同步Mysql的数据。即使原本的Mysql使用了sharing 也是没问题,TIDB兼容了这个访问协议。这样原本在Mysql中跑的复杂的跑批任务就可以无缝的迁移到TIDB中执行。
- 将TIDB用于实时系统,支撑实时数据展示。
TIDB官方说过,TIDB是100%的OLTP+80%的OLAP,那么在OLTP层使用它是毫无疑问了。
业务场景:渠道概要数据(PVUV授信完件放款等指标)涉及到的表较多较大,joinunion较多,因此不支持实时查询,原本做法是每小时30分从数据中心定时跑批到mysql的中间表数据查询展示的,时效性比较差,需要优化。于是我们基于TIDB的DW层数据做渠道概要的准实时查询和展示。
做法:搭建DRC(数据实时处理)系统读取rocketmq的mysql binlog和查询tidb的ods层数据(该数据查询一次就永久缓存到redis),得到的处理后的数据入库到DW层RT实时表中,指定小时之内的数据实时查询RT表,时效性得到了极大的优化。RT表数据会每小时定时跑批到mysql中间表,然后定时备份到TIDB对应的history表并删除指定小时前的数,这样指定小时之前的数据就可以从mysql中间表查询得到。达到了实时离线两不误的效果。
遇到的问题
在使用TIDB的这两个月中,我们生产中遇到的问题主要有:
- 更改表结构导致Syncer退出
用Syncer同步Mysql的时候,如果Mysql更改了表结构(使用gh-ost)的方式,则Syncer会报错退出,并且无法再启动。因此我们每次都要重新dumper、loader、syncer,非常麻烦。TIDB最近推出的DM已经解决了这个问题,只是对机器要求高,我们将在下季度申请到新机器后使用这项新技能。 - Sql别名异常
一些具有别名的Sql在TIDB客户端可以正常执行,但是用JAVA程序(使用的是Spring的jdbc)则会报错 Table'tidb.xxx'does not exist(xxx是我们自己定义的别名),后改用mybatis可以正常执行。 - Syncer同步binlog延迟
我们在零点的时候,某个库的数据量会急速增大,Syncer不能实时同步,通常要到上午10点左右才能同步过来。优化了Syncer相关配置比如batch和worker依然没有解决。跟PingCap的童鞋沟通过,让我们使用DM,也是下季度申请到新机器后再做观察。 - TIDB lost connection
如果同时insert很多数据,或者一条很大的Sql,TIDB可能会出现lost connection的错误,我们在代码层面改善,比如拆分小sql,多条insert sql拼接成一条sql再插入等方式。
展望与致谢
我们是10月中旬搭建的TIDB集群,到目前也仅仅使用了两个月而已,但却深深感受到了TIDB的魅力,TIDB帮助我们解决了很多数据问题,上线至今遇到的bug并不多,加上TIDB技术人员都很热情的帮我们解决,所以一切还算顺利,目前已经稳定运行一个多月。明年我们将会申请更多的机器扩展我们的集群,并且迁移更多的任务。
非常感谢TIDB的童鞋能创造出那么好用的产品,并且无私的开放源码,帮助了越来越多的企业解决他们的数据平台瓶颈。最最重要的,要感谢Tidb的童鞋给我们的支持,在我们遇到棘手问题无法解决的时候,两次亲自前往我司指导工作,并且是无偿的帮助我们,这种敬业精神确实很少有公司可以媲美。相信TIDB会越走越好!