読者です 読者をやめる 読者になる 読者になる

RubyのCassandraクライアントで分散カウンタの削除。

Cassandraクライアントから分散カウンタの削除ができなくてハマったのでメモ。

環境


cassandra (0.12.1)

対策


Cassandraの0.8から分散カウンタが追加されていて、Cassandraクライアントにも"add"というメソッドが追加されています。
これは分散カウンタ用のメソッドで、cassandra-cliの"incr"に相当します。

しかし、Cassandraクライアントから分散カウンタのカラムをremoveしようとしても例外が発生します。
これは多分、Cassandraクライアントのremoveの挙動がrowkey自体の削除ではなく、rowkeyに関連するカラムが削除されてrowkeyが残る仕様になっているのが原因な気がします。
ソースから何かないか探してみると、それっぽいのを発見。

でも扱うメソッドが無いっぽいのでCassandraクライアントを拡張。

対象のソースを見ると、_addの処理と同様の場所に_remove_counterがあるのに、なぜ_remove_counterの実装は無いんだろう?と考えると、見落としてるだけの可能性が高いかも。

require 'cassandra'
class Cassandra
def remove_counter(column_family, key, *columns_and_options)
column_family, column, sub_column, options = extract_and_validate_params(column_family, key, columns_and_options, WRITE_DEFAULTS)

if @batch
mutation_map =
{
key => {
column_family => [ _delete_mutation(column_family, column, sub_column, options[:timestamp]|| Time.stamp) ]
}
}
@batch << [mutation_map, options[:consistency]]
else
args = {:column_family => column_family}
columns = is_super(column_family) ? {:super_column => column, :column => sub_column} : {:column => column}
column_path = CassandraThrift::ColumnPath.new(args.merge(columns))
_remove_counter(key, column_path, options[:consistency])
end
end
end


対象ソース:
cassandra-0.12.1/lib/cassandra/0.8/protocol.rb

8 def _remove_counter(key, column_path, consistency_level)
9 client.remove_counter(key, column_path, consistency_level)
10 end
11
12 def _add(column_family, key, column, sub_column, value, consistency)
13 if is_super(column_family)
14 column_parent = CassandraThrift::ColumnParent.new(:column_family => column_fam
ily, :super_column => column)
15 counter_column = CassandraThrift::CounterColumn.new(:name => sub_column, :valu
e => value)
16 else
17 column_parent = CassandraThrift::ColumnParent.new(:column_family => column_fam
ily)
18 counter_column = CassandraThrift::CounterColumn.new(:name => column, :value =>
value)
19 end
20 client.add(key, column_parent, counter_column, consistency)
21 end