• 1. 分布式MySQL总结同风
  • 2. 背景介绍大数据量的存储需要大量的数据库资源 数据量的不断增长要求数据库存储具有可扩展性 在保证大数据量的情况下,要保证性能、高可用性等质量要求 现有框架中没有彻底解决大数据量的存储问题 Oracle等海量存储方案价格不菲,采用MySQL架构节约IT成本
  • 3. MySQL与ORACLE对比ORACLE RAC 架构shared–storage架构 高性能服务器 高性能存储 专线直连网络
  • 4. MySQL与ORACLE对比MySQL Cluster架构优点: 多个节点之间可以分布在不同的地理位置,因此也是一个实现分布式数据库的方案。 扩展性很好,增加节点即可实现数据库集群的扩展。 冗余性很好,多个节点上都有完整的数据库数据,因此任何一个节点宕机都不会造成服务中断。 实现高可用性的成本比较低,不象传统的高可用方案一样需要共享的存储设备和专用的软件才能实现,NDB 只要有足够的内存就能实现。 缺点: 基于内存,数据库的规模受集群总内存的大小限制 基于内存,断电后数据可能会有数据丢失,这点还需要通过测试验证。 多个节点通过网络实现通讯和数据同步、查询等操作,因此整体性受网络速度影响, 因此速度也比较慢
  • 5. MySQL与ORACLE对比MySQL Sharding架构优点: 不依赖特定数据库软件 水平扩展的解决方案,解决数据库扩展性问题缺点: 对业务依赖大 跨表和join很棘手 规模扩容问题
  • 6. 典型MySQL应用架构压力分摊 -访问压力切分—读写分离 -数据切分—分库分表 -缓存中间层 -数据库中间层(DAL) 数据备份 数据扩容 MySQL架构的挑战
  • 7. 压力分摊
  • 8. 读写分离性能的需要:压力超过单实例承受的极限 冗余的需要:防止单点风险 扩展:由于业务新增了新的需求
  • 9. 读写分离问题: 主库是个单点——主库加standby,添加高性能设备 从库过多会加大同步的延迟
  • 10. 数据切分切分办法? 水平切分——以行为单位,对业务逻辑影响较小 垂直切分——以列为单位,将某些字段拆去为何而切分? 单表数据量过大(kw级),查询性能下降 服务器性能瓶颈
  • 11. 数据切分
  • 12. 数据切分带来的问题跨库和跨表查询 跨库join 结果集合并 结果集排序 全局自增id Sequence服务 Zookeeper? 分布式事务
  • 13. 跨表和跨库查询应用层query cache(跨表,跨库) 利用merge引擎和partion表(跨表) 表级别的主从同步(跨库) 将需要跨表的字段拆出,通过trigger更新(跨表) 目前没有通用方案,还需要根据业务来进行斟酌
  • 14. 缓存中间层同样是个分布式系统 关键: - 一致性策略 - 缓存逐出策略 - 高效数据结构(高空间利用率+无锁数据结构) - 序列化协议 - JVM调优
  • 15. 数据备份
  • 16. 数据备份全量备份: 拷贝文件(myisam:FRM MYI MYD,innodb: frm ibdata ibd ib_logfile ) mysqldump mysqlhotcopy(myisam) SELECT INTO OUTFILE语句 BACKUP TABLE 语句 备份binglog文件 增量备份: Xtrabackup(只能用于innodb) 按日备份binlog(通用)
  • 17. 数据扩容
  • 18. 难点: 规则变更引起业务重新发布 数据的不一致 数据迁移数据扩容在满足基本业务功能的前提下,应当尽量避免数据迁移
  • 19. 如何避免数据迁移? 改变的是应用层规则 迁移的是表而不是行数据扩容
  • 20. 数据库中间层配置集中管理 JDBC请求动态路由:读写分离,库表散列,负载均衡,主备切换 SQL拦截,DB监控和报警 部分中间层还支持query cache数据扩容
  • 21. MySQL Proxy Amoeba HiveDB TDDL数据库中间层数据扩容
  • 22. 拆分举例
  • 23. 实例1.情况: - 用户 超过5亿 - 新增发帖 百万/年 - 新增回复 千万/每年 2.特点: - 典型互联网应用 - 无事务,最终一致性 - 无连接查询,无子查询 3.步骤: - 先分表后分库 - 由memcached到缓存中间层 - 运维问题——开发数据库中间层,建立完善的备份机制
  • 24. 实例UserSubjectReplyid nameid subjectId userIdid userId title body三种查询: getUserSubject getUserReply getSubjectReply 拆分实体表1:N1:N1:N
  • 25. 拆分实体表 getUserSubject (int uid) 实例Subjectid userId title bodySubjectid userId title bodySubjectid userId title body getUserSubject (int sid,int uid)
  • 26. Replyid subjectId userIdReplyid subjectId userIdReplyid subjectId userId拆分实体表getSubjectReply(int sid) getUserReply(int sid,int uid)getSubjectReply(int sid,int uid) getUserReply(int uid) 实例
  • 27. 拆分关系表比如关注关系表(follow_relation): User——User(多对多) 可以按双键拆分: 我关注了谁:hash1(userId)=1 -> follow_relation01 谁关注了我:hash2(userId)=1 -> follow_relation01 实例缺点: follow_relation01中可能会出现重复记录(插入时insert ignore或replace into即可) 表中数据量翻倍
  • 28. 拆分字典表用户(user)和用户类型(usertype): usertype与user无依赖关系 可以进行垂直拆分,将usertype移到新库即可 如果usertype被多个库使用,可以在多库之间进行主从复制实例
  • 29. 解决跨表查询Merge引擎: CREATE TABLE `self_reply` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(10) NOT NULL DEFAULT '0', `subject_id` int(11) NOT NULL DEFAULT '0', `reply_time` date DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `us` (`user_id`,`subject_id`,`reply_time`), KEY `time_key` (`reply_time`) ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 INSERT_METHOD=LAST UNION=(`self_reply_2009`,`self_reply_2010`,`self_reply_2011`); 实例遍历->合并结果集
  • 30. 实例缓存中间层 Memcache(key-value) 自建中间层(key-list) 数据库中间层 基于ICE实现的配置管理和推送 基于zookeeper实现的配置管理和推送
  • 31. 其他
  • 32. myisam与innodb读性能:myisam > innodb 写性能:myisam < innodb(基于索引的更新) 事务:innodb 锁:myisam表锁,innodb行锁(where条件命中) 物理文件:myisam(MYI MYD FRM),innodb表空间和log
  • 33. 引擎特性myisam : select insert速度快 支持表压缩 支持merge引擎 innoDB: 支持事务 行级锁支持 外键支持myisam与innodb
  • 34. 特殊SQLLIMIT REPLACE INTO CONCURRENTINSERT、INSERT DEALY和INSERT IGNORE CREATE ... SELECT TRUNCATE RENAME TABLE …
  • 35. 总结
  • 36. MySQL使用的一些问题单实例的承载能力不是很高(通过架构弥补) 写sql要考虑到引擎(比如count(*)和order by) 主库的单点问题 设计初期必须考虑扩容问题 分库分表往往与业务直接相关 备份问题相对复杂(要针对具体引擎) 需要中间层和缓存的配合