memcached是否有类似ORM的包装器

时间:2009-06-30 16:52:44

标签: ruby memcached

我正在寻找一个ruby gem(或rails插件),它以与ActiveRecord抽象SQL细节相同的方式抽象memcached的细节。我正在寻找帮助缓存memcached中的ActiveRecord模型的东西。我确信大约有4215颗宝石可以帮助解决这个问题。

理想情况下,我希望能够做到这样的事情:

class Apple < MemcachedModel
# whatever else here
end

然后能够做到这样的事情:

my_apple = Apple.find('some memcached key')

将在memcached中查找此类的JSON表示并对其进行反序列化。我也许也可以这样做:

my_apple.color = "red"

# persist changes back to memcached
my_apple.save 

# load any changes from memcached into local model
my_apple.update

似乎有人必须抓住这个痒,并沿着这些线创建一些东西,但每当我谷歌这样的宝石时,我只是不断提出有助于使用memcached缓存AR模型的东西。

5 个答案:

答案 0 :(得分:11)

你可以看一下我的moneta宝石,它是各种钥匙价值商店的ORM之物。您可以在http://github.com/wycats/moneta/tree/master

看到它

moneta背后的基本思想是所有KVS的行为应该与普通Ruby哈希的子集完全相同。我们支持:

#[]
#[]=
#delete
#fetch
#key?
#store
#update_key
#clear

storeupdate_key方法采用额外的选项哈希值,您可以这样使用:

cache = Moneta::Memcache.new(:server => "localhost:11211", :namespace => "me")
cache.store("name", "wycats", :expires_in => 2)
cache.update_key("name", :expires_in => 10)

我们支持大量KVS:

  • 的BerkeleyDB
  • CouchDB的
  • DataMapper(表示DM支持的任何商店)
  • 文件
  • LMC
  • 内存缓存
  • 进程内存
  • MongoDB的
  • Redis的
  • 东京内阁
  • 东京暴君
  • S3
  • SDBM
  • 使用XAttrs的文件

每个商店都支持到期,无论是本机(如在memcached中)还是使用模拟memcache风格到期的标准模块。 API始终相同,并且存在共享规范,即运行所有适配器以确保合规性。

添加自己的适配器也很容易,这就是存在这么多适配器的原因。

答案 1 :(得分:3)

我不知道Memcached的任何类似Ruby ActiveRecord的适配器。类似的库可能很难创建,因为Memcached不能充当关系数据库。

结果是该库无法实现ActiveRecord支持的80%的功能,那么这种实现的好处是什么? 你已经拥有了Rails中所需的一切,可以使用“CRUD”模式处理memcache。

Rails.cache.read('key')
Rails.cache.write('key', 'value')
Rails.cache.delete('key')
Rails.cache.increment('key', 5)
Rails.cache.fetch('key') { 'value' }

如果您感觉更舒服,可以创建一个包装器并使用相应的new / create / update / save / destroy方法代理这些方法。但是,您永远无法超越基本的CRUD系统,因为Memcached不是一个关系数据库。

答案 2 :(得分:2)

实施相当容易。

require 'ostruct'
require 'active_support/cache'

class StoredStruct < OpenStruct
  attr_writer :store
  def self.store
    @store || superclass.store
  end

  def self.expand_key(key)
    'StoredStruct_' + (superclass == OpenStruct ? '' : "#{self}_") + key.to_s
  end

  def self.get_unique_id
    key = expand_key('unique_id')
    store.write(key, 0, :unless_exist => true)
    store.increment(key)
  end

  def self.save(instance)
    id = instance.id || get_unique_id
    store.write(expand_key(id), instance)
    id
  end

  def self.find(id)
    store.read(expand_key(id))
  end

  attr_reader :id

  def attributes
    @table
  end

  def attributes=(hash)
    @table = hash
  end

  def new_record?
    self.id.nil?
  end

  def save
    @id = self.class.save(self)
    true
  end

  def reload
    instance = self.class.find(self.id)
    self.attributes = instance.attributes unless self == instance
    self
  end
end

像这样使用:

# connect to memcached
StoredStruct.store = ActiveSupport::Cache::MemCacheStore.new("localhost:11211")

class Apple < StoredStruct
end

fruit = Apple.new
fruit.color = "red"
fruit.taste = "delicious"

fruit.id
#=> nil

fruit.save
#=> true
fruit.id
#=> 1

# to load any changes:
fruit.reload

Apple.find(1)
#=> fruit

答案 3 :(得分:1)

正如Simone Carletti所写,Memcached不是关系数据库;它甚至无法列出所有键。因此,任何在Memcached中存储数据的类似ActiveRecord的模型都不会包含ActiveRecord的所有功能。尽管如此,我认为为所有模型提供一致的API有一定的价值,因此如果让一个模型将其数据存储在Memcached中是有意义的,那么您可以使用我为此目的创建的模块:

http://blog.slashpoundbang.com/post/1455548868/memcachemodel-make-any-ruby-object-that-persists-in

答案 4 :(得分:0)

您可能正在寻找Nick Kallen's cache-money