一个系统随着业务量的爬升,最初的系统设计往往已经不能满足当前的业务需求,而且大多数的瓶颈都在数据库,
作为一个后端开发者,我们有义务了解该怎么应对处理日益渐增的数据库压力,今天我们就来引入一个数据库的中间件:
oneproxy
oneproxy 能做什么?
我相信有一些同学不太了解这个东西是干吗用的,这里我给大家几个场景
1 读写分离。假如现在公司已经的数据库已经做好了主从,现在需要你将主库作为数据写入的库,从库作为数据读取的库,也就是读写分离开来,这个时候你会怎么做?比较low的做法是在程序端去判断sql 是读还是写,然后连接到不同的数据库去操作。这种做法相对不是很合适,因为如果是一个小项目,代码改动不是很大,但是如果是一个耦合程度很高的板块,想想都头疼。但是如果借助oneproxy中间件,可以非常轻松得完成读写分离。
2 垂直分库,水平分表,假如把一个系统 根据不同的业务板块给解耦,分成N个数据库,又有某些表是大表,还得水平分表,那么当有一些业务请求需要请求不同库的不同表,甚至涉及到事务,这个时候处理起来就会很麻烦。oneproxy 同样可以轻松完成垂直分库,并且程序端无需改动或者甚少改动。
3 高可用,定义好规则后,oneproxy在面对主库或者从库宕机后,会迅速切换数据节点,保证业务的正常运转
4 对应用端透明 比起在应用端去完成这些复杂的读写分离,分库分表,节点切换等功能,oneproxy对程序端是完全透明无感知的,感觉就像用着一个单库。
总结就一句:oneproxy 类似一个连接池,管理着程序端的所有数据连接,根据不同的请求类型和请求目标,分发到不同的数据库,是一个处于应用端和数据库端的高效中间件
那么我们要怎么来使用oneproxy来做读写分离呢,首先你需要几台装好mysql的服务器 ,然后将主机和从机配好主从同步
可以看我之前的博文
docker使用镜像构建多台mysql容器
mysql 实现主从
然后再给三台数据都创建一个一样的mysql账号 具备读写权限。
在准备工作完成后呢,我们开始
登陆中间件服务器
cd /usr/local/src
下载压缩包:
wget http://www.onexsoft.com/software/oneproxy-rhel6-linux64-v6.2.0-ga.tar.gz
解压缩:
tar zxvf oneproxy-rhel6-linux64-v6.2.0-ga.tar.gz
将软件包移动到上级目录下:
mv ./oneproxy ./../oneproxy
那么这个就是我们的软件包了
我们需要修改个文件中的路径
cd oneproxy
vi oneproxy.service
路径修改如下:
保存退出
编辑配置文件:
vi ./conf/proxy.conf
更替如下:
[oneproxy]
#proxy-license = A2FF461456A67F28,D2F6A5AD70C9042D
#保持链接
keepalive = 1
#并发线程
event-threads = 4
#分组:分组读写规则
proxy-group-policy = group1:read-slave
#日志
log-file = log/oneproxy.log
#pid
pid-file = log/oneproxy.pid
#sock
lck-file = log/oneproxy.lck
proxy-auto-readonly = 1
proxy-forward-clientip = 1
proxy-trans-debug = 1
#前端显示数据库版本
mysql-version = 5.7.18
#配置主机 ip:端口@分组
proxy-master-addresses.1 = xxx.xx.x.x:3306@group1
proxy-slave-addresses.2 = xxx.xx.x.x:3306@group1
#配置从机 ip:端口@分组
proxy-slave-addresses.3 = xxx.xx.x.x:3306@group1
#配置mysql访问用户 用户名/密码@数据库名称
proxy-user-list = wujia/CFEBF9F52A8EE496924785935D15C48A09E85EF2@company
proxy-part-template = conf/template.txt
proxy-part-tables.1 = conf/part.txt
proxy-part-tables.2 = conf/part2.txt
proxy-part-tables.3 = conf/cust1.txt
proxy-charset = utf8_bin
proxy-secure-client = 127.0.0.1
#代理对外服务端口
proxy-address = :3307
#监控服务端口
proxy-httpserver = :8081
proxy-httptitle = OneProxy Monitor
注:
1 上面代码的xxx.xx.x.x替换为具体的IP
2 配置mysql账号密码的时候密码不能填写明文,需要用工具先加密
/usr/local/oneproxy/bin/mysqlpwd 你的明文密码
就可以生成加密后的密码了, 然后在配置文件里填上
保存退出,运行
./oneproxy.service start
检查是否运行成功
ps aux | grep oneproxy | grep -v grep
有输出则成功,无输出查看日志/usr/local/oneproxy/log/oneproxy.log
如果/etc/hosts文件有IPv6地址,可能无法启动,需要注释掉
vi /etc/hosts
#号注释掉这行
这个时候我们浏览器访问监控页面:
http://代理服务器IP:8081
输入初始的管理账户和密码:
用户名admin,密码OneProxy
登陆后可以看到,我们几台数据库服务器 已经连接上了
这个时候我们来测试读写分离
先测试读
我们用mysql 终端连接上代理服务器:
mysql -h 代理服务器IP -P 3307 -u 数据库用户名 -p
现在一台主机2台从机的数据都一样我们要怎么测?
这里有个小技巧
我们手动单独修改两台从机的数据就可以啦(手动笑脸)
我们用navicat连接上三个数据库
我们把从库1 改成wujia1
从库2改成wujia2
主机保持为wujia
然后我们尝试在代理终端进行查询:
这里可以看到 多次查询结果都是wujia1 跟 wujia2 并没有查询出wujia 也就是说查询并不会走到主库去(这里查询了几十次,太长不上图了)
然后我们来验证写入:
先把两台从机的slave给关了,这样万一我们修改了主库的数据,从库也不会同步修改,方便我们看出来写入是更改到哪台数据库去了。
登陆到从机的数据库终端:
stop slave
记得两台从机都要关掉slave
然后我们在代理终端更新ad_name字段,改为abc
主机已经被修改成abc了
而两个从库并没有改变
可以看到写入操作是到主库去了,由此可见,读写分离在这里已经完成。
这里给大家再科普几个情况
假如从机中有一台挂掉了 oneproxy不会再请求挂掉的那台,假如两台从机都挂了,主机会同时承担读跟写的任务,等到从机启动后再把更新的数据同步过从机,不影响重启后从机的继续使用
假如是主机挂掉了,两台从机中随机挑选一台来充当主机,承担写的任务,挂掉的主机重启后会充当从机,这个时候我们如果想要把角色切换回来,让之前挂机的主机重新回到主机的位置上,就需要进去管理终端去执行切换主机的命令了,有兴趣的同学可以去试一下。