Giới thiệu gem redis-object
Redis là 1 hệ thống lưu trữ key-value rất mạnh mẽ và phổ biến hiện nay. Redis nổi bật bởi việc hỗ trợ nhiều cấu trúc dữ liệu cơ bản(hash, list, set, sorted set, string), giúp việc thao tác với dữ liệu tốt hơn các hệ thống cũ như memcached rất nhiều. Hôm nay, tôi sẽ giới thiệu gem redis-object để ...
Redis là 1 hệ thống lưu trữ key-value rất mạnh mẽ và phổ biến hiện nay. Redis nổi bật bởi việc hỗ trợ nhiều cấu trúc dữ liệu cơ bản(hash, list, set, sorted set, string), giúp việc thao tác với dữ liệu tốt hơn các hệ thống cũ như memcached rất nhiều.
Hôm nay, tôi sẽ giới thiệu gem redis-object để sử dụng các kiểu dữ liệu Redis trong Ruby. Tôi sẽ dưới thiệu các kiểu dữ liệu sau:
- Value
- List
- Set
- Hash
- Sorted Set
Trước tiên, hãy add nó vào Gemfile của bạn:
gem 'redis-objects'
Value thực sự rất đơn giản:
@value = Redis::Value.new('value_name') @value.value = 'a' @value.delete
Dữ liệu phức tạp sẽ không có vấn đề gì với :marshal => true:
@account = Account.create!(params[:account]) @newest = Redis::Value.new('newest_account', :marshal => true) @newest.value = @account.attributes puts @newest.value['username']
List hoạt động giống như mảng Ruby. List trong Redis là linked list, lưu trữ 1 danh sách có thứ tự (trước sau) của các string. Cách lưu trữ này giúp cho thời gian add thêm 1 phần tử vào đầu hoặc cuối list là hằng số, bất kể size của list là bao nhiêu. Lợi thế này cũng có 1 mặt trái là việc truy xuất đến phần tử theo index của linked list là lâu hơn rất nhiều so với array.
@list = Redis::List.new('list_name') @list << 'a' @list << 'b' @list.include? 'c' # false @list.values # ['a','b'] @list << 'c' @list.delete('c') @list[0] @list[0,1] @list[0..1] @list.shift @list.pop @list.clear # etc
Bạn có thể ràng buộc kích thước của List để chỉ giữ N elements như sau:
# Only holds 10 elements, throws out old ones when you reach :maxlength. @list = Redis::List.new('list_name', :maxlength => 10)
Các kiểu dữ liệu phức tạp được serialized với: marshal => true:
@list = Redis::List.new('list_name', :marshal => true) @list << {:name => "Nate", :city => "San Diego"} @list << {:name => "Peter", :city => "Oceanside"} @list.each do |el| puts "#{el[:name]} lives in #{el[:city]}" end
Set hoạt động như lớp Set trong Ruby. Nó ko có thứ tự, nhưng đảm bảo các member là uniqueness.
@set = Redis::Set.new('set_name') @set << 'a' @set << 'b' @set << 'a' # dup ignored @set.member? 'c' # false @set.members # ['a','b'] @set.members.reverse # ['b','a'] @set.each do |member| puts member end @set.clear # etc
Ngoài ra Redis còn hỗ trợ các phép toán tập hợp, gồm intersect/union/difference.
@set1 = Redis::Set.new('set1') @set2 = Redis::Set.new('set2') @set3 = Redis::Set.new('set3') members = @set1 & @set2 # intersection members = @set1 | @set2 # union members = @set1 + @set2 # union members = @set1 ^ @set2 # difference members = @set1 - @set2 # difference members = @set1.intersection(@set2, @set3) # multiple members = @set1.union(@set2, @set3) # multiple members = @set1.difference(@set2, @set3) # multiple
Hoặc lưu trữ chúng trong Redis:
@set1.interstore('intername', @set2, @set3) members = @set1.redis.get('intername') @set1.unionstore('unionname', @set2, @set3) members = @set1.redis.get('unionname') @set1.diffstore('diffname', @set2, @set3) members = @set1.redis.get('diffname')
Hash làm việc giống với Ruby hash, với một vài Redis-specific bổ sung. Hash lưu trữ tập các map của key và value. Key vẫn là string, còn value có thể là string hoặc số.
@hash = Redis::HashKey.new('hash_name') @hash['a'] = 1 @hash['b'] = 2 @hash.each do |k,v| puts "#{k} = #{v}" end @hash['c'] = 3 puts @hash.all # {"a"=>"1","b"=>"2","c"=>"3"} @hash.clear
Nếu là số thì chúng ta có thể làm các thao tác tăng, giảm giá trị 1 cách đơn giản:
@hash.incr('c', 6) # 9 @hash.bulk_set('d' => 5, 'e' => 6) @hash.bulk_get('d','e') # "5", "6"
Nhớ rằng các con số trở thành chuỗi trong Redis. Không giống với các kiểu dữ liệu Redis khác, redis-object không thể đoán kiểu dữ liệu của bạn trong trường hợp này, vì bạn có thể thực sự muốn lưu trữ "1,5".
Do tính chất độc đáo của chúng, Sorted Set hoạt động giống như sự kết hợp giữa Hash và Array. Bạn chỉ định như Hash, nhưng lấy như một Array:
@sorted_set = Redis::SortedSet.new('number_of_posts') @sorted_set['Nate'] = 15 @sorted_set['Peter'] = 75 @sorted_set['Jeff'] = 24 # Array access to get sorted order @sorted_set[0..2] # => ["Nate", "Jeff", "Peter"] @sorted_set[0,2] # => ["Nate", "Jeff"] @sorted_set['Peter'] # => 75 @sorted_set['Jeff'] # => 24 @sorted_set.score('Jeff') # same thing (24) @sorted_set.rank('Peter') # => 2 @sorted_set.rank('Jeff') # => 1 @sorted_set.first # => "Nate" @sorted_set.last # => "Peter" @sorted_set.revrange(0,2) # => ["Peter", "Jeff", "Nate"] @sorted_set['Newbie'] = 1 @sorted_set.members # => ["Newbie", "Nate", "Jeff", "Peter"] @sorted_set.members.reverse # => ["Peter", "Jeff", "Nate", "Newbie"] @sorted_set.rangebyscore(10, 100, :limit => 2) # => ["Nate", "Jeff"] @sorted_set.members(:with_scores => true) # => [["Newbie", 1], ["Nate", 16], ["Jeff", 28], ["Peter", 76]] # atomic increment @sorted_set.increment('Nate') @sorted_set.incr('Peter') # shorthand @sorted_set.incr('Jeff', 4)
Bạn có thể xem chi tiết gem redis-object tại https://github.com/nateware/redis-objects