이 기사에서는 마스터-슬레이브 지연이 무엇인지, 마스터-슬레이브 지연의 소스 및 마스터-슬레이브 지연 솔루션을 포함하여 마스터-슬레이브 지연 솔루션과 관련된 문제를 주로 정리하는 mysql에 대한 관련 지식을 제공합니다. 아래 내용을 살펴보시고 모든 분들께 도움이 되었으면 좋겠습니다.
추천 학습: mysql 동영상 튜토리얼
이전 프로젝트에서는 MySQL 마스터-슬레이브 복제 및 AOP를 기반으로 읽기-쓰기 분리를 구현했으며, 이 구현 과정을 기록하기 위해 블로그에도 작성했습니다. MySQL 마스터-슬레이브 복제가 구성되어 있기 때문에 자연스럽게 마스터-슬레이브 지연이 발생하게 되는데, 마스터-슬레이브 지연이 애플리케이션 시스템에 미치는 영향을 최소화하는 방법은 개인적으로 마스터-슬레이브 지연에 대한 솔루션이 필요하다고 생각합니다. MySQL 마스터-슬레이브 복제의 핵심인 읽기 쓰기 분리를 구현합니다.
이 주제에 관해서는 사실 예전부터 블로그에 글을 써서 공유할까 생각도 해봤는데 한번도 안건에 올리지 못했습니다. 최근 "SpringBoot에서 MySQL 읽기-쓰기 분리를 구현합니다"에서 한 독자가 이 질문을 묻는 메시지를 남겼고, 이는 나에게도 이 글을 쓰게 된 계기가 되었습니다. 이 문제에 관해서 저는 많은 정보와 블로그를 읽었고, 저만의 실천을 통해 사장님의 어깨 위에 서서 이 블로그를 정리했습니다.
마스터-슬레이브 지연을 해결하는 방법을 논의하기 전에 먼저 마스터-슬레이브 지연이 무엇인지 이해하겠습니다.
마스터-슬레이브 복제를 완료하려면 슬레이브 라이브러리는 I/O 스레드를 통해 마스터 라이브러리의 덤프 스레드가 읽은 binlog 콘텐츠를 가져와 자체 릴레이 로그에 기록한 다음 SQL 스레드를 작성해야 합니다. 슬레이브 라이브러리는 릴레이 로그를 읽고, 릴레이 로그에서 로그를 다시 실행하는 것은 SQL을 다시 실행하고 자신의 데이터베이스를 업데이트하여 데이터 일관성을 달성하는 것과 같습니다.
데이터 동기화와 관련된 시점은 주로 다음 세 가지를 포함합니다.
소위 마스터-슬레이브 지연은 동일한 트랜잭션에 대해 슬레이브 라이브러리의 실행이 완료되는 시간과 메인 라이브러리의 실행이 완료되는 시간의 차이를 말하는데, 바로 T3 - T1
. T3 - T1
。
可以在备库上执行 show slave status
命令,它的返回结果里面会显示 seconds_behind_master
,用于表示当前备库延迟了多少秒。seconds_behind_master
的计算方法是这样的:
seconds_behind_master
。在网络正常的时候,日志从主库传给从库所需的时间是很短的,即 T2 - T1
的值是非常小的。也就是说,网络正常情况下,主从延迟的主要来源是从库接收完 binlog 和执行完这个事务之间的时间差。
由于主从延迟的存在,我们可能会发现,数据刚写入主库,结果却查不到,因为可能还未同步到从库。主从延迟越严重,该问题也愈加明显。
主库和从库在执行同一个事务的时候出现时间差的问题,主要原因包括但不限于以下几种情况:
解决主从延迟主要有以下方案:
seconds_behind_master
showslave status
명령을 실행할 수 있으며, 그 반환 결과는 현재 대기 데이터베이스가 몇 초인지 나타내는 데 사용되는 seconds_behind_master
를 표시합니다. 지연. seconds_behind_master
는 다음과 같이 계산됩니다. seconds_behind_master
를 구합니다. 네트워크가 정상일 때는 마스터 데이터베이스에서 슬레이브 데이터베이스로 로그를 전송하는 데 필요한 시간이 매우 짧습니다. 즉, T2 - T1
값이 매우 작습니다. 즉, 정상적인 네트워크 조건에서 마스터-슬레이브 지연의 주요 원인은 binlog를 수신하는 슬레이브 라이브러리와 트랜잭션을 실행하는 사이의 시간 차이입니다. 마스터-슬레이브 지연의 존재로 인해 데이터가 방금 마스터 데이터베이스에 기록되었지만 아직 슬레이브 데이터베이스에 동기화되지 않았기 때문에 결과를 찾을 수 없다는 것을 알 수 있습니다. 마스터-슬레이브 지연이 심각할수록 이 문제는 더욱 분명해집니다.
Under 일부 배포 조건,
슬레이브 라이브러리 머신의 성능이 기본 데이터베이스의 성능보다 나쁩니다🎜. 🎜🎜🎜슬레이브 데이터베이스에 더 큰 압박이 가해지고 있습니다🎜. 즉, 슬레이브 데이터베이스에 많은 요청이 가해집니다. 🎜🎜🎜큰일을 실행하세요🎜. 기본 데이터베이스는 트랜잭션 실행이 완료될 때까지 기다렸다가 binlog에 기록한 다음 대기 데이터베이스로 전달해야 하기 때문입니다. 마스터 데이터베이스에서 명령문을 실행하는 데 10분이 걸리는 경우 이 트랜잭션으로 인해 슬레이브 데이터베이스에서 10분 지연이 발생할 수 있습니다. 🎜🎜🎜라이브러리의 병렬 복사 기능🎜. 🎜seconds_behind_master code> 매개변수가 이미 0, 비교점임) 🎜🎜🎜병렬 복제🎜 - 라이브러리에서 복사 지연 문제를 해결합니다. 🎜여기에서는 제가 프로젝트에서 사용하는 몇 가지 솔루션, 즉 🎜반동기 복제, 실시간 작업으로 인해 메인 라이브러리를 강제로 사용, 병렬 복제🎜를 주로 소개합니다. 🎜🎜🎜반동기 반동기 복제🎜🎜🎜MySQL에는 세 가지 동기화 모드가 있습니다. 즉: 🎜<p><strong>"비동기 복제"</strong>: MySQL의 기본 복제는 비동기식입니다. 메인 라이브러리는 클라이언트가 제출한 트랜잭션을 실행한 후 즉시 결과를 클라이언트에 반환하며 슬레이브 라이브러리가 이를 수신하고 처리했는지 여부는 신경 쓰지 않습니다. 이로 인해 메인 데이터베이스가 다운되면 네트워크상의 이유로 인해 메인 데이터베이스에 제출된 트랜잭션이 슬레이브 데이터베이스로 전송되지 않을 수 있습니다. 마스터에 연결하면 새 마스터의 데이터가 불완전해질 수 있습니다. </p>
<p><strong>"완전 동기식 복제"</strong>: 메인 라이브러리가 트랜잭션을 완료하고 모든 슬레이브 라이브러리가 트랜잭션을 실행하면 메인 라이브러리가 트랜잭션을 제출하고 결과를 클라이언트에 반환한다는 의미입니다. 반환하기 전에 모든 슬레이브 라이브러리가 트랜잭션을 완료할 때까지 기다려야 하기 때문에 완전 동기 복제 성능은 필연적으로 심각한 영향을 받습니다. </p>
<p><strong>"반동기 복제"</strong>: 완전 동기 복제와 완전 비동기 복제 사이의 유형입니다. 메인 라이브러리는 릴레이 로그 파일을 수신하고 쓰기 위해 적어도 하나의 슬레이브 라이브러리만 기다리면 됩니다. 모든 슬레이브 라이브러리가 마스터 라이브러리에 ACK를 반환할 때까지 기다릴 필요가 없습니다. 기본 라이브러리는 이 ACK를 받은 후에만 "트랜잭션 완료" 확인을 클라이언트에 반환할 수 있습니다. </p>
<p><strong>MySQL의 기본 복제는 비동기식이므로 마스터 데이터베이스와 슬레이브 데이터베이스 사이의 데이터에 일정한 지연이 발생합니다. 더 중요한 것은 비동기식 복제로 인해 데이터 손실이 발생할 수 있다는 것입니다</strong>. 그러나 완전 동기식 복제는 트랜잭션을 완료하는 데 걸리는 시간을 늘리고 성능을 저하시킵니다. 그래서 저는 반동기 복제에 관심을 돌렸습니다. <strong>MySQL 5.5부터 MySQL은 플러그인 형태의 반동기화 복제를 지원합니다</strong>. </p>
<p>비동기 복제와 비교하여 반동기 복제는 데이터 보안을 향상시키고 마스터-슬레이브 지연을 줄입니다. 물론 이 지연은 적어도 하나의 TCP/IP 왕복 시간입니다. 따라서 <strong>반동기 복제는 지연 시간이 짧은 네트워크</strong>에 가장 적합합니다. </p>
<blockquote>
<p>반동기 복제를 수행하려면 마스터 라이브러리와 슬레이브 라이브러리 모두 반동기 복제를 활성화해야 합니다. 그렇지 않으면 마스터 라이브러리가 기본 비동기 복제로 되돌아갑니다. </p>
<ul>대기 프로세스 중에 대기 시간이 구성된 제한 시간을 초과하고 슬레이브 라이브러리로부터 ACK가 수신되지 않으면 이때 기본 라이브러리가 자동으로 비동기 복제로 변환됩니다. 하나 이상의 반동기 슬레이브 노드가 따라잡으면 마스터 데이터베이스가 자동으로 반동기 복제로 변환됩니다. <li>
<li>반동기 복제의 잠재적인 문제</ul>
</blockquote>기존 반동기 복제(MySQL 5.5에서 도입됨)에서 마스터 데이터베이스는 데이터를 binlog에 기록하고 커밋을 실행하여 트랜잭션을 커밋한 후 항상 ACK를 기다립니다. 슬레이브 데이터베이스, 즉 슬레이브 데이터베이스에서 라이브러리가 릴레이 로그를 작성한 후 데이터를 디스크에 쓴 다음 메인 라이브러리에 ACK를 반환한 후에만 메인 라이브러리가 이 ACK를 받은 후에 "트랜잭션 완료"를 반환할 수 있습니다. 클라이언트에게 확인. <h4></h4>
<p></p>
<p>문제가 발생합니다. 즉, 메인 라이브러리가 실제로 트랜잭션을 스토리지 엔진 계층에 커밋했고 애플리케이션은 이미 데이터가 변경되었음을 확인할 수 있으며 반환을 기다리고 있습니다. <img src="https://img.php.cn/upload/article/000/000/067/cbef40562254d59aabda3ee32efe155e-0.jpg" alt="MySQL 마스터-슬레이브 지연에 대한 솔루션을 완전히 마스터하세요.">이 시점에서 메인 데이터베이스가 다운된 경우</p> 슬레이브 데이터베이스가 릴레이 로그를 작성하지 않았을 수 있으며, <p>마스터 데이터베이스와 슬레이브 데이터베이스 간의 데이터 불일치<strong>가 발생합니다. </strong><strong>위 문제를 해결하기 위해 </strong>MySQL 5.7에서는 향상된 반동기 복제</p>를 도입했습니다. 위 그림의 경우 "Waiting Slave dump"는 "Storage Commit" 이전으로 조정됩니다. 즉, 마스터 라이브러리가 binlog에 데이터를 쓴 후 적어도 하나의 슬레이브 라이브러리가 나올 때까지 슬레이브 라이브러리의 응답 ACK를 기다리기 시작합니다. Relay Log에 기록하고, 데이터를 디스크에 기록하고, ACK가 메인 라이브러리로 반환되어 커밋 작업이 수행될 수 있음을 메인 라이브러리에 알리고, 메인 라이브러리가 해당 트랜잭션을 트랜잭션 엔진에 제출합니다. 그래야만 애플리케이션에서 데이터 변경 사항을 볼 수 있습니다. <p><strong></strong><strong></strong></p> 물론 이전 반동기화 솔루션도 지원됩니다. MySQL 5.7.2에는 제어를 위한 새로운 매개변수 <p>가 도입되었습니다. 이 매개변수에는 두 가지 값이 있습니다. <img src="https://img.php.cn/upload/article/000/000/067/cbef40562254d59aabda3ee32efe155e-1.png" alt="MySQL 마스터-슬레이브 지연에 대한 솔루션을 완전히 마스터하세요."></p>
<blockquote>AFTER_SYNC: 이는 새로운 반동기화 방식으로, 스토리지 커밋 전에 슬레이브 덤프를 대기하는 것입니다. <p><code>rpl_semi_sync_master_wait_point
AFTER_COMMIT: 이것은 오래된 반동기식 솔루션입니다.
MySQL 5.7의 기본값은 after_sync입니다. 마스터 데이터베이스는 각 트랜잭션을 binlog에 기록하고 이를 슬레이브 데이터베이스에 전달한 후 디스크(릴레이 로그)에 플러시합니다. 메인 라이브러리는 슬레이브 라이브러리가 ack를 반환할 때까지 기다린 다음 트랜잭션을 커밋하고 커밋 OK 결과를 클라이언트에 반환합니다. 메인 라이브러리가 충돌하더라도 메인 라이브러리에 제출된 모든 트랜잭션은 슬레이브 라이브러리의 릴레이 로그와 동기화되도록 보장할 수 있으며, 이는 after_commit 모드로 인한 팬텀 읽기 및 데이터 손실 문제를 해결합니다. 장애 조치 중에 일관성이 향상됩니다. 개선 . 왜냐하면 슬레이브 데이터베이스가 성공적으로 쓰지 못하면 마스터 데이터베이스가 트랜잭션을 커밋하지 않기 때문입니다. 또한 커밋하기 전에 슬레이브 라이브러리에서 ACK를 기다리면 트랜잭션이 누적될 수 있으며 이는 그룹 커밋 그룹 제출에 유리하고 성능을 향상시킵니다.
하지만 여기에는 문제가 있습니다. 스토리지 엔진이 커밋되기 전에 메인 라이브러리가 중단된다고 가정하면 트랜잭션이 실패한 것이 분명합니다. 그러나 해당 Binlog가 이미 Sync 작업을 수행했기 때문에 슬레이브는 라이브러리가 이러한 Binlog를 수신했으며 실행이 성공하면 슬레이브 데이터베이스에 추가 데이터가 있는 것과 동일합니다(슬레이브 데이터베이스에는 이 데이터가 있지만 기본 데이터베이스에는 없음). 이것도 문제이지만 추가 데이터는 일반적으로 심각한 문제는 아닙니다. 보장할 수 있는 것은 데이터가 손실되지 않는다는 것입니다. 데이터를 잃는 것보다 더 많은 데이터를 갖는 것이 좋습니다.하나의 마스터, 다중 슬레이브슬레이브 데이터베이스가 많은 수의 쿼리 요청을 수행하는 경우 슬레이브 데이터베이스의 쿼리 작업은 많은 CPU 리소스를 소비하므로 동기화 속도에 영향을 미치고 마스터-슬레이브 지연이 발생합니다. 그런 다음 여러 개의 슬레이브 라이브러리를 더 연결하고 이러한 슬레이브 라이브러리가 읽기 압력을 공유하도록 할 수 있습니다. 간단히 말하면 기계를 추가하는 것입니다. 방법은 간단하고 투박하지만 비용도 발생합니다.
MySQL 5.6부터 데이터를 동시에 복원할 수 있는 다중 SQL 스레드 개념, 즉 병렬 복제 기술이 등장합니다. 이는 MySQL 마스터-슬레이브 지연 문제를 매우 잘 해결할 수 있습니다.
단일 스레드 복제부터 최신 버전의 멀티 스레드 복제까지 여러 버전을 거쳐 진화했습니다. 실제로 최종 분석에서 모든 멀티 스레드 복제 메커니즘은 하나의 스레드만 있는 sql_thread를 여러 스레드로 분할하는 것입니다. 이는 모두 다음과 같은 멀티 스레드 모델을 준수함을 의미합니다.coordinator는 원래 sql_thread이지만, 이제는 더 이상 데이터를 직접 업데이트하지 않고 전송 로그를 읽고 트랜잭션을 배포하는 역할만 담당합니다. 실제로 로그를 업데이트하는 것이 작업자 스레드가 됩니다. 작업자 스레드 수는 매개변수 에 의해 결정됩니다. slave_parallel_workers
MySQL 5.6 버전은 병렬 복제를 지원하지만 지원되는 세분성은 베이스별 병렬 처리(스키마 기반)입니다.
핵심 아이디어는 : 서로 다른 스키마의 테이블이 동시에 제출되면 데이터가 서로 영향을 미치지 않습니다. 즉, 슬레이브 라이브러리는 SQL 스레드 기능과 유사한 스레드를 릴레이 로그의 다른 스키마에 할당할 수 있습니다. 릴레이 로그를 재생합니다. 기본 데이터베이스에서 커밋된 트랜잭션은 기본 데이터베이스의 데이터와 일관성을 유지합니다.
메인 데이터베이스에 여러 개의 DB가 있는 경우 이 전략을 사용하면 슬레이브 데이터베이스에서 복제 속도를 크게 향상시킬 수 있습니다. 그러나 일반적으로 단일 데이터베이스에 여러 테이블이 있기 때문에 데이터베이스 기반 동시성은 효과가 없으며 병렬 재생도 전혀 수행할 수 없으므로 이 전략은 많이 사용되지 않습니다.
MySQL 5.7은 그룹 제출 기반 병렬 복제를 도입했으며, 매개변수 slave_parallel_workers
设置并行线程数,由参数 slave-parallel-type
는 병렬 복제 전략을 제어하는 데 사용됩니다.
병렬로 실행될 수 있습니다. 트랜잭션이 잠금 충돌 테스트를 통과했기 때문에 동일한 그룹에 제출된 트랜잭션은 동일한 행을 수정하지 않습니다(MySQL의 잠금 메커니즘으로 인해).
그룹 제출을 기반으로 한 병렬 복제의 구체적인 프로세스는 다음과 같습니다:
. binlog 그룹이 제출한 두 가지 관련 매개변수:
binlog_group_commit_sync_delay 매개변수는 fsync를 호출하여 디스크를 플러시하기 전에 지연해야 하는 마이크로초 수를 나타냅니다.추천 학습:
mysql 비디오 튜토리얼위 내용은 MySQL 마스터-슬레이브 지연에 대한 솔루션을 완전히 마스터하세요.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!