资讯专栏INFORMATION COLUMN

Amazon和Mysql之间的那点事儿

Tamic / 3232人阅读

摘要:摘要本文主要介绍了亚马逊的使用过程中发现的问题以及基于亚马逊实例自己搭建服务器的一些经验。之前公司使用亚马逊的实例,一切都非常好。但是我们架设在亚马逊实例上的服务器为了安全起见都是跨网段的,不支持,实现不了啊。

摘要

本文主要介绍了亚马逊RDS的使用过程中发现的问题以及基于亚马逊EC2实例自己搭建Mysql服务器的一些经验。

初始

公司项目初始,就使用了亚马逊的各项云服务,亚马逊的各项服务真的非常棒,大大简化了公司产品的扩容和运维工作。

之前公司使用亚马逊的EC2实例,一切都非常好。随着业务的扩展,客户需要mysql关系型数据库,为了使用方便,我们选了亚马逊提供的RDS服务,这玩意儿就是那么简单,选个mysql版本,直接就部署好了,什么my.cnf 文件,那是啥?我不关心啊。

开始运行的挺好,各种方便,还能动态制作一个主机的镜像实例,真是简单又省心。

随着用户量的增加,高可用和负载均衡提上了日程。

高可用?很简单啊,亚马逊的RDS高可用跟用户没关系,他自己内部都冗余好了,亚马逊系统自己准备的slave会顶上去的;负载均衡,嗯,这有点麻烦,我找找资料。

深入

亚马逊提供了一个通用的ELB模块,来动态分配访问落到哪台RDS上,但两台RDS的数据一致性怎么解决呢?

mysql社区版本并不提供集群服务,也就是说实际上在很多mysql系统中,并没有官方的负载均衡的解决方案,这就意味着,如果要从系统层面解决,必须使用第三方工具,或者通过用户的应用代码来完成。现在RDS就是提供一个数据库链接,所有系统工具都不能用。

第三方系统工具用不了,那么让用户改代码?这岂不是和我们的目标冲突了?我们的目标就是让用户能够零修改就能使用我们服务。

于是,我们分析了RDS的状况。

优点:

简单易用

自动高可用

定期有snapshot

缺点:

缺乏系统级的数据库管理界面

没有root权限

…(不说了)

缺点的第一和第二两点,足以让我们放弃RDS的应用了。

这难道就是一言不合就开撕?呵呵,并不是,如果亚马逊的RDS能交出root权限,能解决数据同步,读写分离,负载均衡,动态迁移… 。嗯,我们还会是好朋友的 ☺。

弃坑挖新坑

好了言归正传,我们转手搞了3台EC2实例,搭了三个mysql,一主两丛,结构是1常主,一备主,一永从。

这很好理解了,2台做主的,性能比较好,一台永从的,只做数据备份用,按照一定的时间间隔备份数据到S3服务器上。

这里要介绍一个熟悉mysql都会知道的专门搞mysql,扩展mysql的大牛公司:PERCONA。写下这个几个字母的时候,俺的心情是激动的,所以都是大写的。

大家都知道mysql的存储引擎现在主流的有两种MyISAM和INNODB,其中的差别我们不说,只说数据备份,MyISAM的备份很简单,拷贝复制; INNODB的备份就扯了,用mysqldump 命令对数据库进行蹂躏。有时还会偶尔疏忽,漏了个参数,咋办?vi打开sql文件改几十,几百个地方?还是再来重复蹂躏一下,再dump一遍?Oh my god,太痛苦了,想想就是一场噩梦。

一方有难八方支援之一

Percona华丽丽的给出了一份在线热备的工具XtraBackup。这真是mysql admin的居家旅行,XXXX的利器啊,老鸟可以不用在意,小鸟同学们,你们可要好好的掌握这一大杀器啊!

XtraBackup在运行期间,不锁库,不锁库,不锁库。重要的事情说三遍,光这个优势就可以弃用mysqldump了。

还有什么增量备份,差异备份,单库备份恢复等等,犹如瑞士军刀,总有一件适合你。

下面给三条命令:

备份(备份的时候不需要停服务,如果是主库,用户是无感的)

innobackupex --defaults-file=/etc/my.cnf  --user="root" --password="xxxxx" /opt/data/abcd --no-timestamp

注:/opt/data/abcd 是指定数据库备份输出的目录, --no-timestamp让工具不要主动生成时间戳目录

恢复

innobackupex --user=root --default-file=/etc/my.cnf --apply-log  /opt/data/abcd
innobackupex --user=root --default-file=/etc/my.cnf --copy-back  /opt/data/abcd

注1:以上是两条命令

注2:恢复之前,需要停mysql服务,删除mysql的data目录下的所有数据,恢复完之后,需要执行命令chown –R 命令把mysql data目录改为mysql:mysql ,之后启动mysql 服务。

Xtrabackup输出的数据目录会有一个文件,里面记录了bin-log文件的序号和position位置,也就是说,我们在执行Xtrabackup命令进行备份的时候,此时输出的数据,是和此文件序号中的position位置的log记录相匹配的。(如果你搭建过主从,就会明白,否则就会认为我在胡言乱语。)

想要深入了解Xtrabackup是怎么干的,可以去看下[Mysql技术内幕-InnoDB存储引擎]。

有了这个工具,搭建主从不要太方便。

先找台做主服务的EC2,搭个mysql。

装下google的半同步插件(写到这里,不禁想到,RDS不知道是用的是啥,难道是异步同步)

INSTALL PLUGIN rpl_semi_sync_master SONAME "semisync_master.so";
INSTALL PLUGIN rpl_semi_sync_slave SONAME "semisync_slave.so";

把REPLICATION SLAVE和REPLICATION CLIENT都搞上,然后就能用Xtrabackup来一式两份了。

GRANT REPLICATION SLAVE ON *.* to "xxx"@"%" identified by "xxx";
GRANT REPLICATION CLIENT ON *.* to "xxx"@"%" identified by "xxx";

把Xtrabackup输出的目录打个包,scp到两台从机上,恢复并启动mysql服务之后,执行命令:

CHANGE MASTER TO MASTER_HOST="xxx",master_port=3306,master_user="xxx",master_password="xxx",master_log_file="xxx",master_log_pos=xxx;

命令中的xxx各不相同哦,各位谨慎。

master_log_file="xxx",master_log_pos=xxx; 这两个数据可以从xtrabackup_binlog_pos_innodb 文件中获取。

然后在mysql命令行下 show slave statusG; 看下主从复制的情况,就万事OK了!

一方有难八方支援之二

既然搭建了主从,那么MHA也是必须的。

MHA项目地址 https://code.google.com/p/mys...

虽然这个项目许久没有更新,不过历史证明还是蛮可靠的。

我曾经做过一个无负载测试,搞了1600多次,每次都在10-15秒之内顺利切换完成。如果你的服务器能停止mysql服务1600多次,那我还能说什么呢?

MHA一般配合Keepalived 给App提供一个唯一可用的mysql链接ip,一旦MHA脚本检测到mysql 服务中断,可以自己写脚本,中断目标服务器的keepalived服务,这样VIP就漂移到新的服务器上,继续提供服务了。

但是我们架设在亚马逊EC2实例上的mysql服务器为了安全起见都是跨网段的,Keepalived不支持,实现不了啊。还好天无绝人之路,EC2实例提供了辅助私有ip的功能,用AWS命令为主服务器添加一个辅助私有IP,并且把原来的辅助私有IP回收掉,不就可以了吗?

想到就干。

回收:

aws ec2 unassign-private-ip-addresses --network-interface-id xxx --private-ip-addresses $VIP

添加:

aws ec2  assign-private-ip-addresses --network-interface-id xxx --private-ip-addresses $VIP --allow-reassignment

之后我们看下MHA提供的代码:
打开文件master_ip_failover 这是用perl写的(写到这里,又情不自禁的想到了,谁说perl不行了,系统管理处处是perl啊!):

GetOptions(
 "command=s"              => $command,
 "orig_master_host=s"     => $orig_master_host,
 "orig_master_ip=s"       => $orig_master_ip,
 "orig_master_port=i"     => $orig_master_port,
 "orig_master_user=s"     => $orig_master_user,
 "orig_master_password=s" => $orig_master_password,
 "new_master_host=s"      => $new_master_host,
 "new_master_ip=s"        => $new_master_ip,
 "new_master_port=i"      => $new_master_port,
 "new_master_user=s"      => $new_master_user,
 "new_master_password=s"  => $new_master_password,
);

这串代码蛮关键,是上游代码调用该脚本时传进来的参数,这些参数也蛮好理解,望文生意的。通过这些拿到的ip,帐号,就能上服务器去折腾一下,重新分配IP到备主上,这样就能很方便的完成常主->备主的切换了。

再看下MHA的配置脚本:

[server default]
user=xxx
password=xxx
repl_user=xxx
ssh_user=xxx
master_binlog_dir=/opt/mysql
remote_workdir=/var/log/masterha
secondary_check_script= masterha_secondary_check -s x.x.x.x -s x.x.x.x -s x.x.x.x
ping_interval=3
master_ip_failover_script=/mha4mysql/script/master_ip_failover_app1
report_script= /mha4mysql/script/send_report

[server1]
candidate_master=1
hostname=x.x.x.x

[server2]
candidate_master=1
hostname=x.x.x.x

[server3]
no_master=1
hostname=x.x.x.x

需要解释下的包括:

secondary_check_script= masterha_secondary_check -s x.x.x.x -s x.x.x.x -s x.x.x.x 

mha检查机制,内置的,咱不用管,只要接着填写-s 后面的ip就好了,有几个就填几个。

ping_interval=3 

俗语说叫采样间隔,放这儿就叫探测间隔吧。

master_ip_failover_script=/mha4mysql/script/master_ip_failover_app1 

failover时执行的脚本,做一些IP回收,分配啥的,主从强制数据同步,以及最新数据源挑选等在主服务器拒绝服务之后,MHA内置脚本帮我们都搞定了,我们也不要care了。(我们这里不用选,就一个 ☺)

report_script= /mha4mysql/script/send_report 

这个也挺关键,failover之后发送邮件通知,要不数据库少了一个服务,你还不知道,那不是扯淡么。

后台Daemon运行:

nohup masterha_manager --conf=/etc/app1.cnf < /dev/null >> /var/log/masterha/app1.log 2>&1 &

好了,一套可靠的mysql服务就搭好了。

那么各位要说了,MHA搞定了,那负载均衡呢?

呃~ 各位等我喝口水,且听下回分解吧,哈哈!


作者信息
原文作者来自 MaxLeap 团队_Service&Infra 成员:Kevin, 喜欢开发一些小脚本来协助流程建设。
力谱宿云 LeapCloud首发:https://blog.maxleap.cn/archi...

相关阅读
快速部署Test-Driven Development/Debug环境

欢迎大家来请关注我们的微信公众号:MaxLeap_yidongyanfa

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/11766.html

相关文章

  • 我终于搞清楚了String有关那点事儿

    摘要:为了减少在中创建的字符串的数量,字符串类维护了一个字符串常量池。但是当执行了方法后,将指向字符串常量池中的那个字符串常量。由于和都是字符串常量池中的字面量的引用,所以。究其原因,是因为常量池要保存的是已确定的字面量值。 String,是Java中除了基本数据类型以外,最为重要的一个类型了。很多人会认为他比较简单。但是和String有关的面试题有很多,下面我随便找两道面试题,看看你能不能...

    paulli3 评论0 收藏0
  • 【C语言】玩转结构体——结构体那点事儿

    摘要:一结构体的声明与定义结构体的声明结构是一些值的集合,这些值称为成员变量。但是结构体变量的变量名并不是指向该结构体的地址,所以要使用取地址运算符才能获取其地址。因此,结构体传参的时候,要传结构体的地址。 ...

    jeffrey_up 评论0 收藏0
  • 章鱼教你自动生成json数据来测试~

    摘要:如果手动的维护编写格式的数据是很麻烦的,所以推荐生成数据来方便我们进行接口的测试。用真实数据测试将使你的应用程序更加健壮,因为你会有可能发现生产前一天发布的错误。 如果你正在测试一个线上产品,你会想确保你的密切模拟生产环境条件下的测试。在生产中,你将有用户的军队在你的应用程序乒乒乓乓,并用数据填充数据库,这是你的代码压力。更糟的是,你输入的数据将偏向你自己的使用模式,将不符合实际使用,...

    sean 评论0 收藏0
  • 在多主机Docker网络中运行XtraDB Cluster

    摘要:正文以下,我将阐述一下,怎么样在多主机网络中运行。举个例子,当你在主机上运行发现服务的时候,你可以这样启动节点这个节点就会自己把自己注册到发现服务中去,并且加入名为的集群中。 译者前言 Percona 所维护的XtraDB 是mysql的一个分支,使用了性能比innodb更加出色的xtrodb驱动,XtraDB-Cluster产品,是其集群化的方案,方案内容,请自行google。最近X...

    awesome23 评论0 收藏0

发表评论

0条评论

Tamic

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<