概述
先了解读写分离是什么,什么原理,解决了什么问题。
什么是读写分离?
其实就是将数据库分为了主从库,一个主库用于写数据,多个从库完成读数据的操作,主从库之间通过某种机制进行数据的同步,是一种常见的数据库架构,最常用的web应用优化方式之一。
优化原理是:对于常见的web应用,绝大多数是读操作,少数是写操作,数据库的读会是应用的性能瓶颈。故可以用大量机器专门做读操作,少量机器专门做写操作,一来可以可以消除读写锁冲突,二是节约了服务器资源,避免读成为瓶颈的时候,写业务浪费资源。
读写分离解决了数据库的读成为性能瓶颈。
手动读写分离
写两套代码write和read,部署write只做写,部署read只做读。
最原始的实现方法。具体实现很简单不再描述。
– 优点:实现简单,不需要多于知识,性能也会很好。
– 缺点:一旦需要部署的服务一多,部署和维护会非常麻烦。
利用mysql主从架构实现读写分离
因为项目通常会使用ORM,故我们用最常用的node的orm——sequelize作为实现实例。其他ORM或者原生都是类似思路。
主要原理就是创建两个sequelize实例,一个负责读一个负责写,分别指定读写数据库,并且把读写数据库部署在不同的机器或者集群。
egg.default.config.js配置:
config.sequelize = {
dialect: 'mysql',
port: 3306,
replication: {
read: [
{ host: '192.168.0.1', username: 'root', password: 'pass' }, { host: '192.168.0.2', username: 'root', password: 'pass' } ], write: { host: '192.168.0.3', username: 'root', password: 'pass' } } }
replication中的read实例会处理所有的select操作,而write会处理instert、delete、update语句。
- 优点:实现简单,维护方便,代码友好不需要额外知识。
- 缺点:暂时没想到,有想到我再补充。
nginx实现读写分离
nginx基本成为了通用的代理服务器,Nginx的通过配置可以把不用的请求分配到不同的服务器,只要使用了标准的restful或者近似标准的restful(读get写post)。就可以借助nginx实现读写分离
实现原理:WebDAV,一种基于HTTP的通信协议,拓展了HTTP1.1,使应用程序可以读写web server。
nginx.conf配置:
## 读服务器集群
upstream read {
server 192.168.0.1 weight=2 max_fails=2 fail_timeout=2; server 192.168.0.2 weight=2 max_fails=2 fail_timeout=2; server 192.168.0.3 weight=2 max_fails=2 fail_timeout=2; } ## 写服务器集群 upstream write { server 192.168.0.4 weight=2 max_fails=2 fail_timeout=2; server 192.168.0.5 weight=2 max_fails=2 fail_timeout=2; server 192.168.0.6 weight=2 max_fails=2 fail_timeout=2; } server { location / { proxy_pass http://read; if ($request_method = "POST" || $request_method = "DELETE" || $request_method = "PUT" || $request_method = "PATCH"){ proxy_pass http://write; } } }
是我最推荐的一种方式,主要原因是nginx作用很多基本成目前的必须。
- 优点:实现不算难,维护方便,性能高效,不需要接触代码内容,鲁棒性好,通用性好(用人话说,一点都不会的项目我也能把它读写分离部署)。
- 缺点:需要引入nginx,
MySQL-Proxy等中间件解决
此类中间件很多,除了官方的mysql-proxy,还有Amoeba等。
mysql中间件服务,上游可接入若干个mysql-client,后端可连接若干个mysql-server。
mysql-proxy可以分析与修改请求,通过中间件支持的脚本,可以判断mysql-client的操作分配到不同的mysql-server。
-
- 优点:基本不需要修改