求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
 
MySQL架构方案
 

2010-11-9 作者:Richie 来源:cnblogs.com

 

Scale Out:横向扩展,增加处理节点提高整体处理能力

Scale Up:纵向扩展,通过提升单个节点的处理能力达到提升整体处理能力的目的

Replication

MySQL的replication是异步的,适用于对数据实时性要求不是特别关键的场景。slave端的IO线程负责从master读取日志,SQL线程专门负责在slave端应用从master读过来的日志(早期MySQL用一个线程实现,性能问题比较明显)。使用replication必须启用binary log,MySQL用binary log向slave分发更新

复制级别

1. Row Level:5.1.5开始支持。mater记录每行数据的更改日志,slave根据日志逐行应用。优点:数据一致性更有保障。缺点:可能造成日志文件比较大

2. Statement Level:master记录每个执行的query语句以及一些上下文信息,slave节点根据这些信息重新在slave上执行。优点:binary log比较小。缺点:某些情况下数据一致性难以保障

3. Mixed Level:MySQL根据情况选择哪种复制方式。5.1.8开始支持

常用架构

1. Master-Slaves:通常都采用这种方式

2. Dual Master(Master-Master):2个master节点互相同步更新。因为MySQL的异步复制方式,为了防止数据冲突造成的不一致性,一般仅将其中一台用于写操作,另一台不用或仅用于读操作。目的是其中一台master停机维护或者故障中断时可以使用另一台master

3. 级联复制(Master-Slaves-Slaves):在Master Slaves中,如果slaves过多replication将增加master的负载,这时可以让master只向其中几台slave分发更新日志,这几台slave作为一级节点再向下级节点分发更新日志

Cluster

主要通过NDB Cluster存储引擎实现,是一个Share Nothing的架构,各个MySQL Server之间并不需要共享任何数据。可以实现冗余(可靠性)以及负载均衡。刚开始MySQL需要所有数据和索引都能够加载到内存中才能使用Cluster,对内存要求高,目前通过改进只要求索引能全部加载到内存

   

MySQL Clusrer架构示意图,图片来自MySQL官方文档

1. SQL Nodes:负责存储层之外的事情,例如连接管理、query处理和优化、cache管理等,即剥离了存储层的MySQL服务器

2. Data Nodes:存储层的NDB节点,即Cluster环境下的存储引擎。每个cluster节点保存完整数据的一个分片,视节点数目和配置而定,一般data nodes被组织成为一个个group,每个group存有一份完全相同的物理数据(冗余)。NDB存储引擎首先按照冗余参数配置来使用存储节点,然后根据节点数目对数据进行分段

3. Management Server:负责整个clsuter集群中各个节点的管理工作,它保存了整个cluster环境的配置,启动关闭各个节点,实现对各节点的常规维护、备份恢复等,它获取各个节点的状态和错误信息,并反映给整个集群中所有节点

Cache

1. 应用层cache:最普通的cache方式,应用层自己管理cache,与数据库无关

应用层cache的选择方案很多

a). Memcached:分布式的缓存,本身性能优秀,扩展性比较好;虽然比本地缓存方案慢,但具备共享缓存效果

b). Berkeley DB:与Memcached相比,BDB实现本地缓存;Memcached是内存式的缓存,而BDB使用磁盘,成本不一样;Memcached仅支持hash索引,而BDB支持hash索引和B-Tree索引;MySQL数据库方案下使用BDB,主要出于扩展性方面考虑,以及BDB的hash索引可以比MySQL更有效

2. MySQL-Memcached整合:有2种方式

a). 直接用Memcached作为MySQL的二级缓存。这可以增加MySQL的缓存容量,而Memcached对于应用端是不可见的。这种方案适用于一些特定场景,例如数据实在难以切分、很难对应用程序进行改造等
这种方案目前有Waffle Grid开源项目,仅支持InnoDB存储引擎。其原理是当MySQL在Local Buffer Pool中找不到数据时则从磁盘读取,而Waffle Grid在这里加入一段处理,先尝试从Memcached Server读取,如果Memcached Server中不存在,才通过磁盘IO读取,将读取的数据会存入Memcached,并记录在InnoDB Buffer Pool的LRU List中,如果数据变成dirty或者缓存管理将其清出时,InnoDB将对应的LRU List移入FLUSH List,此时Waffle Grid从Mamcached Server删除数据。从上面可以看出,缓存机制仍然由MySQL管理,Memcached中存放的仅为有效的(不是脏数据)、仅作为缓存目的的数据,Memcached Server崩溃停机等不影响MySQL数据

架构示意图(《MySQL性能调优与架构设计》):

Waffle Grid是否会因为网络访问开销导致查询性能下降呢?可以参考Waffle Grid DBT2的测试结果,以及实际测试进行评估

b). 使用MySQL的UDF功能与Memcached进行整合。Memcached的数据由MySQL和应用端程序共同维护,应用端先从Memcached读取数据,读取不到时则从MySQL Server读取,并把数据写入Memcached中,而数据有更新、删除导致Memcached数据失效时,MySQL负责将Memcached中相应数据清除

架构示意图(《MySQL性能调优与架构设计》):

MySQL Memcached UDFs下载和使用参考Using the MySQL memcached UDFs

数据切分、Sharding

分为垂直切分和水平切分,垂直切包括将一个表按不同字段切分成多个表、将不同表建在不同的MySQL Server中,水平切分指将同一个表的数据切分到多个表中存储

1. 表结构设计垂直切分。常见的一些场景包括

a). 大字段的垂直切分。单独将大字段建在另外的表中,提高基础表的访问性能,原则上在性能关键的应用中应当避免数据库的大字段

b). 按照使用用途垂直切分。例如企业物料属性,可以按照基本属性、销售属性、采购属性、生产制造属性、财务会计属性等用途垂直切分

c). 按照访问频率垂直切分。例如电子商务、Web 2.0系统中,如果用户属性设置非常多,可以将基本、使用频繁的属性和不常用的属性垂直切分开

2. Sharding

Sharding指一种"shared nothing"形式的垂直切割,将切割后的部分部署在不同的服务器上。关于sharding和partition的区别可参考DBA Notes冯大辉的开源数据库 Sharding 技术 (Share Nothing)

Sharding方案可以考虑:

a). Session-based sharding,只需在创建session时确定处理节点,随后的请求都直接定向到该节点进行处理

b). Statement-based sharding,每个语句都需要确定处理节点

c). Transaction-based sharding,根据事务中第一条语句确定处理节点

Sharding潜在问题:

a). 被分割开的部分之间无法使用数据库级别的join操作(cross-shard joins,可以考虑将一些公共的、全局的表部署到每一个节点上,使用replication机制分发)

b). 被分割开的部分之间事务处理复杂

c). 对自增长键的管理(主要出现在混合了水平切分的Sharding情况下)

3. 水平切分

示例:

a). 比如在线电子商务网站,订单表数据量过大,按照年度、月度水平切分

b). Web 2.0网站注册用户、在线活跃用户过多,按照用户ID范围等方式,将相关用户以及该用户紧密关联的表做水平切分

c). 例如论坛的置顶帖子,因为涉及到分页问题,每页都需要显示置顶贴,这种情况可以把置顶贴水平切分开来,避免取置顶帖子时从所有帖子的表中读取

难点之一,逻辑、关联关系的复杂性阻碍水平切分。这样的场景难在如何确定切分的范围和策略,例如SAP这样的大型ERP,模块、表非常多,之间的逻辑复杂,SAP按每Client(公司、集团)将整个业务数据完全切分开,如果粒度需要再细化难度就非常大。方案一般有:a). 按主键切分;b). 维护一个主切割索引表,这种方案扩展性非常好,但是需要查找主索引表

第二点是如何使得水平切分具备扩展性。以Web 2.0网站为例,如果按照会员ID范围进行切分,假如现在决定水平切分为5份,如果使用user_id % 5的值确定该用户属于哪个部分,这样在将来随着用户量的增长,如果以后需要再切分成为20份就会相当麻烦

水平切分和Sharding的混合模式,理论上可以实现线性伸缩,但受限于应用程序的状况、设计以及切分、Sharding实现方案

切分和整合方案

主要2种实现思路:

1. 每个应用程序模块配置管理自己需要的一个或多个数据源,直接访问各个数据库

2. 通过中间代理层统一管理所有的数据源,后端数据库集群架构对前端应用透明

使用MySQL Proxy

这是MySQL官方提供的,位于客户端程序与MySQL Server之间,能够监控、分析、转换他们之间的通讯。常用的场景有负载均衡、故障恢复、查询分析、查询过滤和修改,以及基本的HA机制,目前在实现读写分离方面仍存在一些问题,架构示意图(《MySQL性能调优与架构设计》):

MySQL Proxy提供一个基础的框架,其他功能需要编写LUA脚本实现(牺牲一定性能,带来灵活性)

HSCALE是MySQL Proxy的一个LUA模块,他透明的分析和重写查询,切分、分区逻辑从应用程序层转移到代理层

HSCALE项目官方网站:http://www.hscale.org,作者博客网站:http://pero.blogs.aprilmayjune.org/

使用Amoeba

Amoeba是基于Java开发的分布式数据库数据源整合Proxy程序的开源框架,Amoeba 开发者博客项目主页

主要解决以下问题:

a). 数据切分后复杂数据源整合

b). 提供数据切分规则并降低数据切分规则给数据库带来的影响

c). 降低数据库与客户端连接

d). 读写分离路由

Amoeba For MySQL是专门针对MySQL数据库的方案,架构示意图:

图片来自《MySQL性能调优与架构设计》

Amoeba For Aiadin是个更通用的方案,他前端接收MySQL协议的请求,后端可以使用MySQL、Oracle、PostGreSql等其他数据源,这些对应用程序是透明的。架构示意图:

图片来自《MySQL性能调优与架构设计》

使用HiveDB

HiveDB也是基于Java的开源框架,有商业公司支持,目前仅支持水平切分,同时支持数据的冗余及基本的HA机制。他使用Hibernate Shards实现数据水平切分,自行实现数据冗余机制。HiveDB中通过用户自定义的各种Partition keys将数据分散到多个MySQL Server,访问时解析query请求,自动分析过滤条件,并行从多个MySQL Server读取数据,合并结果集返回给客户端应用程序。架构示意图:

Hibernate Shards由Google贡献,他使用标准的Hibernate编程模型,会用Hibernate就会用Hibernate Shards;可扩展的sharding策略;支持virtual shards,用于简化resharding时的处理

Spock Proxy

由实际项目产生的一个开源项目(Spock是Rails的应用,Speck Proxy应当可用于Rails之外的,例如PHP或.NET),基于MySQL Proxy开发,是MySQL Proxy的一个分支,支持range-based horizontal paritioning,他对MySQL Proxy所做的改进包括:

a). 不使用LUA脚本,提升性能。例如将多个数据源返回的结果集合并期间还要与LUA脚本交互,这样的性能开销比较大

b). 客户端登录验证。MySQL Proxy支持客户端与各个服务器直接进行登录验证,Spock Proxy则将其统一管理,分离客户端与服务器的连接

c). 动态连接池。受益于客户端登录认证机制的改善

d). 目前的MySQL Proxy无法做到读写分离,Spock Proxy实现了这一点,并且异步并行执行

架构示意图:

图片来自Spock Proxy官方网站:http://spockproxy.sourceforge.net/

Pyshards

基于Python的Sharding方案,是一个个人研究开源项目,他的目标想实现自动re-balancing(re-sharding),比较有挑战。目前仅支持MySQL。http://code.google.com/p/pyshards/

参考:《MySQL性能调优与架构设计》



MySQL索引背后的数据结构
MySQL性能调优与架构设计
SQL Server数据库备份与恢复
让数据库飞起来 10大DB2优化
oracle的临时表空间写满磁盘
数据库的跨平台设计
更多...   


并发、大容量、高性能数据库
高级数据库架构设计师
Hadoop原理与实践
Oracle 数据仓库
数据仓库和数据挖掘
Oracle数据库开发与管理


GE 区块链技术与实现培训
航天科工某子公司 Nodejs高级应用开发
中盛益华 卓越管理者必须具备的五项能力
某信息技术公司 Python培训
某博彩IT系统厂商 易用性测试与评估
中国邮储银行 测试成熟度模型集成(TMMI)
中物院 产品经理与产品管理
更多...