2009-06-30 30 views
6

Tôi đang tìm kiếm một gem ruby ​​(hoặc plugin rails) để tóm tắt các chi tiết của memcached theo cùng cách mà ActiveRecord tóm tắt các chi tiết của SQL. Tôi đang KHÔNG tìm kiếm thứ gì đó để giúp các mô hình ActiveRecord cache trong memcached. Tôi chắc rằng có khoảng 4215 viên đá quý sẽ giúp giải quyết vấn đề đó.Có một trình bao bọc giống ORM cho memcached

Lý tưởng nhất là những gì tôi muốn là để có thể làm điều gì đó như:

class Apple < MemcachedModel 
# whatever else here 
end 

và sau đó có thể làm công cụ như:

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

mà sẽ tìm kiếm các đại diện JSON của lớp này trong memcached và deserialize nó. Tôi cũng có thể có thể làm những việc như:

my_apple.color = "red" 

# persist changes back to memcached 
my_apple.save 

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

Nó có vẻ như một người nào đó phải có trầy xước ngứa này bởi bây giờ và tạo ra một cái gì đó dọc theo những dòng này, nhưng bất cứ khi nào tôi google cho một viên ngọc như vậy tôi chỉ cần giữ chuyển lên điều giúp các mô hình AR cache sử dụng memcached.

Trả lời

11

Bạn có thể xem đá quý moneta của mình, một thứ ORM'ish dành cho tất cả các loại khóa-giá trị-cửa hàng. Bạn có thể xem tại: http://github.com/wycats/moneta/tree/master

Ý tưởng cơ bản đằng sau moneta là tất cả KVSs nên hoạt động chính xác như một tập con của băm Ruby bình thường.Chúng tôi hỗ trợ:

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

Các storeupdate_key phương pháp có một tùy chọn bổ sung băm mà bạn có thể sử dụng thusly:

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

Chúng tôi hỗ trợ một số lượng lớn các KVSs:

  • BerkeleyDB
  • CouchDB
  • DataMapper (Có nghĩa là bất kỳ cửa hàng được hỗ trợ bởi DM)
  • tập tin
  • LMC
  • Memcache
  • Trong quá trình bộ nhớ
  • MongoDB
  • Redis
  • Tokyo Nội
  • Tokyo Tyrant
  • S3
  • SDBM
  • tập tin sử dụng XAttrs

Mỗi cửa hàng hỗ trợ hết hạn, hoặc là tự nhiên (như trong memcached) hoặc sử dụng một mô-đun tiêu chuẩn mà giả lập memcache kiểu hết hạn. API luôn giống hệt nhau và có thông số chung được chia sẻ rằng tất cả các bộ điều hợp đều chạy ngược lại để đảm bảo tuân thủ.

Nó cũng khá dễ dàng để thêm bộ điều hợp của riêng bạn, đó là lý do tại sao rất nhiều tồn tại.

+0

Đó thực sự là một thư viện thú vị. Cảm ơn bạn đã đăng nó ở đây! –

+0

Tuyệt. cảm ơn Yehuda, tôi sẽ kiểm tra điều này. Tôi đã tìm kiếm một cái cớ để chơi với tất cả các cửa hàng băm liên tục mới đang xuất hiện. –

3

Tôi không biết về bất kỳ bộ điều hợp giống như Ruby ActiveRecord nào dành cho Memcached. Một thư viện tương tự có lẽ sẽ khó tạo ra vì Memcached không hoạt động như một cơ sở dữ liệu quan hệ.

Kết quả là thư viện sẽ không thể triển khai khoảng 80% tính năng được ActiveRecord hỗ trợ, vì vậy lợi ích của việc triển khai như vậy là gì? Bạn đã có mọi thứ bạn cần trong Rails để làm việc với memcache với mẫu "CRUD".

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

Nếu bạn cảm thấy thoải mái hơn, bạn có thể tạo trình bao bọc và proxy các phương pháp mới/tạo/cập nhật/lưu/hủy tương ứng. Tuy nhiên, bạn sẽ không bao giờ có thể vượt qua một hệ thống CRUD cơ bản chỉ vì Memcached không có ý định trở thành một cơ sở dữ liệu quan hệ.

2

Khá dễ thực hiện.

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 

Sử dụng nó như thế này:

# 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 
+0

Tốt. Tôi đặc biệt thích cách bạn thực hiện get_unique_id. Lý tưởng nhất là tôi đang tìm cách sử dụng một thư viện hiện có thay vì tái phát minh ra bánh xe, nhưng nếu tôi cần phải làm điều này từ đầu tôi rất thích ăn cắp những gì bạn có ở đây :) –

0

Bạn có thể tìm kiếm Nick Kallen's cache-money.

+0

Cảm ơn Sarah, nhưng đó là đặc biệt KHÔNG tìm kiếm - một thư viện lưu trữ cho ActiveRecord. –

+0

Ah, tôi hiểu tôi đã hiểu lầm câu hỏi của bạn. Bạn có muốn phân phối với ActiveRecord hoàn toàn và chỉ lưu trữ các đối tượng trong memcached? Tôi tò mò về những thứ bạn sẽ lưu trữ. –

+0

Vâng, tôi có dữ liệu tạm thời mà tôi nhận được từ một API khác. Tôi muốn lưu trữ dữ liệu cục bộ để tôi không phải đi vòng quanh API khác mỗi khi tôi yêu cầu dịch vụ. Nội dung tôi đang lưu vào bộ nhớ cache là thông tin tài khoản - các đối tượng như Người dùng, Tổ chức, v.v. –

1

Như Simone Carletti đã viết, Memcached không phải là một cơ sở dữ liệu quan hệ; nó thậm chí không thể liệt kê tất cả các khóa của nó. Như vậy, mọi mô hình lưu trữ mô hình giống như ActiveRecord trong Memcached sẽ không chứa tất cả chức năng của ActiveRecord. Tuy nhiên, tôi nghĩ rằng có một số giá trị trong việc có API nhất quán cho tất cả các mô hình của bạn, vì vậy nếu có một trong các mô hình lưu trữ dữ liệu trong Memcached, bạn có thể sử dụng mô-đun này tôi đã tạo cho mục đích đó:

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

Các vấn đề liên quan