autopilotpattern / wordpress

A robust and highly-scalable implementation of WordPress in Docker using the Autopilot Pattern
GNU General Public License v2.0
158 stars 41 forks source link

Add multi-data center config example #2

Open misterbisson opened 8 years ago

misterbisson commented 8 years ago

If you look closely at the sample HyperDB config, you spot some details related to usage across data centers. Specifically, note the following:

    // dc is not used in hyperdb. This produces the desired effect of
    // trying to connect to local servers before remote servers. Also
    // increases time allowed for TCP responsiveness check.
    if ( !empty($dc) && defined(DATACENTER) && $dc != DATACENTER ) {
        if ( $read )
            $read += 10000;
        if ( $write ) 
            $write += 10000;
        $timeout = 0.7;
    }

Here's the larger context:

/**
 * This is back-compatible with an older config style. It is for convenience.
 * lhost, part, and dc were removed from hyperdb because the read and write
 * parameters provide enough power to achieve the desired effects via config.
 *
 * @param string $dataset Datset: the name of the dataset. Just use "global" if you don't need horizontal partitioning.
 * @param int $part Partition: the vertical partition number (1, 2, 3, etc.). Use "0" if you don't need vertical partitioning.
 * @param string $dc Datacenter: where the database server is located. Airport codes are convenient. Use whatever.
 * @param int $read Read group: tries all servers in lowest number group before trying higher number group. Typical: 1 for slaves, 2 for master. This will cause reads to go to slaves unless all slaves are unreachable. Zero for no reads.
 * @param bool $write Write flag: is this server writable? Works the same as $read. Typical: 1 for master, 0 for slaves.
 * @param string $host Internet address: host:port of server on internet. 
 * @param string $lhost Local address: host:port of server for use when in same datacenter. Leave empty if no local address exists.
 * @param string $name Database name.
 * @param string $user Database user.
 * @param string $password Database password.
 */
function add_db_server($dataset, $part, $dc, $read, $write, $host, $lhost, $name, $user, $password, $timeout = 0.2 ) {
    global $wpdb;

    // dc is not used in hyperdb. This produces the desired effect of
    // trying to connect to local servers before remote servers. Also
    // increases time allowed for TCP responsiveness check.
    if ( !empty($dc) && defined(DATACENTER) && $dc != DATACENTER ) {
        if ( $read )
            $read += 10000;
        if ( $write ) 
            $write += 10000;
        $timeout = 0.7;
    }

    // You'll need a hyperdb::add_callback() callback function to use partitioning.
    // $wpdb->add_callback( 'my_func' );
    if ( $part )
        $dataset = $dataset . '_' . $part;

    $database = compact('dataset', 'read', 'write', 'host', 'name', 'user', 'password', 'timeout');

    $wpdb->add_database($database);

    // lhost is not used in hyperdb. This configures hyperdb with an
    // additional server to represent the local hostname so it tries to
    // connect over the private interface before the public one.
    if ( !empty( $lhost ) ) {
        if ( $read )
            $database['read'] = $read - 0.5;
        if ( $write )
            $database['write'] = $write - 0.5;
        $wpdb->add_database( $database );
    }
}

Implementing that will require a lot more work in setting up cross-data center networking, but it's worth noting and marking as a project.