mysql proxymysql 支持事务务吗

本文系《开发者头条》8 月 17 日好评文章,感谢作者 flike 自荐。欢迎自荐、投稿,采用就送IO币!原文地址:http://toutiao.io/r/52j7r开发者必装的 App,你装了没?http://toutiao.io/downloadkingshard开源有一段时间了,有些热心的用户发邮件来咨询kingshard的设计和实现问题。于是周末抽空写了一篇介绍kingshard架构和功能实现的文章,希望通过本文能够让用户对kingshard有更深的了解。下面分模块来介绍kingshard的核心组件的设计和实现。1. 整体架构kingshard采用Go开发,充分地利用了Go语言的并发特性。Go语言在并发方面,做了很好的封装,这大大简化了kingshard的开发工作。kingshard的整体工作流程入下所述:读取配置文件并启动,在配置文件中设置的监听端口监听客户端请求。收到客户端连接请求后,启动一个goroutine单独处理该请求。首选进行登录验证,验证过程完全兼容MySQL认证协议,由于用户名和密码在配置文件中已经设置好,所以可以利用该信息验证连接请求是否合法。 当用户名和密码都正确时,转入下面的步骤,否则返回出错信息给客户端。认证通过后,客户端发送SQL语句。kingshard对客户端发送过来的SQL语句,进行词法和语义分析,识别出SQL的类型和生成SQL的路由计划。如果有必要还会改写SQL,然后转发到相应的DB。也有可能不做词法和语义分析直接转发到相应的后端DB。如果转发SQL是分表且跨多个DB,则每个DB对应启动一个goroutine发送SQL和接收该DB返回的结果。接收并合并结果,然后转发给客户端。kingshard工作整体流程可参考下面这幅图。 kingshard整体架构图如下所示 2. 词法和语义分析要将kingshard的功能做的足够强大,就不得不进行SQL的词法和语义分析。SQL语句的词法分析指的是将SQL语句切分成一个一个的关键字。例如对SQL语句:select name from stu where id & 13进行词法分析,得到的结果是:{&select&,&name&,&from&,&stu&,&where&,&id&,&&&,&13&}。 这样做的目的主要为了生成一棵抽象语法树,也就是大家常说的AST(abstract syntax tree),语义分析就是基于这棵语法树来操作的。语义分析的目的主要有以下几个方面:读写分离,只有识别出SQL语句的类型,才能进行正确的读写分离操作。数据分片,解析出表名和查询条件,将SQL路由到正确的DB。SQL黑名单,通过词法和语义分析,也可以快速识别出需要屏蔽的SQL语句。例如,检测到delete语句不带where操作,就可以直接阻断该SQL的转发。kingshard并没有考虑完全兼容MySQL所有语法,因为完全兼容MySQL语法会使得词法和语义分析模块变得异常复杂,而且低效。对于DDL语句其实没必要解析,只要能正确转发到后端相应的DB上就可以。kingshard只对部分DML语句(select,update,insert,delete,replace)进行了解析,这样可以满足绝大部分的分表操作。对于其他语句,kingshard会将其发送到一个默认的DB,或者通过kingshard特有的方式将其发送到指定的DB上,例如: /*node2*/insert into stu(id,name) values(12,'xiaoming'),对于这种带有注释的的sql语句,kingshard能够识别出,然后将这条sql语句发送到node2节点的Master DB上。3. 负载均衡用户使用Mysql Proxy目的很大一部分就是为了降低单台DB的负载,将读压力分担到多台DB上。kingshard支持多个slave,不同的slave可以配置不同的读权重,权重越大分担的读请求越多。kingshard读请求负载均衡采用的是权重轮询调度算法。大部分系统采用该算法时,都是转发SQL语句时,动态地计算出本次选取DB的序号。然后将读请求的SQL语句发送到该DB。仔细分析一下,这样做其实是没有必要的。因为DB的权重是相对固定的,不会经常变动,所以完全可以计算出一个固定的轮询序列,然后将这个序列保存在一个数组中。这样不需要动态计算,每次读取数组就可以。举个例子来说,在kingshard的node配置项中配置slave选项: slave:192.168.0.12@2,192.168.0.13@3 kingshard在读取配置信息初始化系统的时候,就生成了一个轮询数组:[0,0,1,1,1]。在kingshard中会将这个数组打乱顺序,变成:[0,1,1,0,1]。这样就避免了动态计算DB下标的问题,对性能提升有一定帮助。4.sharding实现首选需要介绍两个概念:子表,在kingshard中一张逻辑上的大表由若干张小的子表组成。例如:将stu表分成stu_0000,stu_0001,stu_0002,stu_0003。 在数据库中stu表是不存在的,它只是一张逻辑上的表。数据库中只存在四张子表(stu_0000,stu_0001,stu_0002,stu_0003)。 发送SQL语句时,kingshard会识别出需要分表的SQL语句,并改写该SQL。例如,客户端发送过来的SQL语句是:select name from stu where id =10; kingshard收到该SQL语句后,从配置信息中识别出该表是一个Hash类型的分表。根据分表规则,将该SQL改写成:select name from stu_2 where id =10; 然后发送给对应的DB。Node,子表分布在各个node上,每个node包含一个maser server和若干个slave server(slave个数可以为0)。写请求会发往该node中master server,读请求会发往该node中的slave server。kingshard的sharding采用了两级映射的思想,首选根据SQL语句的分表条件计算出这条SQL语句落在哪个子表上,然后再根据配置信息找到该子表 落在哪个node上。采用两级映射的思想,对于MySQL的扩容和缩容都能很方便地支持。目前kingshard sharding支持insert, delete, select, update和replace语句, 所有这五类操作都支持跨子表。但写操作仅支持单node上的跨子表,select操作则可以跨node,跨子表。对于有些表没有分表,操作该表的SQL语句会发往default node。或者用户可以选择在SQL语句前面加上注释,指定该SQL要发往的node,kingshard接收到语句后,识别出注释中指定的node,然后将该SQL发往对应node中合适的DB。例如用户发送/*node1*/select * from member where id=100,kingshard接收到该SQL后会将其发送到node1的salve上。这样kingshard就能很好地兼容分表和不分表的各种应用场景了。5. 事务的实现所有proxy支持shard后都会面临一个问题:支不支持分布式事务?出于性能和可用性考虑, kingshard只支持单台DB上的事务,不允许跨DB的事务。kingshard处理单DB上的事务流程如下:用户发送begin语句。kingshard接收到SQL语句后,将该连接的状态设置为事务。用户发送DML语句,kingshard识别出语句需要发送到的DB,然后kingshard新建一个与后端DB的连接中取一个连接,利用该连接发送语句。收取SQL语句的结果后,将连接放回。kingshard收到下一条SQL语句,判断该SQL是不是发往同一个DB,如果不是则报错。如果是发往同一个DB,则利用该连接发送语句。收到用户发送的commit语句,将该连接的状态设置为非事务,事务结束。6. 后端DB存活检测kingshard每个node启动了一个goroutine用于检测后端master和slave的状态。当goroutine持续一段时间(由配置文件中down_after_noalive参数设置)ping不通后端的DB后,会将该DB的状态设置为down,后续kingshard就不会将sql语句发往该DB了。7. 客户端白名单机制有时候用户为了安全考虑,希望只能某几台server能够连接kingshard。在kingshard的配置文件中有一个参数:allow_ips,用于实现客户端白名单机制。当管理员设置了该参数,则意味着只有allow_ips指定的IP能够连接kingshard,其他IP都会被kingshard拒绝连接。如果不设置该参数,则连接kingshard的客户端不受限制。8. 管理端设计和实现kingshard的管理端口复用了工作端口,通过特定的关键字(admin)来标示。kingshard是通过对管理端特定的SQL进行词法和语义分析,将SQL语句解析为一条kingshard可以识别的命令。目前支持平滑上下线master和slave,和查看kingshard配置和后端DB状态。后续打算将web页面集成到管理端,这样用户就可以不用输入命令行操作,而是在网页上操作。大大降低用户使用kingshard的门槛。上述各个模块都是kingshard中比较核心的模块,通过这篇文章的介绍,我想读者应该对kingshard的架构和实现有了初步的了解。很多功能的设计和实现,都是作者慢慢地摸索和实践。如果有读者对kingshard的设计或实现感兴趣或者对上述设计有不同的想法,欢迎发邮件()给我。(点击阅读原文完整阅读)《开发者头条》应用下载地址(支持 iOS、Android):http://toutiao.io/download开发者头条 - 开发者的首选阅读分享平台http://toutiao.io/【微信号】 kaifazhetoutiao 欢迎关注!developerWorks(developerWorks) 
 文章为作者独立观点,不代表微头条立场
的最新文章
我们的愿景:打造最优秀的互联网研发团队Android & iOS 开发者必知做最专业的质量跟踪平台七牛直播云服务技术详解快来开通独家号、团队号吧!头条不止是阅读,还有分享,更有IO币。可以兑换机械键盘、技术图书喔。精彩不容错过一波干货等着你!以下内容精选自《开发者头条》每日分享,欢迎分享。头条不止是阅读,还有分享,更有IO币!如何分享?说明:长按识先解释下标题吧:好玩 指的是爱好、觉得有趣,玩好 指的是把事情搞定、让事物变得更好。随着各大公司春招的开始,很多小伙伴都行动起来了,我有幸能够加入百度并和大家分享自己的经验心得。早在 2013 年,好友 waterbin 就写过一篇文章,提到了几个话题,亦即:一,OldSQL、NoSQL、NewSQL;二,DevOps;三,数据可视化;四,DBA 还是 DA。文章中的不少观点,现在看来依然不过时。前前后后做的 IM 和推送系统已经有好几个了,一直都想好好总结下,因此就有了这篇文章。CacheCloud 提供一个 Redis 云管理平台:实现多种类型自动部署、解决 Redis 实例碎片化现象、提供完善统计、监控、运维功能、减少开发人员的运维成本和误操作,提高机器的利用率,提供灵活的伸缩性,提供方便的接入客户端。前几天在「移动学习分享群」分享了关于蘑菇街组件化方面的一点经验,由于时间和文字描述方面的限制,很多东西表述的不是很清楚,让一些同学产生了疑惑,casatwy老师也写了篇文章来纠正其中的一些实现,看完之后确实有不少启发。无论是 IM 消息通信系统还是客户消息系统,其本质都是一套消息发送与投递系统,或者说是一套网络通信系统,其本质两个词:存储与转发。分析移动网络延迟较高的原因,并给出相应的优化方案。订阅地址:http://toutiao.io/s/xrig给新手最好的 Vim 升级教程,没有列举所有的命令,只是列举了那些最有用的命令。本文选自《开发者头条》2 月 28 日最受欢迎文章 Top 3,作者 dylanninin ,感谢 _ReyJavaScript 拥有在我见过的所有语言中最好的开发工具生态系统找工作的时候是否经常看到要求有高并发,分布式系统的开发设计经验,或者高并发,分布式系统的开发设计经验者优先等字样,这时候情不自禁的搜索一下什么是并发,多少算高并发,再思索一下自己的经历哪些是符合这个要求的?从互联网开发的半个门外汉,到如今能设计一些架构、排查一些问题、分享一些经验。本教程向读者介绍 Python 语言及其体系的基本知识与概念订阅地址:http://toutiao.io/s/xrig结合自身的经历,谈谈如何才能成为一名优秀的全栈工程师。之前有不少学弟学妹问我如何学习编程,根据 DRY 法则,还是把自己学习过程中的一些经验整理成一篇博客吧。多种多样的工作流使得在项目中实施 Git 时变得难以选择。这份教程提供了一个出发点,调查企业团队最常见的 Git 工作流。每周一期,欢迎订阅。订阅地址:http://toutiao.io/s/xrig本文将告诉大家如何把我们已经熟悉的 Sublime Text 技巧应用到另一个强大的工具 Chrome DevTools 上。Pray for Paris!第三届中国移动开发者大会·MDCon2015将于日(周六)在上海浦软大厦召开,这是针对移Android 版 v2.0.1 已发布,iOS 版已提交审核。程序员必装的 App,你装了吗?《开发者头条》v2.0 Web & iOS & Android 版正式发布!19 号,也就是下周一,《开发者头条》会正式发布 2.0 版。首度发声,满足你的好奇心。本文系《开发者头条》9 月 6 日好评文章,感谢作者 flike 自荐。欢迎自荐、投稿,采用就送IO币!原文开发者必装的 App,你装了没?http://toutiao.io/download本文系《开发者头条》8 月 31 日好评文章,感谢作者 atleeon 自荐。欢迎自荐、投稿,采用就送IO币本文系《开发者头条》8 月 28 日好评文章,感谢作者 Bruce Dou 自荐。欢迎自荐、投稿,采用就送IdeveloperWorks我们的产品:《码农周刊》 http://manong.io/ 、《开发者头条》 http://toutiao.io/热门文章最新文章developerWorks我们的产品:《码农周刊》 http://manong.io/ 、《开发者头条》 http://toutiao.io/MySQLProxy简介
MySQL Native Driver简称mysqlnd,作为libmysqlclient替代品于PHP5.3.0版本引入。之前,MySQL数据库扩展mysql,mysqli,PDO MYSQL都是通过libmysqlclient实现与MySQL Server的通信。引入mysqlnd,这三个扩展都可以通过mysqlnd实现与MySQL Server的通信。
其较libmysqlclient的通信原理对比如下图:
mysqlnd更容易编译;因为它是php树的一个组成部分;而基于libmysqlclient编译,意味着需要在本地安装MySQL;
mysqlnd和php内部机制结合更紧密,是优化过的mysql驱动;
mysqlnd更节省内存,从测试结果来看,比传统的mysql扩展节省40%的内存;
mysqlnd更快;
mysqlnd提供了丰富的性能统计功能;
mysqlnd通过MySQL Native Driver Plugin API特性来充当MySQL Proxy,实现负载均衡,监控和性能优化
mysqlnd使用了 license以避免不必要的版权纠纷;
./configure --prefix=/usr/local/php-5.3.29-production --with-=mysqlnd --with-mysqli=mysqlnd --with-openssl --with-pdo-mysql=mysqlnd --enable-fpm --enable-mysqlnd
make && make install
[root@/usr/local]# /usr/local/php-5.3.29-production/bin/php -ini|grep mysqlnd
Configure Command =&
'./configure'
'--prefix=/usr/local/php-5.3.29-production' '--with-pear' '--with-iconv=/usr/local/' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-openssl' '--with-libxml-dir' '--with-curl' '--with-pdo-mysql=mysqlnd' '--disable-fileinfo' '--enable-fpm' '--enable-mysqlnd' '--with-mcrypt' '--enable-mbstring'
Client API version =& mysqlnd 5.0.8-dev -
- $Id: 731e5b87ba995d2dfd8b4e40b325 $
Client API library version =& mysqlnd 5.0.8-dev -
- $Id: 731e5b87ba995d2dfd8b4e40b325 $
mysqlnd =& enabled
Version =& mysqlnd 5.0.8-dev -
- $Id: 731e5b87ba995d2dfd8b4e40b325 $
Client API version =& mysqlnd 5.0.8-dev -
- $Id: 731e5b87ba995d2dfd8b4e40b325 $
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'对于数据库主从及分表,你们是更乐意在代码层面来做还是直接使用中间件,比如 mysql-proxy? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
Sponsored by
国内领先的实时后端云野狗 API 可用于开发即时聊天、网络游戏、实时定位等实时场景传输快!响应快!入门快!
Promoted by
对于数据库主从及分表,你们是更乐意在代码层面来做还是直接使用中间件,比如 mysql-proxy?
08:27:15 +08:00 · 1921 次点击
不考虑dz这样的(不是做产品往外卖,自己运营层面的)
14 回复 &| &直到
09:39:23 +08:00
& & 09:03:26 +08:00
代码层面,为了满足一些特殊的需要,比如多实例。
& & 09:11:41 +08:00
我们换成了MongoDB,之后用Sharding。
& & 09:51:05 +08:00
@ MongoDB感觉是用着挺舒服的,和nodejs搭配起来更是非常方便
& & 09:53:05 +08:00
@ 多实例?强制指定连接某台服务器而不是随机抽取slave或master?
& & 09:53:25 +08:00
@ 的确,mongodb的话,自身已经做了类似mysql-proxy的很多工作了
& & 10:27:56 +08:00
刚开始基本都是在代码层面来做吧
& & 11:00:51 +08:00 via Android
@ mongo似乎没有锁和事务?那一些常见问题是怎么处理的呢?
& & 11:06:37 +08:00
mongo有锁,只是你不能mongo.lock()
mongo的确不支持事务,如果需要使用mongodb还需要事务,建议你看一下Tokumx
& & 12:46:58 +08:00
开始都是代码层面上做吧,简单shard之类的。
公司的业务做到后面一般会使用proxy,因为写业务逻辑的人可能根本不知道分表逻辑。
对他们屏蔽底层细节,降低耦合。
个人项目的话,无所谓吧。
& & 14:47:08 +08:00
@ 开发测试环境是内网linux,已经装有atlas了,所以一开始就是中间件的开发环境,分表什么的配置都在中间件中配置,感觉还ok。
mysql实时同步有什么好的建议?mysql replication异步容易延迟。
& & 16:32:06 +08:00
mysql同步机制决定了几乎不存在&实时&同步
数据写入master,master生成bin-log,slave读取bin-log,slave执行bin-log
每一个都可能产生很高的延迟...
& & 16:56:34 +08:00
容易延迟是肯定的,还是要看延迟的原因,如果确定是由于写入量过大导致的(因为master可以多线程写,slave却只能单线程同步),可以考虑使用多线程的同步工具,记得淘宝的mysql组有过成熟的解决方案。
当然延迟也有可能是网络延迟导致的,或者slave机器配置很差或者负载过高。不同原因不同解决思路。
& & 18:29:22 +08:00
@ MongoDB上没有事务。锁倒是有的,应该是隐含的,比如$set,$inc之类的并发锁。
所有“事务”性质的请求都可以拆分成“非事务”的,只是清理垃圾数据的时候得自己来,呵呵。
& & 09:39:23 +08:00
@ 同步方面,其中一个就是采用/*master*/开头把语句导向主库,另外一个就是先放到缓存里 读的时候先读缓存
& · & 1701 人在线 & 最高记录 2011 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.3 · 57ms · UTC 06:53 · PVG 14:53 · LAX 23:53 · JFK 02:53? Do have faith in what you're doing.MySQL Proxy的安装及基本命令使用教程
Proxy最壮大的一项功能是告终“读写离别(Read/Write Splitting)”。它的原理是让主数据库处理事务性查询,而从数据库处理SELECT查询。数据库复制被用来把事务性查询导致的改变同步到集群中的从数据库。
0.必备软件:
能够去LUA的官方下载:dpa.nsysu.edu.tw/Downloads/MySQL-Proxy/。
可能去MYSQL官方下载源代码。
我这里下载了:
mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.6.0.tar.gz
3、测验过程中废止了B和C的REPLICATION。这么SQL语句一下子就看出来从哪里来的。
万一是M-S(能够先在SLAVE上举行STOP SLAVE)
下载已经编译好的安装包,或者预编译安装包均可,在这里,使用预编译版本。
[@ ~]# tar zxf mysql-proxy-0.6.0-linux-rhas4-x86.tar.gz
[@ ~]# cd mysql-proxy-0.6.0-linux-rhas4-x86
#可以看到有2个目录
[@ mysql-proxy-0.6.0-linux-rhas4-x86]# ls
sbin share
[@ mysql-proxy-0.6.0-linux-rhas4-x86]# mv sbin/mysql-proxy /usr/local/sbin/
[@ mysql-proxy-0.6.0-linux-rhas4-x86]# ls share
mysql-proxy
tutorial-constants.lua tutorial-packets.lua
tutorial-rewrite.lua tutorial-warnings.lua
tutorial-basic.lua tutorial-inject.lua
tutorial-query-time.lua tutorial-states.lua
#将lua脚本放到/usr/local/share下,以备他用
[@ mysql-proxy-0.6.0-linux-rhas4-x86]# mv share/mysql-proxy /usr/local/share/
#删除符号连接等垃圾代码
[@ mysql-proxy-0.6.0-linux-rhas4-x86]# strip /usr/local/sbin/mysql-proxy
编译一下启动管理脚本:
[@ ~]# vi /etc/init.d/mysql-proxy
export LUA_PATH=/usr/local/share/mysql-proxy/?.lua
if [ -z "$mode" ] ; then
mode="start"
case $mode in
mysql-proxy --daemon \
--admin-address=:4401 \
--proxy-address=:3307 \
--proxy-backend-addresses=:3306 \
--proxy-read-only-backend-addresses=192.168.133.232:3306 \
--proxy-read-only-backend-addresses=10.10.74.61:3306 \
--proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua
killall mysql-proxy
'restart')
if $0 then
echo "retart failed!!!"
现在解释一下启动脚本:
--daemon 采用daemon方式启动
--admin-address=:4401 指定mysql proxy的管理端口,在这里,表示本机的4401端口
--proxy-address=:3307 指定mysql proxy的监听端口,也可以用 127.0.0.1:3307 表示
--proxy-backend-addresses=:3306 指定mysql主机的端口
--proxy-read-only-backend-addresses=192.168.1.1:3306 指定只读的mysql主机端口
--proxy-read-only-backend-addresses=192.168.1.2:3306 指定另一个只读的mysql主机端口
--proxy-lua-script=/usr/local/share/mysql-proxy/rw-splitting.lua 指定lua脚本,在这里,使用的是rw-splitting脚本,用于读写分离
完整的参数可以运行以下命令查看:
mysql-proxy --help-all
运行以下命令启动/停止/重启mysql proxy:
[@ ~]# /etc/init.d/mysql-proxy start
[@ ~]# /etc/init.d/mysql-proxy stop
[@ ~]# /etc/init.d/mysql-proxy restart
[@ ~]# mysql -h127.0.0.1 -uroot -P3307
+-------+------+----------------+------+---------+------+-------+------------------+
| User | Host
| Command | Time | State | Info
+-------+------+----------------+------+---------+------+-------+------------------+
| 30052 | root | localhost:9656 | NULL | Query
0 | NULL | show processlist |
+-------+------+----------------+------+---------+------+-------+------------------+
可以看到,产生了一个新连接。
用sysbench测试一下,看会不会挂掉:
[@ ~]# sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=1000000 \
--mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=test prepare
[@ ~]# sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=1000000 \
--mysql-socket=/tmp/mysql.sock --mysql-user=root --mysql-db=test run
Threads fairness:
events (avg/stddev):
execution time (avg/stddev):
还好,没给大家丢脸,剩下的测试自己完成吧 :)
mysql proxy还可以实现连接池的功能,这在很多LAMP开发中是软肋,因此,有了mysql proxy,就可以不用再担心连接数超限的问题了。
如果使用rw-splitting.lua脚本的话,最好修改以下2个参数的默认值:
min_idle_connections = 1
max_idle_connections = 3
顶一下(0) 踩一下(0)
热门标签:文章来自整理:/94606/其中Amoeba for MySQL也是实现读写分离
环境描述:操作系统:CentOS6.5 32位主服务器Master:192.168.179.146从服务器Slave:192.168.179.147调度服务器MySQL-Proxy:192.168.179.142由于电脑配置不行,安装了三台虚拟机,就卡死了,只能将就一下,由于是一主一从,所以,导致读写都在master上,有机会,再弄两台slave来测试一.mysql主从复制,参考:/lin3615/p/5679828.html
二、mysql-proxy实现读写分离1、安装mysql-proxy实现读写分离是有lua脚本实现的,现在mysql-proxy里面已经集成,无需再安装
下载:/downloads/mysql-proxy/ 一定要下载对应的版本
tar zxvf mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit.tar.gz
mv mysql-proxy-0.8.5-linux-glibc2.3-x86-32bit /usr/local/mysql-proxy
2、配置mysql-proxy,创建主配置文件
cd /usr/local/mysql-proxy
mkdir lua #创建脚本存放目录
mkdir logs #创建日志目录
cp share/doc/mysql-proxy/rw-splitting.lua ./lua #复制读写分离配置文件
cp share/doc/mysql-proxy/admin-sql.lua ./lua #复制管理脚本
vi /etc/mysql-f
#创建配置文件
[mysql-proxy]
user=root #运行mysql-proxy用户
admin-username=lin3615 #主从mysql共有的用户
admin-password=123456 #用户的密码
proxy-address=192.168.179.142:4040 #mysql-proxy运行ip和端口,不加端口,默认4040
proxy-read-only-backend-addresses=192.168.179.147 #指定后端从slave读取数据
proxy-backend-addresses=192.168.179.146 #指定后端主master写入数据
proxy-lua-script=/usr/local/mysql-proxy/lua/rw-splitting.lua #指定读写分离配置文件位置
admin-lua-script=/usr/local/mysql-proxy/lua/admin-sql.lua #指定管理脚本
log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log #日志位置
log-level=info #定义log日志级别,由高到低分别有(error|warning|info|message|debug)
daemon=true
#以守护进程方式运行
keepalive=true #mysql-proxy崩溃时,尝试重启
#保存退出!
chmod 660 /etc/f
3、修改读写分离配置文件
vim /usr/local/mysql-proxy/lua/rw-splitting.lua
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 1, #默认超过4个连接数时,才开始读写分离,改为1
max_idle_connections = 1, #默认8,改为1
is_debug = false
4、启动mysql-proxy
/usr/local/mysql-proxy/bin/mysql-proxy --defaults-file=/etc/mysql-f
netstat -tupln | grep 4000 #已经启动
killall -9 mysql-proxy #关闭mysql-proxy使用
5、测试读写分离(1).在主服务器创建proxy用户用于mysql-proxy使用,从服务器也会同步这个操作
mysql& grant all on *.* to 'lin3615'@'192.168.179.142' identified by '123456';
(2).使用客户端连接mysql-proxy
mysql -u lin3615 -h 192.168.179.142 -P 4040 -p123456
接下来就按基本的 curd执行即可,由于只有一台slave,测试时,每次读写都是从master,电脑性能无法开四台虚拟机,所以有机会,再测试多台 slave,看下是否OK
读写分离,延迟是个大问题
在slave服务器上执行 show slave status,可以看到很多同步的参数,要注意的参数有:Master_Log_File:slave中的I/O线程当前正在读取的master服务器二进制式日志文件名.Read_Master_Log_Pos:在当前的 master服务器二进制日志中,slave中的I/O线程已经读取的位置Relay_Log_File:SQL线程当前正在读取与执行中继日志文件的名称Relay_Log_Pos:在当前的中继日志中,SQL线程已读取和执行的位置Relay_Master_Log_File:由SQL线程执行的包含多数近期事件的master二进制日志文件的名称Slave_IO_Running:I/O线程是否被启动并成功连接到masterSlave_SQL_Running:SQL线程是否被启动Seconds_Behind_Master:slave服务器SQL线程和从服务器I/O线程之间的差距,单位为秒计
slave同步延迟情况出现:1.Seconds_Behind_Master不为了,这个值可能会很大2.Relay_Master_Log_File和Master_Log_File显示bin-log的编号相差很大,说明bin-log在slave上没有及时同步,所以近期执行的 bin-log和当前I/O线程所读的 bin-log相差很大3.mysql的 slave数据库目录下存在大量的 mysql-relay-log日志,该日志同步完成之后就会被系统自动删除,存在大量日志,说明主从同步延迟很厉害
mysql主从同步延迟原理mysql主从同步原理主库针对读写操作,顺序写 binlog,从库单线程去主库读"写操作的binlog",从库取到 binlog在本地原样执行(随机写),来保证主从数据逻辑上一致.mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生 binlog,binlog是顺序写,所以效率很高,slave的Slave_IO_Running线程到主库取日志,效率比较高,下一步问题来了,slave的 slave_sql_running线程将主库的 DDL和DML操作在 slave实施。DML,DDL的IO操作是随即的,不能顺序的,成本高很多,还有可能slave上的其他查询产生 lock,由于 slave_sql_running也是单线程的,所以 一个 DDL卡住了,需求需求执行一段时间,那么所有之后的DDL会等待这个 DDL执行完才会继续执行,这就导致了延迟.由于master可以并发,Slave_sql_running线程却不可以,所以主库执行 DDL需求一段时间,在slave执行相同的DDL时,就产生了延迟.
主从同步延迟产生原因当主库的TPS并发较高时,产生的DDL数量超过Slave一个 sql线程所能承受的范围,那么延迟就产生了,当然还有就是可能与 slave的大型 query语句产生了锁等待首要原因:数据库在业务上读写压力太大,CPU计算负荷大,网卡负荷大,硬盘随机IO太高次要原因:读写 binlog带来的性能影响,网络传输延迟主从同步延迟解决方案架构方面1.业务的持久化层的实现采用分库架构,mysql服务可平行扩展分散压力2.单个库读写分离,一主多从,主写从读,分散压力。3.服务的基础架构在业务和mysql之间加放 cache层4.不同业务的mysql放在不同的机器5.使用比主加更了的硬件设备作slave反正就是mysql压力变小,延迟自然会变小
硬件方面:采用好的服务器
mysql主从同步加速1、sync_binlog在slave端设置为02、&logs-slave-updates 从服务器从主服务器接收到的更新不记入它的二进制日志。3、直接禁用slave端的binlog4、slave端,如果使用的存储引擎是innodb,innodb_flush_log_at_trx_commit =2
从文件系统本身属性角度优化master端修改linux、Unix文件系统中文件的etime属性, 由于每当读文件时OS都会将读取操作发生的时间回写到磁盘上,对于读操作频繁的数据库文件来说这是没必要的,只会增加磁盘系统的负担影响I/O性能。可以通过设置文件系统的mount属性,组织操作系统写atime信息,在linux上的操作为:打开/etc/fstab,加上noatime参数/dev/sdb1 /data reiserfs noatime 1 2然后重新mount文件系统#mount -oremount /data
主库是写,对数据安全性较高,比如sync_binlog=1,innodb_flush_log_at_trx_commit = 1 之类的设置是需要的而slave则不需要这么高的数据安全,完全可以讲sync_binlog设置为0或者关闭binlog,innodb_flushlog也可以设置为0来提高sql的执行效率1、sync_binlog=1 oMySQL提供一个sync_binlog参数来控制数据库的binlog刷到磁盘上去。默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。如果sync_binlog&0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,同样很大的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过高对IO的影响也非常大。对于高并发事务的系统来说,&sync_binlog&设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。所以很多MySQL DBA设置的sync_binlog并不是最安全的1,而是2或者是0。这样牺牲一定的一致性,可以获得更高的并发和性能。默认情况下,并不是每次写入时都将binlog与硬盘同步。因此如果操作系统或机器(不仅仅是MySQL服务器)崩溃,有可能binlog中最后的语句丢失了。要想防止这种情况,你可以使用sync_binlog全局变量(1是最安全的值,但也是最慢的),使binlog在每N次binlog写入后与硬盘同步。即使sync_binlog设置为1,出现崩溃时,也有可能表内容和binlog内容之间存在不一致性。
2、innodb_flush_log_at_trx_commit (这个很管用)抱怨Innodb比MyISAM慢 100倍?那么你大概是忘了调整这个值。默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬 盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统 挂了时才可能丢数据。
3、ls(1) 命令可用来列出文件的 atime、ctime 和 mtime。atime 文件的access time 在读取文件或者执行文件时更改的ctime 文件的create time 在写入文件,更改所有者,权限或链接设置时随inode的内容更改而更改mtime 文件的modified time 在写入文件时随文件内容的更改而更改ls -lc filename 列出文件的 ctimels -lu filename 列出文件的 atimels -l filename 列出文件的 mtimestat filename 列出atime,mtime,ctimeatime不一定在访问文件之后被修改因为:使用ext3文件系统的时候,如果在mount的时候使用了noatime参数那么就不会更新atime信息。这三个time stamp都放在 inode 中.如果mtime,atime 修改,inode 就一定会改, 既然 inode 改了,那ctime也就跟着改了.之所以在 mount option 中使用 noatime, 就是不想file system 做太多的修改, 而改善读取效能
4.进行分库分表处理,这样减少数据量的复制同步操作
阅读(...) 评论()

我要回帖

更多关于 mysql proxy 事务支持 的文章

 

随机推荐