【问题标题】:Is there an ORM-like wrapper for memcached是否有类似 ORM 的 memcached 包装器
【发布时间】:2009-06-30 16:52:44
【问题描述】:

我正在寻找一个 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

似乎现在一定有人已经解决了这个问题并按照这些思路创建了一些东西,但是每当我在谷歌上搜索这样一个 gem 时,我都会不断地找到有助于使用 memcached 缓存 AR 模型的东西。

【问题讨论】:

    标签: ruby memcached


    【解决方案1】:

    你可以看看我的moneta gem,这是一个适合各种键值存储的 ORM'ish 东西。您可以在以下位置查看: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:

    • 伯克利数据库
    • 沙发数据库
    • DataMapper(表示 DM 支持的任何存储)
    • 文件
    • LMC
    • 内存缓存
    • 进程内内存
    • MongoDB
    • Redis
    • 东京内阁
    • 东京暴君
    • S3
    • SDBM
    • 使用 XAttrs 的文件

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

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

    【讨论】:

    • 这是一个非常有趣的库。感谢您在这里发布!
    • 酷。谢谢耶胡达,我会检查一下。我一直在寻找一个借口来使用所有这些新出现的持久性哈希存储。
    【解决方案2】:

    我不知道任何用于 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 并非旨在成为关系数据库。

    【讨论】:

      【解决方案3】:

      实现起来相当容易。

      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
      

      【讨论】:

      • 不错。我特别喜欢你实现 get_unique_id 的方式。理想情况下,我希望使用现有的库而不是重新发明轮子,但是如果我确实需要从头开始这样做,我很想偷你这里的东西:)
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

        • 谢谢莎拉,但这正是我不想要的——ActiveRecord 的缓存库。
        • 啊,我明白我误解了你的问题。你想完全放弃 ActiveRecord 并且只将对象存储在 memcached 中吗?我很好奇你会储存什么样的东西。
        • 是的,我有从另一个 API 获得的瞬态数据。我想在本地缓存数据,这样每次我为请求提供服务时就不必往返于这个其他 API。我正在缓存的东西是帐户信息的东西 - 像用户、组织等对象。
        猜你喜欢
        • 1970-01-01
        • 2022-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-04
        • 2013-08-26
        相关资源
        最近更新 更多