Look at the absolute difference in maximum usage percentage. (#454)

diff --git a/pulsar-broker-common/src/main/java/com/yahoo/pulsar/broker/ServiceConfiguration.java b/pulsar-broker-common/src/main/java/com/yahoo/pulsar/broker/ServiceConfiguration.java
index e7691d6..29fde1a7 100644
--- a/pulsar-broker-common/src/main/java/com/yahoo/pulsar/broker/ServiceConfiguration.java
+++ b/pulsar-broker-common/src/main/java/com/yahoo/pulsar/broker/ServiceConfiguration.java
@@ -200,8 +200,10 @@
     // load placement strategy
     private String loadBalancerPlacementStrategy = "weightedRandomSelection"; // weighted random selection
     // Percentage of change to trigger load report update
+    @FieldContext(dynamic = true)
     private int loadBalancerReportUpdateThresholdPercentage = 10;
     // maximum interval to update load report
+    @FieldContext(dynamic = true)
     private int loadBalancerReportUpdateMaxIntervalMinutes = 15;
     // Frequency of report to collect
     private int loadBalancerHostUsageCheckIntervalMinutes = 1;
diff --git a/pulsar-broker/src/main/java/com/yahoo/pulsar/broker/loadbalance/impl/ModularLoadManagerImpl.java b/pulsar-broker/src/main/java/com/yahoo/pulsar/broker/loadbalance/impl/ModularLoadManagerImpl.java
index 5739591..a882703 100644
--- a/pulsar-broker/src/main/java/com/yahoo/pulsar/broker/loadbalance/impl/ModularLoadManagerImpl.java
+++ b/pulsar-broker/src/main/java/com/yahoo/pulsar/broker/loadbalance/impl/ModularLoadManagerImpl.java
@@ -340,14 +340,15 @@
     private boolean needBrokerDataUpdate() {
         final long updateMaxIntervalMillis = TimeUnit.MINUTES
                 .toMillis(conf.getLoadBalancerReportUpdateMaxIntervalMinutes());
-        if (System.currentTimeMillis() - localData.getLastUpdate() > updateMaxIntervalMillis) {
+        long timeSinceLastReportWrittenToZooKeeper = System.currentTimeMillis() - localData.getLastUpdate();
+        if (timeSinceLastReportWrittenToZooKeeper > updateMaxIntervalMillis) {
             log.info("Writing local data to ZooKeeper because time since last update exceeded threshold of {} minutes",
                     conf.getLoadBalancerReportUpdateMaxIntervalMinutes());
             // Always update after surpassing the maximum interval.
             return true;
         }
         final double maxChange = Math
-                .max(percentChange(lastData.getMaxResourceUsage(), localData.getMaxResourceUsage()),
+                .max(100.0 * (Math.abs(lastData.getMaxResourceUsage() - localData.getMaxResourceUsage())),
                         Math.max(percentChange(lastData.getMsgRateIn() + lastData.getMsgRateOut(),
                                 localData.getMsgRateIn() + localData.getMsgRateOut()),
                                 Math.max(
@@ -355,8 +356,9 @@
                                                 localData.getMsgThroughputIn() + localData.getMsgThroughputOut()),
                                         percentChange(lastData.getNumBundles(), localData.getNumBundles()))));
         if (maxChange > conf.getLoadBalancerReportUpdateThresholdPercentage()) {
-            log.info("Writing local data to ZooKeeper because maximum change {}% exceeded threshold {}%", maxChange,
-                    conf.getLoadBalancerReportUpdateThresholdPercentage());
+            log.info("Writing local data to ZooKeeper because maximum change {}% exceeded threshold {}%; " +
+                    "time since last report written is {} seconds", maxChange,
+                    conf.getLoadBalancerReportUpdateThresholdPercentage(), timeSinceLastReportWrittenToZooKeeper/1000.0);
             return true;
         }
         return false;