复制和分离
数据库通过复制来创建冗余副本,达到分散查询压力。
主从复制
mysql主从复制:
1、开启服务器上的二进制日志(log-bin)
2、在服务器和从服务器上分别进行简单的配置和授权
mysql主从复制是依据主服务器的二进制日志进行的,主服务器上的日志记录操作会在从服务器上进行重放,从而实现复制。
这种复制是异步进行,从服务器定是向主服务器请求最新日志,而主服务器只需要通过一个I/O线程来读取本地二进制日志,并输送到服务器上就可以了。
减少磁盘压力,可以采用多级复制策略。
读写分离
所有更新操作,必须让他作用于主服务器,这样才能保证所有数据库服务器上的数据一致。
对数据库的写操作指向主服务器,而将读操作指向从服务器。
(用于站点数据库读操作比写操作密集且查询条件丰富的服务器 对于用户创建内容为主的站点来说,写操作密集,则通过分区来实现扩展思路。)
使用数据库反向代理
mysql 可以使用mysql proxy
存在大量的从服务器时,mysql proxy必然就会出现瓶颈效应,不过,即使是到了那个时候,主服务器已经无法承受写操作的压力了。
垂直分区
对于数据库写操作频繁,仅采用只从复制和读写分离可能效果并不明显。
最简单的方法当然是讲不通数据库分不到不同的服务器上,例如:数据库之间不存在关系,不需要进行联合查询的分别移到独立的数据库服务器上。
(当存在关系的数据库主服务器再次遇到无法承受写操作压力时,水平区分)
水平区分
水平区分意味着我们可以将同一数据表中的记录通过特定的算法进行分离,分别保存在不同的数据库表中,从而可以部署在不同的数据库服务器上。
(大规模的站点基本上都经历了从简单的主从复制到垂直分区,再到水平分区的步骤。)
水平分区并不依赖特定的技术,他更多的是一种逻辑层面的规划。
把数据放在不同分区中
例如通过user_id的奇偶性质来分别储存到不同的数据库服务器中。
或者通过user_id%10将划分10个分区取值。
分区和分表
分表:例如
1、tbl_YYYY按照年来分表
2、user_id%10 数据库表 tbl_user_00,tbl_user_01,...,tbl_user_10
这种策略在数据库建立时便采用,数据表记录数量相对少,利于减少查询时间,从而为数据库减少不必要的开销。
分表只是单台数据库的优化策略,一旦到了必须考虑扩展的时候 ,分区便派上用场。不过已经实现分表将使得分区更加容易,因为数据库已经分离,只需要迁移到其他服务器上即可。
例如: 数据库表 tbl_user_00,tbl_user_01,...,tbl_user_10 前五个放到一个数据库中。后五个放到另一个数据库中。
分区
考虑:那些数据进行分区,那些数据可以放到分区中。
1、哈希算法
哈希算法可以为多个分区比较均衡地分配工作量,特别是当记录数量较多时,各个分区更加趋近于均衡。
但是这种算法对于扩展并不友好,一旦我们需要从10个分区扩展到20个分区,这便涉及所有数据的重新分区。
2、范围
按照分区索引字段范围进行分区,例如user_id前1-100000为一个分区,后100000-200000位另一个分区中。
他可以带来更好的扩展性,随着用户数量的不断增长,我们可以创建更多的分区。但是各个分区的工作量会存在较大的差异,比如id接近热点用户导致分区压力过大。
3、映射关系
将分区索引字段的每个可能的结果创建一个分区映射关系,使用数据库来维护他。
例如:我们需要知道uer_id在那个分区,必须查询数据库获得答案。使用缓存来提高性能。
这种分区具有较强的可伸缩性,我们可以灵活地控制他们的规模,并且轻松地将一个分区迁移到另一个分区。
分区扩展
分区扩展更多的体现在能否快速的平滑地实现扩展,并且进行最少的单位数据移动。
分区反向代理
spockProxy他可以帮助应用陈旭实现水平分区的访问调度。意味着我们不需要再应用程序中维护那些分区对应关系了。
spock Proxy 本身的大部分代码正式基于mysql proxy ,同时他也进行了一些改进。