remodel your storage layer
use redis instead of mysql to store your application data.
remodel (= redis model) is an ActiveRecord-like mapping layer which offers familiar syntax
like has_many
, has_one
etc. to build your domain model in ruby.
entities are serialized to json and stored as fields in a redis hash. using different hashes (called 'contexts' in remodel), you can easily separate data belonging to multiple users, for example.
why redis?
redis offers in-memory read and write performance β on the order of 10K to 100K operations per second, comparable to memcached β plus asynchronous persistence to disk. for example, on my macbook (2 ghz):
$ redis-benchmark -d 100 -r 10000 -q
SET: 13864.27 requests per second
GET: 18152.17 requests per second
INCR: 17006.80 requests per second
LPUSH: 17243.99 requests per second
LPOP: 18706.54 requests per second
how to get started
-
install redis and the redis-rb ruby client:
$ brew install redis $ gem install redis
-
start redis:
$ ./redis-server
-
now the tests should run successfully:
$ rake Started ....................................................................................... Finished in 0.072304 seconds. 87 tests, 138 assertions, 0 failures, 0 errors
example
define your domain model like this:
class Book < Remodel::Entity
has_many :chapters, :class => 'Chapter'
property :title, :short => 't', :class => 'String'
property :year, :class => 'Integer'
property :author, :class => 'String', :default => '(anonymous)'
end
class Chapter < Remodel::Entity
property :title, :class => String
end
now you can do:
>> require './example/book'
=> true
>> context = Remodel.create_context('shelf')
=> #<Remodel::Context(shelf)>
>> book = Book.create context, :title => 'Moby Dick', :year => 1851
=> #<Book(shelf, 1) title: "Moby Dick", year: 1851, author: "(anonymous)">
>> chapter = book.chapters.create :title => 'Ishmael'
=> #<Chapter(shelf, 1) title: "Ishmael">
all entities have been created in the redis hash 'shelf' we have used as context:
>> Remodel.redis.hgetall 'shelf'
=> {"b"=>"1", "b1"=>"{\"t\":\"Moby Dick\",\"year\":1851}", "c"=>"1",
"c1"=>"{\"title\":\"Ishmael\"}", "c1_book"=>"b1", "b1_chapters"=>"[\"c1\"]"}
inspired by
- how to redis β good overview of different mapping options by mattmatt.
- hurl β basically defunkts Hurl::Model is what i started with.
- ohm β object-hash mapping for redis. somewhat similar, but instead of serializing to json, stores each attribute under a separate key.
todo
- better docs
- make serializer (json, messagepack, marshal ...) configurable
status
it has some rough edges, but i have successfully been using remodel in production since summer 2010.