MySQL 高扩展架构构建百万在线系统实践

3,123 阅读7分钟


内容来源:2017 年 10 月24 日,知数堂 MySQL技术专家吴炳锡在“2017 MySQL技术交流大会---上海站”进行《MySQL高扩展架构设计》演讲分享。IT 大咖说(微信id:itdakashuo)作为独家视频合作方,经主办方和讲者审阅授权发布。

阅读字数:2571 | 7分钟阅读

嘉宾演讲视频及PPT回顾:suo.im/4rykSK

摘要

随着传统企业去IOE的声音越来越大,也有很多朋友来咨询MySQL的架构设计问题,本次分享讨论如何利用MySQL构建一个高扩展的架构,从而在MySQL上构建出来基于百万在线的系统。

MySQL 在高并发结构中的挑战

挑战

数据量大是现阶段非常明显的挑战,我们最近接触的案例中有很多数据量轻易就达到了8个多T,数据的备份都变得很麻烦。现在已经到了一个海量数据的年代。

以前的互联网行业可能对一致性的要求并不会太高,但是像银行这样的传统金融行业,单单转账操作的流程就有280多个,而现在之所以能如此迅速的完成转账操作,强一致性在其中发挥了重要的作用。

类似微信、支付宝的扫码功能都和数据库有联系,要是这些功能出现问题想必大家都会很恼火,这其中涉及到了数据库的可用性问题。

最后还有一个服务范围广的问题,比如如何处理认证中心的一点注册多地登录情况。

优点

MySQL的高并发、灵活的特性是其他数据库无法比拟的。多IDC架构使得MySQL能够分布到多个机房,架构处理非常简单。另外MySQL是Sharp nothing的,每个节点都有一份数据,损坏率被极大的减小。

MySQL本身的特点

- 无执行计划缓存,cpu占用较高

- Query单核运算,不适合运行较大较复杂的SQL

- 在MySQL5.7以前对于连接数据敏感(建议控制在300个以下)

- 基于存储引擎的解决方案(Innodb,TokuDB,MyRocks,Spider)

- 不支持事务嵌套,不支持hash join

即使面临如此多的挑战,国内成功的案列却非常多。比如微信财付通、物流、P2P信贷、游戏行业、互联网行业。

成功的经验总结

容量规划

容量规划这块特别需要注意资源分配对齐,很多公司的数据库规模参差不齐,大的有十几个T,小的可能只有几十兆。

这样整个资源的管理会非常混乱,要想进行大规模的管理就需要把DB作为一个存储资源,制定分配标准。比如单实例在PCIE上运行,实例大小1T左右,单库大小200G左右 ,超过200G就进行拆分。

另外我们提倡单机多实例。这样的好处在于可控,方便迁移,内部做成DB资源管理平台易下手。反之单机单实例,存储4T以上,备份管理非常难受。

分库分表

在项目逐渐增大后,大家都将面临如何分拆数据的问题。我的建议是分拆冒尖的数据,比如项目中的用户好友关系数据如果非常大,那么就分拆它,还有一些不规范的比如日志类的数据也可以分拆。这样一步步的分拆,就能更早的规划资源耗费严重的数据。

我们提倡的拆分原则是先按功能进行拆分,比如分为认证类型、用户核心类型、用户基本资料等。按功能拆分完在单库大于200G后再考虑水平拆分,这里一般采用两种算法:Range和Hash。当单实例达到1T左右时,考虑分Set,比如1-2000万是Set1,2000万-4000万是Set2,通过Set治理,也可以方便的解决数据在多IDC分布的问题。

分布式事务

分布式事务是常见的复杂类型事务,一个比较常见的场景就是十几个接口的调用都在同个DB上,如何拆分事务成了一个问题。在分布式事务中,可以想象出这样的场景,在一个高速通道中将并发的数量限制在所支持数量内,并且每个用户只能操作自身所处环境的数据。这种方式就是利用消息队列解耦。另外为了防止用户在没有完成当前事务的情况下又开始新的事务,则需要引入状态机的概念。

DB调用

复杂项目的DB调用面临的最无语的问题,莫过于一个DB被N多的服务调用,最后无法分辨哪个IP对应哪个服务,当DB需要进行迁移时,不知道具体需要通知谁。

为了解决问题,就需要应用虚拟DB功能,单DB只对自己的服务开放权限,拒绝其他服务直接访问其他功能DB,并且服务之间只走服务调用而不与DB发生联系。

另外在不知道自身并发极限的情况下,应该采用流式调用,把并发控制在一定范围之内,引入过载保护。

长服务链调用有时会碰到开发人员连数据库Timeout的情况,这极有可能是因为,开发从连接池获取到连接,处理完成后才将连接放回连接池。而正确的做法是拿到连接获取到结果,就把连接放到连接池,再去处理结果。为了避免这种情况,应当就长服务链调用的问题及时与开发沟通好。

可用性

可用性这块首先要谈的就是高可用,这方面最早使用的是MHA,到了现在基本上每个公司都会维护一份自己的MHA代码,而不去直接使用官方的。另一种方式是自主实现,基于MHA的思想,自己通过Python之类的语言实现。

再往上的服务架构上的支持,要考虑DB在故障切换中程序会不会异常,DB切换后故障,有没有备选方案。

以我们的经验来看可用性要考虑几方面的措施,包括自动化的安全阈值控制、高可用切换过程中产生的DB不可用处理、多写的机制中数据一致性是不是方便校检以及后期数据补偿方案。

多IDC结构

多机房部署是各大公司都在探索的一个领域,它有着很多特性。比如单节点写入,其它IDC就近读取。多点写入,总线汇总。另外多机房代码发布需要访问每个机房自身的数据库,一般这种情况我们都会引入SmartDNS。

Cache 选择

Cache的选择其实是比较多的,一般项目开始阶段可以不考虑Cache只缓存调用最多的。我们在下文列出了一些Cache分类。

易失性 Cache

- Memcache

- Redis

非易失性 Cache

- Redis

- MongoDB

- MySQL NDB Cluster

比较推荐的是Redis – Cluster以及MongoDB Cluster。易失性这方面则可以选择Redis,但是一定要考虑Redis挂了后,数据库能够扛的住,一般的解决方案是在发现数据库响应较慢的时候,连接层自动降级。