Skip to content
Browse files

reduce UPDATE's to device table

each tracker would update all device rows every 15 seconds. For setups with
lots of trackers, lots of devices, or both, this could end up with a huge
number of UPDATE's per second.

Now it tries pretty hard to update each row at most once every 15 seconds, at
the expensive of one extra DB read per monitor cycle.
  • Loading branch information...
1 parent 215dd9e commit 662f33cbc51575ce98bb322d4fa92aa979062a91 @dormando dormando committed Feb 28, 2012
Showing with 23 additions and 11 deletions.
  1. +23 −11 lib/MogileFS/Worker/Monitor.pm
View
34 lib/MogileFS/Worker/Monitor.pm
@@ -4,7 +4,6 @@ use warnings;
use base 'MogileFS::Worker';
use fields (
- 'last_db_update', # devid -> time. update db less often than poll interval.
'last_test_write', # devid -> time. time we last tried writing to a device.
'skip_host', # hostid -> 1 if already noted dead (reset every loop)
'seen_hosts', # IP -> 1 (reset every loop)
@@ -29,7 +28,6 @@ sub new {
my $self = fields::new($class);
$self->SUPER::new($psock);
- $self->{last_db_update} = {};
$self->{last_test_write} = {};
$self->{iow} = MogileFS::IOStatWatcher->new;
$self->{prev_data} = { domain => {}, class => {}, host => {},
@@ -75,6 +73,14 @@ sub usage_refresh {
debug("Monitor running; scanning usage files");
my $have_dbh = $self->validate_dbh;
+ my $updateable_devices;
+
+ # See if we should be allowed to update the device table rows.
+ if ($have_dbh && Mgd::get_store()->get_lock('mgfs:device_update', 0)) {
+ # Fetch the freshlist list of entries, to avoid excessive writes.
+ $updateable_devices = { map { $_->{devid} => $_ }
+ Mgd::get_store()->get_all_devices };
+ }
$self->{skip_host} = {}; # hostid -> 1 if already noted dead.
$self->{seen_hosts} = {}; # IP -> 1
@@ -89,11 +95,16 @@ sub usage_refresh {
}
$cur_iow->{$dev->id} = $self->{devutil}->{cur}->{$dev->id};
next if $self->{skip_host}{$dev->hostid};
- $self->check_device($dev, $have_dbh) if $dev->dstate->should_monitor;
+ $self->check_device($dev, $have_dbh, $updateable_devices)
+ if $dev->dstate->should_monitor;
$self->still_alive; # Ping parent if needed so we don't time out
# given lots of devices.
}
+ if ($have_dbh) {
+ Mgd::get_store()->release_lock('mgfs:device_update');
+ }
+
$self->{devutil}->{prev} = $cur_iow;
# Set the IOWatcher hosts (once old monitor code has been disabled)
@@ -304,7 +315,7 @@ sub ua {
}
sub check_device {
- my ($self, $dev, $have_dbh) = @_;
+ my ($self, $dev, $have_dbh, $updateable_devices) = @_;
my $devid = $dev->id;
my $host = $dev->host;
@@ -367,14 +378,15 @@ sub check_device {
}
# only update database every ~15 seconds per device
- my $last_update = $self->{last_db_update}{$dev->id} || 0;
- my $next_update = $last_update + UPDATE_DB_EVERY;
my $now = time();
- if ($now >= $next_update && $have_dbh) {
- Mgd::get_store()->update_device_usage(mb_total => int($total / 1024),
- mb_used => int($used / 1024),
- devid => $devid);
- $self->{last_db_update}{$devid} = $now;
+ if ($have_dbh && $updateable_devices) {
+ my $devrow = $updateable_devices->{$devid};
+ my $last = ($devrow && $devrow->{mb_asof}) ? $devrow->{mb_asof} : 0;
+ if ($last + UPDATE_DB_EVERY < $now) {
+ Mgd::get_store()->update_device_usage(mb_total => int($total / 1024),
+ mb_used => int($used / 1024),
+ devid => $devid);
+ }
}
# next if we're not going to try this now

0 comments on commit 662f33c

Please sign in to comment.
Something went wrong with that request. Please try again.