cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brandonwilli...@apache.org
Subject svn commit: r1037055 - in /cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra: dht/ service/ tools/
Date Fri, 19 Nov 2010 22:22:59 GMT
Author: brandonwilliams
Date: Fri Nov 19 22:22:59 2010
New Revision: 1037055

URL: http://svn.apache.org/viewvc?rev=1037055&view=rev
Log:
nodetool ring shows the percentage each node owns.  Patch by Jon Hermes, reviewed by brandonwilliams
for CASSANDRA-1553

Modified:
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/IPartitioner.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/RandomPartitioner.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageServiceMBean.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeCmd.java
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeProbe.java

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
(original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
Fri Nov 19 22:22:59 2010
@@ -20,10 +20,7 @@ package org.apache.cassandra.dht;
 
 import java.math.BigInteger;
 import java.text.Collator;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Locale;
-import java.util.Random;
+import java.util.*;
 
 import org.apache.commons.lang.ArrayUtils;
 
@@ -152,4 +149,6 @@ public class CollatingOrderPreservingPar
             return MINIMUM;
         return new BytesToken(collator.getCollationKey(key).toByteArray());
     }
+
+    public Map<Token, Float> describeOwnership(List<Token> sortedTokens){ throw
new UnsupportedOperationException(); }
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/IPartitioner.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/IPartitioner.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/IPartitioner.java (original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/IPartitioner.java Fri
Nov 19 22:22:59 2010
@@ -18,7 +18,8 @@
 
 package org.apache.cassandra.dht;
 
-import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.cassandra.db.DecoratedKey;
 
@@ -80,4 +81,13 @@ public interface IPartitioner<T extends 
      * it generates.
      */
     public boolean preservesOrder();
+
+    /**
+     * Calculate the deltas between tokens in the ring in order to compare
+     *  relative sizes.
+     *
+     * @param sortedTokens a sorted List of Tokens
+     * @return the mapping from 'token' to 'percentage of the ring owned by that token'.
+     */
+    public Map<Token, Float> describeOwnership(List<Token> sortedTokens);
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java
(original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/OrderPreservingPartitioner.java
Fri Nov 19 22:22:59 2010
@@ -20,12 +20,10 @@ package org.apache.cassandra.dht;
 
 import java.io.UnsupportedEncodingException;
 import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Random;
+import java.util.*;
 
-import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.DecoratedKey;
+import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.cassandra.utils.Pair;
 
@@ -165,4 +163,35 @@ public class OrderPreservingPartitioner 
     {
         return new StringToken(key);
     }
+
+    public Map<Token, Float> describeOwnership(List<Token> sortedTokens)
+    {
+        // alltokens will contain the count and be returned, sorted_ranges is shorthand for
token<->token math.
+        Map<Token, Float> alltokens = new HashMap<Token, Float>();
+        List<Range> sorted_ranges = new ArrayList<Range>();
+
+        // this initializes the counts to 0 and calcs the ranges in order.
+        Token last_t = sortedTokens.get(sortedTokens.size()-1);
+        for (Token node : sortedTokens)
+        {
+            alltokens.put(node, new Float(0.0));
+            sorted_ranges.add(new Range(last_t, node));
+            last_t = node;
+        }
+
+        for (Range r : sorted_ranges)
+        {
+            // Looping over every KS:CF:Range, get the splits size and add it to the count
+            alltokens.put(r.right, alltokens.get(r.right) + StorageService.instance.getSplits(r,
1).size());
+        }
+
+        // Sum every count up and divide count/total for the fractional ownership.
+        Float total = new Float(0.0);
+        for (Float f : alltokens.values()) { total += f; }
+        for (Map.Entry<Token, Float> row : alltokens.entrySet()) {
+            alltokens.put(row.getKey(), row.getValue() / total);
+        }
+        
+        return alltokens;
+    }
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/RandomPartitioner.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/RandomPartitioner.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/RandomPartitioner.java
(original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/dht/RandomPartitioner.java
Fri Nov 19 22:22:59 2010
@@ -18,8 +18,9 @@
 
 package org.apache.cassandra.dht;
 
+import java.math.BigDecimal;
 import java.math.BigInteger;
-import java.util.Comparator;
+import java.util.*;
 import java.util.regex.Pattern;
 
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -117,4 +118,36 @@ public class RandomPartitioner implement
             return MINIMUM;
         return new BigIntegerToken(FBUtilities.hash(key));
     }
+
+    public Map<Token, Float> describeOwnership(List<Token> sortedTokens)
+    {
+        Map<Token, Float> ownerships = new HashMap<Token, Float>();
+        Iterator i = sortedTokens.iterator();
+
+        // 0-case
+        if (!i.hasNext()) { throw new RuntimeException("No nodes present in the cluster.
How did you call this?"); }
+        // 1-case
+        if (sortedTokens.size() == 1) {
+            ownerships.put((Token)i.next(), new Float(1.0));
+        }
+        // n-case
+        else {
+            // NOTE: All divisions must take place in BigDecimals, and all modulo operators
must take place in BigIntegers.
+            final BigInteger ri = new BigInteger("2").pow(127);                         
   //  (used for addition later)
+            final BigDecimal r  = new BigDecimal(ri);                                   
   // The entire range, 2**127
+            Token start = (Token)i.next(); BigInteger ti = ((BigIntegerToken)start).token;
 // The first token and its value
+            Token t; BigInteger tim1 = ti;                                              
   // The last token and its value (after loop)
+            while (i.hasNext()) {
+                t = (Token)i.next(); ti = ((BigIntegerToken)t).token;                   
   // The next token and its value
+                float x = new BigDecimal(ti.subtract(tim1)).divide(r).floatValue();     
   // %age = T(i) - T(i-1) / R
+                ownerships.put(t, x);                                                   
   // save (T(i) -> %age)
+                tim1 = ti;                                                              
   // -> advance loop
+            }
+            // The start token's range extends backward to the last token, which is why both
were saved
+            //  above. The simple calculation for this is: T(start) - T(end) + r % r / r.
+            //  (In the 1-case, this produces 0% instead of 100%.)
+            ownerships.put(start, new BigDecimal(((BigIntegerToken)start).token.subtract(ti).add(ri).mod(ri)).divide(r).floatValue());
+        }
+        return ownerships;
+    }
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
(original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageService.java
Fri Nov 19 22:22:59 2010
@@ -1645,4 +1645,14 @@ public class StorageService implements I
         tokenMetadata_ = tmd;
         return old;
     }
+
+    public Map<Token, Float> getOwnership()
+    {
+        List<Range> ranges = new ArrayList<Range>(getRangeToEndPointMap(null).keySet());
+        List<Token> sortedTokens = new ArrayList<Token>();
+        for(Range r : ranges) { sortedTokens.add(r.left); }
+        Collections.sort(sortedTokens);
+
+        return partitioner_.describeOwnership(sortedTokens);
+    }
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageServiceMBean.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageServiceMBean.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageServiceMBean.java
(original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/StorageServiceMBean.java
Fri Nov 19 22:22:59 2010
@@ -27,6 +27,7 @@ import java.util.Set;
 import java.util.concurrent.ExecutionException;
 
 import org.apache.cassandra.dht.Range;
+import org.apache.cassandra.dht.Token;
 
 
 public interface StorageServiceMBean
@@ -184,4 +185,10 @@ public interface StorageServiceMBean
 
     /** save row and key caches */
     public void saveCaches() throws ExecutionException, InterruptedException;
+
+    /**
+     * given a list of tokens (representing the nodes in the cluster), returns
+     *   a mapping from "token -> %age of cluster owned by that token"
+     */
+    public Map<Token, Float> getOwnership();
 }

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeCmd.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeCmd.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeCmd.java (original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeCmd.java Fri
Nov 19 22:22:59 2010
@@ -26,6 +26,7 @@ import org.apache.cassandra.concurrent.I
 import org.apache.cassandra.db.ColumnFamilyStoreMBean;
 import org.apache.cassandra.db.CompactionManager;
 import org.apache.cassandra.dht.Range;
+import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.utils.EstimatedHistogram;
 import org.apache.commons.cli.*;
 
@@ -33,6 +34,7 @@ import java.io.IOException;
 import java.io.PrintStream;
 import java.lang.management.MemoryUsage;
 import java.net.InetAddress;
+import java.text.DecimalFormat;
 import java.util.*;
 import java.util.Map.Entry;
 import java.util.concurrent.ExecutionException;
@@ -90,18 +92,20 @@ public class NodeCmd {
         Set<String> liveNodes = probe.getLiveNodes();
         Set<String> deadNodes = probe.getUnreachableNodes();
         Map<String, String> loadMap = probe.getLoadMap();
+        Map<Token, Float> ownerships = probe.getOwnership();
 
         // Print range-to-endpoint mapping
         int counter = 0;
         outs.print(String.format("%-14s", "Address"));
         outs.print(String.format("%-11s", "Status"));
         outs.print(String.format("%-14s", "Load"));
+        outs.print(String.format("%-8s", "Owns"));
         outs.print(String.format("%-43s", "Range"));
         outs.println("Ring");
         // emphasize that we're showing the right part of each range
         if (ranges.size() > 1)
         {
-            outs.println(String.format("%-14s%-11s%-14s%-43s", "", "", "", ranges.get(0).left));
+            outs.println(String.format("%-14s%-11s%-14s%-8s%-43s", "", "", "", "", ranges.get(0).left));
         }
         // normal range & node info
         for (Range range : ranges) {
@@ -120,6 +124,9 @@ public class NodeCmd {
             String load = loadMap.containsKey(primaryEndpoint) ? loadMap.get(primaryEndpoint)
: "?";
             outs.print(String.format("%-14s", load));
 
+            DecimalFormat df = new DecimalFormat("##0.00%");
+            outs.print(String.format("%-8s", df.format(ownerships.get(range.right))));
+
             outs.print(String.format("%-43s", range.right));
 
             String asciiRingArt;

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeProbe.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeProbe.java?rev=1037055&r1=1037054&r2=1037055&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeProbe.java (original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/tools/NodeProbe.java Fri
Nov 19 22:22:59 2010
@@ -24,6 +24,7 @@ import java.lang.management.ManagementFa
 import java.lang.management.MemoryMXBean;
 import java.lang.management.MemoryUsage;
 import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.Constructor;
 import java.net.InetAddress;
 import java.util.AbstractMap;
 import java.util.ArrayList;
@@ -46,6 +47,7 @@ import org.apache.cassandra.db.ColumnFam
 import org.apache.cassandra.db.CompactionManager;
 import org.apache.cassandra.db.CompactionManagerMBean;
 import org.apache.cassandra.dht.Range;
+import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.service.StorageServiceMBean;
 import org.apache.cassandra.streaming.StreamingService;
 import org.apache.cassandra.streaming.StreamingServiceMBean;
@@ -250,6 +252,11 @@ public class NodeProbe
         return ssProxy.getLoadMap();
     }
 
+    public Map<Token, Float> getOwnership()
+    {
+        return ssProxy.getOwnership();
+    }
+
     public Iterator<Map.Entry<String, ColumnFamilyStoreMBean>> getColumnFamilyStoreMBeanProxies()
     {
         try



Mime
View raw message