06月03, 2016

网站部署多服务器实战 —— MySQL 读写分离

在上一篇文章,我们成功的在服务器部署了 MySQL 数据库主从复制。这样不仅能有效的降低跨服务器读取数据库的时间,而且能保证数据库的一致性。但是这样部署后,从库是不可写的,如果用户在从库所在的服务器进行编辑的时候,就会出现错误。为了解决这个问题。我们引入了 MySQL 读写分离。这样网站就能在读库时读从库,写库时写主库。

实现 MySQL 的读写分离大致有两种:应用层实现和代理实现。像 Firekylin 这些采用 ThinkJS 的博客系统,ThinkJS 官网就有介绍如何修改数据库配置文件 db.js 来实现读写分离。然而我们的服务器上不仅有我的博客在使用 MySQL 数据库,还有其他的网站也在使用。如果全都在应用层实现,那么每个网站都要做出修改,比较耗费精力。因此我们采用的是后者,代理实现。

ThinkJS 分布式数据库:https://thinkjs.org/zh-cn/doc/2.2/model_config.html

所谓的代理实现,就是在网站与数据库之间,引入中间件。应用层访问代理,代理根据请求类型(读 / 写)自动分流到不同的数据库服务器。中间件不仅仅能做到读写分离,还能分库分表,均衡负载等等。

网上的很多读写分离教程是为了达到均衡负载,而把中间件放到了单独的服务器上。而我们现在的主从复制是为了解决不同地区的用户访问速度的问题,服务器分布在全球的不同地方。如果把中间件放在单独的一个服务器上,那么速度反而跟没有主从复制时差不多。因此,我们把中间件放到每一台从服务器上,网站读取 127.0.0.1:3306 的数据库,写入远程主库。

我们采用的中间件叫 Kingshard ,是一款由 Go 开发的 MySQL Proxy 项目。其实中间件还有很多,比如 MySQL-Proxy 、 360 的 Atlas ,和阿里巴巴的 Amoeba、Cobar 等等。这些我们都跳过坑,尝试过,只是因我们的技术水平有限,到最后都没能成功配置好。最后我们在 Kingshard 上成功的实现了读写分离。

https://github.com/flike/kingshard

在安装 Kingshard 之前,我们需要给服务器配置好 Go 1.3 以上的环境:

wget -c https://storage.googleapis.com/golang/go1.6.linux-amd64.tar.gz
tar -C /usr/local -xzf go1.6.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
export GOPATH=~/.go

Kingshard 的功能有很多,而我们只需要用到读写分离,其他功能大家可以自行研究。

在这里贴出我们实现读写分离的 etc/ks.yaml 配置文件:

# server listen addr 
addr : 0.0.0.0:8888 

# server user and password
user :  steven
password : steven

# if set log_path, the sql log will write into log_path/sql.log,the system log
# will write into log_path/sys.log
#log_path : /Users/flike/log

# log level[debug|info|warn|error],default error
log_level : debug

# if set log_sql(on|off) off,the sql log will not output
log_sql: on

# only log the query that take more than slow_log_time ms
#slow_log_time : 100

# the path of blacklist sql file
# all these sqls in the file will been forbidden by kingshard
#blacklist_sql_file: /Users/flike/blacklist

# only allow this ip list ip to connect kingshard
allow_ips: 127.0.0.1

# the charset of kingshard, if you don"t set this item
# the default charset of kingshard is utf8.
#proxy_charset: gbk

# node is an agenda for real remote mysql server.
nodes :
-
    name : node1

    # default max conns for mysql server
    max_conns_limit : 32

    # all mysql in a node must have the same user and password
    user :  steven
    password : steven

    # master represents a real mysql master server
    master : 8.8.8.8:3306

    slave : 127.0.0.1:3306@1

# schema defines sharding rules, the db is the sharding table database.
schema :
    db :
    nodes: [node1]
    default: node1
    shard:

配置完 Kingshard 后,我们可通过 Supervisor 守护工具来守护 Kingshard 进程,防止进程意外退出。

Ubuntu 下安装 Supervisor 非常简单,运行 apt-get install supervisor 即可。

安装完后运行 cd /etc/supervisor/conf.d/ 并在这个目录下新建一个 *.conf 的配置文件,如:

[program:ks]
directory=/root/src/github.com/flike/kingshard
command=/root/src/github.com/flike/kingshard/bin/kingshard -config=etc/ks.yaml
autorestart=true
user=root

配置完后运行 service supervisor restart 即可。

至此,MySQL 读写分离就已经配置好了。

本文链接:https://g.32ph.com/post/mysql-mysql-read-write-split.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。