diff --git a/doc/Extensions/Distributed-Poller.md b/doc/Extensions/Distributed-Poller.md new file mode 100644 index 0000000000..86cd35d3fe --- /dev/null +++ b/doc/Extensions/Distributed-Poller.md @@ -0,0 +1,23 @@ +# Distributed Poller +LibreNMS has the ability to distribute polling of devices to other machines. + +These machines can be in a different physical location and therefore minimize network latencies for colocations. + +Devices can also be groupped together into a `poller_group` to pin these devices to a single or a group of designated pollers. + +All pollers need to share their RRD-folder, for example via NFS or a combination of NFS and rrdcached. +It is also required that all pollers can access the central memcached to communicate with eachother. + +In order to enable distributed polling, set `$config['distributed_poller'] = true` and your memcached details into `$config['distributed_poller_memcached_host']` and `$config['distributed_poller_memcached_port']`. +By default, all hosts are shared and have the `poller_group = 0`. To pin a device to a poller, set it to a value greater than 0 and set the same value in the poller's config with `$config['distributed_poller_group']`. +Usually the poller's name is equal to the machine's hostname, if you want to change it set `$config['distributed_poller_name']`. + +## Configuration +```php +// Distributed Poller-Settings +$config['distributed_poller'] = false; +$config['distributed_poller_name'] = file_get_contents('/proc/sys/kernel/hostname'); +$config['distributed_poller_group'] = 0; +$config['distributed_poller_memcached_host'] = 'example.net'; +$config['distributed_poller_memcached_port'] = '11211'; +``` diff --git a/includes/defaults.inc.php b/includes/defaults.inc.php index f0599fb836..d160cb0cb9 100644 --- a/includes/defaults.inc.php +++ b/includes/defaults.inc.php @@ -589,4 +589,11 @@ $config['enable_clear_discovery'] = 1;// Set this to 0 if $config['enable_footer'] = 1;// Set this to 0 if you want to disable the footer copyright in the web interface $config['api_demo'] = 0;// Set this to 1 if you want to disable some untrusting features for the API +// Distributed Poller-Settings +$config['distributed_poller'] = false; +$config['distributed_poller_name'] = file_get_contents('/proc/sys/kernel/hostname'); +$config['distributed_poller_group'] = 0; +$config['distributed_poller_memcached_host'] = 'example.net'; +$config['distributed_poller_memcached_port'] = '11211'; + ?> diff --git a/poller-wrapper.py b/poller-wrapper.py index 9200e422cc..148e15bd04 100755 --- a/poller-wrapper.py +++ b/poller-wrapper.py @@ -74,9 +74,66 @@ db_password = config['db_pass'] db_server = config['db_host'] db_dbname = config['db_name'] +# (c) 2015, GPLv3, Daniel Preussker << << << << << << 0 and nodes is not None: + try: + time.sleep(1) + nodes = memc.get("poller.nodes") + except: + pass + print "Clearing Locks" + x = minlocks + while x <= maxlocks: + memc.delete('poller.device.'+str(x)) + x = x+1 + print "%s Locks Cleared" % x + print "Clearing Nodes" + memc.delete("poller.master") + memc.delete("poller.nodes") + else: + memc.decr("poller.nodes") + print "Finished %s." % time.time() +# EOC6 show_stopper = False +query = "update pollers set last_polled=NOW(), devices='%d', time_taken='%d' where poller_name='%s'" % (polled_devices, total_time, config['distributed_poller_name']) +response = cursor.execute(query) +if response == 1: + db.commit() +else: + query = "insert into pollers set poller_name='%s', last_polled=NOW(), devices='%d', time_taken='%d'" % (config['distributed_poller_name'],polled_devices, total_time) + cursor.execute(query) + db.commit() +db.close() + + if total_time > 300: recommend = int(total_time / 300.0 * amount_of_workers + 1) print "WARNING: the process took more than 5 minutes to finish, you need faster hardware or more threads" @@ -195,4 +344,5 @@ if total_time > 300: print "ERROR: Some devices are taking more than 300 seconds, the script cannot recommend you what to do." if show_stopper == False: print "WARNING: Consider setting a minimum of %d threads. (This does not constitute professional advice!)" % recommend + sys.exit(2) diff --git a/poller.php b/poller.php index 2a1f348e18..6608b32547 100755 --- a/poller.php +++ b/poller.php @@ -118,7 +118,7 @@ $poller_end = utime(); $poller_run = $poller_end - $poller_start; $poller_time = if ($polled_devices) { - dbInsert(array('type' => 'poll', 'doing' => $doing, 'start' => $poller_start, 'duration' => $poller_time, 'devices' => $polled_devices ), 'perf_times'); + dbInsert(array('type' => 'poll', 'doing' => $doing, 'start' => $poller_start, 'duration' => $poller_time, 'devices' => $polled_devices, 'poller' => $config['distributed_poller_name'] ), 'perf_times'); } $string = $argv[0] . " $doing " . date($config['dateformat']['compact']) . " - $polled_devices devices polled in $poller_time secs"; diff --git a/sql-schema/042.sql b/sql-schema/042.sql new file mode 100644 index 0000000000..6c66ad7ec3 --- /dev/null +++ b/sql-schema/042.sql @@ -0,0 +1,2 @@ +CREATE TABLE `pollers` (`id` int(11) NOT NULL AUTO_INCREMENT, `poller_name` varchar(255) NOT NULL, `last_polled` datetime NOT NULL, `devices` int(11) NOT NULL, `time_taken` double NOT NULL, KEY `id` (`id`)) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +ALTER TABLE `devices` ADD `poller_group` INT(11) NOT NULL DEFAULT '0';