Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

A Ruby-based, in-memory KVS with one half of the peristence you want

branch: master

Fetching latest commit…

Octocat-spinner-32-eaf2f5

Cannot retrieve the latest commit at this time

Octocat-spinner-32 benchmarks
Octocat-spinner-32 bin
Octocat-spinner-32 lib
Octocat-spinner-32 spec
Octocat-spinner-32 .gitignore
Octocat-spinner-32 LICENSE
Octocat-spinner-32 README.markdown
Octocat-spinner-32 Rakefile
Octocat-spinner-32 VERSION
Octocat-spinner-32 oria.gemspec
README.markdown

Oria

Oria (oh-rye-uh) is an in-memory, Ruby-based, zero-configuration Key-Value Store. It's designed to handle moderate amounts of data quickly and easily without causing deployment issues or server headaches. It uses EventMachine to provide a networked interface to a semi-persistent store and asynchronously writes the in-memory data to YAML files.

Installation

Oria is provided as a Gem. You can be up-and-running in three steps:

  1. Install it. Use the following command to install it:

    gem install oria --source http://gemcutter.org
    
  2. Require it. Add require "oria" somewhere in your application

  3. Use it. Oria[:foo] = {:bar => "baz"}

Command Line

The recommended pattern for starting and stopping Oria is using the Oria command line application, like so:

$ oria start|stop|restart [-d]

That's it! Oria will run in-memory, and you can always shut it down using oria stop.

Auto-Start and Daeomonizing

I recommend you use the command line to control Oria, but on certain platforms, you don't have access to the command line. And since Oria was built to be simple to use and to deploy, it also supports auto-starting and stopping. It will detect a downed server and boot itself up.

The auto-start feature currently relies on Oria being installed as a gem, so "vendoring" is unfortunately not possible at this time. Also, I have not tested this on Heroku, but you will AT LEAST need to point Oria to the correct tmp directory, which is fairly volatile on Heroku, so it may never be a real solution for that platform.

Usage

Okay, now for the fun part. Oria behaves (mostly) like a Hash - you could say that it responds to 2/3 of @wycats' Moneta plugin. Specifically, it responds to the following Hash methods:

[]=(value)          Set a key to ... something.

[]                  Retrieve a key

delete(key)         Delete and return a key's value

key?(key)           Returns a boolean value for whether or not that key exists

has_key?(key)       Same as key

clear               Clears all keys and values from Oria

In addition to those methods, Oria also supports a method inspired by some other KVS's:

stash(value)        Stash a value in Oria. Returns the randomly generated key it stored the value under. This
                    is useful for when you need to store something temporarily, e.g. stash it, pass the key
                    in a URL, and retrieve / delete it.

So let's play:

Oria[:foo] = 'bar'  #=> "bar"
Oria[:foo]          #=> "bar"
Oria.key?(:foo)     #=> true
Oria.delete(:foo)   #=> "bar"
Oria[:foo]          #=> nil
Oria.stash("baz")   #=> "wZ"

Nothing exciting? Try shutting your app down and booting it back up.

Oria[:wZ]           #=> "baz"

Bam. A relatively fast KVS with no configuration or special server setup.

But wait, I stored a #RubyObject:0x10162ad70! WTF?

Ah yes. You've found Oria's Achilles heel. Oria speaks JSON, so everything you give it must be capable of JSON'ing. That means Oria[:user] = User.find(1) ain't working any time soon. Likewise, and perhaps more unfortunately, things like Oria[:my_cool_hash] = {:key => "Key!!!!!1", :value => "valyooooo"} are going to return {"key" => "Key", etc...} so your hashes are going to respond to string keys and not symbols once they've been through Oria.

It's a bummer, I know. But Oria is kept lightweight by being able to handle a basic data-set without having to marshal or unmarshal classes. In general, the practice of using only these data types for off-site storage will force you to write more thoughtful software.

And there is some good news - JSON supports Arrays, Hashes, Booleans, Floats, and Integers just fine. So you're not completely limited.

Configuration

Oria is built the be configuration-less out of the box, but if you really need to, you can tell it to do lots of things. It's built on top of EventMachine, so networking is an option - but if you're networking your KVS, you should think about upgrading to something like Redis or Memcached. Oria is meant to be used in situations where a database OR a high-powered KVS would be overkill. But then again, you can use Oria to decentralize some of your tasks over a network, which is fun. Observe:

Oria.connect(server, port)      Connect to a server / port. Defaults to localhost and 6851

Oria.app_key = value            Oria supports "splitting" your apps, much like how Resque supports named queues. Specifying an
                                app key will effectively change the hash you are working with. It defaults to "default," cause
                                I'm original like that.

Let's try it out:

Oria.connect("192.168.1.22", 8080)

Oria.app_key = "my_app_1"
Oria[:foo] = "bar"
Oria[:foo] #=> "bar"

Oria.app_key = "my_app_2"
Oria[:foo] #=> nil
Oria.app_key = "my_app_1"
Oria[:foo] #=> "bar"

Oria.app_key = "my_app_1"
Oria[:foo] #=> "bar"

That's it! I hope you enjoy Oria, and please let me know if you find any issues or have any trouble. As you will no doubt see from the current version information, it's a very young project, and any contribution is welcome.

Dependencies

Oria speaks JSON, so it relies on the JSON gem. It depends on the newest stable version (1.2.0), so be sure to add the right version checking code to your legacy apps before using Oria!

It also needs EventMachine to do everything. I could have used Drb or straight UDP sockets, but EventMachine is seriously, seriously, seriously awesome, and works very well without me writing an insane amount of code I couldn't write very well anyway. Check it out and see for yourself.

Benchmarks

Want to find out how well Oria will perform compared to existing solutions? Here are a few benchmarks.

Here's Redis and Oria:

                     user     system      total        real
Redis (write):   0.040000   0.020000   0.060000 (  0.112147)
Oria (write):    0.130000   0.100000   0.230000 (  0.394356)
Redis (read):    0.070000   0.020000   0.090000 (  0.140881)
Oria (read):     0.130000   0.100000   0.230000 (  0.394533)

Obviously, Redis is going to smack Oria down no matter what. Still, it's in a competitive range - which is good.

Here's MySQL and Oria:

                     user     system      total        real
MySQL (write):   0.260000   0.030000   0.290000 (  0.423971)
Oria (write):    0.140000   0.100000   0.240000 (  0.406949)
MySQL (read):    0.310000   0.020000   0.330000 (  0.468195)
Oria (read):     0.100000   0.100000   0.200000 (  0.330884)

Oh snap! Oria outperforms MySQL. How about SQLite3, in memory?

                      user     system      total        real
SQLite3 (write):  0.360000   0.010000   0.370000 (  0.376660)
Oria (write):     0.100000   0.100000   0.200000 (  0.368118)
SQLite3 (read):   0.370000   0.010000   0.380000 (  0.379038)
Oria (read):      0.150000   0.100000   0.250000 (  0.406342)

Looks like Oria will write faster but read slower than SQLite3 in-memory.

Copyright (c) 2009 Flip Sasser, released under the MIT license

Something went wrong with that request. Please try again.