对web系统来说,瓶颈大多在数据库和磁盘IO上面,而不是服务器的计算能力。对于系统伸缩性我们一般有2种解决方案,scale-up(纵向扩展)和scale-out(横向扩展)。前者如扩内存,增加单机性能,更换ssd等,虽然看似指标不治本而且比较昂贵,但确实是非常有效的,大多数应用的数据规模不是很大,当内存足够缓存下所有数据的时候,磁盘就没有什么压力了;后者譬如各类分布式解决方案,冗余磁盘阵列等。

  在我看来,mysql读写分离是一个scale-up和scale-out的结合体,通过多个机器服务来提升系统吞吐,但并没有增加存储总量。对于一些关键业务是比较适用的,毕竟关键业务的数据量不会达到单机的存储上限。非关键数据可以放到各类缓存系统就行。mysql官方提供了mysql-proxy来做负载均衡(Qihoo360团队的开源项目Atlas看着更为强大,优化了后段连接及lua部分的代码),方便我们统一的调度mysql资源,不用我们在业务层自己来做负载均衡。

  使用Mysql-Proxy还有个好处,可以在proxy上实现统一的udf和memcached等缓存系统对接。此外,mysql-proxy自身可以用heartbeat做热备,因为proxy上无存储数据,所以还可以方便线性扩容。基于mysql主从复制和mysql-proxy我们可以搭建个高可用的数据库集群,构成图如下。

准备工作,三个服务器
192.168.1.107,安装mysql-proxy(依赖libevent)
192.168.1.108,安装mysql-server,作为slave,可多几个slave server,需要在mysql-proxy上添加配置
192.168.1.109,安装mysql-server,作为master
开启mysql-server的远程登录,

  1. mysql> GRANT ALL PRIVILEGES ON *.* TO root@'%' IDENTIFIED BY "rootpwd" WITH GRANT OPTION;
  2. mysql> FLUSH PRIVILEGES;

1, 配置主mysql(192.168.1.109)的配置文件如下,然后重启

  1. server-id = 1 #主数据库id最好为1
  2. log_bin = /var/log/mysql/mysql-bin.log
  3. expire_logs_days = 10
  4. max_binlog_size = 100M
  5. #binlog_do_db = include_database_name
  6. binlog_ignore_db = mysql
  7. binlog_ignore_db = information_schema

增加从数据库权限,多个从服务器需要多次配置(rsyncuser和rsyncowd为用作同步的用户,密码,最好不用root)

  1. mysql> grant replication slave on *.* to rsyncuser@'192.168.1.108' identified by 'rsyncpwd';
  2. mysql> flush privileges;
  3. mysql> show master status;
  4. +------------------+----------+--------------+--------------------------+
  5. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  6. +------------------+----------+--------------+--------------------------+
  7. | mysql-bin.000001 | 333 | | mysql,information_schema |
  8. +------------------+----------+--------------+--------------------------+
  9. 1 row in set (0.00 sec)
  10. mysql> show variables like 'server_id'

2, 配置从mysql(192.168.1.108)的配置文件如下(从数据库id必须比主数据库id大),然后重启

  1. server-id = 2

指向主数据库,开启同步

  1. mysql> change master to master_host='192.168.1.109', master_user='rsyncuser',master_password='rsyncpwd', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos=333;
  2. mysql> show variables like 'server_id'
  3. mysql> start slave
  4. mysql> show slave status;

如果一切正常则主从复制已经搭建好了。(如果start slave不成功,看看server_id是不是生效)

3, 配置proxy(192.168.1.107)如下(多个从服务器需要添加多个--proxy-read-only-backend-addresses参数):

  1. #vi /etc/init.d/mysql-proxy
  2.  
  3. #!/bin/bash
  4. export LUA_PATH="/usr/share/mysql-proxy/?.lua"
  5. mode=$1
  6. if [ -z "$mode" ] ; then
  7. mode="start"
  8. fi
  9. case $mode in
  10. 'start')
  11. mysql-proxy --admin-username=admin --admin-password=adminpwd --daemon --admin-address=:4401 --proxy-address=:3307 --proxy-backend-addresses=192.168.1.109:3306 --proxy-read-only-backend-addresses=192.168.1.108:3306 --admin-lua-script=/usr/share/mysql-proxy/rw-splitting.lua
  12. ;;
  13. 'stop')
  14. killall mysql-proxy
  15. ;;
  16. 'restart')
  17. if $0 stop ; then
  18. $0 start
  19. else
  20. echo "retart failed!!!"
  21. exit 1
  22. fi
  23. ;;
  24. esac

启动proxy服务

service mysql-proxy start

用客户端连接mysql -uroot -p -h192.168.1.107 -P3307 (管理端mysql -uadmin -p -h192.168.1.107 -P4401)

  1. * 原理(Replication
  2. master通过复制机制,将master的写操作通过binlog传到slave生成中继日志(relaylog),slave再将中继日志redo,使得主库和从库的数据保持同步
  3.  
  4. * 3Mysql线程
  5. 1slave上的I/O线程:向master请求数据
  6. 2master上的Binlog Dump线程:读取binlog事件并把数据发送给slaveI/O线程
  7. 3slave上的SQL线程:读取中继日志并执行,更新数据库
  8. 属于slave主动请求拉取的模式
  9.  
  10. * 实际可能遇到的问题
  11. 数据非强一致:CDB默认为异步复制,masterslave的数据会有一定延迟(称为主从同步距离,一般<1s)
  12. 主从同步距离变大:可能是DB写入压力大,也可能是slave机器负载高,网络波动等原因,具体问题具体分析
  13.  
  14. * 监控命令
  15. show processlist :查看Mysql进程信息,包括3个同步线程的当前状态
  16. show master status :查看master配置及当前复制信息
  17. show slave status :查看slave配置及当前复制信息

数据备份与修复也很重要

1、数据备份与恢复,采用xtrabackup;参考http://blog.csdn.net/yongsheng0550/article/details/6682162
2、主从同步一致性检查,采用pt-table-checksum;参考http://www.cnblogs.com/likyzh/archive/2012/11/13/2768783.html
3、主从同步修复,采用pt-table-sync;参考http://blog.csdn.net/lidan3959/article/details/9429069
4、数据误删,快速恢复,采用parse_binlog.pl。参考http://hidba.org/?p=662

附:

Mysql为了安全性,在默认情况下用户只允许在本地登录,有些情况需要进行远程连接,因此为了使其可以远程需要进行如下操作:
一、允许root用户在任何地方进行远程登录,并具有所有库任何操作权限,具体操作如下: 

  1. mysql -uroot -prootpwd
  2. mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY "rootpwd" WITH GRANT OPTION;
  3. mysql> FLUSH PRIVILEGES;

二、允许root用户在一个特定的IP进行远程登录,并具有所有库任何操作权限,具体操作如下:

  1. mysql -uroot -prootpwd
  2. mysql> GRANT ALL PRIVILEGES ON *.* TO root@"192.168.1.107" IDENTIFIED BY "rootpwd" WITH GRANT OPTION;
  3. mysql> FLUSH PRIVILEGES;

三、允许root用户在一个特定的IP进行远程登录,并具有所有库特定操作权限,具体操作如下:

  1. mysql -uroot -prootpwd
  2. mysql> GRANT selectinsertupdatedelete ON *.* TO root@"172.16.16.152" IDENTIFIED BY "rootpwd";
  3. mysql> FLUSH PRIVILEGES;

四、删除用户授权,需要使用REVOKE命令

  1. REVOKE privileges ON 数据库[.表名] FROM user-name;
  2. mysql -uroot -prootpwd 进行授权操作:
  3. GRANT selectinsertupdatedelete ON TEST-DB TO test-user@"192.168.1.107" IDENTIFIED BY "rootpwd";
  4. #再进行删除授权操作:
  5. REVOKE all on TEST-DB from test-user;
  6. #该操作只是清除了用户对于TEST-DB的相关授权权限,但是这个“test-user”这个用户还是存在。
  7. #最后从用户表内清除用户:
  8. DELETE FROM user WHERE user="test-user";
  9. #重载授权表:
  10. FLUSH PRIVILEGES;
  11. #退出mysql数据库:

五、MYSQL权限详细分类:

  1. 全局管理权限:
  2. FILE: MySQL服务器上读写文件。 PROCESS: 显示或杀死属于其它用户的服务线程。 RELOAD: 重载访问控制表,刷新日志等。 SHUTDOWN: 关闭MySQL服务。
  3. 数据库/数据表/数据列权限:
  4. ALTER: 修改已存在的数据表(例如增加/删除列)和索引。 CREATE: 建立新的数据库或数据表。 DELETE: 删除表的记录。 DROP: 删除数据表或数据库。 INDEX: 建立或删除索引。 INSERT: 增加表的记录。 SELECT: 显示/搜索表的记录。 UPDATE: 修改表中已存在的记录。
  5. 特别的权限:
  6. ALL: 允许做任何事(和root一样)。 USAGE: 只允许登录--其它什么也不允许做。

高可用mysql集群搭建的更多相关文章

  1. Hadoop-HA(高可用)集群搭建

    Hadoop-HA集群搭建 一.基础准备工作 1.准备好5台Linux系统虚拟服务器或物理服务器 我这里演示采用虚拟服务器搭建Hadoop-HA集群,各自功能分配如下: NameNode节点:vt-s ...

  2. 高可用k8s集群搭建

    虚拟机选择 Win10 Hyper-V 总体架构 三个master,三个node master的组件 etcd kube-apiserver kube-controller-manager kube- ...

  3. docker swarm使用keepalived+haproxy搭建基于percona-xtradb-cluster方案的高可用mysql集群

    一.部署环境 序号 hostname ip 备注 1 manager107 10.0.3.107 centos7;3.10.0-957.1.3.el7.x86_64 2 worker68 10.0.3 ...

  4. ElasticSearch 高可用分布式集群搭建,与PHP多线程测试

    方案: 使用HAproxy:当其中一台ElasticSearch Master宕掉时,ElasticSearch集群会自动将运行正常的节点提升为Master,但HAproxy不会将失败的请求重新分发到 ...

  5. activeMq-2 高可用以及集群搭建

    Activemq 的集群方法可以有多种实现方式,我们这里使用zookeeper来实现 要搭建集群,请确保已经搭建好zookeeper环境.这里不再演示. 基本原理: 使用ZooKeeper(集群)注册 ...

  6. 4 种高可用 RocketMQ 集群搭建方案!

    背景 笔者所在的业务线,最初化分为三个服务,由于业务初期业务复杂度相对简单,三个业务服务都能很好的独立完成业务功能. 随着产品迭代,业务功能越来越多后慢慢也要面对高并发.业务解耦.分布式事务等问题,所 ...

  7. Haproxy Mysql cluster 高可用Mysql集群

    -----client-----------haproxy---------mysql1----------mysql2------192.168.1.250 192.168.1.1 192.168. ...

  8. Apache tomcat高可用web集群搭建过程配置记录

    说明,本文仅作为个人搭建配置保存,问题处理没有一一列出,过程也未见详尽,有问题的朋友可以直接留言给我,会一一回复,谢谢. 小目标: 支持故障转移(或主备,扩展性不佳),保证故障转移后,对前端用户透明, ...

  9. HA 高可用mysql集群

    注意问题: 1.保持mysql用户和组的ID号是一致的: 2.filesystem 共享存储必须要有写入权限: 3.删除资源必须先删除约束,在删除资源: 1.安装数据库,这里使用maridb数据库: ...

随机推荐

  1. jquery.qrcode二维码插件生成彩色二维码

    jquery.qrcode.js 是居于jquery类库的绘制二维码的插件,用它来实现二维码图形渲染支持canvas和table两种绘图方式. (jquery.qrcode.js 设置显示方式为tab ...

  2. html回车事件

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  3. JS笔记 入门第三

    认识DOM 文档对象模型DOM(Document Object Model)定义访问和处理HTML文档的标准方法.DOM 将HTML文档呈现为带有元素.属性和文本的树结构(节点树) 把上面的代码进行分 ...

  4. C#进程管理程序实现

    运行效果图 部分代码如下: #region 打开应用程序按钮事件处理程序 /// <summary> /// 打开应用程序按钮事件处理程序 /// </summary> /// ...

  5. 文件保护DEP

    文件保护DEP数据执行保护(DEP)引起的电脑故障一例 症状:双击桌面上的“我的电脑”.“我的文档”等,explorer.exe重新起动,反复如此,简单说就是“我的电脑”打不开,一双击桌面上就啥都没有 ...

  6. 一步一步学习SignalR进行实时通信_2_Persistent Connections

    原文:一步一步学习SignalR进行实时通信_2_Persistent Connections 一步一步学习SignalR进行实时通信\_2_Persistent Connections Signal ...

  7. stringstream字符串流

    例题详解 題目:输入的第一行有一个数字 N 代表接下來有 N 行資料,每一行資料里有不固定個數的整數(最多 20 個,每行最大 200 個字元),請你寫一個程式將每行的总和印出來. 輸入: 3 1 2 ...

  8. Android进程的内存管理分析

    尊重原创作者,转载请注明出处: http://blog.csdn.net/gemmem/article/details/8920039 最近在网上看了不少Android内存管理方面的博文,但是文章大多 ...

  9. openGl学习之加入颜色

    OpenGL 支持两种颜色模式:一种是 RGBA模式.一种是 颜色索引模式. 不管哪种颜色模式.计算机都必须为每个像素保存一些数据,即通过每个像素的颜色,来改变总体图形的颜色.不同的是. RGBA 模 ...

  10. SharePoint 2007 (MOSS/WSS) - how to remove "Download a Copy" context menu from a Document Library

    One of my friend and colleague asked me this question. I found it tricky and a good post for my blog ...