问题
my partition keys are id(int) and name(text). Below command works fine until there is no space in name(text). nodetool getendpoints test testtable2 1:aaa;
if am using nodetool getendpoints test testtable2 3:aac cc; it throws an error as :nodetool: getendpoints requires keyspace, table and partition key arguments See 'nodetool help' or 'nodetool help '.
i got token by executing SELECT id,name, token(id,name) FROM test.testtable2 where name='aac cc'AND id=3; and tried to search nodetool getendpoints test testtable2 -7072928299163215694; error: For input string: "-7072928299163215694" -- StackTrace -- java.lang.NumberFormatException: For input string: "-7072928299163215694"
how can i search if partition key (name) has space?
回答1:
This is an issue of nodetool
command.
I have modified the nodetool
script and create getendpoints
script to support getendpoints with partition key has space
Here is the getendpoints
code :
#!/bin/sh
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
if [ "`basename "$0"`" = 'nodeprobe' ]; then
echo "***************************************************************" >&2
echo "WARNING: $0 is obsolete, use `dirname "$0"`/nodetool instead" >&2
echo "***************************************************************" >&2
fi
if [ "x$CASSANDRA_INCLUDE" = "x" ]; then
for include in "`dirname "$0"`/cassandra.in.sh" \
"$HOME/.cassandra.in.sh" \
/usr/share/cassandra/cassandra.in.sh \
/usr/local/share/cassandra/cassandra.in.sh \
/opt/cassandra/cassandra.in.sh; do
if [ -r "$include" ]; then
. "$include"
break
fi
done
elif [ -r "$CASSANDRA_INCLUDE" ]; then
. "$CASSANDRA_INCLUDE"
fi
# Use JAVA_HOME if set, otherwise look for java in PATH
if [ -x "$JAVA_HOME/bin/java" ]; then
JAVA="$JAVA_HOME/bin/java"
else
JAVA="`which java`"
fi
if [ -z "$CASSANDRA_CONF" -o -z "$CLASSPATH" ]; then
echo "You must set the CASSANDRA_CONF and CLASSPATH vars" >&2
exit 1
fi
# Run cassandra-env.sh to pick up JMX_PORT
if [ -f "$CASSANDRA_CONF/cassandra-env.sh" ]; then
. "$CASSANDRA_CONF/cassandra-env.sh"
fi
# JMX Port passed via cmd line args (-p 9999 / --port 9999 / --port=9999)
# should override the value from cassandra-env.sh
ARGS=""
JVM_ARGS=""
SSL_FILE=$HOME/.cassandra/nodetool-ssl.properties
KS=""
CF=""
KEY=""
while true
do
if [ ! $1 ]; then break; fi
case $1 in
-p)
JMX_PORT=$2
shift
;;
--port=*)
JMX_PORT=$(echo $1 | cut -d '=' -f 2)
;;
--port)
JMX_PORT=$2
shift
;;
--ssl)
if [ -f $SSL_FILE ]
then
SSL_ARGS=$(cat $SSL_FILE | tr '\n' ' ')
fi
JVM_ARGS="$JVM_ARGS -Dssl.enable=true $SSL_ARGS"
;;
-D*)
JVM_ARGS="$JVM_ARGS $1"
;;
-k)
KS=$2
shift
;;
-t)
CF=$2
shift
;;
*)
if [ ! $KEY ]; then
KEY="$1"
else
KEY="$KEY $1"
fi
;;
esac
shift
done
# Special-case path variables.
case "`uname`" in
CYGWIN*)
CLASSPATH="`cygpath -p -w "$CLASSPATH"`"
CASSANDRA_CONF="`cygpath -p -w "$CASSANDRA_CONF"`"
;;
esac
"$JAVA" $JAVA_AGENT -cp "$CLASSPATH" \
-Xmx128m \
-Dcassandra.storagedir="$cassandra_storagedir" \
-Dlogback.configurationFile=logback-tools.xml \
-Dstorage-config="$CASSANDRA_CONF" \
$JVM_ARGS \
org.apache.cassandra.tools.NodeTool -p $JMX_PORT getendpoints $KS $CF "$KEY"
Put getendpoints
file under $CASSANDRA_HOME/bin
directory.
Now you can run this file with nodetool argument,along with below argument
getendpoints -k keyspace_name -t table_name key
Example :
getendpoints -k test -t testtable2 3:aac cc
回答2:
Which Cassandra version you are using.
I have tested it from Cassandra 2.x and Cassandra 3.x version. It is working properly.
root@cqlsh:test_db> SELECT token(name) from test_temp ; system.token(name) --------------------- -907920378987128470 nodetool getendpoints test_db test_temp -907920378987128470; 192.168.8.52
Updated Answer: Got the issue
Issue is generated for when 1st part of partition key is int.
CREATE TABLE test6 ( age int PRIMARY KEY, name text ); bin/nodetool getendpoints test test6 -7072928299163215694
error: For input string: "-7072928299163215694"java.lang.NumberFormatException: For input string:"-
7072928299163215694"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:583)
at java.lang.Integer.parseInt(Integer.java:615)
But works properly for below input
bin/nodetool getendpoints test test6 -7072 127.0.0.1
From DataStax Doc:
Provides the end points that own the partition key. The partitioner returns a token for the key. Cassandra will return an endpoint whether or not data exists on the identified node for that token. ** key is the partition key of the end points you want to get.
nodetool getendpoints actually takes the value of the partition key as input. In this case '-7072928299163215694' it is parsing it as an Integer thus end up thowing exception. It is working for long or String (it is taking '-7072928299163215694' value as a String) cause it has taken this as value of the key not actual token. It is not parsing tokens. So providing tokens as an input will not work.
getendpoints generates tokens from the value of the key and provide you the endpoints (nodes) the key is residing.
Please check this link: What node does Cassandra store data on?
A patch has been provided for this:
https://issues.apache.org/jira/browse/CASSANDRA-4551
Hope this helps.
来源:https://stackoverflow.com/questions/42903926/cassandra-getendpoints-with-partition-key-has-space