Giter Site home page Giter Site logo

kestrel's Introduction

Kestrel

Project status

Kestrel is based on Blaine Cook's "starling" simple, distributed message queue, with added features and bulletproofing, as well as the scalability offered by actors and the JVM.

Each server handles a set of reliable, ordered message queues. When you put a cluster of these servers together, with no cross communication, and pick a server at random whenever you do a set or get, you end up with a reliable, loosely ordered message queue.

In many situations, loose ordering is sufficient. Dropping the requirement on cross communication makes it horizontally scale to infinity and beyond: no multicast, no clustering, no "elections", no coordination at all. No talking! Shhh!

For more information about what it is and how to use it, check out the included guide.

Kestrel has a mailing list here: [email protected]

Author's address: Robey Pointer <[email protected]>

Status

We've deprecated Kestrel because internally we've shifted our attention to an alternative project based on DistributedLog, and we no longer have the resources to contribute fixes or accept pull requests. While Kestrel is a great solution up to a certain point (simple, fast, durable, and easy to deploy), it hasn't been able to cope with Twitter's massive scale (in terms of number of tenants, QPS, operability, diversity of workloads etc.) or operating environment (an Aurora cluster without persistent storage).

Features

Kestrel is:

  • fast

    It runs on the JVM so it can take advantage of the hard work people have put into java performance.

  • small

    Currently about 2500 lines of scala, because it relies on Netty (a rough equivalent of Danger's ziggurat or Ruby's EventMachine) -- and because Scala is extremely expressive.

  • durable

    Queues are stored in memory for speed, but logged into a journal on disk so that servers can be shutdown or moved without losing any data.

  • reliable

    A client can ask to "tentatively" fetch an item from a queue, and if that client disconnects from kestrel before confirming ownership of the item, the item is handed to another client. In this way, crashing clients don't cause lost messages.

Anti-Features

Kestrel is not:

  • strongly ordered

    While each queue is strongly ordered on each machine, a cluster will appear "loosely ordered" because clients pick a machine at random for each operation. The end result should be "mostly fair".

  • transactional

    This is not a database. Item ownership is transferred with acknowledgement, but kestrel does not support grouping multiple operations into an atomic unit.

Downloading it

The latest release is always on the homepage here:

Or the latest development versions & branches are on github:

Building it

Kestrel requires java 6 and sbt 0.11.2. Presently some sbt plugins used by kestrel depend on that exact version of sbt. On OS X 10.5, you may have to hard-code an annoying JAVA_HOME to use java 6:

$ export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home

Building from source is easy:

$ sbt clean update package-dist

Scala libraries and dependencies will be downloaded from maven repositories the first time you do a build. The finished distribution will be in dist.

Running it

You can run kestrel by hand, in development mode, via:

$ ./dist/kestrel-VERSION/scripts/devel.sh

Like all ostrich-based servers, it uses the "stage" property to determine which config file to load, so devel.sh sets -Dstage=development.

When running it as a server, a startup script is provided in dist/kestrel-VERSION/scripts/kestrel.sh. The script assumes you have daemon, a standard daemonizer for Linux, but also available here for all common unix platforms.

The created archive kestrel-VERSION.zip can be expanded into a place like /usr/local (or wherever you like) and executed within its own folder as a self-contained package. All dependent jars are included. The current startup script, however, assumes that kestrel has been deployed to /usr/local/kestrel/current (e.g., as if by capistrano), and the startup script loads kestrel from that path.

The default configuration puts logfiles into /var/log/kestrel/ and queue journal files into /var/spool/kestrel/.

The startup script logs extensive GC information to a file named stdout in the log folder. If kestrel has problems starting up (before it can initialize logging), it will usually appear in error in the same folder.

Configuration

Queue configuration is described in detail in docs/guide.md (an operational guide). Scala docs for the config variables are here.

Performance

Several performance tests are included. To run them, first start up a kestrel instance locally.

$ sbt clean update package-dist
$ ./dist/kestrel-VERSION/scripts/devel.sh

Put-many

This test just spams a kestrel server with "put" operations, to see how quickly it can absorb and journal them.

A sample run on a 2010 MacBook Pro:

$ ./dist/kestrel/scripts/load/put-many -n 100000
Put 100000 items of 1024 bytes to localhost:22133 in 1 queues named spam
  using 100 clients.
Finished in 6137 msec (61.4 usec/put throughput).
Transactions: min=71.00; max=472279.00 472160.00 469075.00;
  median=3355.00; average=5494.69 usec
Transactions distribution: 5.00%=485.00 10.00%=1123.00 25.00%=2358.00
  50.00%=3355.00 75.00%=4921.00 90.00%=7291.00 95.00%=9729.00
  99.00%=50929.00 99.90%=384638.00 99.99%=467899.00

Many-clients

This test has one producer that trickles out one item at a time, and a pile of consumers fighting for each item. It usually takes exactly as long as the number of items times the delay, but is useful as a validation test to make sure kestrel works as advertised without blowing up.

A sample run on a 2010 MacBook Pro:

$ ./dist/kestrel/scripts/load/many-clients
many-clients: 100 items to localhost using 100 clients, kill rate 0%,
  at 100 msec/item
Received 100 items in 11046 msec.

This test always takes about 11 seconds -- it's a load test instead of a speed test.

Flood

This test starts up one producer and one consumer, and just floods items through kestrel as fast as it can.

A sample run on a 2010 MacBook Pro:

$ ./dist/kestrel/scripts/load/flood
flood: 1 threads each sending 10000 items of 1kB through spam
Finished in 1563 msec (156.3 usec/put throughput).
Consumer(s) spun 0 times in misses.

Packing

This test starts up one producer and one consumer, seeds the queue with a bunch of items to cause it to fall behind, then does cycles of flooding items through the queue, separated by pauses. It's meant to test kestrel's behavior with a queue that's fallen behind and stays behind indefinitely, to make sure the journal files are packed periodically without affecting performance too badly.

A sample run on a 2010 MacBook Pro:

$ ./dist/kestrel/scripts/load/packing -c 10 -q small
packing: 25000 items of 1kB with 1 second pauses
Wrote 25000 items starting at 0.
cycle: 1
Wrote 25000 items starting at 25000.
Read 25000 items in 5279 msec. Consumer spun 0 times in misses.
cycle: 2
Wrote 25000 items starting at 50000.
Read 25000 items in 4931 msec. Consumer spun 0 times in misses.
...
cycle: 10
Wrote 25000 items starting at 250000.
Read 25000 items in 5304 msec. Consumer spun 0 times in misses.
Read 25000 items in 3370 msec. Consumer spun 0 times in misses.

You can see the journals being packed in the kestrel log. Like "many-clients", this test is a load test instead of a speed test.

Leaky-reader

This test starts a producer and several consumers, with the consumers occasionally "forgetting" to acknowledge an item that they've read. It verifies that the un-acknowledged items are eventually handed off to another consmer.

A sample run:

$ ./dist/kestrel/scripts/load/leaky-reader -n 100000 -t 10
leaky-reader: 10 threads each sending 100000 items through spam
Flushing queues first.
1000
2000
100000
Finished in 40220 msec (40.2 usec/put throughput).
Completed all reads

Like "many-clients", it's just a load test.

kestrel's People

Contributors

alex-hofsteede avatar bengl avatar blair avatar dhamanka avatar eric avatar gphat avatar halfnelson avatar hugohallqvist avatar jeffstyr avatar matterkkila avatar mattparlane avatar maw avatar okapies avatar qhoxie avatar readmecritic avatar robey avatar rvoicilas avatar szegedi avatar travisbrown avatar trustin avatar zuercher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kestrel's Issues

can't build master

[ej@tw-mbp-ejensen-2 ~/workspace/kestrel (master)]$ rm -rf ~/.ivy2/cache/*; sbt update && sbt package-dist
Getting Scala 2.7.7 ...
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.7.7/scala-compiler-2.7.7.jar ...
[SUCCESSFUL ] org.scala-lang#scala-compiler;2.7.7!scala-compiler.jar (8565ms)
downloading http://repo1.maven.org/maven2/org/scala-lang/scala-library/2.7.7/scala-library-2.7.7.jar ...
[SUCCESSFUL ] org.scala-lang#scala-library;2.7.7!scala-library.jar (5739ms)
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/315ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...
downloading http://databinder.net/repo/org.scala-tools.sbt/sbt_2.7.7/0.7.4/jars/sbt_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#sbt_2.7.7;0.7.4!sbt_2.7.7.jar (2971ms)
downloading http://repo1.maven.org/maven2/com/jcraft/jsch/0.1.31/jsch-0.1.31.jar ...
[SUCCESSFUL ] com.jcraft#jsch;0.1.31!jsch.jar (446ms)
downloading http://repo1.maven.org/maven2/org/scala-tools/testing/test-interface/0.5/test-interface-0.5.jar ...
[SUCCESSFUL ] org.scala-tools.testing#test-interface;0.5!test-interface.jar (61ms)
downloading http://repo1.maven.org/maven2/org/apache/ivy/ivy/2.1.0/ivy-2.1.0.jar ...
[SUCCESSFUL ] org.apache.ivy#ivy;2.1.0!ivy.jar (2185ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compile_2.7.7/0.7.4/jars/compile_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compile_2.7.7;0.7.4!compile_2.7.7.jar (157ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/launcher-interface/0.7.4/jars/launcher-interface.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#launcher-interface;0.7.4!launcher-interface.jar (102ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/interface/0.7.4/jars/interface.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#interface;0.7.4!interface.jar (111ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/ivy_2.7.7/0.7.4/jars/ivy_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#ivy_2.7.7;0.7.4!ivy_2.7.7.jar (543ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/io_2.7.7/0.7.4/jars/io_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#io_2.7.7;0.7.4!io_2.7.7.jar (340ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/classpath_2.7.7/0.7.4/jars/classpath_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#classpath_2.7.7;0.7.4!classpath_2.7.7.jar (101ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compiler-interface/0.7.4/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compiler-interface;0.7.4!compiler-interface-bin.jar (254ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/compiler-interface/0.7.4/jars/compiler-interface-src.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#compiler-interface;0.7.4!compiler-interface-src.jar (106ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/control_2.7.7/0.7.4/jars/control_2.7.7.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#control_2.7.7;0.7.4!control_2.7.7.jar (100ms)
downloading http://repo1.maven.org/maven2/jline/jline/0.9.94/jline-0.9.94.jar ...
[SUCCESSFUL ] jline#jline;0.9.94!jline.jar (339ms)
downloading http://databinder.net/repo/org.scala-tools.sbt/precompiled-2.8.0.rc2_2.8.0.RC2/0.7.4/jars/compiler-interface-bin.jar ...
[SUCCESSFUL ] org.scala-tools.sbt#precompiled-2.8.0.rc2_2.8.0.RC2;0.7.4!compiler-interface-bin.jar (298ms)
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
15 artifacts copied, 0 already retrieved (4096kB/178ms)
[info] Recompiling plugin definition...
[info] Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.
[info]
[info] Updating plugins...
[info] downloading http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar ...
[info] [SUCCESSFUL ] com.twitter#standard-project;0.7.17!standard-project.jar (162ms)
[info] downloading http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar ...
[info] [SUCCESSFUL ] ivysvn#ivysvn;2.1.0!ivysvn.jar (5888ms)
[info] :: retrieving :: plugin-definition#plugin-definition_2.7.7 [sync]
[info] confs: [compile, runtime, test, provided, system, optional, sources, javadoc]
[info] 2 artifacts copied, 0 already retrieved (2997kB/42ms)
[success] Plugins updated successfully.
[info]
[info] Extracted source plugin ./lib_managed/scala_2.7.7/standard-project-0.7.17.jar ...
[info] Recompiling plugin...
[info] Source analysis: 14 new/modified, 0 indirectly invalidated, 0 removed.
[info] Recompiling project definition...
[info] Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.
[info] Standard project rules 0.7.14 loaded (2010-11-18).
[warn] No .svnrepo file; no svn repo will be configured.
[info] Building project kestrel 1.2.9-SNAPSHOT against Scala 2.7.7
[info] using KestrelProject with sbt 0.7.4 and Scala 2.7.7
[info]
[info] == update ==
[info] downloading http://maven.twttr.com/net/lag/naggati_2.7.7/0.7.5/naggati_2.7.7-0.7.5.jar ...
[info] [SUCCESSFUL ] net.lag#naggati_2.7.7;0.7.5!naggati_2.7.7.jar (528ms)
[info] downloading http://maven.twttr.com/net/lag/configgy/1.6.4/configgy-1.6.4.jar ...
[info] [SUCCESSFUL ] net.lag#configgy;1.6.4!configgy.jar (1346ms)
[info] downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/slf4j/slf4j-api/1.5.2/slf4j-api-1.5.2.jar ...
[info] [SUCCESSFUL ] org.slf4j#slf4j-api;1.5.2!slf4j-api.jar (359ms)
[info] downloading http://maven.twttr.com/com/twitter/xrayspecs/1.0.7/xrayspecs-1.0.7.jar ...
[info] [SUCCESSFUL ] com.twitter#xrayspecs;1.0.7!xrayspecs.jar (168ms)
[info] downloading http://maven.twttr.com/com/twitter/twitteractors/1.1.0/twitteractors-1.1.0.jar ...
[info] [SUCCESSFUL ] com.twitter#twitteractors;1.1.0!twitteractors.jar (1872ms)
[info] downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/slf4j/slf4j-jdk14/1.5.2/slf4j-jdk14-1.5.2.jar ...
[info] [SUCCESSFUL ] org.slf4j#slf4j-jdk14;1.5.2!slf4j-jdk14.jar (193ms)
[info] downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/apache/mina/mina-core/2.0.0-M6/mina-core-2.0.0-M6.jar ...
[info] [SUCCESSFUL ] org.apache.mina#mina-core;2.0.0-M6!mina-core.jar(bundle) (1720ms)
[info] downloading http://maven.twttr.com/org/scala-tools/vscaladoc/1.1-md-3/vscaladoc-1.1-md-3.jar ...
[info] [SUCCESSFUL ] org.scala-tools#vscaladoc;1.1-md-3!vscaladoc.jar (875ms)
[info] downloading http://maven.twttr.com/com/twitter/twitteractors_2.7.7/2.0.1/twitteractors_2.7.7-2.0.1.jar ...
[info] [SUCCESSFUL ] com.twitter#twitteractors_2.7.7;2.0.1!twitteractors_2.7.7.jar (796ms)
[info] downloading http://mirrors.ibiblio.org/pub/mirrors/maven2/org/scala-tools/testing/specs/1.6.2.1/specs-1.6.2.1.jar ...
[info] [SUCCESSFUL ] org.scala-tools.testing#specs;1.6.2.1!specs.jar (5892ms)
[info] downloading http://scala-tools.org/repo-releases/com/twitter/json/1.1.3/json-1.1.3.jar ...
[info] [SUCCESSFUL ] com.twitter#json;1.1.3!json.jar (189ms)
[info] :: retrieving :: net.lag#kestrel [sync]
[info] confs: [compile, runtime, test, provided, system, optional, sources, javadoc]
[info] 12 artifacts copied, 0 already retrieved (7188kB/172ms)
[info] == update ==
[success] Successful.
[info]
[info] Total time: 118 s, completed Jan 28, 2011 3:19:36 PM
[info]
[info] Total session time: 143 s, completed Jan 28, 2011 3:19:36 PM
[success] Build completed successfully.
[info] Standard project rules 0.7.14 loaded (2010-11-18).
[warn] No .svnrepo file; no svn repo will be configured.
[info] Building project kestrel 1.2.9-SNAPSHOT against Scala 2.7.7
[info] using KestrelProject with sbt 0.7.4 and Scala 2.7.7
[info]
[info] == check-deps-exist ==
[info] == check-deps-exist ==
[info]
[info] == compile-thrift-ruby ==
[info] == compile-thrift-ruby ==
[info]
[info] == compile-thrift-java ==
[info] == compile-thrift-java ==
[info]
[info] == compile ==
[info] Source analysis: 13 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/Journal.scala:23: imported Time' is permanently hidden by definition of object Time in package kestrel [warn] import com.twitter.xrayspecs.Time [warn] ^ [error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/Journal.scala:80: value inMilliseconds is not a member of Long [error] val tmpFile = new File(queuePath + "~~" + Time.now.inMilliseconds) [error] ^ [warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/QItem.scala:21: importedTime' is permanently hidden by definition of object Time in package kestrel
[warn] import com.twitter.xrayspecs.Time
[warn] ^
[warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/Kestrel.scala:26: imported Time' is permanently hidden by definition of object Time in package kestrel [warn] import com.twitter.xrayspecs.Time [warn] ^ [error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/Kestrel.scala:55: value inMilliseconds is not a member of Long [error] private val _startTime = Time.now.inMilliseconds [error] ^ [warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:26: importedTime' is permanently hidden by definition of object Time in package kestrel
[warn] import com.twitter.xrayspecs.Time
[warn] ^
[warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/QueueCollection.scala:23: imported Time' is permanently hidden by definition of object Time in package kestrel [warn] import com.twitter.xrayspecs.Time [warn] ^ [warn] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/KestrelHandler.scala:26: importedTime' is permanently hidden by definition of object Time in package kestrel
[warn] import com.twitter.xrayspecs.Time
[warn] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/Kestrel.scala:158: value inMilliseconds is not a member of Long
[error] def uptime() = (Time.now.inMilliseconds - _startTime) / 1000
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/KestrelHandler.scala:295: value inMilliseconds is not a member of Long
[error] report += (("time", (Time.now.inMilliseconds / 1000).toString))
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:222: value inMilliseconds is not a member of Long
[error] val now = Time.now.inMilliseconds
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:294: value inMilliseconds is not a member of Long
[error] Actor.self.reactWithin((timeoutAbsolute - Time.now.inMilliseconds) max 0) {
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:314: value inMilliseconds is not a member of Long
[error] val gotSomething = Actor.self.receiveWithin((timeoutAbsolute - Time.now.inMilliseconds) max 0) {
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:505: value inMilliseconds is not a member of Long
[error] val now = Time.now.inMilliseconds
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/PersistentQueue.scala:531: value inMilliseconds is not a member of Long
[error] if ((realExpiry != 0) && (realExpiry < Time.now.inMilliseconds)) {
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/QItem.scala:59: value inMilliseconds is not a member of Long
[error] QItem(Time.now.inMilliseconds, if (expiry == 0) 0 else expiry * 1000, bytes, 0)
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/QueueCollection.scala:113: value inMilliseconds is not a member of Long
[error] val now = Time.now.inMilliseconds
[error] ^
[error] /Users/ej/workspace/kestrel/src/main/scala/net/lag/kestrel/QueueCollection.scala:142: value inMilliseconds is not a member of Long
[error] q.removeReact(if (timeout == 0) timeout else Time.now.inMilliseconds + timeout, transaction) {
[error] ^
[warn] 6 warnings found
[error] 12 errors found
[info] == compile ==
[info]
[info] == copy-test-resources ==
[info] == copy-test-resources ==
[info]
[info] == copy-resources ==
[info] == copy-resources ==
[info]
[info] == write-build-properties ==
[info] == write-build-properties ==
[error] Error running compile: Compilation failed
[info]
[info] Total time: 10 s, completed Jan 28, 2011 3:19:48 PM
[info]
[info] Total session time: 11 s, completed Jan 28, 2011 3:19:48 PM
[error] Error during build.

Problem finding sbt version 2.8.1;0.7.4 โ€” required by master

When I try to compile kestrel I get the following error:

$ sbt clean update package-dist
Getting org.scala-tools.sbt sbt_2.8.1 0.7.4 ...

:: problems summary ::
:::: WARNINGS
        module not found: org.scala-tools.sbt#sbt_2.8.1;0.7.4

    ==== local: tried

      /Users/eric/.ivy2/local/org.scala-tools.sbt/sbt_2.8.1/0.7.4/ivys/ivy.xml

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      /Users/eric/.ivy2/local/org.scala-tools.sbt/sbt_2.8.1/0.7.4/jars/sbt_2.8.1.jar

    ==== Maven2 Local: tried

      file:///Users/eric/.m2/repository/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      file:///Users/eric/.m2/repository/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

    ==== typesafe-ivy-releases: tried

      http://repo.typesafe.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt_2.8.1/0.7.4/ivys/ivy.xml

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      http://repo.typesafe.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt_2.8.1/0.7.4/jars/sbt_2.8.1.jar

    ==== Maven Central: tried

      http://repo1.maven.org/maven2/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      http://repo1.maven.org/maven2/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

    ==== Scala-Tools Maven2 Repository: tried

      http://scala-tools.org/repo-releases/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      http://scala-tools.org/repo-releases/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

    ==== Scala-Tools Maven2 Snapshots Repository: tried

      http://scala-tools.org/repo-snapshots/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

      -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

      http://scala-tools.org/repo-snapshots/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

        ::::::::::::::::::::::::::::::::::::::::::::::

        ::          UNRESOLVED DEPENDENCIES         ::

        ::::::::::::::::::::::::::::::::::::::::::::::

        :: org.scala-tools.sbt#sbt_2.8.1;0.7.4: not found

        ::::::::::::::::::::::::::::::::::::::::::::::



:: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
unresolved dependency: org.scala-tools.sbt#sbt_2.8.1;0.7.4: not found
Error during sbt execution: Error retrieving required libraries
  (see /Users/eric/src/kestrel/project/boot/update.log for complete log)
Error: Could not retrieve sbt 0.7.4

Do I need to do something special to get this to work?

The link to the "guide" 404's

From the homepage of the project:
"For more information about what it is and how to use it, check out the included guide."

The "guide" link shows a 404 page

Expected result: Clicking "guide" takes you to the installation guide or current doc

Changing from absolute to relative timeouts in {operate,peek,remove}{React,Receive}

Ran into a bug yesterday with some code using peekReceive(). It was passing 15,000 millseconds to the method as a timeout, which was interpreted as being 15,000 milliseconds past January 1st, 1970, so of course, the call didn't block at all and the code calling it consumed 100% of the CPU.

Given that all the methods (that I'm aware of) in the Java world take a relative timeout time and not the absolute time when the timeout should expire (including Object#wait() and Scala's actor's methods), I suggest moving the methods to using that. This will also have the improvement of reducing the number of system calls it takes, both in the calling code and in Kestrel itself.

Personally speaking, I would rather take longer for a test suite to run than to have an unobvious API plus additional work that the server needs to perform in a high-load environment.

If changing the code is acceptable, I'll code it up.

Kestrel from maven repository

I am trying to import Kestrel into an existing project that is build using standard Maven and Java. Following Kestrel's sbt configuration, I found the repository http://maven.twttr.com/ and setup a dependency to net.lang.kestrel. The pom file for v1.3 includes a dependency to com.twitter.xrayspecs 1.0.7. The dependency is reachable from the web here

http://maven.twttr.com/com/twitter/xrayspecs/1.0.7/

However, the dependency directory does not include a pom file and therefore maven's dependency resolution mechanism fails and I cannot use kestrel. Is there any other way to get kestrel through maven?

PS: I am not sure whether this is the right place to ask this question...

Blocking set operation

Additional feature that is similar to blocking get (i.e., get with timeout). I am thinking of a set/t=500 similar to get/t=500. That means, whenever you put a new item in the queue and the queue is already full, the client will be blocked for at most 500ms until an error occurs.

Kestrel ignores memcache flags

Module python-memcached uses memcache ability to add meta-data (flags) to store type of data, and uses it for parsing.

For example it sets flags=0x1 to say that data is pickled and should be unpickled.

Kestrel silently drops flags so meta-data is lost which leads us to unexpected behavior: we write python tuple "(1000, 100)", we get "(I1000
I100
tp1
." as a result.

As far as I understand Kestrel code, to achieve this functionality we should:

  1. add .flags member to QItem
  2. move instantiation of QItem from PersistentQueue.add to KestrelHandler.set
  3. use item.flags in formatting response in KestrelHandler.get

If these are acceptable changes I'm going to code them and present patch for review shortly.

write-build-properties error (java.lang.RuntimeException: Nonzero exit value: 128)

I'm trying to build on OS X and get the following:

sbt clean update package-dist
[info] Standard project rules 0.12.7 loaded (2011-05-24).
[warn] No .svnrepo file; no svn repo will be configured.
[info] Building project kestrel 2.1.0-SNAPSHOT against Scala 2.8.1
[info] using KestrelProject with sbt 0.7.4 and Scala 2.7.7
[info]
[info] == clean-dist ==
[info] Deleting directory /Users/petter/13th/workspace/descriptorservice/messagequeue/kestrel/dist
[info] == clean-dist ==
[info]
[info] == clean ==
[info] Deleting directory /Users/petter/13th/workspace/descriptorservice/messagequeue/kestrel/target
[info] == clean ==
[success] Successful.
[info]
[info] Total time: 1 s, completed Jul 24, 2011 5:03:38 PM
[info]
[info] == update ==
Warning: org.apache.ivy.plugins.conflict.StrictConflictException: com.twitter#util-core;1.8.5 (needed by [com.twitter#ostrich;4.2.0, com.twitter#util-logging;1.8.5]) conflicts with com.twitter#util-core;1.8.1 (needed by [net.lag#kestrel;2.1.0-SNAPSHOT])
Warning: org.apache.ivy.plugins.conflict.StrictConflictException: com.twitter#util-core;1.8.1 (needed by [net.lag#kestrel;2.1.0-SNAPSHOT]) conflicts with com.twitter#util-core;1.8.5 (needed by [com.twitter#util-eval;1.8.5, com.twitter#ostrich;4.2.0, com.twitter#util-logging;1.8.5])
[info] :: retrieving :: net.lag#kestrel [sync]
[info] confs: [compile, runtime, test, provided, system, optional, sources, javadoc]
[info] 0 artifacts copied, 25 already retrieved (0kB/165ms)
[info] == update ==
[success] Successful.
[info]
[info] Total time: 3 s, completed Jul 24, 2011 5:03:41 PM
[info]
[info] == check-deps-exist ==
[info] == check-deps-exist ==
[info]
[info] == compile ==
[info] Source analysis: 16 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[info] Compilation successful.
[info] Post-analysis: 216 classes.
[info] == compile ==
[info]
[info] == copy-test-resources ==
[info] == copy-test-resources ==
[info]
[info] == copy-resources ==
[info] == copy-resources ==
[info]
[info] == test-compile ==
[info] Source analysis: 17 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling test sources...
[info] Compilation successful.
[info] Post-analysis: 915 classes.
[info] == test-compile ==
[info]
[info] == doc ==
[info] Generating API documentation for main sources...
model contains 0 documentable templates
[info] API documentation generation successful.
[info] == doc ==
[info]
[info] == test-start ==
[info] == test-start ==
[info]
[info] == net.lag.kestrel.ServerSpec ==
[info] + Server should
[info] + configure per-queue
[info] + reload
[info] + set and get one entry
[info] + set with expiry
[info] + set and get binary data
[info] + commit a transactional get
[info] + abort a transactional get
[info] + auto-rollback a transaction on disconnect
[info] + auto-commit cycles of transactional gets
[info] + age
[info] + peek
[info] + rotate logs
[info] + collect stats
[info] + return a valid response for an unknown command
[info] + disconnect and reconnect correctly
[info] + flush expired items
[info] == net.lag.kestrel.ServerSpec ==
[info]
[info] == net.lag.kestrel.QueueCollectionSpec ==
[info] + QueueCollection should
[info] + create a queue
[info] + load from journal
[info] + queue hit/miss tracking
[info] + proactively load existing queue files
[info] + ignore partially rolled queue files
[info] + delete a queue when asked
[info] + fanout queues
[info] + generate on the fly
[info] + preload existing
[info] + delete on the fly
[info] + pass through fanout-only master
[info] + expire items when (and only when) they are expired
[info] + move expired items from one queue to another
[info] == net.lag.kestrel.QueueCollectionSpec ==
[info]
[info] == net.lag.kestrel.JournalSpec ==
[info] + Journal should
[info] + walk
[info] + recover from corruption
[info] + identify valid journal files
[info] + simple
[info] + half-finished pack
[info] + missing last file
[info] + missing any files
[info] + journalsBefore and journalAfter
[info] + pack old files
[info] + report file sizes correctly
[info] + rebuild from a checkpoint correctly
[info] == net.lag.kestrel.JournalSpec ==
[info]
[info] == net.lag.kestrel.ReadBehindSpec ==
[info] + PersistentQueue read-behind should
[info] + drop into read-behind mode on insert
[info] + drop into read-behind mode on startup
[info] + drop into read-behind mode during journal processing, then return to ordinary times
[info] + cope with read-behind on the primary journal file after it gets moved
[info] + follow read-behind from several files back
[info] == net.lag.kestrel.ReadBehindSpec ==
[info]
[info] == net.lag.kestrel.TextHandlerSpec ==
[info] + TextCodec should
[info] + get request
[info] + put request
[info] + quit request
[info] + success response
[info] + error response
[info] + empty response
[info] + item response
[info] + TextHandler should
[info] + get request
[info] + closes transactions
[info] + with timeout
[info] + value ready immediately
[info] + value ready eventually
[info] + timed out
[info] + empty queue
[info] + item ready
[info] + put request
[info] + delete request
[info] == net.lag.kestrel.TextHandlerSpec ==
[info]
[info] == net.lag.kestrel.KestrelHandlerSpec ==
[info] + KestrelHandler should
[info] + set and get
[info] + track stats
[info] + abort and confirm a transaction
[info] + open several transactions
[info] + on one queue
[info] + on several queues
[info] + but not if transactions are limited
[info] + close all transactions
[info] == net.lag.kestrel.KestrelHandlerSpec ==
[info]
[info] == net.lag.kestrel.PersistentQueueSpec ==
[info] + PersistentQueue should
[info] + add and remove one item
[info] + resist adding an item that's too large
[info] + flush all items
[info] + rotate journals
[info] + rotate journals with an open transaction
[info] + recover the journal after a restart
[info] + recover a journal with a rewritten transaction
[info] + honor max_age
[info] + allow max_journal_size and max_memory_size to be overridden per queue
[info] + handle timeout reads
[info] + success
[info] + timeout
[info] + correctly interleave transactions in the journal
[info] + recover a journal with open transactions
[info] + continue a queue item
[info] + recreate the journal file when it gets too big
[info] + don't recreate the journal file if the queue itself is still huge
[info] + report an age of zero on an empty queue
[info] + PersistentQueue with no journal should
[info] + create no journal
[info] + lose all data after being destroyed
[info] + PersistentQueue with item/size limit should
[info] + honor max_items
[info] + honor max_size
[info] + drop older items when discard_old_when_full is set
[info] + PersistentQueue with item expiry should
[info] + expire items into the ether
[info] + expire items into a queue
[info] == net.lag.kestrel.PersistentQueueSpec ==
[info]
[info] == test-complete ==
[info] == test-complete ==
[info]
[info] == ==
[info] == ==
[info]
[info] == write-build-properties ==
java.lang.RuntimeException: Nonzero exit value: 128
at scala.Predef$.error(Predef.scala:76)
at sbt.AbstractProcessBuilder.getString(ProcessImpl.scala:138)
at sbt.AbstractProcessBuilder.$bang$bang(ProcessImpl.scala:141)
at com.twitter.sbt.ScmAdapters$$anon$1.currentRevision(SourceControlledProject.scala:25)
at com.twitter.sbt.SourceControlledProject$$anonfun$currentRevision$1.apply(SourceControlledProject.scala:38)
at com.twitter.sbt.SourceControlledProject$$anonfun$currentRevision$1.apply(SourceControlledProject.scala:37)
at scala.Option.map(Option.scala:70)
at com.twitter.sbt.SourceControlledProject$class.currentRevision(SourceControlledProject.scala:37)
at com.twitter.sbt.StandardProject.currentRevision(StandardProject.scala:45)
at com.twitter.sbt.BuildProperties$$anonfun$writeBuildPropertiesTask$1.apply(BuildProperties.scala:23)
at com.twitter.sbt.BuildProperties$$anonfun$writeBuildPropertiesTask$1.apply(BuildProperties.scala:17)
at sbt.TaskManager$Task.invoke(TaskManager.scala:62)
at sbt.impl.RunTask.doRun$1(RunTask.scala:77)
at sbt.impl.RunTask.runTask(RunTask.scala:85)
at sbt.impl.RunTask.sbt$impl$RunTask$$runIfNotRoot(RunTask.scala:60)
at sbt.impl.RunTask$$anonfun$runTasksExceptRoot$2.apply(RunTask.scala:48)
at sbt.impl.RunTask$$anonfun$runTasksExceptRoot$2.apply(RunTask.scala:48)
at sbt.Distributor$Run$Worker$$anonfun$2.apply(ParallelRunner.scala:131)
at sbt.Distributor$Run$Worker$$anonfun$2.apply(ParallelRunner.scala:131)
at sbt.Control$.trapUnit(Control.scala:19)
at sbt.Distributor$Run$Worker.run(ParallelRunner.scala:131)
[info] == write-build-properties ==
[info]
[info] == package-src ==
[info] Packaging ./target/kestrel-2.1.0-SNAPSHOT-sources.jar ...
[info] Packaging complete.
[info] == package-src ==
[info]
[info] == package-docs ==
[info] Packaging ./target/kestrel-2.1.0-SNAPSHOT-javadoc.jar ...
[info] Packaging complete.
[info] == package-docs ==
[info]
[info] == copy-scripts ==
[info] == copy-scripts ==
[info]
[info] == test-finish ==
[info] Passed: : Total 106, Failed 0, Errors 0, Passed 106, Skipped 0
[info]
[info] All tests PASSED.
[info] == test-finish ==
[info]
[info] == test-cleanup ==
[info] == test-cleanup ==
[error] Error running write-build-properties: java.lang.RuntimeException: Nonzero exit value: 128
[info]
[info] Total time: 87 s, completed Jul 24, 2011 5:05:08 PM
[info]
[info] Total session time: 92 s, completed Jul 24, 2011 5:05:08 PM
[error] Error during build.

1.2.6 - Exception on startup:-(

kestrel claims, it running, but any telnet connections/commands simply hang:-( Any idea?

Exception in thread "main" java.lang.ExceptionInInitializerError
at com.twitter.actors.Actor$class.scheduler(Actor.scala:374)
at com.twitter.actors.Actor$$anon$1.scheduler(Actor.scala:94)
at com.twitter.actors.Actor$class.start(Actor.scala:783)
at com.twitter.actors.Actor$$anon$1.start(Actor.scala:94)
at com.twitter.actors.Actor$.actor(Actor.scala:97)
at net.lag.kestrel.Kestrel$.startup(Kestrel.scala:141)
at net.lag.kestrel.Kestrel$.main(Kestrel.scala:67)
at net.lag.kestrel.Kestrel.main(Kestrel.scala)
Caused by: java.lang.IllegalArgumentException
at java.util.concurrent.ThreadPoolExecutor.(ThreadPoolExecutor.java:589)
at java.util.concurrent.ThreadPoolExecutor.(ThreadPoolExecutor.java:548)
at com.twitter.actors.threadpool.ActorThreadPoolExecutor.(ActorThreadPoolExecutor.java:171)
at com.twitter.actors.threadpool.ActorThreadPoolExecutor.(ActorThreadPoolExecutor.java:134)
at com.twitter.actors.FJTaskScheduler2.(FJTaskScheduler2.scala:78)
at com.twitter.actors.Scheduler$.makeNewScheduler(Scheduler.scala:26)
at com.twitter.actors.Scheduler$.(Scheduler.scala:33)
at com.twitter.actors.Scheduler$.(Scheduler.scala)
... 8 more

[root@kexapp04z1:/opt/kenai/kestrel] # ls kestrel-1.2.6.jar libs/
kestrel-1.2.6.jar

libs/:
configgy-1.6.4.jar scala-library.jar twitteractors-1.1.0.jar
json-1.1.3.jar slf4j-api-1.5.2.jar twitteractors_2.7.7-2.0.0.jar
mina-core-2.0.0-M6.jar slf4j-jdk14-1.5.2.jar vscaladoc-1.1-md-3.jar
naggati_2.7.7-0.7.4.jar specs-1.6.2.1.jar xrayspecs-1.0.7.jar
[root@kexapp04z1:/opt/kenai/kestrel] # java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Server VM (build 16.3-b01, mixed mode)

Durable journal

The default journal behavior is to do no syncing of the journal, which can lead to lost items if there is a system or process crash after an item is added to the queue and the journal is flushed to disk.

Additionally, during journal rolling, the existing journal is renamed and items from it are played into a new empty journal with the original path. If there is a crash, then many items can be lost.

Both of these issues are fixed in my fork. For the second one, a temporary journal is made with a temporary filename which is then renamed into place when it has been completely written.

cant get Kestrel as a library

i want use Kestrel as a library , but failing to update .


[1] val kestrel = "net.lag" % "kestrel" % "1.3.0"
[2] val kestrel = "net.lag" % "kestrel" % "1.2.4-config-SNAPSHOT"
[3] val kestrel = "com.twitter" % "finagle-kestrel" % "1.5.1"


I try to use them , but anyone can be used .
[1] : rightly download ,but there are no argument in the interface . like [queue.add()]
[2] and [3] : can not download .

what should i do ? can u help me ?

may be a bug . in Jouranl.scala

when queueConfig.sycnJournal not equal 0.seconds or Duration.maxValue, Journal will not work
PersistentQueueSpec will stop at queue.remove , and not retrun .
because :

  • in kestrelย /ย srcย /ย mainย /ย scalaย /ย netย /ย lagย /ย kestrelย / Journal.scalaย  line:471
    ย val future = writer.write(byteBuffer)ย ย ย ย 
    if (allowSync) future()
    future with "()" , it will wait for result to call apply , but in
    kestrelย /ย srcย /ย mainย /ย scalaย /ย netย /ย lagย /ย kestrelย / PeriodicSyncFile.scala <line: 60>
    promise is without promise.setValue(()) .

change
kestrelย /ย srcย /ย mainย /ย scalaย /ย netย /ย lagย /ย kestrelย / Journal.scalaย  line:471
if (allowSync) future()
to if (allowSync) future
it seems work well .

I am not familiar with promise , please check it . wait your comment .

Blocking on queue peeks

Another way of handling items in the queue is to peek for them and then just delete the head if the item was successfully handled. This is an alternative to using a tentative delete which requires writes to the journal. What I wanted was a way to block on a peek() instead of having to poll the queue for the head item.

This has been implemented in my fork using the same infrastructure as a blocking remove.

Threads hangs infinitely on MemcacheConnection serverActor !? Store

Affects version 1.2

Under not entirely known circumstances (but usually connected with heavy loads) I'm getting a bug, that hangs all my threads, that try to send message to Kestrel queue.
It appears, that server actor never responds to message sent
synchronously via !? method, and my actor waits forever:

The stacktrace is at:
http://gist.github.com/723222

The failure pattern is like that: when one such stacktrace appears on
the jstack output, in few seconds all of my actor threads start to
hang in the same way.

I'm curious, what happens with that server actor - why does it
stop responding?

Cannot build master due to failure of test

Hi, i try to build Kestrel myself, but failed. Looks like it cannot pass the tests, any idea? or is there any option that i can disable test during building?

[info] Standard project rules 0.12.7 loaded (2011-05-24).
[warn] No .svnrepo file; no svn repo will be configured.
[info] Building project kestrel 2.1.0-SNAPSHOT against Scala 2.8.1
[info] using KestrelProject with sbt 0.7.4 and Scala 2.7.7
[info]
[info] == check-deps-exist ==
[info] == check-deps-exist ==
[info]
[info] == compile ==
[info] Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[info] Nothing to compile.
[info] Post-analysis: 217 classes.
[info] == compile ==
[info]
[info] == test-compile ==
[info] Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling test sources...
[info] Nothing to compile.
[info] Post-analysis: 915 classes.
[info] == test-compile ==
[info]
[info] == copy-resources ==
[info] == copy-resources ==
[info]
[info] == copy-test-resources ==
[info] == copy-test-resources ==
[info]
[info] == test-start ==
[info] == test-start ==
[info]
[info] == net.lag.kestrel.KestrelHandlerSpec ==
[info] + KestrelHandler should
[info] + set and get
[info] + track stats
[info] + abort and confirm a transaction
[info] + open several transactions
[info] + on one queue
[info] + on several queues
[info] + but not if transactions are limited
[info] + close all transactions
[info] == net.lag.kestrel.KestrelHandlerSpec ==
[info]
[info] == net.lag.kestrel.ServerSpec ==
[error] x Server should
[info] + configure per-queue
[info] + reload
[info] + set and get one entry
[info] + set with expiry
[info] + set and get binary data
[info] + commit a transactional get
[info] + abort a transactional get
[info] + auto-rollback a transaction on disconnect
[info] + auto-commit cycles of transactional gets
[info] + age
[info] + peek
[error] x rotate logs
[error] '16428' is not equal to '0' (ServerSpec.scala:314)
[info] + collect stats
[info] + return a valid response for an unknown command
[info] + disconnect and reconnect correctly
[info] + flush expired items
[info] == net.lag.kestrel.ServerSpec ==
[info]
[info] == net.lag.kestrel.JournalSpec ==
[error] x Journal should
[info] + walk
[info] + recover from corruption
[info] + identify valid journal files
[info] + simple
[info] + half-finished pack
[info] + missing last file
[info] + missing any files
[info] + journalsBefore and journalAfter
[error] x pack old files
[error] 'List(0, 0, 42)' is not equal to 'List(21, 21, 0)' (JournalSpec.scala:134)
[error] x report file sizes correctly
[error] '0' is not equal to '21' (JournalSpec.scala:157)
[error] x rebuild from a checkpoint correctly
[error] '[]' is not equal to '[add(1:0:A), remove-tentative(6), add(1:0:B), remove-tentative(7), add(1:0:C), remove-tentative(8), add(1:0:D), add(1:0:E), add(1:0:F)]' (JournalSpec.scala:185)
[info] == net.lag.kestrel.JournalSpec ==
[info]
[info] == net.lag.kestrel.PersistentQueueSpec ==
[error] x PersistentQueue should
[info] + add and remove one item
[info] + resist adding an item that's too large
[info] + flush all items
[info] + rotate journals
[info] + rotate journals with an open transaction
[info] + recover the journal after a restart
[error] x recover a journal with a rewritten transaction
[error] 'add([4:0:zero), add(]5:0:first), [add(6:0:second), ]remove-tentative([1]), confirm-remove, r]e[m]o[ve-te]n[tative(2]), confirm-remove(2)... is not equal to 'add([]5:0:first), []remove-tentative([2]), add, confirm-remove(2)... (PersistentQueueSpec.scala:218)
[info] + honor max_age
[info] + allow max_journal_size and max_memory_size to be overridden per queue
[info] + handle timeout reads
[info] + success
[info] + timeout
[info] + correctly interleave transactions in the journal
[info] + recover a journal with open transactions
[info] + continue a queue item
[error] x recreate the journal file when it gets too big
[error] 'add(512:0), add(512:0), remove, add(512:0), remove, add(512:0), remove, add(512:0), remove, add(512:0), remove' is not equal to 'add(512:0)' (PersistentQueueSpec.scala:440)
[error] x don't recreate the journal file if the queue itself is still huge
[error] 1066 is not less than 1066 (PersistentQueueSpec.scala:457)
[info] + report an age of zero on an empty queue
[info] + PersistentQueue with no journal should
[info] + create no journal
[info] + lose all data after being destroyed
[info] + PersistentQueue with item/size limit should
[info] + honor max_items
[info] + honor max_size
[info] + drop older items when discard_old_when_full is set
[info] + PersistentQueue with item expiry should
[info] + expire items into the ether
[info] + expire items into a queue
[info] == net.lag.kestrel.PersistentQueueSpec ==
[info]
[info] == net.lag.kestrel.QueueCollectionSpec ==
[error] x QueueCollection should
[info] + create a queue
[info] + load from journal
[info] + queue hit/miss tracking
[info] + proactively load existing queue files
[info] + ignore partially rolled queue files
[error] x delete a queue when asked
[error] 'List(apples, oranges)' is not equal to 'List(apples)' (QueueCollectionSpec.scala:145)
[error] x fanout queues
[error] 'List(jobs, jobs+client1)' is not equal to 'List(jobs)' (QueueCollectionSpec.scala:190)
[info] + generate on the fly
[info] + preload existing
[error] x delete on the fly
[error] 'List(jobs, jobs+client1)' is not equal to 'List(jobs)' (QueueCollectionSpec.scala:190)
[info] + pass through fanout-only master
[info] + expire items when (and only when) they are expired
[info] + move expired items from one queue to another
[info] == net.lag.kestrel.QueueCollectionSpec ==
[info]
[info] == net.lag.kestrel.ReadBehindSpec ==
[error] x PersistentQueue read-behind should
[info] + drop into read-behind mode on insert
[error] x drop into read-behind mode on startup
[error] 'true' is not equal to 'false' (ReadBehindSpec.scala:125)
[info] + drop into read-behind mode during journal processing, then return to ordinary times
[info] + cope with read-behind on the primary journal file after it gets moved
[error] x follow read-behind from several files back
[error] 'true' is not the same as 'false' (ReadBehindSpec.scala:217)
[info] == net.lag.kestrel.ReadBehindSpec ==
[info]
[info] == net.lag.kestrel.TextHandlerSpec ==
[info] + TextCodec should
[info] + get request
[info] + put request
[info] + quit request
[info] + success response
[info] + error response
[info] + empty response
[info] + item response
[info] + TextHandler should
[info] + get request
[info] + closes transactions
[info] + with timeout
[info] + value ready immediately
[info] + value ready eventually
[info] + timed out
[info] + empty queue
[info] + item ready
[info] + put request
[info] + delete request
[info] == net.lag.kestrel.TextHandlerSpec ==
[info]
[info] == test-finish ==
[error] Failed: : Total 106, Failed 17, Errors 0, Passed 89, Skipped 0
[info] == test-finish ==
[info]
[info] == test-cleanup ==
[info] == test-cleanup ==
[error] Error running net.lag.kestrel.QueueCollectionSpec: Test FAILED
[error] Error running net.lag.kestrel.JournalSpec: Test FAILED
[error] Error running net.lag.kestrel.ReadBehindSpec: Test FAILED
[error] Error running test: One or more subtasks failed
[error] Error running net.lag.kestrel.ServerSpec: Test FAILED
[error] Error running net.lag.kestrel.PersistentQueueSpec: Test FAILED
[info]
[info] Total time: 7 s, completed 2011-7-1 18:49:21
[info]
[info] Total session time: 7 s, completed 2011-7-1 18:49:21
[error] Error during build.

WriteToClosedSessionException

We are seeing an intermittent error in the kestrel.log:

ERR [20100730-11:28:02.365] kestrel: Exception caught on session 48: null
ERR [20100730-11:28:02.365] kestrel: org.apache.mina.core.write.WriteToClosedSessionException
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.core.polling.AbstractPollingIoProcessor.clearWriteRequestQueue(AbstractPollingIoProcessor.java:526)
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeNow(AbstractPollingIoProcessor.java:488)
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.core.polling.AbstractPollingIoProcessor.remove(AbstractPollingIoProcessor.java:458)
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:57)
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:872)
ERR [20100730-11:28:02.365] kestrel: at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:65)
ERR [20100730-11:28:02.365] kestrel: at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
ERR [20100730-11:28:02.365] kestrel: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
ERR [20100730-11:28:02.365] kestrel: at java.lang.Thread.run(Thread.java:637)

We are connecting to kestrel-1.2 using php's Memcached classes, but I can simulate this from the command line.

Create a commands file with two lines (newline terminated):

stats
quit

Send these commands to the kestrel server:

curl telnet://localhost:22133 < kestrel_commands

Check out the kestrel.log to see a new instance of the WriteToClosedSessionException. There are two problems illustrated in this bug.

  1. Kestrel does not have a 'quit' command, although it is a part of the memcached protocol. Any command not recognized by Kestrel outputs CLIENT_ERROR and severs the client connection. This is a problem because memcached client libraries may be sending non-Kestrel commands and getting cut off. I suspect this to be the case with PHP's Memcached library.
  2. If a previous command is in the process of writing back to the client, an erroneous command following quickly behind causes the client cutoff. Meanwhile the first command continues to try to write hitting the WriteToClosedSessionException. Or at least that is my loose hypothesis.

Patch suggestions:

A. Support more of the memcached protocol (i.e. 'quit').

B. Don't kill connections on CLIENT_ERRORs.

I wouldn't suggest suppressing the WriteToClosedSessionException as it is the only indicator of the deeper problem.

journal file size on disk grows

Why does the journal file size increase on disk when you're just reading items from kestrel and acking them which would remove them from the queue? That seems...odd. Shouldn't it get smaller if anything?

get commands slow to a crawl once journaling starts

Not sure how to describe it, but at least with up to 1.2.6 if a queue becomes overwhelmed such that it starts journaling (with hundred-megabyte large journals) get commands slow down terribly.

We will see this in production when a huge spike occurs and workers cannot pull entries off the queue fast enough, Kestrel will begin to journal and then the number of backlogged items increases from there.

The scenario seems to be:

  • Experience load spike
  • SomeQueue starts journaling
  • workers fetching from SomeQueue receive fewer jobs/second
  • SomeQueue gets further and further backed up (since items are still being set, but get'ed at a reduced rate
  • some-host eventually runs out of disk space

The current workaround I've got to this is to quickly restart a Kestrel instance with a different spool directory but binding to the same port, while bringing up a secondary (catch-up) instance to chew through the previous journals.

Let me know if there's further information I can find out about this when it happens again :)

Kestrel 1.2.8 crashes frequently

Hello,

We're using kestrel on our production servers (running on an amazon instance with 60+ GB of memory) and it crashes frequently. The start command is:

java -Xms1024m -Xmx6144m -XX:-UseGCOverheadLimit -jar dist/kestrel-1.2.8/kestrel-1.2.8.jar

The symptoms are the following: when it crashes, the clients are getting timed out, and sometimes (not always), the following error is thrown:

INF [20110428-00:00:05.811] kestrel: Replaying transaction journal for 'mentions-identifier'
INF [20110428-00:00:05.812] kestrel: No transaction journal for 'mentions-identifier'; starting with empty queue.
INF [20110428-00:00:05.812] kestrel: Finished transaction journal for 'mentions-identifier' (0 items, 0 bytes)
ERR [20110428-00:00:54.539] kestrel: Exception caught on session 3349: org.apache.mina.core.write.WriteToClosedSessionException
ERR [20110428-00:00:54.539] kestrel: org.apache.mina.core.write.WriteToClosedSessionException
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.core.polling.AbstractPollingIoProcessor.clearWriteRequestQueue(AbstractPollingIoProcessor.java:539)
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.core.polling.AbstractPollingIoProcessor.removeNow(AbstractPollingIoProcessor.java:492)
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.core.polling.AbstractPollingIoProcessor.remove(AbstractPollingIoProcessor.java:471)
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.core.polling.AbstractPollingIoProcessor.access$600(AbstractPollingIoProcessor.java:56)
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.core.polling.AbstractPollingIoProcessor$Processor.run(AbstractPollingIoProcessor.java:896)
ERR [20110428-00:00:54.539] kestrel:     at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:64)
ERR [20110428-00:00:54.539] kestrel:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
ERR [20110428-00:00:54.539] kestrel:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
ERR [20110428-00:00:54.539] kestrel:     at java.lang.Thread.run(Thread.java:636)

Here's our production.conf file:

queue_path = "/mnt/kestrel"
timeout = 5
max_journal_size = 67108864 # 64 MB
max_memory_size = 536870912 # 512 MB
max_journal_overflow = 10

Any ideas on why this happens?

Thank you,
Mihnea @ uberVU

Provide a configurable timeout for reaping fanout children

I am looking to create a fanout child for each worker that I have and they do not have a unique identifier that persists across worker restart. I was hoping to use hostname:pid as a unique child queue name but need some way to clean up old child queues that are not properly deleted.

@evan suggested on twitter that providing a timeout for reaping the children of a fanout queue would be a good solution to this problem and I completely agree.

Delayed item abort

I'd like something that lets you delay when the item is added back to the head after an abort.

Maybe: /abort/t=300

This would add the item back to the head of the queue after 300ms. Right now I have clients that hang for a certain amount of time.

Update kestrel to utilize the binary memcache protocol

There's proof out there that the gap in performance between the text based protocol and the binary one widens with more concurrently connected clients.

The binary protocol also has and will continue to have more clients available for it which helps kestrel's adoption.

Error when trying to view Admin interface

When I try to view stats through the admin interface I receive the following error in the kestrel.log...

this is running in development mode on a Mac OS X lion instance.

ERR [20110725-15:13:27.982] admin: Exception processing admin http request
ERR [20110725-15:13:27.982] admin: java.util.NoSuchElementException
ERR [20110725-15:13:27.982] admin: at scala.collection.LinearSeqOptimized$class.last(LinearSeqOptimized.scala:147)
ERR [20110725-15:13:27.982] admin: at scala.collection.immutable.List.last(List.scala:45)
ERR [20110725-15:13:27.982] admin: at com.twitter.ostrich.admin.CommandRequestHandler.handle(AdminHttpService.scala:195)
ERR [20110725-15:13:27.982] admin: at com.twitter.ostrich.admin.CgiRequestHandler.handle(AdminHttpService.scala:143)
ERR [20110725-15:13:27.982] admin: at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:65)
ERR [20110725-15:13:27.982] admin: at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:68)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:555)
ERR [20110725-15:13:27.982] admin: at com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:65)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:527)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.ServerImpl$DefaultExecutor.execute(ServerImpl.java:119)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.ServerImpl$Dispatcher.handle(ServerImpl.java:349)
ERR [20110725-15:13:27.982] admin: at sun.net.httpserver.ServerImpl$Dispatcher.run(ServerImpl.java:321)
ERR [20110725-15:13:27.982] admin: at java.lang.Thread.run(Thread.java:680)

scripts/kestrel.sh VERSION is old

Downloaded Kestrel v1.2.
The example startup script scripts/kestrel.sh is on version:

VERSION="1.1.1"

This provided a minor bit of confusion for me (a kestrel noob). Suggest using ant to keep the version here current.

can't build dist from 1.3.0

Just downloaded 1.3.0 package, unpackaged, installed sbt, and try "sbt clean update package-dist".

It gave an error: unresolved dependency: org.scala-tools.sbt#sbt_2.8.1;0.7.4: not found

I checked out http://scala-tools.org/repo-snapshots/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar,
There is no one existing.

The following is build log:

kestrel-1.3.0.0$ sbt clean update package-dist
Getting org.scala-tools.sbt sbt_2.8.1 0.7.4 ...

:: problems summary ::
:::: WARNINGS
module not found: org.scala-tools.sbt#sbt_2.8.1;0.7.4

==== local: tried

  /Users/ThoughtWorks/.ivy2/local/org.scala-tools.sbt/sbt_2.8.1/0.7.4/ivys/ivy.xml

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  /Users/ThoughtWorks/.ivy2/local/org.scala-tools.sbt/sbt_2.8.1/0.7.4/jars/sbt_2.8.1.jar

==== Maven2 Local: tried

  file:///Users/ThoughtWorks/.m2/repository/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  file:///Users/ThoughtWorks/.m2/repository/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

==== typesafe-ivy-releases: tried

  http://repo.typesafe.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt_2.8.1/0.7.4/ivys/ivy.xml

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  http://repo.typesafe.com/typesafe/ivy-releases/org.scala-tools.sbt/sbt_2.8.1/0.7.4/jars/sbt_2.8.1.jar

==== Maven Central: tried

  http://repo1.maven.org/maven2/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  http://repo1.maven.org/maven2/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

==== Scala-Tools Maven2 Repository: tried

  http://scala-tools.org/repo-releases/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  http://scala-tools.org/repo-releases/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

==== Scala-Tools Maven2 Snapshots Repository: tried

  http://scala-tools.org/repo-snapshots/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.pom

  -- artifact org.scala-tools.sbt#sbt_2.8.1;0.7.4!sbt_2.8.1.jar:

  http://scala-tools.org/repo-snapshots/org/scala-tools/sbt/sbt_2.8.1/0.7.4/sbt_2.8.1-0.7.4.jar

    ::::::::::::::::::::::::::::::::::::::::::::::

    ::          UNRESOLVED DEPENDENCIES         ::

    ::::::::::::::::::::::::::::::::::::::::::::::

    :: org.scala-tools.sbt#sbt_2.8.1;0.7.4: not found

    ::::::::::::::::::::::::::::::::::::::::::::::

:: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
unresolved dependency: org.scala-tools.sbt#sbt_2.8.1;0.7.4: not found
Error during sbt execution: Error retrieving required libraries
(see /Users/ThoughtWorks/Downloads/kestrel-1.3.0.0/project/boot/update.log for complete log)
Error: Could not retrieve sbt 0.7.4

Kestrel cannot start since "/etc/kestrel.conf" is missing

I looked through the documentation and the source, and I cannot find any reference to needing /etc/kestrel.conf. It appears to be coming out of ostrich, but I'm starting to feel like I'm digging further than I may need to. I also tried just touching an /etc/kestrel.conf but it also complains about that. What type of format is kestrel expecting for this config file? Am I missing something glaringly obvious?

Recognize flag byte in memcache set

The memcache protocol allows you set a flag byte during a set, kestrel ignores this and defaults it to 0.

Many languages uses a flag to denote the data is serialized so that the client can then deserialize it.

Error when loading a big journal file

This happens when trying to read a large journal file for whatever reason:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at net.lag.kestrel.QItem$.unpack(QItem.scala:38)
at net.lag.kestrel.Journal.readJournalEntry(Journal.scala:254)
at net.lag.kestrel.Journal$$anonfun$fillReadBehind$1.apply(Journal.scala:177)
at net.lag.kestrel.Journal$$anonfun$fillReadBehind$1.apply(Journal.scala:171)
at scala.Option.foreach(Option.scala:94)
at net.lag.kestrel.Journal.fillReadBehind(Journal.scala:171)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

String split typo

I'm very new to Scala and I know next to nothing about the Memcache protocol, so forgive me if this is incorrect. At KestrelHandler.scala:156 there is

val options = name.split("/")

and I believe it should be

val options = name.split('/')

expiration for items is in milliseconds instead of seconds

The docs say "When they come from a client, expiration times are handled in the same way as memcache: if the number is small (less than one million), it's interpreted as a relative number of seconds from now. Otherwise it's interpreted as an absolute unix epoch time, in seconds since the beginning of 1 January 1970 GMT."

But based on my testing of setting a timeout of 3600, which should be 1 hour, it actually times out rather quickly, looking into the code I don't see where the expiry is multiplied by 1000 to convert it to ms before it gets normalized in QueueCollection:add().

can't build release_1_2 or release_1_3

missing dependency: com.twitter#standard-project;0.7.17

Getting Scala 2.7.7 ...
:: retrieving :: org.scala-tools.sbt#boot-scala
confs: [default]
2 artifacts copied, 0 already retrieved (9911kB/31ms)
Getting org.scala-tools.sbt sbt_2.7.7 0.7.4 ...
:: retrieving :: org.scala-tools.sbt#boot-app
confs: [default]
15 artifacts copied, 0 already retrieved (4096kB/28ms)
[info] Recompiling plugin definition...
[info] Source analysis: 1 new/modified, 0 indirectly invalidated, 0 removed.
[info]
[info] Updating plugins...
[error] Server access Error: Connection timed out url=http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[error] Server access Error: Connection timed out url=http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] module not found: com.twitter#standard-project;0.7.17
[warn] ==== local: tried
[warn] /home/tjulien/.ivy2/local/com.twitter/standard-project/0.7.17/ivys/ivy.xml
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] /home/tjulien/.ivy2/local/com.twitter/standard-project/0.7.17/jars/standard-project.jar
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://repo1.maven.org/maven2/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ==== Scala-Tools Maven2 Repository: tried
[warn] http://scala-tools.org/repo-releases/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://scala-tools.org/repo-releases/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.twitter#standard-project;0.7.17: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[info]
[error] :: problems summary ::
[warn] :::: WARNINGS
[warn] module not found: com.twitter#standard-project;0.7.17
[warn] ==== local: tried
[warn] /home/tjulien/.ivy2/local/com.twitter/standard-project/0.7.17/ivys/ivy.xml
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] /home/tjulien/.ivy2/local/com.twitter/standard-project/0.7.17/jars/standard-project.jar
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ==== public: tried
[warn] http://repo1.maven.org/maven2/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://repo1.maven.org/maven2/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ==== Scala-Tools Maven2 Repository: tried
[warn] http://scala-tools.org/repo-releases/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[warn] -- artifact com.twitter#standard-project;0.7.17!standard-project.jar:
[warn] http://scala-tools.org/repo-releases/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: com.twitter#standard-project;0.7.17: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[error] :::: ERRORS
[error] Server access Error: Connection timed out url=http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.pom
[error] Server access Error: Connection timed out url=http://maven.twttr.com/com/twitter/standard-project/0.7.17/standard-project-0.7.17.jar
[info]
[info] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
[error] sbt.ResolveException: unresolved dependency: com.twitter#standard-project;0.7.17: not found
sbt.ResolveException: unresolved dependency: com.twitter#standard-project;0.7.17: not found

Hit enter to retry or 'exit' to quit:

Journal not rolled when all removes are transactional

PersistentQueue.remove only rolls the journal if the queue length = 0, journal size >= max journal size, AND open transactions = 0. This will never occur if all removes are transactional and rolling will only occur when the journal size > max journal size * journal overflow. Perhaps a similar check should be performed if the queue length is 0 and nothing is removed? Or perhaps the journal should be rolled even is there are open transactions?

How to typically start kestrel on windows... in simple steps.

Everyone can see from the below output that, i am inside the kestrel folder. i have tried with below set of commands... no one seems to have worked for me. Please let me know the right way or do we need a different kind of build for kestrel on windows...?

java -Dstage=developement -jar kestrel-2.1.0.jar
java -Dstage=developement -cp config -jar kestrel-2.1.0.jar
java -Dstage=developement -cp config;kestrel-2.1.0.jar -jar kestrel-2.1.0.jar

C:\Downy\frameworks\kestrel-2.1.0\kestrel-2.1.0>java -Dstage=developement -jar kestrel-2.1.0.jar
Exception in thread "main" java.io.FileNotFoundException: \etc\kestrel.conf (The system cannot find the path specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:106)
at scala.io.Source$.fromFile(Source.scala:76)
at com.twitter.util.Eval$$anonfun$apply$1.apply(Eval.scala:69)
at com.twitter.util.Eval$$anonfun$apply$1.apply(Eval.scala:69)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:206)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:34)
at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:32)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:206)
at scala.collection.mutable.WrappedArray.map(WrappedArray.scala:32)
at com.twitter.util.Eval$.apply(Eval.scala:69)
at com.twitter.ostrich.admin.RuntimeEnvironment.loadConfig(RuntimeEnvironment.scala:162)
at com.twitter.ostrich.admin.RuntimeEnvironment.loadRuntimeConfig(RuntimeEnvironment.scala:173)
at net.lag.kestrel.Kestrel$.main(Kestrel.scala:203)
at net.lag.kestrel.Kestrel.main(Kestrel.scala)

DUMP_CONFIG no esta

The guide mentions a DUMP_CONFIG memcached command, but it is nowhere to be found. Did it get removed, or maybe never actually added?

Nagios plugin support

I'm not sure if this is something to add into Kestrel itself, but tight Nagios integration would be a huge plus :)

Distributing kestrel

How exactly do you even distribute kestrel?

Most common memcached libs won't round robin read when it receives a None since they hash the key and horizontally partition.

What are people doing since I see nothing available short of building my own way to distribute tonight.

Cannot build kestrel with sbt

Hi all,

I tried to build kestrel with sbt, i do exactly step by step of this article : http://martincozzi.blogspot.com/2011/01/how-to-install-kestrel-on-ubuntu-1004.html, but when i try to run this command : sbt clean update package-dist from kestrel folder, it always have this error:

[info] downloading http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar ...
[warn] [FAILED ] ivysvn#ivysvn;2.1.0!ivysvn.jar: Downloaded file size doesn't match expected Content Length for http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar. Please retry. (46401ms)
[warn] [FAILED ] ivysvn#ivysvn;2.1.0!ivysvn.jar: Downloaded file size doesn't match expected Content Length for http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar. Please retry. (46401ms)
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: FAILED DOWNLOADS ::
[warn] :: ^ see resolution messages for details ^ ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: ivysvn#ivysvn;2.1.0!ivysvn.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[info]
[warn] :: problems summary ::
[warn] :::: WARNINGS
[warn] [FAILED ] ivysvn#ivysvn;2.1.0!ivysvn.jar: Downloaded file size doesn't match expected Content Length for http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar. Please retry. (46401ms)
[warn] [FAILED ] ivysvn#ivysvn;2.1.0!ivysvn.jar: Downloaded file size doesn't match expected Content Length for http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar. Please retry. (46401ms)
[warn] ==== twitter.com: tried
[warn] http://maven.twttr.com/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: FAILED DOWNLOADS ::
[warn] :: ^ see resolution messages for details ^ ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: ivysvn#ivysvn;2.1.0!ivysvn.jar
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[info]
[info] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS
[error] sbt.ResolveException: download failed: ivysvn#ivysvn;2.1.0!ivysvn.jar
sbt.ResolveException: download failed: ivysvn#ivysvn;2.1.0!ivysvn.jar

Anyone can help me on this?

Thank you so much for help.

"stats" command not reliably returning data

It seems that Kestrel (1.2) doesn't reliably respond with stats when asked, for example, using my Python memcached client I call get_stats() (sends the "stats" command) which sporadically returns results, i.e.:

>>> pprint(c.get_stats())
[('127.0.0.1:22133 (1)',
  {'bytes': '0',
   'bytes_read': '12',
   'bytes_written': '1745',
   'cmd_get': '0',
   'cmd_peek': '0',
   'cmd_set': '0',
   'curr_connections': '1',
   'curr_items': '0',
   'get_hits': '0',
   'get_misses': '0',
   'queue_MapUrl_age': '0',
   'queue_MapUrl_bytes': '0',
   'queue_MapUrl_discarded': '0',
   'queue_MapUrl_expired_items': '0',
   'queue_MapUrl_items': '0',
   'queue_MapUrl_logsize': '8798',
   'queue_MapUrl_mem_bytes': '0',
   'queue_MapUrl_mem_items': '0',
   'queue_MapUrl_open_transactions': '0',
   'queue_MapUrl_total_items': '34',
   'queue_MapUrl_waiters': '0',
   'queue_Recompute_age': '0',
   'queue_Recompute_bytes': '0',
   'queue_Recompute_discarded': '0',
   'queue_Recompute_expired_items': '0',
   'queue_Recompute_items': '0',
   'queue_Recompute_logsize': '591',
   'queue_Recompute_mem_bytes': '0',
   'queue_Recompute_mem_items': '0',
   'queue_Recompute_open_transactions': '0',
   'queue_Recompute_total_items': '3',
   'queue_Recompute_waiters': '0',
   'queue_default_age': '0',
   'queue_default_bytes': '0',
   'queue_default_discarded': '0',
   'queue_default_expired_items': '0',
   'queue_default_items': '0',
   'queue_default_logsize': '0',
   'queue_default_mem_bytes': '0',
   'queue_default_mem_items': '0',
   'queue_default_open_transactions': '0',
   'queue_default_total_items': '0',
   'queue_default_waiters': '0',
   'queue_kestrel.log_age': '0',
   'queue_kestrel.log_bytes': '0',
   'queue_kestrel.log_discarded': '0',
   'queue_kestrel.log_expired_items': '0',
   'queue_kestrel.log_items': '0',
   'queue_kestrel.log_logsize': '0',
   'queue_kestrel.log_mem_bytes': '0',
   'queue_kestrel.log_mem_items': '0',
   'queue_kestrel.log_open_transactions': '0',
   'queue_kestrel.log_total_items': '0',
   'queue_kestrel.log_waiters': '0',
   'time': '1259186080',
   'total_connections': '2',
   'total_items': '0',
   'uptime': '443',
   'version': '1.2'})]
>>> pprint(c.get_stats())
[('127.0.0.1:22133 (1)', {})]

I've jumped into the debugger and it looks like Kestrel just isn't returning anything to the command.

Sync Issue in PersistentQueue on I/O Exception?

Upon close inspection of the PersistentQueue class, it occurred to me that if an I/O Exception is raised at certain points, the in-memory queue may become out of sync with the journal. For example, this can occur in add if an I/O Exception occurs on journal.add after the item has been added to the in-memory queue. Similar behavior exists in remove. Is this an accurate reading of the code? If so, what is the reasoning behind it? Thanks.

Startup script does not work under FreeBSD

Hi there. Just wanted to report a small bug- apparently the daemon utility is different under FreeBSD versus Linux. It does not let you lookup the PID, which blows up the shutdown function. I changed the startup script to use pgrep when running under FreeBSD. My fix is attached below (I can send you a pull request, but it might be overkill).

I'm not sure if pgrep is a common linux utility or not, which is why I made the change FreeBSD specific instead of changing the entire function to use pgrep.

http://github.com/stevecorona/kestrel/commit/b07a1bd3440f927bca6ff45f3c3f6c12dacf9dc5

Can't install

Error follows:

[root@li152-32 kestrel]# sbt clean update package-dist

[info]

[info] Updating plugins...

[warn] module not found: ivysvn#ivysvn;2.1.0

[warn] ==== local: tried

[warn] /root/.ivy2/local/ivysvn/ivysvn/2.1.0/ivys/ivy.xml

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] /root/.ivy2/local/ivysvn/ivysvn/2.1.0/jars/ivysvn.jar

[warn] ==== nexus: tried

[warn] http://nexus.scala-tools.org/content/repositories/releases/ivysvn/ivysvn/2.1.0/
ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://nexus.scala-tools.org/content/repositories/releases/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar

[warn] ==== public: tried

[warn] http://repo1.maven.org/maven2/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://repo1.maven.org/maven2/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar

[warn] ==== Scala-Tools Maven2 Repository: tried

[warn] http://scala-tools.org/repo-releases/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://scala-tools.org/repo-releases/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar

[info] downloading http://nexus.scala-tools.org/content/repositories/releases/com/
twitter/standard-project/0.7.1/standard-project-0.7.1.jar ...

[info] [SUCCESSFUL ] com.twitter#standard-project;0.7.1!standard-project.jar
(385ms)

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[warn] :: UNRESOLVED DEPENDENCIES ::

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[warn] :: ivysvn#ivysvn;2.1.0: not found

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[info]

[warn] :: problems summary ::

[warn] :::: WARNINGS

[warn] module not found: ivysvn#ivysvn;2.1.0

[warn] ==== local: tried

[warn] /root/.ivy2/local/ivysvn/ivysvn/2.1.0/ivys/ivy.xml

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] /root/.ivy2/local/ivysvn/ivysvn/2.1.0/jars/ivysvn.jar

[warn] ==== nexus: tried

[warn] http://nexus.scala-tools.org/content/repositories/releases/ivysvn/ivysvn/2.1.0/
ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://nexus.scala-tools.org/content/repositories/releases/ivysvn/ivysvn/2.1.0/
ivysvn-2.1.0.jar

[warn] ==== public: tried

[warn] http://repo1.maven.org/maven2/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://repo1.maven.org/maven2/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar

[warn] ==== Scala-Tools Maven2 Repository: tried

[warn] http://scala-tools.org/repo-releases/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.pom

[warn] -- artifact ivysvn#ivysvn;2.1.0!ivysvn.jar:

[warn] http://scala-tools.org/repo-releases/ivysvn/ivysvn/2.1.0/ivysvn-2.1.0.jar

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[warn] :: UNRESOLVED DEPENDENCIES ::

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[warn] :: ivysvn#ivysvn;2.1.0: not found

[warn] ::::::::::::::::::::::::::::::::::::::::::::::

[info]

[info] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS

[error] sbt.ResolveException: unresolved dependency: ivysvn#ivysvn;2.1.0: not found

sbt.ResolveException: unresolved dependency: ivysvn#ivysvn;2.1.0: not found

Hit enter to retry or 'exit' to quit:

I'm have zero experience with java or ivy or maven, so can't solve it on my own...

Why is PersistentQueue.fillReadBehind() called synchronously?

I noticed that PersistentQueue._remove() is synchronously calling fillReadBehind() which means the thing fetching the message will not return until the IO has been done to refill the message being dequeued.

Is there a reason why this is not done in the background?

I would expect if this was done separately it would allow for the messages in memory to be drained faster and would allow for more bulk IO operations, which I would expect the OS would be able to handle more efficiently.

Slowdown due to receiveBufferSize

Testing locally, if I run sbt "put-many -b 2036 -n 1000 -c 1", throughput slows to a crawl after several requests. Specifically, the first several puts complete quickly, and then all subsequent put take a bit over 5 seconds to complete. (It varies from run-to-run, but slowdown starts at either 32, 128, or 255 puts.) It happens with a higher client count too, it's just easier to debug with "-c 1".

Adding some logging to the test code, I narrowed this down to the client-side blocking on reading the response back from kestrel.

Using tcpdump and dtruss, I could see that the response is being send immediately, but the underlying read() call on the client side is blocking for about 5 seconds.

If I comment out the bootstrap.setOption("child.receiveBufferSize", 2048) line in Kestrel.scala, the problem goes away.

This also seems to be the cause of the "huge message" unit test failure in grabby-hands (see issue 4); commenting out that line fixes this as well.

(I'm running on Mac OS X 10.6.7)

I don't completely understand why setting a small buffer size is causing this behavior, but it seems to be.

removeReact with timeout from sample code does not work

The following sample code works fine as is. When I remove the add statement, the removeReact method returns right away with a SuspendActorException. It does not block for 5 seconds as expected.

Output:
INF [20100311-17:09:38.245] kestrel: Configuring queue myqueue: journal=true, max_items=2147483647, max_size=9223372036854775807, max_age=0, max_journal_size=16777216, max_memory_size=134217728, max_journal_overflow=10, max_journal_size_absolute=9223372036854775807, discard_old_when_full=false, sync_journal=false
INF [20100311-17:09:38.261] kestrel: Replaying transaction journal for 'myqueue'
INF [20100311-17:09:38.292] kestrel: Finished transaction journal for 'myqueue' (0 items, 32 bytes)
Exception in thread "main" scala.actors.SuspendActorException

Thanks,
Elliot

    var config = new Config();
var queue = new PersistentQueue("/tmp", "myqueue", config)
queue.setup()

// add an item with no expiration:
queue.add("hello".getBytes, 0)

// remove an item with a 5000msec timeout, and confirm it:
queue.removeReact(System.currentTimeMillis + 5000, true) { x =>
  x match {
    case None =>
      println("nothing. :(")
    case Some(item) =>
      println("got: " + new String(item.data))
      queue.confirmRemove(item.xid)
  }
}

queue.close()

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.