>  기사  >  데이터 베이스  >  MySQL 읽기 및 쓰기 분리 실습 - 고성능 웹 구축을 위한 코드 예제

MySQL 읽기 및 쓰기 분리 실습 - 고성능 웹 구축을 위한 코드 예제

黄舟
黄舟원래의
2017-03-11 14:28:241114검색

완전한 MySQL 읽기-쓰기 분리 환경에는 다음 부분이 포함됩니다.

  • 애플리케이션 클라이언트

  • 데이터베이스 프록시

  • 데이터베이스 클러스터

이 실제 전투에서 애플리케이션 클라이언트는 c3p0을 기반으로 백엔드 데이터베이스 프록시에 연결됩니다. 데이터베이스 프록시는 오픈 소스 프레임워크인 amoeba를 사용하여 클라이언트가 실제로 데이터베이스에 액세스할 수 있도록 라우팅 전략을 관리하는 역할을 담당합니다. 데이터베이스 클러스터는 mysql의 마스터-슬레이브 복제 솔루션을 사용합니다. 전체 환경의 구조도는 다음과 같습니다.

실습 단계 및 자세한 설명

1 mysql의 마스터-슬레이브 환경을 구축합니다.

1) 호스트1(10.20.147.110)과 호스트2(10.20.147.111)에 각각 mysql(5.0.45)을 설치합니다. 자세한 설치 방법은 공식 문서

2) 마스터 구성

먼저 /etc/my.cnf를 편집하고 다음 구성을 추가합니다:

log-bin=mysql-bin #slave会基于此log-bin来做replication
server-id=1 #master的标示
binlog-do-db = amoeba_study #用于master-slave的具体数据库

그런 다음 복제를 위해 특별히 사용자를 추가합니다:

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@10.20.147.111 IDENTIFIED BY '111111';

mysql을 다시 시작하여 구성을 적용합니다:

/etc/init.d/mysqld restart

마지막으로 마스터 상태 확인:


3) 슬레이브 구성

첫 번째 편집/ etc/my.cnf를 실행하고 다음 구성을 추가합니다.

server-id=2 #slave label

구성이 적용된 후 마스터와의 연결을 구성합니다:

mysql> CHANGE MASTER TO
    -> MASTER_HOST='10.20.147.110',
   
 -> MASTER_USER='repl',
    -> MASTER_PASSWORD='111111',
   
 -> MASTER_LOG_FILE='mysql-bin.000003',
    -> 
MASTER_LOG_POS=161261;

여기서 MASTER_HOST는 마스터 머신의 IP이고, MASTER_USER 및 MASTER_PASSWORD는 우리입니다. 방금 마스터에 추가한 사용자, MASTER_LOG_FILE 및 MASTER_LOG_POS는 마스터 상태의 정보에 해당합니다.

마지막으로 슬레이브 시작:

mysql> start slave;

4) 마스터-슬레이브 빌드가 적용되는지 확인


슬레이브 머신의 로그(/var/log/mysqld.log)를 확인하세요.

100703 10:51:42 [Note] Slave I/O thread: connected to master 'repl@10.20.147.110:3306',  
replication started in log 'mysql-bin.000003' at position 161261

위의 정보는 문제가 있는 경우 이 로그를 통해 원인을 확인할 수도 있습니다


2. 데이터베이스 프록시 구축

실제 전투에서는 데이터베이스 프록시가 아메바를 사용합니다. , 관련 정보는 공식 문서에서 찾을 수 있지만 여기에는 자세히 설명되어 있지 않습니다

1) amoeba 설치

amoeba(1.2.0-GA)를 다운로드하고 로컬로 압축을 푼다(D: /openSource/amoeba -mysql-1.2.0-GA) 즉, 설치가 완료됩니다

2) 아메바 구성

먼저 프록시 연결과 백마다 연결정보를 구성합니다- end mysql 서버(D:/openSource/amoeba-mysql-1.2.0-GA/conf/amoeba.xml):

위는 프록시가 클라이언트에 제공하는 연결 구성입니다

<dbServerList>  
    <dbServer name="server1">           
        <!-- PoolableObjectFactory实现类 -->  
        <factoryConfig class="com.meidusa.amoeba.mysql
        <a href="http://lib.csdn.net/base/dotnet" class=&#39;replace_word&#39; title=".NET知识库" target=&#39;_blank&#39; style=&#39;color:#df3434; font-weight:bold;&#39;>.NET</a>
        .MysqlServerConnectionFactory">  
            <property name="manager">defaultManager</property>  
              
            <!-- 真实mysql数据库端口 -->  
            <property name="port">3306</property>  
              
            <!-- 真实mysql数据库IP -->  
            <property name="ipAddress">10.20.147.110</property>  
            <property name="schema">amoeba_study</property>  
              
            <!-- 用于登陆mysql的用户名 -->  
            <property name="user">root</property>  
              
            <!-- 用于登陆mysql的密码 -->  
            <property name="password"></property>  
              
        </factoryConfig>  
          
        <!-- ObjectPool实现类 -->  
        <poolConfig class="com.meidusa.amoeba
        <a href="http://lib.csdn.net/base/dotnet" class=&#39;replace_word&#39; title=".NET知识库" target=&#39;_blank&#39; style=&#39;color:#df3434; font-weight:bold;&#39;>.Net</a>
        .poolable.PoolableObjectPool">  
            <property name="maxActive">200</property>  
            <property name="maxIdle">200</property>  
            <property name="minIdle">10</property>  
            <property name="minEvictableIdleTimeMillis">600000</property>  
            <property name="timeBetweenEvictionRunsMillis">600000</property>  
            <property name="testOnBorrow">true</property>  
            <property name="testWhileIdle">true</property>  
        </poolConfig>  
    </dbServer>  
    <dbServer name="server2">  
          
        <!-- PoolableObjectFactory实现类 -->  
        <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">  
            <property name="manager">defaultManager</property>  
              
            <!-- 真实mysql数据库端口 -->  
            <property name="port">3306</property>  
              
            <!-- 真实mysql数据库IP -->  
            <property name="ipAddress">10.20.147.111</property>  
            <property name="schema">amoeba_study</property>  
              
            <!-- 用于登陆mysql的用户名 -->  
            <property name="user">root</property>  
              
            <!-- 用于登陆mysql的密码 -->  
            <property name="password"></property>  
              
        </factoryConfig>  
          
        <!-- ObjectPool实现类 -->  
        <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">  
            <property name="maxActive">200</property>  
            <property name="maxIdle">200</property>  
            <property name="minIdle">10</property>  
            <property name="minEvictableIdleTimeMillis">600000</property>  
            <property name="timeBetweenEvictionRunsMillis">600000</property>  
            <property name="testOnBorrow">true</property>  
            <property name="testWhileIdle">true</property>  
        </poolConfig>  
    </dbServer>         
</dbServerList>

위는 프록시 및 백엔드 mysql 데이터베이스 서버의 구성 정보입니다. 구체적인 구성은 주석에서 매우 명확합니다.

마지막으로 읽기-쓰기 분리 전략 구성:

에서 위 구성에서 쓰기 작업은 server1(마스터)로, 읽기 작업은 server2(슬레이브)로 라우팅되는 것을 알 수 있습니다

3) amoeba

를 시작하고 D:/openSource를 실행합니다. /amoeba-mysql-1.2.0-GA/amoeba.bat 명령줄:

log4j:WARN log4j config load completed from file:D:/openSource/amoeba-mysql-1.2.0-GA/conf/log4j.xml
log4j:WARN ip access config load completed from file:D:/openSource/amoeba-mysql-1.2.0-GA/conf/access_list.conf
2010-07-03 09:55:33,821 INFO  net.ServerableConnectionManager - Server listening on 0.0.0.0/0.0.0.0:8066.

3. 클라이언트측 호출 및 테스트

1 ) 클라이언트 호출 프로그램 작성

구체적인 프로그램 세부 사항은 자세히 설명하지 않으며 mysql 드라이버 jdbc 데이터베이스 운영 프로그램을 기반으로 하는 가장 일반적인 프로그램입니다

2) 데이터베이스 연결 구성

이 클라이언트는 c3p0을 기반으로 합니다. 구체적인 데이터 소스 구성은 다음과 같습니다.

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"  
    destroy-method="close">  
    <property name="driverClass" value="com.mysql.jdbc.Driver" />  
    <property name="jdbcUrl" value="jdbc:mysql://localhost:8066/amoeba_study" />  
    <property name="user" value="root" />  
    <property name="password" value="root" />  
    <property name="minPoolSize" value="1" />  
    <property name="maxPoolSize" value="1" />  
    <property name="maxIdleTime" value="1800" />  
    <property name="acquireIncrement" value="1" />  
    <property name="maxStatements" value="0" />  
    <property name="initialPoolSize" value="1" />  
    <property name="idleConnectionTestPeriod" value="1800" />  
    <property name="acquireRetryAttempts" value="6" />  
    <property name="acquireRetryDelay" value="1000" />  
    <property name="breakAfterAcquireFailure" value="false" />  
    <property name="testConnectionOnCheckout" value="true" />  
    <property name="testConnectionOnCheckin" value="false" />  
</bean>

클라이언트는 프록시에만 연결하면 되며 실제 데이터베이스와는 아무 관련이 없습니다. jdbcUrl, 사용자 및 비밀번호 구성은 모두 amoeba에서 노출된 구성 정보와 일치합니다

3) 호출 및 테스트

먼저 데이터 조각을 삽입합니다:

insert into zone_by_id(id,name) values(20003,&#39;name_20003&#39;)

를 확인하여 마스터 머신에 /var/lib/mysql/mysql_log.log 기록:

100703 11:58:42       1 Query       set names latin1
                      1 Query       SET NAMES latin1
                      1 Query       SET character_set_results = NULL
                      1 Query       SHOW VARIABLES
                      1 Query       SHOW COLLATION
                      1 Query       SET autocommit=1
                      1 Query       SET sql_mode='STRICT_TRANS_TABLES'
                      1 Query       SHOW VARIABLES LIKE 'tx_isolation'
                      1 Query       SHOW FULL TABLES FROM `amoeba_study` LIKE 'PROBABLYNOT'
                      1 Prepare     [1] insert into zone_by_id(id,name) values(?,?)
                      1 Prepare     [2] insert into zone_by_id(id,name) values(?,?)           
                      1 Execute     [2] insert into zone_by_id(id,name) values(20003,&#39;name_20003&#39;)

마스터 머신에서 쓰기 작업이 발생했음을 알아보세요.

슬레이브 머신의 로그를 확인하여/var/ lib/mysql/mysql_log.log:

100703 11:58:42       2 Query       insert into zone_by_id(id,name) values(20003,&#39;name_20003&#39;)

는 슬레이브가 이 명령문을 동기적으로


실행한 다음 데이터 조각을 확인했음을 알게 되었습니다. zone_by_id t에서 t.name을 선택하세요. id = 20003

슬레이브 머신의 /var/lib/mysql/mysql_log.log 로그를 확인하면

100703 12:02:00      33 Query       set names latin1
                     33 Prepare     [1] select t.name from zone_by_id t where t.id = ?
                     33 Prepare     [2] select t.name from zone_by_id t where t.id = ?    
                     33 Execute     [2] select t.name from zone_by_id t where t.id = 20003

슬레이브 머신에서 읽기 작업이 발생한 것으로 알려져 있습니다

그리고 슬레이브 머신의 /var/lib/mysql/mysql_log.log 로그를 확인해보니 이 명령문이 마스터에서는 실행되지 않은 것으로 나타났습니다

위의 확인을 통해 단순 마스터가 -슬레이브 설정 및 실제 전투가 가능합니다

위 내용은 MySQL 읽기 및 쓰기 분리 실습 - 고성능 웹 구축을 위한 코드 예제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.