ホームページ  >  記事  >  データベース  >  MySQL の読み取りと書き込みの分離の実践 - 高パフォーマンス Web を構築するためのコード例

MySQL の読み取りと書き込みの分離の実践 - 高パフォーマンス Web を構築するためのコード例

黄舟
黄舟オリジナル
2017-03-11 14:28:241067ブラウズ

完全な mysql 読み取り/書き込み分離環境には、次の部分が含まれます:

  • アプリケーション クライアント

  • データベース プロキシ

  • データベース クラスター

この実際の戦闘では、アプリケーション クライアントは c3p0 接続バックエンドに基づいています。データベースプロキシ。データベース プロキシは、オープン ソース フレームワーク アメーバを使用して、クライアントが実際にデータベースにアクセスするためのルーティング戦略を管理する責任を負います。データベース クラスターは、mysql のマスター/スレーブ レプリケーション ソリューションを使用します。環境全体の構成図は次のとおりです:

実践的な手順と詳細な説明

1. host1 (10.20.147.110) と host2 (10.20.110) に mysql マスター/スレーブ環境を構築します

1)。 147.111) mysql (5.0.45) をコンピューターにインストールします。具体的なインストール方法は公式ドキュメントに記載されています

2) master を設定します

最初に /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 マーク

設定が有効になったら、マスターとの接続を設定します:

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) アメーバの設定

まず、プロキシ接続と各バックエンド 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) アメーバを起動します

コマンドラインで 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;)

スレーブがこのステートメントを同期的に実行したことが分かりました

そしてデータの一部を確認しました: select t.name fromzone_by_id t where t. 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 を確認すると、このステートメントがマスター上で実行されていないことがわかりました

上記の検証により、単純なマスターとスレーブのセットアップと実際の戦闘には時間がかかることがわかりました効果

以上がMySQL の読み取りと書き込みの分離の実践 - 高パフォーマンス Web を構築するためのコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。