《MySQL架构设计谈:从开发规范、选型、拆分到减压》要点:
本文介绍了MySQL架构设计谈:从开发规范、选型、拆分到减压,希望对您有用。如果有疑问,可以联系我们。
作者介绍
李辉,原新浪爱彩票运维负责人,常用网名:门牙没了.曾主导新浪爱彩票的MySQL运维工作.培训合伙人、资深讲师,中国科学院大学在读研究生(大数据方向),擅长大型项目的关系型数据库运维和管理,现在在数据库运维自动化方向研究.
随着MySQL自身的发展与不断完善,不知不觉中整个互联网行业已离不开这个完善又小巧的关系型数据库,整个生态链也已经变得非常成熟,即便是初创企业和传统企业也可以放心大胆地把数据库迁移到MySQL上来.在大家和MySQL数据库愉快玩耍的同时,我来聊聊MySQL架构设计相关的一些话题.
本文大纲:
数据库规范到底有多重要?有过初创公司经历的朋友应该都深有体会.规范是数据库运维的一个基石,能有效地减少数据库出问题的概率,保障数据库schema的合理设计并方便后续自动化的管理.
曾经我们花了大半年时间来做数据库规范化的工作,例如制定数据库开发指南、给程序员做培训等,推进的时候也会遇到一些阻力.但规范之后运维质量会有一个质的提升,也增进了DBA的工作效率.
在开发规范方面,我们划分为开发规范和运维规范两部分.
表设计的规范:
索引设计的规范:
1)所有表必须有显式主键
2)合理地建立索引
SQL编写规范:
1)避免在数据库中进行大量计算任务
2)优化join
3)注重where条件,多用EXPLAIN确认
Schema Review:
1)字符集问题
表字符集选择UTF8 ,如果需要存储emoj表情,就改成UTF8mb4
2)Schema设计原则
3)Schema设计目标
整体来说,这部分规范还是很容易遵守的,实现起来也没有什么难度,就能取得很好的效果.
(1)SQL审核
SQL评审这部分工作相信让很多的DBA同学都叫苦不迭,人肉审核不仅效率低下,容易出错,对DBA的自身发展也非常不利,难道我们来上班就是为了审核SQL的吗?在经过了一段痛苦的人肉审核之后,我们接入了去哪儿网开源的Inception,并根据自身的业务特点做了一些调整.当然现在开源的SQL评审软件已经很多了,大家可以自由选择,也可以自行开发.
在审核与执行上线DDL语句的时候,要注意MySQL官方原生Online DDL和Percona公司的pt-osc之间的一些差异,例如pt-osc在执行时每次都要copy全表,相对来说比较慢,好处是不锁表,并且有完善的条件检测和延时负载策略控制.官方Online DDL虽然官方也一直在改进,但生产环境使用还不是很完美,尤其要注意执行过程中容易导致MDL锁.官方Online DDL也有优于pt-osc的地方,比如增删索引,重命名列等,如下图所示.
(2)权限控制
MySQL从5.6开始,逐步完善了权限系统,比如MySQL5.6可以安装检查密码强度的插件,5.7开始增加了密码过期机制、账户锁定等功能,对SSL这一块也做了一些优化,8.0版本增加了角色的功能,权限系统已经逐步在向Oracle数据库靠拢了.在日常运维中,也可以使用pt-show-grants工具提高权限审查的力度.应用程序账号应只赋予SELECT、INSERT、UPDATE权限,DELETE的逻辑改用UPDATE实现,并启用sql_safe_updates选项.
另一个有效控制权限的方法就是SQL堡垒机,早期我们通过改造MyWebSQL实现,在Web版客户端的基础上加入了一些资源控制策略、审计、语法校验等功能.后续又使用Python开发了功能更完备的SQL堡垒机,同时支持MySQL、Oracle、Greenplum等数据库.
SQL堡垒机不仅可控制公司内部人员的数据库权限,追溯各类人员对数据库的操作,也能避免大查询或全表更新的情况发生,支持审计需求,整体运维质量提升了一个台阶.
(3)MySQL版本选择
对于版本选择这件事,建议大家还是跟进官方社区版比较好,目前比较稳定的版本是MySQL5.6,推荐大家使用.有特殊需求的话再选择MySQL5.7、PXC、TiDB、TokuDB等数据库.
MySQL高可用方面,目前业界主流依然是基于异步复制的技术,例如Keepalived、MHA、ZooKeeper等,要求数据强一致的场景逐步开始使用分布式协议,这方面的典型代表有PXC、Group Replication、TiDB.下面我们就重点来说说keepalived、MHA和PXC这几种大家用得比较多的架构.
业内使用非常普遍,它部署容易、方便维护,还节省服务器资源.这种架构的一个好处就是在发生切换后,原Master只需重新拉起来即可恢复高可用,不需要过多干预.扩展起来也方便,可以任意挂载只读库和灾备库.但它存在的问题也很明显,比如Keepalived的检测机制不完善、有脑裂隐患、数据一致性较弱等等.
还需要注意主从拓扑的设计.如下图,只读库挂到哪个Master比较合适?显然是M2,其它两种拓扑在发生切换后都会影响到只读库的访问.
MHA自诞生以来,就得到了业内的广泛关注,并迅速流行开来.与keepalived相比,MHA最大的优点就是在发生故障切换之后,能自动补齐binlog,最大程度保证数据一致性.从服务器能自动切换,无需人工干预,能非常好的工作在读写分离的环境下.基于Perl语言的脚本也非常方便进行二次开发.MHA非常适合读写压力比较大的应用.
但由于MHA在工作时需要配置SSH互信,因此选择这种架构时内网安全一定要做到位.另外也可以搭配Binlog Server使用.
PXC全称是Percona XtraDB Cluster,是Percona公司基于Galera协议开发的一个产品.PXC牺牲了CAP里面的P(Partition Tolerance),保留了C(Consistency )和A(Availability ).这种结构非常适合电商、金融类业务,自PXC和Group Replication出现以后,MySQL彻底扫清了进入金融行业的障碍.
PXC的优势:
使用PXC要注意的问题:
除此之外,还有一类采用DNS/ZooKeeper的高可用架构,这种架构通常都需要自行开发,无通用的方案,比较适合大规模集群的高可用,这里我们不过多赘述.
下面简单回顾一下上述几种高可用架构:
总而言之,没有最完美的架构,只有最适合的架构.选择适合自己业务的即可.
接下来是第三个议题,MySQL拆分原则和分库分表设计.
首先先提一个问题,为什么要拆,不拆不行吗?按照我们的经验来看,当数据和业务到了一定的规模,都不可避免的要面临分库分表的问题.这就好像汽车的发动机一样,要达到更高的性能,4缸6缸明显是不够用的,V8、V12才是王道.
拆分能解决如下几个问题:
确定要进行数据库的拆分了,应该怎么拆呢?
垂直拆分
优点:
缺点:
水平拆分
优点:
缺点:
要先分库还是先分表?
一巴掌拍板直接选分库或分表都是不可取的,主要是看需要达到什么样的扩展方式,才能决定先分库还是先分表,根据具体的场景决定.分库分表的最终目的还是为了扩展,而且要看拆分的规划设计是针对哪一层.
上述问题都解决了,该考虑如何实现了,到底是在应用程序中实现,还是使用中间件?个人建议如果是小规模的拆分,直接在程序逻辑中实现即可,大规模的拆分再考虑使用各种中间件.
目前业内已经开源了很多的MySQL中间件产品,例如Atlas、DBProxy、MyCAT、OneProxy、DRDS、Vitess等等,每个中间件都有自己的特点,个别不太成熟的可能会存在一些Bug,选用之前要做好相关的调研与测试工作,上线使用一定要保证自己能hold住.如果要完全贴合自身业务,并且掌控得较好的还是要自行开发.
下面说说我们的拆分经验.
首先我们先在压力比较大的数据库上做垂直拆分,剥离出活动、后台统计等业务.这一步也是最容易实现的.
接下来,如果是消息类的数据,就基于时间维度进行拆分,单表控制在5-10G,行数控制到500-1000w这个样子.这个时候我们发现数据库的性能是比较好的,而且比较好维护.如果是用户类的数据,就按照Hash或Range进行拆分.这种情况下用这种方法拆分会拆的比较均匀一些.
并发仍然比较高怎么办?可以在时间维度拆分的基础上再按Range或Hash进行拆分.
最后要注意的就是不要过度的拆分,会造成复杂度的上升.Schema设计合理的情况下,10亿的数据量也能跑的好好的.个别不关键的应用,例如日志、监控数据等,使用分区表、TokuDB也能抗.拆分对应用层总是有损的.
要做个“懒”DBA.
最后一个议题,我们聊一聊NoSQL.NoSQL现在遍地开花,应用也很广泛了,业内用的比较多的主要集中在Redis、MongoDB、Cassandra等NoSQL数据库上.今天我们主要来说说和MySQL关联最为密切的Redis.
为什么要使用Redis?
Redis主要作用还是抗读的压力.读操作先到Redis,Redis中取不到再从MySQL数据库访问,从MySQL读取到数据后,还要回写到Redis.
使用Redis要注意的几点:
性能方面,由于Redis完全是基于内存的访问,性能无需担心.
在使用Redis时,要注意Cache 和Storage不要混合使用.不要依赖Redis的持久化,持久化这一块Redis要努力的还很多.另外如果你把Redis拿来做Storage的话,一旦Redis的内存跑满,那就惨了,所有的Redis连接都会卡着不响应.如果只是把Redis来做cache的话,那问题就不大.
还有诸如缓存穿透、缓存雪崩、热点key重建时缓存失效这些问题也是重点关注的对象.
如何利用Redis给MySQL加速:
1)利用K/V结构,缓存结果,例如存储用户信息、全局排行、统计信息等.
2)利用其丰富的数据结构为MySQL减压,例如计数器、排序、Hash(把表映射到Redis中)、消息队列等.
系统架构设计是一个长期总结与进化的过程,讲究均衡与取舍.在进行大规模MySQL架构设计的过程中,除了要汲取别人的经验之外,还要关注各种架构背后的业务场景与架构思想,与自己的实际业务场景相结合,才能设计出一个好的系统架构来.
转载请注明本页网址:
http://www.vephp.com/jiaocheng/1978.html