- 浏览: 181260 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
freespace:
qiyating0808 写道我也遇到了。请问楼主有解决吗?无 ...
mongodb重启引起数据丢失 -
qiyating0808:
我也遇到了。请问楼主有解决吗?
mongodb重启引起数据丢失 -
真心_1314:
我也遇到了,好纠结。你最后是怎么解决的...
mongodb重启引起数据丢失 -
tinwan:
为何我的也不能压缩?我把解压的文件放在js文件夹下,点击.ba ...
JS批量压缩工具包 -
freespace:
这个随便,用客户端也可以。
Mysql 自增长ID的恢复
来自:http://lmylvmingyue.blog.163.com/blog/static/46601701201141033510225/
当网站越做越大的时候,资料库的 HA (High Available) 就很重要了。业界常用的是 DRBD,上个月我去了北京参加系统架构师大会,中国的网站大部分解决资料库 HA 都是用 DRBD 。
DRBD 简单说就是 RAID 1 over TCP 。也就是透过 TCP 让两台主机的硬碟内容完全一模一样,因此不只是 MySQL 可以使用 DRBD ,只要是任何会需要用到硬碟的 Server ,都可以用 DRBD 来做 HA,加上 MySQL InnoDB Engine 本身的 crash safe ,可以做到当一台主机挂点时,另一台主机可以用一模一样的硬碟内容在最短时间把服务重新跑起来。
DRBD 已经被业界使用了多年,已经算是一个很成熟的架构。2005 年 8 月,LiveJournal 的 Brad Fitzpatrick (也是memcached, MogileFS, Perlbal, Gearman 的作者) ,写了一篇 LiveJournal’s Backend ,里面也有提到 DRBD 。那份文件也成为了很多新兴网站架构时参考的文件,去北京的系统架构师大会时也发现中国的网站架构大部分与 Livejournal 相似,大概也都受到这份文件影响吧。
2006 年,出现了新的 MMM(Mysql Master-Master Replication Manager) 的架构,到现在来说也算是比较新的技术,业界上使用的也不多,上个月去北京参加系统架构师大会时也没有任何一家公司有提到。但是相对 DRBD 起来,我比较喜欢MMM 的架构,所以这篇文章应该也会比较著重於 MMM 的介绍。
MMM 就是在 MySQL 的 Master-Master 加强版。多用一台 Monitor 去监控两台 MySQL 主机,当主机挂点时,会主动让另一台主机变成 Master 。
来画个 DRBD vs MMM 的优缺点比较表格。
DRBD | MMM | |
架构复杂度(1) | (胜) RAID 1 的系统架构可以让两台主机视为一台,架构单纯。加 SLAVE 也很好加。 |
(败) 两台都是 Master ,程式上必需要把 Master/Slave 分开处理。如果需要再加 SLAVE 上来的话,设定也比较复杂,因为 MASTER 是两台机器会跳来跳去。 |
架构复杂度(2) | (胜) IP 至少需要三个,不需要 Monitor 。 |
(败) IP 至少需要四个(两台主机 + Writer IP + Reader IP),还需要一台 Monitor。 |
架构复杂度(3) | (胜) 因为视为一台主机,资料可以随意 INSERT、UPDATE、DELETE |
(败) 另外因为两台 MySQL ,可能会造成一些 Query 使得 Replication Error |
Warn-up | (败) Stand by 的机器平常 MySQL 是没跑起来的状态,当跳机器时可能需要 1 分钟以上的 slow start 时间。 |
(胜) Stand by 的机器平时就是 online 当 reader 的状态,因此跳机器时几乎没有 slow start 时间,对 user 来讲没有断线时间。 |
Replication Delay | (胜) 因为架构上可以视为只有一台主机,因此完全不需要 care replication delay 问题。 |
(败) 平常上线状态算是 Master/Slave 架构,因此需要注意 Replication Delay 问题。 |
Slow Query (Ex: ALTER TABLE) | (败) 架构上相当於只有一台主机,因此做 Slow Query 比较困难。 |
(胜) Master/Slave 的架构,可以把 Slave 先 offline ,做完 ALTER TABLE 后,再让 Slave 跳成 Master ,换成另一台做。 |
机器使用率 | (败) Stand by 的那台主机真的就是 Stand by ,完全没有使用到。 |
(胜) Stand by 的主机还可以当作 Reader ,当一个 Master/Slave 的 slave 用。 |
Split-Brain | (平) 发生机率低,但是发生之后很难不舍弃资料,必须要放弃一边的资料让两边重新同步一次 |
(平) 若 SQL query 设计的不够好,在跳机器时就很容易发生,但是如果发生的话,要修复资料的难度比较低,不过需要工人智慧来做处理。 |
以上是这一年来 PIXNET 使用 DRBD 和 MMM 上大概遇到的状况的比较。
接下来下面再针对以上提到的问题再提出解决问题的方法吧。
1. 架构复杂度:(败的 MMM 的解决方法)
DRBD 不太需要讲了,因为架构上可以把他视为只有一台 MySQL 主机,很单纯没什麼问题需要解决,以下来讲 MMM 的解决法。
在 PIXNET 这边,去年八月改版之后,就没有什麼地方会直接用 PHP 执行 MySQL query 了,我们所有跟资料库有关的存取,都是透过我们自己写的一套 library ,而这套 library 就已经解决了写入会透过 Master , 读取会透过 Slave 的问题。
如果要使用 MMM 或是任何 Master/Master 架构的话,就尽量不要自己写 SQL query 用 mysql_query 的写法,最好是把所有透过 MySQL 的存取的部分用 library 解决,这样子可以保证写入会透过 Master ,读取就全部从 Slave ,如此达到 load balance。但是相对的就会遇到架构比较复杂,也会有 「Replication Delay」 的问题(后面会讲解决法。)
另外在 Query 的架构上,因为 MMM 是两台 Master ,有可能会造成两台 Master 分别 INSERT 而 Primary key 重覆而 Replication Error。 (Ex: 目前 A[Master],B[Slave] 两台机器 max increment id 都是 12345 ,这时候我在 A 机器 INSERT 一笔资料(Auto Increment ID = 12346)之后,这个 Query 还来不及 Repliction 到 B 去,A 机器网路就挂了,於是 B 机器就自动成为 Master ,接下来再有人 INSERT 资料进 B 之后,又出现一笔 ID = 12346 的资料。等到 A 机器复活之后,两台都有了 ID = 12346 的资料,於是就造成 Replication Error 了。
解决方法就是利用 MySQL 的 auto_increment_increment 和 auto_increment_offset 两个设定
auto_increment_increment = 2 让两台机器的 auto incenment 不是每次加一,而是每次加二
然后两台主机一台的 auto_increment_offset 设 0 ,一台设 1 。这样子就会让两台主机的 auto increment id 一台是奇数、一台是偶数,两台主机绝对不会遇到撞到的情况。
另外在 CREATE TABLE 或是 DROP TABLE 时的指令,也要记得下 CREATE TABLE IF EXISTS ,让 Slave 在不存在该 table 时也能正常运作。 UPDATE 的 ON DUPLICATE KEY UPDATE 也要常用。
2. Warm up:
当 DRBD 要跳机器时,因为 stand by 的那台机器等於是重新跑起来一台 MySQL server ,在资料库 loading 比较大时,因为资料库的内容都没有在 memory cache 内,因此可能会需要 1 分钟以上的 slow start 时间(依照 PIXNET 的经验一分钟以内大部分的 Query 都会累积著,此时机器的 IO Usage 也是 100% ,一分钟开始 Query 就会消化完,机器重开两分钟后就可以正常运作了。这边我不知道 DRBD 有什麼解决方法,MMM 的话则是完全没这问题,因为 MMM 的 slave 平常就是 online 状态了。(不过正常来讲也不会有这麼多 Warm up 的状况吧?谁没事会无聊去重开MySQL server ?)
3. Replication delay:
这点算是 MMM 的致命伤吧,因为 MMM 算是 Master/Slave 的架构,因此就会遇到 Replication delay 。使用者在 Master 写入了一笔资料,接下来页面重新整理在 Slave 要抓资料,但是该笔 Master 写入的资料还来不及写入 Slave ,因此在新的页面中使用者就没看到刚刚所写入的资料,让使用者误以为刚刚写入失败。
这边的解决方法有几个。
(1) 使用 memcache : 在写入资料库时,同时也写入 memcache ,然后要读取的时候优先去 memcache 抓,抓不到才会去资料库问,如此一来架构上因为 memcache 做了,效能提升了,也因为 memcache 同一个 ID 只会对应到一台,因此不用 care replication 的问题。
但是此法在 PHP 似乎无用,原因是可能会有 race condition 。
在写入 cache 的流程大部分是这样
a. 取得 cache 资料,存进变数 $cache
b.把要 INSERT 的资料塞进资料库后,再把这资料同时也塞进 $cache 内
c. 把 $cache 写进 cache
但是如果有两个人在几乎同时要写入资料,原先的 a => b => c 的流程
变成 a1 => b1 => c1 和 a2 => b2 => c2 。
因为两者的时间太过接近,可能变成 a1 => a2 => b1 => b2 => c1 => c2 的流程。结果 c2 把 c1 的写入完全覆盖掉,c1 的修改就在 cache 中消失的无影无踪了。
Memcached protocol 在这方面有提供解决方案,叫 cas unique。
单笔 row 只要有修改过,他的 cas unique 一定会修改。
在 get 一笔资料时,他会回传一个 cas unique 给你。
你在 set 资料时,可以同时把 cas unique 也带进去。 如果当你 set 时,server 的 cas unique 等於你所给的数字。表示从你 get 到 set 之间,这资料都没有被任何人改过,那麼你可以放心的 set 进去修改他的值。
如果说这段期间 cas unique 不一样了,那麼你的 set 会失败,表示中间已经被人抢先修改过了,那麼你就必须视情况看该怎麼处理。
set, delete 会需要 cas unique ,如果你用 inc, append, prepend 等指令的话,就可以不用在乎 race condition 问题。
不过可惜的是 PHP 预设的 memcache extension 只支援最基本的 set/get ,没有 cas unique 功能,因此这部分没办法这样解决。
(2) 当资料库有修改时,接下来的几笔 query 要直接从 Master 去要,而不是从 Slave
这 点的话光靠程式写是很困难的。 PIXNET 这边有透过自己写的 library ,有做到当这次的 PHP process 有连到过 master 的话,接下来无论是读写都会从 master 去读写资料。只有在完完全全纯粹是读资料的 process ,才有可能会从 slave 去 query 资料。
不过这种作法并没办法完全解决问题,原因是很多网页的作法是
a. POST 到页面,去资料库写入资料,写入成功后, 302 Redirect 到成功页面
b. 在成功页面 GET 资料。
其中 a 和 b 已经可能是两个完全不同的 PHP process ,因此 a 在 master 写入资料后, b 是在 slave 读资料,还是有可能有因为资料还没从 master replication 到 slave 去而读不到资料的情况。
(3) 使用 MySQL 的 MASTER_POS_WAIT(‘binlog file’, ‘binlog pos’, ['timeout']) function
这 方法并不是一个很乾净的作法, 在 SLAVE 机器上下 SELECT MASTER_POS_WAIT(‘xxx’, ’1234′); 的 MySQL query。他会等到 replication 追到 xxx 这个 replication binlog file 的 1234 的位置他才会 return。如此一来可以作到保证在 slave 的 process 也可以读到刚刚在 master 写入的资料。 但是这作法之所以不乾净是因为写程式的人必须要顾虑到 database 架构,等於是程式和 db 架构的分野不够清楚。而且如果两者的 replication delay 太大,可能会造成 MASTER_POS_WAIT 永无止尽而让呼叫他的 PHP 程式就卡在那边。所以这不算是个好方法。
(4) 把写入和回传资料的部分都用同一个 process 处理。
在 (2) 中提到大部分网页的 a, b 两步骤,写入成功后就用 302 redirect 导到成功页面去。这边改成写入成功后不导页面,而是在process 直接回传成功页面给你。 由於都是同一个页面,因此不会有重新连到 slave 抓资料的问题。资料可以全部都是从 master 抓的。就不会有 Replication Delay 的问题了。
缺点时因为不是用 302 重导的,在 Browser 来讲,这一页还是一个以 POST 所产生的页面,因此 user 可以按 F5 重新整理重送一次 POST 资料,造成 User 有机会可以洗资料。(有时候 User 按 F5 不是恶意的,纯粹只是想要重整资料)
不过现在 AJAX 的技术越来越成熟,如果写入和处理回传资料都是用 AJAX 的话,这个缺点就不存在了,因为在 AJAX 里没有使用者重新整理重送资料的问题。
4. 需要做 Slow Query:
MMM 的架构,是可以在完全不中断服务的情况下做到 ALTER TABLE 这种 slow query。现在是 Master Master 架构,首先先把 web 上所有 read/write 都导到同一台 Master ,让另一台 Master 完全没有量。接下来就在那一台 Master 做出你要的 ALTER TABLE 动作。等到做完 ALTER TABLE 之后,这台 Master 会再自动把另一台这段期间 replication 的资料再抓回来。等到 replication 同步了就大功告成了,再来就是把量都导到这台再重覆同样的动作,就做到了 ALTER TABLE 而且完全不会中断服务。
不过这部分要注意就是在做 ALTER TABLE 的时候,必须要 ALTER TABLE 成不影响上线服务的状态。像是 INT 改成 BIGINT 、增加一组 INDEX KEY 之类的,这些做了之后不会影响到原先的服务。
Split-Brain 和其他杂七杂八的地方就留到第二篇再讲吧。
========================================
ronny 去了在北京办的「2009系统架构师大会」 写的文章:「MySQL 的 DRBD 与 MMM (1)」。
里面有些地方可以补充一下,在不完全能接受 replication delay 的情况下,可以用 Google 提供的SemiSyncReplicationDesign patch,所 有在 master 的新增、更新、删除动作时 (也就是有写入的动作时) 都会等到 master 传给 slave,并且 slave 说 OK 才结束。
=========
Mysql Proxy的延迟问题
读写分离不能回避的问题之一就是延迟,可以考虑Google提供的SemiSyncReplicationDesign补丁。半同步复制机制。http://code.google.com/p/google-mysql-tools/wiki/SemiSyncReplicationDesign
发表评论
-
Mysql获取当前时间戳
2013-06-25 05:10 941unix_timestamp(now()) 和php ... -
Mysql导出查询结果到文件的方法
2013-05-31 13:30 920就是使用into outfile语句,例子如下: s ... -
杀死某个mysql的耗时查询的方法
2013-05-31 13:25 1141杀死某个mysql的耗时查询的方法: 命令行登录mysq ... -
mysql order by 根据 in 的顺序排序
2013-01-18 05:01 840使用关键字field ... IN(4, 5, 3, ... -
MySQL server has gone away
2012-12-17 23:15 703在导入数据的时候,报“MySQL server has gon ... -
延长phpmyadmin登录过期时间的方法
2012-09-20 09:07 2131方法1. phpmyadmin/libraries/c ... -
mysql导出、导入数据
2011-12-20 19:33 878导出: mysqldump -h127.0.0.1 -u ... -
mysql 创建用户
2011-12-06 18:00 9601、查看用户名为user的用户的权限 show gra ... -
如何清除mysql的mysql-bin日志(转载)
2011-10-17 13:53 1540文章来自:http://jk.aiwaly.com/wp ... -
Navicate 9.1.11英文版注册码
2011-07-18 11:27 599NAVD-ULQR-YD73-V3BR -
Mysql 自增长ID的恢复
2011-06-03 15:04 2790truncate table tablename,直接 ... -
Mysql 5.5的配置和以前版本有变化
2011-04-21 15:38 672原来的default-character-set 参数不能用了 ... -
oracle参数说明
2010-10-25 09:02 997oracle参数说明 Oracle ... -
mysql 命令行导入大数据的方法
2010-09-08 11:41 842mysql -hlocalhost -uroot -pxxx ... -
配置高可用性的MySQL服务器负载均衡群集
2008-11-27 10:14 978最近在研究Mysql的群集 ...
相关推荐
DRBD+Mysql实现Mysql高可用
总结来说,搭建DRBD+HEARTBEAT+MYSQL的高可用MySQL集群涉及多个步骤,包括DRBD的安装配置、HEARTBEAT的设置、MySQL的主从复制以及全面的测试验证。通过这样的部署,可以确保数据库服务的连续性和数据的安全性,对于...
根据提供的信息,我们可以详细探讨如何构建一个基于MySQL、DRBD(Distributed Replicated Block Device)、Heartbeat以及Amoeba的高可用性和负载均衡的数据库集群系统。这种集群配置旨在提高系统的稳定性和数据的...
总结来说,"Heartbeat MySQL DRBD构建高可用MySQL方案"是一种结合了软件层面的心跳监控与硬件级别的数据复制的高可用性解决方案。它通过DRBD的实时数据同步和Heartbeat的故障检测及资源管理,实现了MySQL数据库的高...
【Heartbeat DRBD MySQL 高可用方案搭建】 在IT领域,构建高可用系统是保障业务连续性和数据安全的重要措施。本方案将详细讲解如何利用Heartbeat、DRBD和MySQL搭建一个高可用环境,确保数据库服务的稳定运行。 **...
Centos5.6 x86_64 下部署安装 DRBD+Heartbeat+MySQL 服务器平台的实现方法 本文档旨在指导用户在 Centos5.6 x86_64 操作系统下部署安装 DRBD+Heartbeat+MySQL 服务器平台,实现高可用集群环境。通过本文档,用户...
heartbeat+drbd+mysql安装部署
在Heartbeat或DRBD这样的系统中,libnet库可能会被用来创建网络连接,发送心跳包,以及进行网络通信相关的其他操作。 在实际部署中,MySQL+Heartbeat+DRBD的组合通常用于构建高可用性的数据库环境。首先,MySQL的主...
基于Drbd+Corosync+Pacemaker的MYSQL高可用集群部署,原创,通俗易懂.
通过DRBD同步的MySQL数据库以及设置与主库相同的虚拟IP,可以在主库宕机后快速完成数据同步,从而保证业务连续性。 #### 四、系统环境与配置 ##### 4.1 系统环境 - **主服务器(MySQL_M)** - eth0:10.0.0.3...
在本场景中,DRBD 被用于保障 MySQL 数据库服务的连续性,通过创建多个实例来支持不同的数据库需求。 在搭建 DRBD 环境的 MySQL 多实例服务时,首先需要确保 DRBD 环境已经正常运行。这意味着两个节点之间的通信应...
### Heartbeat+DRBD+MySQL高可用架构方案与实施过程细节 #### 互联网公司从初期到后期的数据库架构拓展 随着互联网公司的成长和发展,数据库架构也需要不断地调整和优化以满足不断增长的需求。从最初的单一服务器...
在介绍如何利用Heartbeat和DRBD技术搭建MySQL高可用环境之前,需要先理解相关技术的基础知识以及它们是如何协同工作的。 DRBD(Distributed Replicated Block Device)是一种基于Linux内核的软件,它实现了网络镜像...
Mysql+DRBD+heartbeat配置手册.docx
Mysql+DRBD+heartbeat配置手册.pdf