肖鹏,微博研发中心技术经理,主要负责微博数据库(MySQL/Reids/HBase/Memcached)相关的业务保障、性能优化、架构设计,以及周边的自动化系统建设。经历了微博数据库各个阶段的架构改造,包括服务保障及SLA体系建设、微博多机房部署、微博平台化改造等项目。10年互联网数据库架构和管理经验,专注于数据库的高性能和高科用技术保障方向。
与MySQL结缘主要也是源于兴趣,第一份工作在一家小公司,各个领域的工作都会有接触,全都做下来发现还是对数据库最感兴趣,所以就一直从事和数据库相关的技术工作了。随着工作年限的增加,我在数据库方面积累的经验也逐步增加,越来越发现数据库管理员(DBA)是一个偏实践的工种,很多理论上的东西在现实中会有各种的变化,比如「反范式」设计等等。所以我建议大家:如果想成为数据库方面的专家,一定要挑选好环境,大平台很多时候会由于量变引发质变产生很多有挑战的问题,而解决这些问题是成为技术专家的必经之路。
微博到今天已经有6年了,非常有幸全程参与了这6年的变化。新浪的MySQL集群结构主要经历了3次重大的变化。
初期微博作为一个内部创新产品,功能比较简洁,而数据库架构也采用的标准1M2S1MB结构,按照读写分离设计,主库承担写入,而从库承担访问。如果访问压力过大,可以通过扩容从库的数量获得scale out的能力。
随着微博上线之后的用户活跃度增加,数据库的压力也与日俱增。我们首先通过采购高性能的硬件设备来对单机性能进行scale up,以满足支撑业务的高速发展的需求。然后,通过使用高性能设备争取来的时间对与微博进行整体上的业务垂直拆分,将用户、关系、博文、转发、评论等功能模块分别独立存储,并在垂直拆分的基础上,对一些预期会产生海量数据的业务模块再次进行了二次拆分。
以博文为例,博文是微博用户主要产生的内容,可以预见会随着时间维度不断增大,最终会变得非常巨大。如何在满足业务性能需求的情况下,尽可能使用较少的成本存储,这是我们面临的一个比较有挑战的问题。
在上一个阶段,微博的数据库经历了很多的拆分改造,这也就直接造成了规模的成倍增长,而随着业务经历了高速增长之后,也开始趋于稳定。在这个阶段,我们开始着重进行自动化的建设。将之前在快速扩张期间积攒下来的经验转变为自动化工具,对外形成标准化和流程化的平台服务。我们相继建设改造了备份系统、监控系统、AutoDDL系统、MHA系统、巡检系统、慢查系统、maya中间件系统,等等。并且为了提高业务使用效率和降低沟通成倍,相对于内部管理系统,我们重新开发了iDB系统对数据库平台的用户使用。通过iDB系统,用户可以便捷地了解自己业务数据库的运行状态,并可以直接提交对数据库的DDL修改需求。DBA仅需点击审核通过,即可交由Robot在线上执行,不但提高了工作效率,也提高了安全性和规范性。
数据库平台并不仅有MySQL 还有Redis、Memcached、HBase等数据库服务,而在缓存为王的趋势下,我们2015年重点将研发精力投入在Redis上。
Redis中间件
在2015年我们自研的Redis中间件tribe系统完成了开发和上线。tribe采用有中心节点的proxy架构设计,通过configer server管理集群节点,并借鉴官方Redis cluster的slot分片的设计思路来完成数据存储。最终实现了路由、分片、自动迁移、fail over等功能,并且预留了操作和监控的API接口,以便同其他的自动化运维系统对接。
Databus
由于我们先有MySQL后有的Redis和HBase等数据库,故存在一种场景就是目前数据已经写入到MySQL中,但是需要将这些数据同步到其他数据库软件中。所以我们为此开发了Databus,可以基于MySQL的binlog将数据同步到其他异构的数据库中,并且支持自定义业务逻辑。目前已经实现了MySQL到Redis和MySQL到HBase的数据流向,下一步计划开发Redis到MySQL的数据流向。
反范式设计带来便利的同时确实也带来了一些问题,尤其是在数据规模变大之后,通常来说会有如下几种解决方案:
微博使用Redis的时间较早,并且一开始量就很大,于是在实际使用过程中遇到了很多实际的问题,我们的内部分支版本都是针对这些实际问题进行优化的。比较有特点的有如下三个:
增加基于pos位同步功能
在2.4版本中,Redis 的同步一旦出现中断就会重新将主库的数据 全部 传输到从库上,这就会造成瞬时的网络带宽峰值,并且对于数据量较大的业务,从库恢复的时间较为缓慢。为此我们联合架构组的同学借鉴MySQL的主从同步复制机制,将Redis的aof改造为记录pos位,并让从库记录已经同步的pos位置。这样在网络出现波动的时候即使重传,也仅仅只是一部分数据,并不会影响到业务。
在线热升级
在使用初期,由于很多新功能的加入,Redis版本不断升级,每次升级为了不影响业务都需要进行主库切换,对于运维带来了很大的挑战。于是我们开发了热升级机制,通过动态加载libredis.so来实现版本的改变,不再需要进行主库切换,极大地提升了运维的效率,也降低了变更带来的风险。
定制化改造
在使用Redis的后期,由于微博产品上技术类的需求非常多,所以我们为此专门开发了兼容Redis的redisscounter专门存储技术类的数据。通过使用array替换hash table极大降低了内存占用。而在此之后,我们开发了基于bloom filter的phantom解决判断类场景需求,
目前这个事情的进展不是很理想,主要我们发现MySQL的扩容速度跟不上业务的变化,有些时候扩容完毕之后业务的高峰已经过去了,接下来就需要做缩容,等于做了无用功。所以,目前我们的思路改为扩缩容cache层,首先实现cache层的自动扩缩容,然后同业务监控系统或者接入层的自动化系统进行联通,比如,如果计算节点扩容100个node,那么我们的cache层就联动扩容20node,以此来达到业务联动。
随着业务的发展,会遇到越来越多的场景,我们希望可以引进最适合的数据库来解决场景问题,比如PostgreSQL、SSDB等。同时,利用MySQL新版本的特性(比如5.7的并行复制、GTID、动态调整BP),不断优化现有服务的性能和稳定性。
另外,对于现有的NoSQL服务,推进服务化,通过使用proxy将存储节点进行组织之后对外提供服务。对外降低开发人员的开发复杂度和获取资源的时间,对内提高单机利用率并解决资源层横向扩展的瓶颈问题。
同时,尝试利用各大云计算的资源,实现cache层的动态扩缩容,充分利用云计算的弹性资源,解决业务访问波动的问题。
数据库圈子的变化确实很快,NoSQL还刚刚方兴未艾,NewSQL又开始你方唱罢我登场。我个人并不认为某种数据库会取代另一种数据库,就如同NoSQL刚刚兴起的时候很多声音说会它彻底取代MySQL,但是从实际情况看依然还是互依并存的关系。以我负责的集群来说,反倒是MySQL更多一些。我个人认为,每种数据库都有他最擅长的场景,在特定场景下它就是最佳的数据库,但是如果脱离了场景则很难说谁优谁劣。
我个人MySQL使用得较多,MongoDB和PostgreSQL都有过一些接触,MySQL作为LAMP中的一员,老实说在大部分场景都是合适的,尤其是在并发和数据库量并没有达到一个很大值的时候。但是,在某些场景下MongoDB和PostgreSQL确实更胜一筹。
比如我们在门户的新闻发布系统中使用了MongoDB,其schema less的设计模式和新闻非常贴合,而其sharding功能又解决了容量上的横向扩张问题,在这个场景下,MySQL并不具备什么优势。
而在LBS(基于地理位置信息服务)相关的方面,PostgreSQL和PostGIS更具有优势,利用其空间数据索引R-tree和实体类型点、线、线段、方形,以及特定的函数,可以很方便地实现空间计算需求。
就我个人来说,每种数据库都有其擅长的场景。如果没有特殊的架构需求,一般选择MySQL都不会出问题,而如果有特殊的架构需求,那么就需要根据需求的特点来选择不同的数据库了。
首先,多读书,至少将 High Performance MySQL 通读一遍。
其次,有条件的话,最好找一些大平台历练一下,在很多情况下经验和能力等同于你解决过的问题的广度和深度,而环境决定你遇到的问题。
最后,有机会的话多做一些技术分享,很多知识点自己明白和能给别人讲明白是两个完全不同的境界。