好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Mysql读写分离

首先我们必须知道为什么要分离。这个一般是由于以下原因导致的。 性能,单台数据库实在是撑不住了 HA ,防止单台数据库挂掉造成应用不可用 扩展,由于业务新增了新的需求 以上几种是我们常见的要进行分离的原因。其中做多的可能是第一和第二种。这个主要还是

首先我们必须知道为什么要分离。这个一般是由于以下原因导致的。

性能,单台数据库实在是撑不住了 HA ,防止单台数据库挂掉造成应用不可用 扩展,由于业务新增了新的需求

以上几种是我们常见的要进行分离的原因。其中做多的可能是第一和第二种。这个主要还是涉及到钱和服务器的数量上。一般业务都会在前端部署更多的服务器,而在最后端的数据库服务器往往比较少。但是对于好多 web2.0 UGC 这样的业务的网站还是有必要重视后端的速度和稳定性。

分离的多种方案

query proxy ,这个一般是由单独的服务器来进行的,由它负责这个 sql 语句路由到哪个服务器上。这种 proxy 的话最好还是要建立 HA 方式,不然这个 proxy 就是一个单点故障。这个在之前人人的系统中就是如此,虽然只是负责发起查询的时候建立真实 mysql 服务器和应用服务器连接,但是还是比较危险的。 Load balance, 后面一堆服务器,通过轮寻的方式来访问 mysql 服务器。这个很多时候是通过内部 DNS 来实现。

分离的多个原则

根据内容进行分离,针对某个表或者某个库的查询到哪个服务器上。这个其实就是数据库分区的概念。这个在之前的人人系统中我们也经历过从单台数据库服务器,最终分离出所有的应用到单独的数据库中,并且都有了单独的服务器。这样一旦服务器出现问题,也只会影响到单独的应用,而不会是全部的应用都不可用。 根据后端 mysql 服务器的状态,当第一台服务器到达某个标准状态时候再请求到第二台服务器上。这种原则容易造成第一台服务器长时间的高负载运行。 根据 session 分离,根据 session 和后端服务器的映射表来分离。这个对于 proxy 的要求比较高,需要在内部存储这样一个映射表,并且要可以实时进行更新映射表。

现有的问题

有多个写,这个现在有双 MASTER 的方案。多个分区的也会总有一个 master 实在忙不过来的时候,特别是 web2.0 网站的 UGC 内容。对于 cms 系统来说完全没有必要。 没有 session 隔离,这个有可能导致查询到的数据不准确。这个就是如何保证用户刚提交内容后马上看到提交后的结果。这个之前在人人某个网页游戏中发生过类似事情,在程序中 update 数据后立刻去读数据库。但是实际上是 update 到 master 数据库,但是 select 查询的是 slave 数据库。后面我说到 seconds_behind_master 这个时间并不准就是这里,虽然 seconds_behind_master=0 但是还是不能在 master 做了 update 后可以实时的传导到 slave 上啊。 需要用到内部 DNS ,或者 hosts 文件来进行调度。

这种分离导致的问题

导致问题的复杂,一个简单的 update 语句会导致所有的相关数据库服务器进行 update 。 导致过多的读写, slave 方案的最大问题就是在 master 服务器上的写同样会传导到 slave 服务器上,同时 slave 服务器还要支持读。

现在我们在 mysql5.1 以上的版本中使用行复制,但是这个现在还不是很成熟。

不要相信 show slave status\G; 中的 seconds_behind_master ,这个在实际中并不太准确。

之前我用到的几种 query proxy 。

一种是比较山寨的方法,让程序员在在代码中嵌入, insert, update 这种语句直接连接 master 服务器,而 select 直接连接到 slave 服务器。在多个 slave 服务器之前使用 haproxy 进行调度代理。这种方法的缺点是,当业务调整,或者服务器 IP 更改后还要去修改 DNS 服务器去,同时还得寄希望于程序中没有把 insert 这种语句没有一个指向 slave 服务器上。当然优点就是部署简单。 mysql proxy: 这个貌似很官方的,但是配置语法较麻烦,容易弄错,自己没有实践过,周边同事实践后感觉不好。 最后一种是人人正在使用的。是完全自己做的,用的是 ICE 框架。直接一个单独的配置文件进行配置就可。配置文件的主要内容是 instance 名字,数据库名,数据库 IP 地址,读还是写,还是读写都可。这个东西使用方式对于程序员来说很简单,它只要知道连接哪个数据库用什么 instance 名字就可,不需要知道其他任何信息。其它信息(读写方式,数据库地址等等)都是靠这个中间层来确定的。同时对于这些信息都会缓存在应用程序本地,以后不用再次请求中间层,而是直接连接对应的数据库就可以了。第一次应用程序请求的时候会请求到中间层,中间层返回对应的数据库地址和名字以及数据库的用户名密码等信息,然后应用程序使用这些信息来连接数据库,而第二次请求的时候就直接连接数据库了。但是这个系统的问题是每个应用程序本地都要知道这个中间层的地址,每次修改中间层的配置文件后都要重新 reload 下通知所有应用程序下次请求都要先请求下中间层,无论修改的配置跟你这个应用程序有没有关系。

查看更多关于Mysql读写分离的详细内容...

  阅读:42次