アクセス量が比較的多い一部のプロジェクトでは、ユーザーの操作を分散させ、負荷分散を実現するために、データベースのマスタースレーブ方式を使用して読み取りと書き込みを分離することがよくあります。そこで、ネット上で関連情報を調べてまとめてみました。以下の概念の一部は百科事典またはオンライン PPT から引用されており、最後のコードはこのプロジェクトからのものです。
まず第一に、これまでに同様の機能を実行したことがないため、概念的に理解する必要があります:
負荷分散
負荷分散: 負荷 (作業タスク) を複数のオペレーティングユニットに分散してバランスをとって実行し、作業タスクをまとめて完了します。大きく分けて2種類に分かれます
1. クラスタリング
単一の高負荷オペレーションを複数のノードデバイスに分散して並列処理し、各ノードデバイスの処理完了後に結果が要約されてユーザーに返されるため、システムの処理能力が大幅に向上します。
2. 気晴らし
大量の同時アクセスまたはデータ トラフィックを複数のノード デバイスで個別に処理することで共有し、ユーザーが応答を待つ時間を短縮します。これは主に Web サーバー、FTP サーバー、エンタープライズ キー アプリケーション サーバーなどのネットワーク アプリケーションを対象としています。マスター/スレーブ アーキテクチャは、このタイプの負荷分散です。
マスタースレーブアーキテクチャの利点
1. ロードバランシング(読み書きを分離し、データ処理効率を向上)
2. 高可用性とフェイルオーバー機能 (データ分散、安定性の向上。マスターサーバーに障害が発生した場合でも、スレーブサーバーを使用してサポートできます)
3. バックアップ (それ自体をバックアップすることはできませんが、データベースの災害復旧、バックアップ、リカバリ、その他の操作を容易にするバックアップ マシンを提供できます)
4. データの一貫性と競合の回避
5. Mysql のアップグレードをテストします
Mysqlコピー関数
1: 1 つのマスターと複数のスレーブのメカニズムをサポートします。データはマスター サーバーからスレーブ サーバーにコピーされます。
2: マルチレベル構造をサポートします。マスターとスレーブ、スレーブとスレーブ、マスターとスレーブ(相互にマスターとスレーブ)。
3: フィルタリング機能をサポートします (メインサーバー上のデータのすべてではなく、一部のみをコピーできます)。
コピーの種類
1. ステートメントベースのレプリケーション: SQL ステートメントがマスター サーバーで実行され、同じ SQL ステートメントがスレーブ サーバーで実行されます。 Mysql はデフォルトでステートメントベースのレプリケーションを使用します。これは比較的効率的です。
2. 行ベースのレプリケーション: スレーブ サーバーでコマンドを実行する代わりに、変更された内容をコピーします (mysql5.0 以降でサポート)。
3. 混合タイプのレプリケーション: デフォルトではステートメントベースのレプリケーションが採用されます。ステートメントベースのレプリケーションが正確ではないことが判明した場合は、行ベースのレプリケーションが使用されます
対応するバイナリ ログが 3 つあります:
1:ステートメント
2:ロウ
3: ミックス
サーバー構造の要件
1: マスター/スレーブ サーバー内のテーブルは、異なるテーブル タイプを使用できます。さらに、複数のスレーブ サーバーを同時に持つマスター サーバーはパフォーマンスに影響します。1 台のサーバーをスレーブ サーバー プロキシとして使用し、BLOCKHOLE テーブル タイプを使用できます。ログを記録するだけであり、パフォーマンスを向上させるために複数のサーバーを駆動します。
2: マスター/スレーブ サーバー内のテーブルは、異なるフィールド タイプを使用できます。
3: マスター/スレーブ サーバー内のテーブルは異なるインデックスを使用できます。マスター サーバーは主に書き込み操作に使用されるため、主キーや一意のインデックスなどのデータの関係を保証するインデックスを追加する必要はありません。スレーブ サーバーは通常、読み取り操作に使用されるため、インデックスを設定できます。クエリの特性。さらに、異なるスレーブ サーバーは、異なるクエリに対して異なるインデックスを設定できます。
コピープロセス
1: マスターサーバーは変更をバイナリログファイルに記録します。これらの記録はバイナリログイベント
と呼ばれます。
2: スレーブサーバーはマスターのバイナリログイベントをリレーログにコピーします
3: スレーブはリレー ログ内のイベントをやり直し、変更を自身のデータに反映します。
PHPコードの実装
1.サーバー接続設定ファイル
多態性のマスター/スレーブ サーバーがある場合は、数値を下方向に増やすだけです。
[php]
[データベース]
dbname = "vis_db"
文字セット = "utf8"
;主様
servers.0.master = true
servers.0.adapter = "MYSQLI"
servers.0.host = "vis_db"
servers.0.username = "vis"
servers.0.password = "vis"
;从
servers.1.master = false
servers.1.adapter = "MYSQLI"
servers.1.host = "vis_mmc"
servers.1.username = "vis"
servers.1.password = "vis"
2. データベース操作コード
ユーザー IP に基づいて余りを計算した後、サーバー上のどのデータベースに接続するかを決定します。
プロジェクトでは Zend Framework が使用されています。
[php]
/**
* データベースファクトリークラス
*
* @create 2012-05-29
* @note: このクラスは、さまざまな構成パラメーターの Zend_Db_Adapter インスタンスを作成するために使用されます
*/
include_once 'lib/getRequestIP.php';
クラス Free_Db_Factory
{
/**
* * Zend_Db_Adapter インスタンス配列
*
* @var 配列
*/
保護された静的 $_dbs = array();
保護された関数 __construct($sName)
{
{
をお試しください
$params = $this->getDbConfig($sName);
self::$_dbs[$sName] = Zend_Db::factory($params['adapter'], $params);
} catch (例外 $e) {
if (デバッグ) {
エコー $e->getMessage();
出る
}
}
/**
* Zend_Db_Adapter インスタンスを取得します
* @return Zend_Db_Adapter
*/
パブリック静的関数 getDb($sName)
{
If (emptyempty($sName)) {
出る
}
If (!isset(self::$_dbs[$sName])) {
新しい自分($sName)
}
自己を返す::$_dbs[$sName]
}
/**
* データベース構成を取得します
*/
プライベート関数 _getDbConfig($sName)
{
$configArr = 配列();
$dbConfig = Zend_Registry::get('db')->database->toArray();
$serverConfigs = $dbConfig['servers'];
$masters = array();
$slaves = array();
foreach ($serverConfigs を $value) {
If (!isset($value['master'])) {
続く;
If (true == $value['master']) {
$masters[] = $value;
If (false == $value['master']) {
$slaves[] = $value;
}
$masterNum = count($masters);
$slaveNum = count($slaves);
$requestIP = $this->_getRequestIP();
スイッチ ($sName) {
ケース「マスター」:
if ($masterNum > 1) {
$configArr = $masters[$requestIP % $masterNum];
} その他 {
$configArr = $masters[0];
}
壊す;
ケース「スレーブ」:
if ($slaveNum > 1) {
$configArr = $slaves[$requestIP % $slaveNum];
} その他 {
$configArr = $slaves[0];
}
壊す;
デフォルト:
壊す;
}
if (emptyempty($configArr)) {
戻り配列();
}
$configArr['dbname'] = $dbConfig['dbname'];
$configArr['charset'] = $dbConfig['charset'];
$configArr を返します。
}
/**
* リクエストIPを取得します
*/
プライベート関数 _getRequestIP()
{
$ip = getRequestIP(true);
return sprintf('%u', ip2long($ip));
} www.2cto.com
/**
* Zend_Db_Adapter エンティティを破棄します (一部のリクエストには時間がかかるため、この期間にデータベースがタイムアウトする可能性があります)
*/
パブリック静的関数 destructDb($sName = null)
{
if (null === $sName) {
self::$_dbs = null;
} その他 {
unset(self::$_dbs[$sName]);
}
}
}
暗号を使用して、マークを入力し、操作主がデータベースからであることを確認します:
[php]
$oSlaveDb = Free_Db_Factory::getDb('スレーブ');