可扩展性。 即通过增加资源提升整个系统吞吐量的能力
一般会有如下的角度影响负载:
可扩展性的数学表现:
通常系统初建时要考虑一点可扩展性。在扩展之前,要先压榨单机性能,比如算法调优等等。
向上扩展就是换CPU,磁盘等等。对部分应用来说这是唯一需要做的。
优点:
为了能够更好的在大型服务器上运行MySQL,一定要尽量使用最新的版本。
如果应用变得非常庞大,向上扩展可能就没有办法。
向外扩展有时也称为横向扩展或者水平扩展,策略划分为三个部分:复制、拆分,以及数据分片(sharding)。
最简单的扩展方法是通过复制将数据分发到多个服务器上,然后将备库用于读查询,即读写分离。
另外一个比较常见的向外扩展方法是将工作负载分布到多个“节点”。许多大型的MySQL应用不能自动分布负载,就算有也没有做到完全的自动化。
一个节点可能就是一台服务器,如果设计冗余,那么一个节点通常是下面的某一种:主主复制,一主多备复制,一主多备DRBD复制,共享存储。大多数情况下,一个节点内的所有服务器应该拥有相同的数据。我们倾向于把主主复制架构作为两台服务器的主动被动节点。
安功能拆分
按功能拆分,或者说按业务拆分,意味着不同的节点执行不同的任务。将独立的服务节节点分配给不同的应用,这样每个节点只包含特定应用的数据,即按库划分。
另一个可能的按功能划分方法是对单个服务器的数据进行划分,确保划分的表集合之间不会执行关联操作,即按表划分。
但是功能划分不能无限地进行扩展,因为如果一个功能区哉被捆绑到单个MySQL节点,就只能进行垂直扩展。如果进行了太多的功能划分,以后就很难采用更具扩展性的设计了。
数据分片
在目前用于扩展大型MySQL应用的方案中,数据分片是最通用且最成功的方法。它把数据分割成一小片,或者说一块,然后存储到不同的节点中。
数据分片和某些类型的按功能划分联合使用时非常有用。大多数分片系统也有一些“全局”的数据不会被分片(例如城市列表或者登录数据)。全局数据一般存储在单个节点上,并且通常保存在类似 memcached 这样的缓存里。
实际上,大多数应用只会对需要的数据做分片,通常是那些将会增长得非常庞大的数据。
如果事先知道应用会扩大到很大的规模,并且清楚按功能划分的局限性,就可以跳过中间步骤,直接从单个节点升级为分片数据存储。事实上,这种前瞻性可以帮你避免由于粗糙分片方案带来的挑战。
采用分片的应用常用一个数据库访问抽象层,用以降低应用和分片数据存储之间通信的复杂度,但无法完全隐藏分片。因为相比数据存储,应用通常更了解跟查询相关的一些信息。
分片?还是不分片?
答案很简单:如非必要,尽量不分片。首先看是否能通过性能调优或者更好的应用或数据库设计来推迟分片。如果能足够长时间地推迟分片,也许可以直接购买更大的服务器,升级MySQL到性能更优的版本,然后继续使用单台服务器,也可以增加或减少复制。
简单的说,对单台服务器而言,数据大小或负载变得太大时,分片将是不避免的,如果不分片,而是尽可能地优化应用,系统能扩展到什么程度呢?答案可能会让你很惊讶。有些非常受欢迎的应用,你可能以为从一开始就分片了,但实际上直到已经值数十亿美元并且流量极其巨大也还没有采用分片的设计。在没有必要的情况下采用分片的架构来构建应用会步履维艰。
选择分区键
数据分片最大的挑战就是查找和获取数据:如何查找数据又取决于如何分片。我们的目标就是对重要并且频繁查询的数据减少分片(可扩展性法则的其中一个条件就是避免不同节点间的交互)
多个分区键
这种情况可以把要分区的键的表的关键字段在其中另外一个键的表中做冗余。来做关联查询
问题1: 跨片查询和聚合。 可以使用汇总表,搜索引擎
问题2:一致性。外键失效,需要应用保证
分配数据、分片和节点
在节点上部署分片
常用方法:
数据分配策略
都会有分区方法,传入分区键, 输出分区号
固定分配
分区方法只依赖分区键。
比如哈希函数和取模运算。 CRC32();
特性:
动态分配
利用外部资源,可以是表或者是目录服务器等等。来记录分区键和分区iD之间的关系。 这种可以很灵活。
通常都是两种结合使用。 比如先用静态的方式处理一下分区键,再用动态的方式把处理后的结果映射到分区Id上
显示分配
就是分配策略本身已经显示成为了分区键的一部分。能直接看出来。
重新均衡分片数据
可以使用动态分配策略。相对随机的分配。
并且还能够根据每个服务器的负载情况选择关闭 。
还可以为想均衡的表简历备库,然后修改访问机制,各负责一般的数据,然后删除不用的数据。
唯一ID
分片了,自增主键就不好用了。
可以有如下的方案搞:
分片工具
基于分片的系统,如果应用创建多个数据源分别访问分片就有点数不过去了,应该有抽象层。其应该具有如下的功能:
有很多不错的工具可用:
为了更大的压榨CPU的性能,可以单机多实例多分片的部署 。
还可以通过虚拟化技术 。
这种扩展可能会带来I/O的瓶颈,可以使用多网卡的方式。
云,集群。这个是理想的状态,数据库能够弹性扩展,自动分片等等。
Mysql收到了No SQL的挑战,其中一点就是Nosql可以更好地集群,但是Nosql存在很多其他的问题,比如事务,查询上的弱点,其为了解决这些弱点,也越来越像关系型数据库。
NDB Cluster是一个可扩展的数据库,既可以使用NoSQL,又可以使用Mysql存储引擎,我们经常可以选用的类似的组件有:
对不需要的数据进行归档和清理
需要考虑如下的问题:
保持活跃数据独立
前端负载均衡器,根据服务器性能情况分发请求。
目的: 更有效的使用资源。 可用性提高(保证有服务有用), 透明。
跟分片和复制关系密切,可以部署在任何一个环节,比如应用前端,数据库前端等
可选的方案: DNS, LVS, TCP代理等等。普遍使用F5, HAProxy
应用直连。不使用中间件完全用业务来判断负载,如选择不同的备库做不同的逻辑。
负载均衡器
1.一般的负载均衡器都是HTTP协议的,但是Mysql需要TCP协议的,因此要使用能支持TCP协议的,但是这不是专门为Mysql设计的,还是会有一些限制。
不能很好的均衡,因为无法知道负载权重
2.均衡器并不能很好的分辨Mysql连接的状态,保证他能尽量练到固定的服务器,提高缓存效率
3.线程池可能用不到负载分发
4.要求均衡器支持TCP分发及TCP端口监测等等。
负载均衡算法
1.随机
2.轮询 依次发送请求
3.最少连接数 适合有新服务器加入的时候,因为加入了新的服务器,其响应速度没有缓存会比较慢,因此先把最少连接数
4.最快响应
5.哈希 对源IP进行hash
6.权重
7.排队,设置最大连接数。排队处理
正确地扩展MySQL并没有看起来那么美好。从第一天就建立一个Facebook架构,这并不是正确的方式。最好的策略是实现应用所明确需要的,并为可能的快速增长做好预先规划,成功的规划是可以为任何必要的措施筹集资金以满足需求。
在MySQL扩展策略方面,典型的应用在增长到非常庞大时,通常先从单个服务器转移到向外扩展的拥有读备库的架构,再到数据分片和按功能分区。我们并不同意那些提倡为每个应用“尽早分片,尽量分片”(shardearly, shard often)的建议。这很复杂且代价昂贵,并且许多应用可能根本不需要。可以花一些时间去看看新的硬件和新版本的MySQL有哪些变化。
当存在多个服务器时,可能出现跟一致性或原子性相关的问题。我们看到的最普遍的问题是缺少会话一致性。负载均衡器可以解决这个问题,但它本身也有一些问题。