Cassandra 0.7.4でColumnFamilyのキーを取得する。
Cassandraのメーリングリストで「userアットcassandra.apache」というのがあります。
そこの投稿で「newbie question: how do I know the total number of rows of a cf?」という質問があったので、調べてみました。
質問の回答は
1. run a map reduce. Pig is really helpful in these cases. Make sure you run your MR using Hadoop task tracker on your nodes - or your performance will take a hit. 2. dump all keys using sstablekeys script from relevant files on all machines and count unique values. I do that using "sort -n keys.txt |uniq >> unique_keys.txt"
とか
sort -n keys.txt | uniq | wc -l
とあるのだが、keys.txtはどうやって出力するのか調べてみました。
Cassandraのbinディレクトリをみると「bin/sstablekeys」というのがある。
ついでに、「/bin/sstable2json」というのもある。
とりあえず、実行してみた。
Usage: sstablekeys <sstable>
sstablekeysの中身をみてみると
if [ "x$CASSANDRA_INCLUDE" = "x" ]; then for include in /usr/share/cassandra/cassandra.in.sh \ /usr/local/share/cassandra/cassandra.in.sh \ /opt/cassandra/cassandra.in.sh \ ~/.cassandra.in.sh \ /usr/local/cassandra/bin/cassandra.in.sh \ `dirname $0`/cassandra.in.sh; do if [ -r $include ]; then . $include break fi done elif [ -r $CASSANDRA_INCLUDE ]; then . $CASSANDRA_INCLUDE fi
cassandra.in.shのありかを指定しないといけないらしいので「/usr/local/cassandra/bin/cassandra.in.sh \」を追加してみました。
「./bin/sstablekeys Keyspace1」を実行してみると、
Exception in thread "main" java.util.NoSuchElementException at java.util.StringTokenizer.nextToken(StringTokenizer.java:332) at org.apache.cassandra.io.sstable.Descriptor.fromFilename(Descriptor.java:139) at org.apache.cassandra.io.sstable.Descriptor.fromFilename(Descriptor.java:119) at org.apache.cassandra.tools.SSTableExport.enumeratekeys(SSTableExport.java:271) at org.apache.cassandra.tools.SSTableExport.main(SSTableExport.java:462)
とでてしまいました。
org.apache.cassandra.tools.SSTableExportのソース462行目を読んでみる。enumeratekeys(ssTableFileName, System.out);というメソッドがあるみたい。
実装を確認してみます。
public static void enumeratekeys(String ssTableFile, PrintStream outs) throws IOException { Descriptor desc = Descriptor.fromFilename(ssTableFile); KeyIterator iter = new KeyIterator(desc); DecoratedKey lastKey = null; while (iter.hasNext()) { DecoratedKey key = iter.next(); // validate order of the keys in the sstable if (lastKey != null && lastKey.compareTo(key) > 0 ) throw new IOException("Key out of order! " + lastKey + " > " + key); lastKey = key; outs.println(bytesToHex(key.key)); } iter.close(); outs.flush(); }
標準出力にssTableFileというものをだしているっぽい。多分。
「/var/lib/cassandra/data/Keyspace1/」にStandard2-f-1-Index.dbというファイルがあるので
指定して実行してみました。
$ ./bin/sstablekeys /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db 6d69636869626174616a65737369636133 736173616b696e6f7a6f6d69 736173616b696e6f7a6f6d6933
なんかそれっぽいのがでました。
「./bin/sstable2json /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db」も試してみました。
$ ./bin/sstable2json /var/lib/cassandra/data/Keyspace1/Standard2-f-1-Index.db { "6d69636869626174616a65737369636133": [["616765", "3235", 1300717063585, false], ["6669727374", "4a657373696361", 1300717063585, false], ["6c617374", "4d6963686962617461", 1300717063585, false]], "736173616b696e6f7a6f6d69": [["616765", "3232", 1300716830310000, false], ["6669727374", "6e6f7a6f6d69", 1300716779268000, false], ["6c617374", "736173616b69", 1300716823681000, false]], "736173616b696e6f7a6f6d6933": [["616765", "3232", 1300717063585, false], ["6669727374", "6e6f7a6f6d69", 1300717063585, false], ["6c617374", "736173616b69", 1300717063585, false]] }
それっぽいデータがまたでました。
「Standard2-f-1-Data.db」「Standard2-f-1-Filter.db」「Standard2-f-1-Statistics.db」でもそれぞれ
同じようにキーが出力されるみたいです。