Làm thế nào để có được lõi để tận dụng cấu hình chủ / nô lệ của MySQL?


21

Tôi đọc câu hỏi này Bản sao chủ / nô lệ của MySQL không hoạt động và câu trả lời của nó:

Sử dụng cơ sở dữ liệu nô lệ hầu như không được thực hiện trong lõi Drupal. Nếu bạn đang phát triển các mô-đun của riêng mình thì các cuộc gọi đến db_query cần chỉ định rằng họ muốn sử dụng cơ sở dữ liệu nô lệ bằng cách sử dụng mảng tùy chọn $. Xem DatabaseConnection :: defaultOptions để biết cách đặt mảng này.

Có cách nào mà không giết mèo con hack lõi để lấy db_query()db_select()thực hiện nhiều truy vấn CHỌN nô lệ hơn không?

Theo mặc định, các hàm này sẽ truy vấn chủ trừ khi được yêu cầu truy vấn nô lệ cụ thể (xem API của chúng). Bạn phải viết db_query($query, $args, array('target' => 'slave'))để truy vấn nô lệ và lõi (và tất cả các mô-đun) không được viết để đạt được điều này.

Chỉ tìm kiếm (xem phần nô lệ) và tập hợp dường như tận dụng điều này.

Chỉnh sửa: Tháng 10, 25
Tôi thấy báo chí 7 đã hết nhưng tôi không chắc liệu nó có giúp được gì nhiều không.
Tôi đã không tìm thấy một cái gì đó có liên quan vì vậy chúng ta hãy thử một chút tiền thưởng để giúp câu trả lời này.

Chỉnh sửa: Tháng Mười, 31
Tôi chủ yếu lo lắng về những bình luận của Crell về chủ đề này: Phải làm gì với nô lệ? .
Chủ yếu, có vấn đề gì không nếu tôi gửi SELECTtruy vấn đến nô lệ, điều xảy ra với sự chậm trễ trong quá trình sao chép và thực tế là tôi có thể muốn thực hiện node_load()ngay sau khi lưu một nút mới.

Câu trả lời:


17

Đây là cách tôi hiện đang thực hiện điều này.

Trước tiên, bạn cần thiết lập một lớp SelectQueryExtender như thế này:

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');
  }
}

Khi bạn đã có điều đó, tất cả những gì bạn phải làm là nhận tất cả các truy vấn khác để mở rộng bộ mở rộng. :) nếu điều đó hợp lý. Đây là đoạn trích.

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

Và bây giờ, tất cả các lựa chọn của bạn đánh vào nô lệ ;-) Đây là cách duy nhất tôi có thể thực hiện được. Dù sao nó hoạt động tuyệt vời.

Ngoài ra, nếu bạn có cái này trên một mô-đun tùy chỉnh, bạn có thể thiết lập SlaveTarget thành nó trên tệp SlaveTarget.inc và thêm một tệp [] = SlaveTarget.inc vào tệp thông tin mô-đun của bạn.


Xin chào Eric, cảm ơn câu trả lời của bạn, điều chủ yếu làm tôi lo lắng là chủ đề này: Làm gì với nô lệ? bình luận của Crell về nô lệ . Vì vậy, bạn có giải pháp an toàn trong mọi trường hợp? Bạn có hạn chế một số SELECTtruy vấn? Làm thế nào để bạn đối phó với sự chậm trễ trong việc sao chép và thực tế là việc tải một nút ngay sau khi lưu nó có thể gây rắc rối?
tostinni

Điều này đang thay đổi cơ sở dữ liệu thành nô lệ chỉ trên Chọn truy vấn. Điều này chỉ xảy ra khi truy vấn đã được viết bằng SelectQuery chứ không phải db_query nên không cần phải lo lắng và chèn hoặc cập nhật được nhắm mục tiêu vào nô lệ. Chúng tôi đang chạy trên 3 môi trường sản xuất lớn mà không gặp vấn đề gì. Tôi đã không lo lắng nhiều về việc sao chép mysql gần như ngay lập tức (trong trường hợp của tôi) nhưng tôi có thể thấy đó có thể là một vấn đề nhỏ trong một số môi trường nhất định.
ericduran

Cảm ơn câu trả lời của bạn, đó là một giải pháp tuyệt vời, tôi sẽ xem liệu điều này có khả thi trên môi trường của chúng tôi không.
tostinni

Eric, mã này ở đâu đó như một mô-đun đóng góp hoặc hộp cát?
paul-m


5

Các AutoSlave đổi hướng mô-đun SELECTtruy vấn đến cơ sở dữ liệu chỉ đọc Replicant, nó sẽ đưa vào lag sao chép tài khoản.

Theo các tài liệu mô-đun, nó chỉ sử dụng trình sao chép chỉ đọc khi tất cả các điều kiện sau là đúng:

  1. Truy vấn là một truy vấn chọn
  2. Các bảng trong truy vấn chọn không được ghi vào trong yêu cầu và trong độ trễ sao chép giả định
  3. Một giao dịch chưa được bắt đầu
  4. Các bảng trong truy vấn chọn không được chỉ định trong tùy chọn 'bảng' trong cài đặt trình điều khiển
  5. Khóa chưa được khởi động (hỗ trợ khóa db và khóa memcache)

1

từ những gì tôi nghe được tại Drupal BADcamp Pressflow gần đây là cách để đi nếu bạn muốn cấu hình chính / phụ. Bạn sẽ bị giới hạn ở Mysql là DB. Ngoài ra, hãy kiểm tra " nhóm hiệu suất cao " trên


1
Hiện tại Pressflow 7 = D7, chưa có gì (chưa) mà Pressflow làm mà D7 không :(
tostinni

1

Mặc dù tất cả các công việc tuyệt vời được thực hiện trên lớp trừu tượng cơ sở dữ liệu trong Drupal 7, nhưng điều này vẫn rất khó thực hiện với lõi Drupal. Như những người khác đã đề cập, AutoSlave là một tùy chọn, mặc dù không phải tôi đã cố gắng vì sự từ chối cứng đầu của tôi để tin rằng nó sẽ khó thực hiện điều này.

Một giải pháp đơn giản hơn tôi đã tìm thấy là sau đây. Để định tuyến tất cả SELECT s đến máy chủ nô lệ, bạn tạo một tệp có tiêu đề select.incbên trong includes/database/mysqlthư mục lõi với các nội dung sau:

<?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".
 */

Có một số rủi ro với phương pháp này:

  1. Phương pháp này sẽ chiếm quyền điều khiển tất cả SELECT và chuyển chúng đến nô lệ, điều này chắc chắn sẽ gây ra vấn đề nếu bạn có bất kỳ độ trễ nào trong quá trình sao chép. Đọc câu đó một lần nữa.
  2. Khi bạn nâng cấp lõi Drupal, có thể tệp này sẽ bị xóa.
  3. Nếu lõi Drupal đã từng bắt đầu giao hàng với chính nó includes/database/mysql/select.inc, thì tệp của bạn sẽ bị ghi đè trong quá trình nâng cấp và bạn sẽ phải bắt đầu duy trì phiên bản vá của riêng mình của select.inc gửi cùng với lõi Drupal.

Nếu bạn không có bất kỳ máy chủ nô lệ nào được chỉ định trong settings.php, đoạn mã trên sẽ không gây ra sự cố. Nó sẽ vẫn duyên dáng làm suy giảm việc sử dụng tổng thể máy chủ.


Có, nó xuất hiện ngay cả khi kết nối có thể được đặt thành "nô lệ", nếu bản thân truy vấn không có target => 'slave'tùy chọn được đặt, nó vẫn sẽ chạy trên kết nối mặc định. Thật khó để đặt mục tiêu kết nối dễ dàng hơn ở query_altercấp độ.
David Thomas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.