Merge branch 'cassandra-1.2' into cassandra-2.0

This commit is contained in:
Jonathan Ellis 2013-12-06 09:50:37 -06:00
commit f2a82ee731
7 changed files with 1204 additions and 98 deletions

View File

@ -19,6 +19,7 @@ Merged from 1.2:
* Warn when collection read has > 65K elements (CASSANDRA-5428)
* Fix cache persistence when both row and key cache are enabled
(CASSANDRA-6413)
* (Hadoop) add describe_local_ring (CASSANDRA-6268)
2.0.3

View File

@ -770,6 +770,11 @@ service Cassandra {
list<TokenRange> describe_ring(1:required string keyspace)
throws (1:InvalidRequestException ire),
/** same as describe_ring, but considers only nodes in the local DC */
list<TokenRange> describe_local_ring(1:required string keyspace)
throws (1:InvalidRequestException ire),
/** get the mapping between token->node ip
without taking replication into consideration
https://issues.apache.org/jira/browse/CASSANDRA-4092 */

View File

@ -56,6 +56,6 @@ import org.slf4j.LoggerFactory;
public class cassandraConstants {
public static final String VERSION = "19.38.0";
public static final String VERSION = "19.39.0";
}

View File

@ -19,12 +19,7 @@ package org.apache.cassandra.hadoop;
import java.io.IOException;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@ -134,6 +129,7 @@ public abstract class AbstractColumnFamilyInputFormat<K, Y> extends InputFormat<
partitioner = ConfigHelper.getInputPartitioner(context.getConfiguration());
logger.debug("partitioner is " + partitioner);
// cannonical ranges, split into pieces, fetching the splits in parallel
ExecutorService executor = new ThreadPoolExecutor(0, 128, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
List<InputSplit> splits = new ArrayList<InputSplit>();
@ -330,7 +326,7 @@ public abstract class AbstractColumnFamilyInputFormat<K, Y> extends InputFormat<
List<TokenRange> map;
try
{
map = client.describe_ring(ConfigHelper.getInputKeyspace(conf));
map = client.describe_local_ring(ConfigHelper.getInputKeyspace(conf));
}
catch (InvalidRequestException e)
{

View File

@ -37,6 +37,7 @@ import javax.management.ObjectName;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.collect.*;
import com.google.common.util.concurrent.AtomicDouble;
import com.google.common.util.concurrent.FutureCallback;
@ -1062,16 +1063,62 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
}
public Map<Range<Token>, List<InetAddress>> getRangeToAddressMap(String keyspace)
{
return getRangeToAddressMap(keyspace, tokenMetadata.sortedTokens());
}
public Map<Range<Token>, List<InetAddress>> getRangeToAddressMapInLocalDC(String keyspace)
{
Predicate<InetAddress> isLocalDC = new Predicate<InetAddress>()
{
public boolean apply(InetAddress address)
{
return isLocalDC(address);
}
};
Map<Range<Token>, List<InetAddress>> origMap = getRangeToAddressMap(keyspace, getTokensInLocalDC());
Map<Range<Token>, List<InetAddress>> filteredMap = Maps.newHashMap();
for (Map.Entry<Range<Token>, List<InetAddress>> entry : origMap.entrySet())
{
List<InetAddress> endpointsInLocalDC = Lists.newArrayList(Collections2.filter(entry.getValue(), isLocalDC));
filteredMap.put(entry.getKey(), endpointsInLocalDC);
}
return filteredMap;
}
private List<Token> getTokensInLocalDC()
{
List<Token> filteredTokens = Lists.newArrayList();
for (Token token : tokenMetadata.sortedTokens())
{
InetAddress endpoint = tokenMetadata.getEndpoint(token);
if (isLocalDC(endpoint))
filteredTokens.add(token);
}
return filteredTokens;
}
private boolean isLocalDC(InetAddress targetHost)
{
String remoteDC = DatabaseDescriptor.getEndpointSnitch().getDatacenter(targetHost);
String localDC = DatabaseDescriptor.getEndpointSnitch().getDatacenter(FBUtilities.getBroadcastAddress());
return remoteDC.equals(localDC);
}
private Map<Range<Token>, List<InetAddress>> getRangeToAddressMap(String keyspace, List<Token> sortedTokens)
{
// some people just want to get a visual representation of things. Allow null and set it to the first
// non-system keyspace.
if (keyspace == null)
keyspace = Schema.instance.getNonSystemKeyspaces().get(0);
List<Range<Token>> ranges = getAllRanges(tokenMetadata.sortedTokens());
List<Range<Token>> ranges = getAllRanges(sortedTokens);
return constructRangeToEndpointMap(keyspace, ranges);
}
/**
* The same as {@code describeRing(String)} but converts TokenRange to the String for JMX compatibility
*
@ -1108,6 +1155,19 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
* @throws InvalidRequestException if there is no ring information available about keyspace
*/
public List<TokenRange> describeRing(String keyspace) throws InvalidRequestException
{
return describeRing(keyspace, false);
}
/**
* The same as {@code describeRing(String)} but considers only the part of the ring formed by nodes in the local DC.
*/
public List<TokenRange> describeLocalRing(String keyspace) throws InvalidRequestException
{
return describeRing(keyspace, true);
}
private List<TokenRange> describeRing(String keyspace, boolean includeOnlyLocalDC) throws InvalidRequestException
{
if (keyspace == null || Keyspace.open(keyspace).getReplicationStrategy() instanceof LocalStrategy)
throw new InvalidRequestException("There is no ring for the keyspace: " + keyspace);
@ -1115,7 +1175,12 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
List<TokenRange> ranges = new ArrayList<TokenRange>();
Token.TokenFactory tf = getPartitioner().getTokenFactory();
for (Map.Entry<Range<Token>, List<InetAddress>> entry : getRangeToAddressMap(keyspace).entrySet())
Map<Range<Token>, List<InetAddress>> rangeToAddressMap =
includeOnlyLocalDC
? getRangeToAddressMapInLocalDC(keyspace)
: getRangeToAddressMap(keyspace);
for (Map.Entry<Range<Token>, List<InetAddress>> entry : rangeToAddressMap.entrySet())
{
Range range = entry.getKey();
List<InetAddress> addresses = entry.getValue();

View File

@ -1394,6 +1394,19 @@ public class CassandraServer implements Cassandra.Iface
}
}
@Override
public List<TokenRange> describe_local_ring(String keyspace) throws InvalidRequestException, TException
{
try
{
return StorageService.instance.describeLocalRing(keyspace);
}
catch (RequestValidationException e)
{
throw ThriftConversion.toThrift(e);
}
}
public Map<String, String> describe_token_map() throws InvalidRequestException
{
return StorageService.instance.getTokenToEndpointMap();