web-dev-qa-db-ja.com

コアでMySQLマスター/スレーブ構成を活用するにはどうすればよいですか?

私はこの質問を読みます MySQLマスター/スレーブレプリケーションが機能していません とその答え:

スレーブデータベースの使用は、Drupalコアにほとんど実装されていません。独自のモジュールを開発している場合、db_queryへの呼び出しで、$ options配列を使用してスレーブデータベースを使用することを指定する必要があります。DatabaseConnectionを参照してください。 :defaultOptionsは、この配列を設定する方法を示します。

なしの方法はありますか 子猫を殺す コアをハッキングして db_query() および db_select() を取得し、より多くのスレーブSELECTクエリを作成しますか?

デフォルトでは、これらの関数は、特にスレーブにクエリするように指示されない限り、マスターにクエリします(APIを参照)。これを達成するためにスレーブとコア(およびすべてのモジュール)をクエリするためにdb_query($query, $args, array('target' => 'slave'))を記述する必要はありません。

search (スレーブ部分を参照)とアグリゲーターのみがこれを利用しているようです。

編集:10月25日
私はプレスフロー7が出ているのを見ましたが、それが現在多くの助けになるかどうかはわかりません。
何か関連するものが見つからなかったので、これを解決するために少しの賞金を試してみましょう。

編集:10月31日
私は主にこのトピックに関して Crellのコメント について心配しています: スレーブで何をするか?
主に、スレーブにSELECTクエリを送信すると問題が発生します。レプリケーションの遅延で何が発生し、直後にnode_load()を実行する可能性があるという事実があります新しいノードを保存します。

20
tostinni

これが私が現在これを実装する方法です。

最初に、次のようなSelectQueryExtenderクラスを設定する必要があります。

class SlaveTarget extends SelectQueryExtender {
  public function __construct(SelectQueryInterface $query, DatabaseConnection $connection) {
    if ($connection->getTarget() != 'slave') {
      $connection = Database::getConnection('slave', $connection->getKey());
    }
    parent::__construct($query, $connection);
    $this->addTag('SlaveTarget');
  }
}

それができたら、他のすべてのクエリを取得してエクステンダーを拡張するだけです。 :)それが理にかなっている場合。これがスニペットです。

/**
 * Implements hook_query_alter().
 */
function example_query_alter(QueryAlterableInterface $query) { 
  if (is_a($query, 'SelectQuery') && !$query->hasTag('SlaveTarget')) {
    $query->extend('SlaveTarget');
  }
}

そして今、あなたのすべてのSelectQueryがスレーブをヒットします;-)これが私がこれを達成することができた唯一の方法です。とにかくそれは素晴らしい働きをします。

また、カスタムモジュールにこれがある場合は、SlaveTargetをファイルSlaveTarget.incにあるように設定し、files [] = SlaveTarget.incをモジュール情報ファイルに追加できます。

17
ericduran

AutoSlave モジュールはSELECTクエリを読み取り専用のレプリカントデータベースにリダイレクトしますandレプリケーションラグを考慮に入れます。

モジュールのドキュメントによると、次の条件がすべて当てはまる場合にのみ、読み取り専用レプリカントを使用します。

  1. クエリは選択クエリです
  2. 選択クエリのテーブルは、リクエスト中に書き込まれず、想定されるレプリケーションラグ内にあります
  3. トランザクションが開始されていません
  4. 選択クエリのテーブルが、ドライバー設定の「テーブル」オプションで指定されていません
  5. ロックが開始されていません(コアdb-lockおよびmemcache-lockがサポートされています)
5
smokris

私が最近聞いた話からDrupal BADcamp Pressflowは、マスター/スレーブ構成が必要な場合に行く方法です。DBとしてMysqlに制限されます。また、「- ハイパフォーマンスグループ "on do.

1
uwe

Drupal 7のデータベースアブストラクションレイヤーで行われたすべての驚くべき作業にもかかわらず、これはDrupalコアをそのまま使用することで驚くほど困難です。 AutoSlave はオプションですが、頑固にこれを行うのは難しいはずだと信じるのを拒んだため、私は試みていません。

私が見つけたより簡単な解決策は次のとおりです。 allSELECTsをスレーブサーバーにルーティングするには、コア内にselect.incという名前のファイルを作成しますincludes/database/mysql次の内容のディレクトリ:

<?php

/**
 * @file
 * Select builder for MySQL database engine, routing all SELECTs to the slave.
 */

/**
 * @addtogroup database
 * @{
 */

class SelectQuery_mysql extends SelectQuery {
  public function __construct($table, $alias = NULL, DatabaseConnection $connection, $options = array()) {
    $key = $connection->getKey();
    $connection = Database::getConnection('slave', $key);
    $options['target'] = 'slave';
    parent::__construct($table, $alias, $connection, $options);
  }
}

/**
 * @} End of "addtogroup database".
 */

この方法にはいくつかのリスクがあります。

  1. このメソッドはallSELECTsをハイジャックし、スレーブに送信します。レプリケーションに遅延がある場合、間違いなく問題が発生します。その文をもう一度読んでください。
  2. Drupalコアをアップグレードすると、このファイルが削除される可能性があります。
  3. Drupalコアが独自のincludes/database/mysql/select.incで出荷を開始する場合、ファイルはアップグレード中に上書きされ、select.incの独自のパッチバージョンを維持し始める必要があります。 Drupalコアが付属しています。

Settings.phpでスレーブサーバーを指定していない場合、上記のコードは問題を引き起こしません。それでもmasterサーバーを使用するように正常に低下します。

1
q0rban