diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2008-08-15 01:29:47 +0200 |
commit | 370e83bb0dfd0c70de268c93bf07ad5ee0897192 (patch) | |
tree | 491674f4c242e4d6ba0d04eafa305174c35a3391 /includes/db/LoadMonitor.php | |
parent | f4debf0f12d0524d2b2427c55ea3f16b680fad97 (diff) |
Update auf 1.13.0
Diffstat (limited to 'includes/db/LoadMonitor.php')
-rw-r--r-- | includes/db/LoadMonitor.php | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/includes/db/LoadMonitor.php b/includes/db/LoadMonitor.php new file mode 100644 index 00000000..8e16f1a1 --- /dev/null +++ b/includes/db/LoadMonitor.php @@ -0,0 +1,121 @@ +<?php + +/** + * An interface for database load monitoring + */ + +interface LoadMonitor { + /** + * Construct a new LoadMonitor with a given LoadBalancer parent + */ + function __construct( $parent ); + + /** + * Perform pre-connection load ratio adjustment. + * @param array $loads + * @param string $group The selected query group + * @param string $wiki + */ + function scaleLoads( &$loads, $group = false, $wiki = false ); + + /** + * Perform post-connection backoff. + * + * If the connection is in overload, this should return a backoff factor + * which will be used to control polling time. The number of threads + * connected is a good measure. + * + * If there is no overload, zero can be returned. + * + * A threshold thread count is given, the concrete class may compare this + * to the running thread count. The threshold may be false, which indicates + * that the sysadmin has not configured this feature. + * + * @param Database $conn + * @param float $threshold + */ + function postConnectionBackoff( $conn, $threshold ); + + /** + * Return an estimate of replication lag for each server + */ + function getLagTimes( $serverIndexes, $wiki ); +} + + +/** + * Basic MySQL load monitor with no external dependencies + * Uses memcached to cache the replication lag for a short time + */ + +class LoadMonitor_MySQL implements LoadMonitor { + var $parent; // LoadBalancer + + function __construct( $parent ) { + $this->parent = $parent; + } + + function scaleLoads( &$loads, $group = false, $wiki = false ) { + } + + function getLagTimes( $serverIndexes, $wiki ) { + wfProfileIn( __METHOD__ ); + $expiry = 5; + $requestRate = 10; + + global $wgMemc; + $masterName = $this->parent->getServerName( 0 ); + $memcKey = wfMemcKey( 'lag_times', $masterName ); + $times = $wgMemc->get( $memcKey ); + if ( $times ) { + # Randomly recache with probability rising over $expiry + $elapsed = time() - $times['timestamp']; + $chance = max( 0, ( $expiry - $elapsed ) * $requestRate ); + if ( mt_rand( 0, $chance ) != 0 ) { + unset( $times['timestamp'] ); + wfProfileOut( __METHOD__ ); + return $times; + } + wfIncrStats( 'lag_cache_miss_expired' ); + } else { + wfIncrStats( 'lag_cache_miss_absent' ); + } + + # Cache key missing or expired + + $times = array(); + foreach ( $serverIndexes as $i ) { + if ($i == 0) { # Master + $times[$i] = 0; + } elseif ( false !== ( $conn = $this->parent->getAnyOpenConnection( $i ) ) ) { + $times[$i] = $conn->getLag(); + } elseif ( false !== ( $conn = $this->parent->openConnection( $i, $wiki ) ) ) { + $times[$i] = $conn->getLag(); + } + } + + # Add a timestamp key so we know when it was cached + $times['timestamp'] = time(); + $wgMemc->set( $memcKey, $times, $expiry ); + + # But don't give the timestamp to the caller + unset($times['timestamp']); + $lagTimes = $times; + + wfProfileOut( __METHOD__ ); + return $lagTimes; + } + + function postConnectionBackoff( $conn, $threshold ) { + if ( !$threshold ) { + return 0; + } + $status = $conn->getStatus("Thread%"); + if ( $status['Threads_running'] > $threshold ) { + return $status['Threads_connected']; + } else { + return 0; + } + } +} + |