I am currently testing Cassie and its performance regarding connections and connection management. After turning on the OstrichStatsReceiver, I noticed that there are various things you have to do to get the values of "connects", "connections", and "load balancer" counts to change. With our initial implementation, we were only getting one "connection" for the entire application and one "connect" for each akka actor that contained our Cassie cluster and keyspace definitions.
My question is: What is the standardized way to access Cassie to get optimal connection performance. I can think of three ways to setup cassie given our paradigm. I have pasted all three definitions at the bottom. After writing out these tests, it seems like the final implementation is the correct one.
import com.twitter.cassie.{CounterColumn, Column, Cluster}
import com.twitter.finagle.stats.OstrichStatsReceiver
import com.twitter.finagle.tracing.NullTracer
import com.twitter.cassie.codecs.{ByteArrayCodec, Utf8Codec, LongCodec, IntCodec}
abstract class CassieStuff extends akka.actor.Actor {
protected val cluster = new Cluster(Set("localhost"), 9160, new OstrichStatsReceiver(), NullTracer.factory)
protected val keyspaceName = "distserv"
protected def insert()
def receive = {
case _ => insert()
}
}
class CassieTest1 extends CassieStuff {
// Connection immediately established
private val keyspace = cluster.keyspace(keyspaceName)
.minConnectionsPerHost(5)
.maxConnectionsPerHost(10)
.connect()
// Column Family definitions use keyspace instance
private val batchInfo = keyspace.columnFamily("BatchInfo", Utf8Codec, Utf8Codec, ByteArrayCodec)
private val batchCount = keyspace.counterColumnFamily("BatchCount", Utf8Codec, Utf8Codec)
protected def insert() {
val batchID = "123"
batchInfo.batch()
.insert(batchID, Column("batchCount", IntCodec.encode(5)))
.insert(batchID, Column("startTime", LongCodec.encode(10)))
.execute()
batchCount.add(batchID, CounterColumn("batchCount", 5))
}
}
class CassieTest2 extends CassieStuff {
private val cluster = new Cluster(Set("localhost"), 9160, new OstrichStatsReceiver(), NullTracer.factory)
// Connection is not immediately established on the keyspace
private val keyspace = cluster.keyspace(keyspaceName)
.minConnectionsPerHost(5)
.maxConnectionsPerHost(10)
// Keyspace builder creates connection per keyspace definition
private val batchInfo = keyspace.connect().columnFamily("BatchInfo", Utf8Codec, Utf8Codec, ByteArrayCodec)
private val batchCount = keyspace.connect().counterColumnFamily("BatchCount", Utf8Codec, Utf8Codec)
protected def insert() {
val batchID = "123"
batchInfo.batch()
.insert(batchID, Column("batchCount", IntCodec.encode(5)))
.insert(batchID, Column("startTime", LongCodec.encode(10)))
.execute()
batchCount.add(batchID, CounterColumn("batchCount", 5))
}
}
class CassieTest3 extends CassieStuff {
// Connection is not immediately established on the keyspace
private val keyspace = cluster.keyspace(keyspaceName)
.minConnectionsPerHost(5)
.maxConnectionsPerHost(10)
// Column family definitions are changed from properties to methods to yield a new connection per reference
private def batchInfo = keyspace.connect().columnFamily("BatchInfo", Utf8Codec, Utf8Codec, ByteArrayCodec)
private def batchCount = keyspace.connect().counterColumnFamily("BatchCount", Utf8Codec, Utf8Codec)
protected def insert() {
val batchID = "123"
batchInfo.batch()
.insert(batchID, Column("batchCount", IntCodec.encode(5)))
.insert(batchID, Column("startTime", LongCodec.encode(10)))
.execute()
batchCount.add(batchID, CounterColumn("batchCount", 5))
}
}