构建高性能的web站点需要考虑很多方面,我们在这了解一下其中一项---------数据库扩展,希望能够让没有接触过这方面知识的朋友对数据库扩展有个认识吧。
随着用户数量的不断增加,数据库将面临着巨大的增删改查,即便我们将sql语句优化的很好,但是数据库服务器仍然抵挡不了千军万马似的select,我们不得不考虑其他方法来解决这个问题。和web站点服务器一样,既然一台服务器不能承受不了,人多力量大,我们首先想到了增加服务器去分担压力。
一个新的解决方案肯定会带来新的问题-
如何扩展?
一般对数据库中的操作中读的(select)操作远远超过写的操作,那么我可以讲读写分离,原理是用一台主服务器专门用来写,多个从服务器同步主服务器中的数据。
多个数据库服务器,我们的程序怎样知道该访问那一台服务器呢?
我们通过代码控制?如果某一台服务器宕掉的话怎么办?这些问题都是我们需要考虑的,于是我们想到了反向代理,他可以向web反向代理一样,为我们按照我们制定的规则访问相应的服务器,如果检测到某一台服务器宕掉的话,它会自动将该台服务器从列表中移除。
现在我们使用一台服务器作为写服务器,由图可知,随着站点的增长,写操作会越来越频繁,如果写的操作占操作中的80%,那么从服务器必须花费80%去同步主服务器中的数据,只有20%的时间去处理用户的读操作了,而且如果写操作再大一些的话,写服务器已经无法承受写的压力了,这个问题是很严重的。
我们应该怎样办呢?
垂直分区:将彼此不经常交互的数据分类分别放在不同服务器数据库中
最简单的方法是将不同的数据库分布到不同的服务器上,你会发现有很多的数据库之间并不存在关系,或者不需要进行join查询,那为什么不把他们放在不同的服务器上呢?
我们将博客数据库与好友数据库分开了,并且从主服务器中独立出来,这样就可以将这两个数据库的操作的负担从主服务器卸下来了,按照这样的思路,随着互联网的发展,越来越多的人写博客了,一台blog服务器可能不能处理现在的工作了于是我们采用同样的方法来扩展,进行读写分离
随着时间的增加,新的问题又来了,博客的写服务器再也承受不了写的压力了(对数据库中的各个表写操作数据量太大了),于是我们想到了将数据库操作的表分离到不同的数据库服务器上,但是如果数据表也达到了写的操作极限呢?现在innodb一个表可以容纳64TB的数据,这只是存储容量
水平分区:将同一个数据表按一定规则分别放在不同的数据库中
例如加入我们拥有10个服务器,我们可以根据userid%10将用户数据分别存放在不同的数据库中,这样的话我们就可以用户分别存放在这10个数据库分区中
那么我们怎样知道数据在哪个数据库中存放呢?按找传统的方式是不行的
传统的方式:
"select *from tablename where blogid="$post_id;
因为我们只能通过userid来确定用户的数据在哪个个数据库,所以我们需要将userID传递过去
<?php
$db = new DataAccess($user_id);
$db->selectDb("db_blog");
$tbl_name = getTblName($user_id);
$sql = "select * from " . $tbl_name . " where post_id=" . $post_id;
$result = $db->query($sql);
?>
哪些数据数据应该分区呢?用户信息,好友关系这些很难回答,必须根据具体情况而定,很多时候对那些数据进行分区不是我们可以选择的,对那些频繁访问导致网站接近崩溃的数据我们必须对其进行分区
分区的会不会给我们带来不便么?
答案是肯定的,比如,原本你可能通过一条联合查询就可能搞定任务,分区之后我们必须根据用户ID来确定分区,然后通过好友ID找到好友数据所在的分区。。。很不灵活吧
常见的分区算法
哈希算法 user_id%10 这种就是
范围 1-10000存放在分区1 10001-20000存放在分区2中
映射关系 还不是太理解,以后理解了再补充上
OK,今天只讲一些mysql扩展的常用几种方法和使用情况给介绍了,以后等我的知识增加了,将实现也和大家分享一下。