1. 개요
이 글을 시작으로 mysql의 다양한 서비스 클러스터를 구축하는 방법을 소개하겠습니다. 일반적인 논의 아이디어는 가장 간단한 MySQL 마스터-슬레이브 솔루션으로 시작하여 이 솔루션의 단점을 보다 복잡한 클러스터 솔루션으로 확장하고 후자가 이러한 단점을 어떻게 개선하는지 소개하는 것입니다.
2. MySQL의 가장 간단한 마스터-슬레이브 방식과 작동 원리
우리가 설명하는 버전은 여전히 현재 프로덕션에서 가장 많이 사용되는 버전 5.6을 기반으로 합니다. 환경 및 일부 기능 버전 5.7과 최신 버전 8.0에는 개선이 있었지만 이는 독자가 기사를 통해 MySQL 클러스터 구축에 대한 기술적 아이디어를 이해하는 능력에 영향을 미치지 않으며 이 메커니즘은 다음으로 확장될 수도 있습니다. 마리아DB. 예를 들어, MySQL과 함께 제공되는 로그 복제 메커니즘(Replicaion 메커니즘)은 곧 언급될 것입니다.
MySQL의 자체 로그 복제 메커니즘을 MySQL-Replicaion이라고 합니다. 복제 기술은 MySQL의 초기 버전 5.1부터 사용 가능했으며 현재 버전에서는 이 기술이 매우 성숙해졌으며 지원 기술자는 다양한 MySQL 클러스터 구조를 만들 수 있습니다. 물론 나중에 타사 소프트웨어/구성 요소가 지원하는 일부 MySQL 클러스터 솔루션도 소개할 예정입니다.
2-1. MySQL-Replicaion의 기본 작동 원리
Replicaion 메커니즘 기술적 관점에서 보면 Master와 Salve의 두 가지 기본 역할이 있습니다. 마스터 노드는 복제 메커니즘에서 하나 이상의 대상에 데이터를 출력하는 역할을 담당하고, Salve 노드는 복제 메커니즘에서 마스터 노드로부터 데이터를 수락하는 역할을 담당합니다. 실제 비즈니스 환경에서 마스터 노드와 Salve 노드는 각각 쓰기 노드와 읽기 노드라는 다른 이름을 갖습니다. - 예, 복제 메커니즘을 사용하면 읽기 및 쓰기 분리를 목표로 하는 MySQL 클러스터 서비스를 구축할 수 있습니다. 그러나 독자들이 기사의 내용을 읽을 때 모호함이 없도록 하기 위해 이 기사(및 후속 기사)에서는 마스터 노드(Master node) 및 살브 노드(Salve node)라는 용어를 사용합니다. 복제 메커니즘은 MySQL 서비스의 바이너리 로그를 사용하여 데이터를 동기화합니다.
위 그림에서 볼 수 있듯이 Salve는 시작 후 마스터 노드와 네트워크 연결을 설정합니다. 마스터 노드의 바이너리 로그가 변경되면 하나 이상의 MySQL Salve 서비스 노드가 네트워크를 통해 이러한 변경 로그를 모니터링합니다. 그런 다음 Salve 노드는 먼저 이러한 변경 사항을 릴레이 로그 파일(Relay Log)에 기록합니다. 이는 예외가 발생할 때 MySQL 서비스가 데이터를 동기화하는 데 실패하는 것을 방지하기 위해 수행됩니다. 이전에 소개된 InnoDB 로그. 릴레이 로그 파일이 기록되면 MySQL Salve 서비스는 이러한 변경 사항을 해당 데이터 테이블에 반영하여 데이터 동기화 프로세스를 완료합니다. 마지막으로 Salve는 Redo 로그 파일의 업데이트 지점(Position)을 업데이트하고 다음 Replicaion 작업을 준비합니다.
이 과정에서 여러 요소를 구성할 수 있습니다. 예를 들어 마스터 노드의 데이터 작업 횟수와 로그 쓰기 횟수의 비율은 sync_binlog 매개변수를 통해 구성할 수 있으며, binlog_format 매개변수를 통해 로그 데이터를 구성할 수 있으며, 시스템이 Salve 노드에서 수신한 로그 데이터 수와 sync_relay_log 매개변수를 통해 릴레이 로그 파일에 기록되는 횟수의 비율을 구성할 수 있습니다. 예제에 사용된 이러한 매개변수와 기타 매개변수는 이 문서의 후속 섹션에서 설명됩니다.
2-2.MySQL 1개의 마스터와 여러 개의 슬레이브 구성 방법
MySQL Replicaion 메커니즘의 기본 작동 방법을 소개한 후 빠르게 마스터 MySQL 클러스터를 구축하겠습니다. 노드와 Salve 노드로 구성됩니다. 독자는 이 1-마스터-1-슬레이브 MySQL 클러스터 솔루션을 1-마스터 및 다중 슬레이브 클러스터 솔루션으로 확장할 수 있습니다.
이 예에서는 버전 5.6을 사용합니다. 물론 버전 5.7의 설치도 비슷합니다. 또한, Linux 운영체제(Centos 5.6/5.7/6.X)에서 MySQL 서비스를 설치하고 기본 설정을 하는 과정은 길이와 글 위치상의 이유로 여기서는 설명하지 않겠습니다. 다음 IP를 사용하여 Linux에 클러스터의 마스터 노드와 Salve 노드를 각각 설치합니다.
MySQL 마스터 서비스: 192.168.61.140
MySQL Salve 서비스: 192.168.61.141
2-2-1. 마스터 서버 설정
먼저 MySQL 마스터 서비스 my.cnf 기본 구성 파일의 정보를 변경해야 합니다. 주요 목적은 바이너리를 활성화하는 것입니다. 마스터 노드의 로그 기능(여기서 언급된 로그는 InnoDB 엔진 로그가 아닙니다).
# my.cnf文件中没有涉及Replicaion机制的配置信息, 就不在这里列出了 ...... # 开启日志 log_bin
# 다음 매개변수는 나중에 설명합니다
sync_binlog=1
binlog_format=mixed
binlog-do-db=qiang
binlog_checksum=CRC32
binlog_cache_size=2M
max_binlog_cache_size=1G
max_binlog_size=100M
# 이 MySQL 서비스 노드에 대해 설정해야 합니다. 클러스터의 고유한 서버 ID 정보
server_id=140
......
在Master节点的设置中,有很多参数可以对日志的生成、存储、传输过程进行控制。具体可以参见MySQL官网中的介绍:http://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html。这里我们主要对以上配置示例中出现的参数进行概要介绍:
sync_binlog:该参数可以设置为1到N的任何值。该参数表示MySQL服务在成功完成多少次不可分割的数据操作后(例如InnoDB引擎下的事务操作),才进行一次二进制日志文件的写入操作。设置成1时,写入日志文件的次数是最频繁的,也会造成一定的I/O性能消耗,但同时这样的设置值也是最安全的。
binlog_format:该参数可以有三种设置值:row、statement和mixed。row代表二进制日志中记录数据表每一行经过写操作后被修改的最终值。各个参与同步的Salve节点,也会参照这个最终值,将自己数据表上的数据进行修改;statement形式是在日志中记录数据操作过程,而非最终的执行结果。各个参与同步的Salve节点会解析这个过程,并形成最终记录;mixed设置值,是以上两种记录方式的混合体,MySQL服务会自动选择当前运行状态下最适合的日志记录方式。
binlog-do-db:该参数用于设置MySQL Master节点上需要进行Replicaion操作的数据库名称。
binlog_checksum:该参数用于设置Master节点和Salve节点在进行日志文件数据同步时,所使用的日志数据校验方式。这个参数是在version 5.6版本开始才支持的新配置功能,默认值就是CRC32。如果MySQL集群中有MySQL 节点使用的是version 5.5或更早的版本,请设置该参数的值为none。
binlog_cache_size:该参数设置Master节点上为每个客户端连接会话(session)所使用的,在事务过程中临时存储日志数据的缓存大小。如果没有使用支持事务的引擎,可以忽略这个值的设置。但是一般来说我们都会使用InnoDB引擎,所以该值最好设置成1M——2M,如果经常会执行较复杂的事务,则可以适当加大为3M——4M。
max_binlog_cache_size:该值表示整个MySQL服务中,能够使用的binlog_cache区域的最大值。该值不以session为单位,而是对全局进行设置。
max_binlog_size : 该参数设置单个binlog文件的最大大小。MySQL服务为了避免binlog日志出错或者Salve同步失败,会在两种情况下创建新的binlog文件:一种情况是MySQL服务重启后,另一种情况是binlog文件的大小达到一个设定的阀值(默认为1GB)。max_binlog_size参数就是设置这个阀值的。
完成my.cnf文件的更改后,重启Linux MySql服务新的配置就生效了。接下来需要在Master节点中设置可供连接的Salve节点信息,包括进行Replicaion同步的用户和密码信息:
# 只用MySQL客户端,都可以进行设置: # 这里我们直接使用root账号进行同步, 但是生产环境下不建议这样使用 > grant replication slave on *.* to root@192.168.61.141 identified by '123456'
# 通过以下命令,可以查看设置完成后的Master节点工作状态
> show master status;
+----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| kp2-bin.000002 | 404 | qiang | | |
+----------------+----------+--------------+------------------+-------------------+
以上master节点状态的描述中,File属性说明了当前二进制日志文件的名称,它的默认位置在Linux操作系统下的var/lib/mysql目录下。Position属性说明了当前已完成日志同步的数据点在日志文件中的位置。Binlog_Do_DB属性是我们之前设置的,需要进行Replicaion操作的数据库名称,Binlog_Ignore_DB属性就是明确忽略的,不需要进行Replicaion操作的数据库名称。
2-2-2、设置Salve服务器
完成MySQL Master服务的配置后,我们来看看Salve节点该如何进行设置。这里我们只演示一个Salve节点的设置,如果您还要在集群中增加新的Salve节点,那么配置过程都是类似的。无非是要注意在Master节点上增加新的Salve节点描述信息。
首先我们还是需要设置Salve节点的my.cnf文件:
# my.cnf文件中没有涉及Replicaion机制的配置信息,就不在这里列出了 ...... # 开启日志 log-bin
sync_relay_log=1
# 必须为这个MySQL服务节点设置一个集群中唯一的server id信息
server_id=140
......
在MySQL官方文档中也详细描述了中继日志的各种控制参数,这里我们只使用了sync_relay_log参数。这个参数说明了Salve节点在成功接受到多少次Master同步日志信息后,才刷入中继日志文件。这个参数可以设置为1到N的任意一个值,当然设置为1的情况下虽然会消耗一些性能,但对于日志数据来说却是最安全的。
Salve的设置相对简单,接下来我们需要在Salve端开启相应的同步功能。主要是指定用于同步的Master服务地址、用户和密码信息:
# 请注意这里设置的用户名和密码信息要和Master上的设置一致 # 另外master log file所指定的文件 名也必须和Master上使用的日志文件名一致 > change master to master_host='192.168.61.140', master_user='root',master_password='123456', master_log_file='kp2-bin.000002',master_log_pos=120;
# 启动Savle同步
> start slave;
# 然后我们就可以使用以下命令查看salve节点的同步状态
> show slave status;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.61.140
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: kp2-bin.000002
Read_Master_Log_Pos: 404
Relay_Log_File: vm2-relay-bin.000002
Relay_Log_Pos: 565
Relay_Master_Log_File: kp2-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
......
Master_Server_Id: 140
Master_UUID: 19632f72-9a90-11e6-82bd-000c290973df
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log;
waiting for the slave I/O thread to update it
Master_Retry_Count: 86400
......
Auto_Position: 0
完成以上过程,一主一从的MySQL集群就配置完成了。
2-3、一主多从方案的使用建议
一主多从的MySQL集群方案,已经可以解决大部分系统结构化数据存储的性能要求。特别是那种数据查询频率/次数远远大于数据写入频率/次数的业务场景,例如电商系统的商品模块、物流系统的车辆/司机信息模块、电信CRM系统的客户信息模块、监控系统中保存的基本日志数据。但是这种架构方案并不能解决所有的问题,而且方案本身有一些明显的问题(后文详细讨论),所以在这里本文需要为各位将要使用类似MySQL集群方案的读者提供一些使用建议。
Master单节点性能应该足够强大,且只负责数据写入操作:一主多从的MySQL集群方式主要针对读密集型业务系统,其主要目标是将MySQL服务的读写压力进行分离。所以Master节点需要集中精力处理业务的写操作请求,这也就意味着业务系统所有的写操作压力都集中到了这一个节点上(write业务操作)。我们暂且不去分析这个现象可能导致的问题(后续内容会提到这种做法的问题),但这至少要求Master节点的性能足够强大。这里的性能不单单指通过MySQL InnoDB引擎提供的各种配置(一般我们使用InnoDB引擎),并结合业务特点所尽可能榨取的性能,最根本的还需要提升Master节点的硬件性能。
使用固态硬盘作为MySQL服务的块存储基础,并使用RAID 10磁盘阵列作为硬件层构建方案——这是生产环境下单个MySQL服务节点的基本组成逻辑,当然读者可以视自己生产环境下的的实际容量和性能要求进行必要的调整:
应使用一个独立的Salve节点作为备用的Master节点,虽然这种方式不可作为异地多活方案的基础但可作为本地高可用方案的实现基础。当然,为了防止由于日志错误导致的备份失败,这个备份的Salve节点也可以采用MySQL Replicaion机制以外的第三方同步机制,例如:Rsync、DRBD。Rsync是笔者在工作实践中经常使用的,进行MySQL数据增量同步的方式,而DRBD的差异块同步方式是互联网上能够找到最多资料的方式:
在后续的文章中,我们还会专门讨论针对Master节点的集群调整方案,并且建议读者如何使用适合系统自身业务的高可用方案。例如使用Keepalived / Heartbeat进行主备Master节点的切换:
复杂的统计查询需要专门的Salve节点进行支持。参与生产环境实时业务处理的任何MySQL服务节点,在这些服务节点上所运行的SQL查询应该尽可能简单,并且需要使用索引对检索进行支持。特别是数据量非常大的数据表,必须保证所有的检索操作都有索引提供支持,否则Table Full Scan的检索过滤方式不但会拖慢检索操作本身,还可能会明显拖慢其它的事务操作。通过MySQL提供的执行计划功能,技术人员能够很方便实现以上的要求。如果您的业务系统存在复杂的业务查询要求,例如周期性的财务流水报表,周期性的业务分组统计报表等,那么您最好专门准备一个(或多个)脱离实时业务的Salve节点,完成这个工作。
3. 솔루션에서 노출된 문제
그러나 이 MySQL 클러스터 솔루션에도 추가 개선이 필요한 문제가 많이 있습니다. 후속 기사에서는 MySQL 클러스터에 여전히 존재하는 다음과 같은 문제에 대해 논의할 것입니다.
상위 계층 시스템이 직면한 문제: MySQL 1-마스터 다중 슬레이브 클러스터에는 여러 서비스 노드가 있습니다. 그러면 상위 계층 비즈니스 시스템이 데이터베이스 작업(쓰기 작업이든 읽기 작업이든)을 수행할 때 이러한 특정 서비스 노드를 명확히 알고 연결해야 할까요? 아시다시피, 상위 수준 비즈니스 시스템이 점점 더 많은 요소를 제어해야 할 때 비즈니스 시스템 개발자에게 필요한 유지 관리 노력은 기하급수적으로 증가합니다.
고가용성 수준의 문제: MySQL 1-마스터-다중 슬레이브 클러스터에는 여러 개의 Salve 노드(비즈니스 속성 읽기)가 있지만 일반적으로 마스터 노드(비즈니스 속성 쓰기)는 하나만 있습니다. 마디). 하나 이상의 Salve 노드가 충돌하는 경우 전체 클러스터에 큰 영향을 미치지 않습니다(그러나 상위 비즈니스 시스템의 특정 하위 시스템에는 영향을 미칠 수 있습니다). MySQL 클러스터의 단점은 마스터 노드가 하나만 있다는 것입니다. 일단 충돌이 발생하면 기본적으로 전체 클러스터가 정상적으로 작동할 수 없습니다. 따라서 우리는 이러한 잠재적인 위험을 변화시킬 수 있는 몇 가지 방법을 생각해야 합니다.