ruby-on-rails - 如何获取多个rails版本应用程序中连接的redis数据?
问题描述
我正在使用 redis 缓存在我的 rails 应用程序中获取数据。简而言之,我可以说我有两个应用程序,第一个基于rails 4,第二个基于rails 6。我必须在两个应用程序中使用缓存数据。
在 rails 4 应用程序中:- 我在 rails 4 应用程序中创建了缓存,它成功地获取了数据。
Rails.cache.fetch("test_cache"){User.last}
=> #<User id: 100973, email: "xxxx.com", encrypted_password: "$2a$10$D8aOhoSWvNWeEQE2swAX2OEVIF5H0aY8sR/fGVQ3BhU...........>
在 rails 6 应用程序中:- 但是当我想在我的 rails 6 应用程序中加载相同的缓存时,会出现错误。
Rails.cache.fetch("test_cache"){User.last}
Traceback (most recent call last):
2: from (irb):18
1: from (irb):18:in `rescue in irb_binding'
NameError (uninitialized constant ActiveRecord::AttributeSet)
Did you mean? ActiveRecord::Attributes
然后我找到了一种解决方案,使用as_json
Rails.cache.fetch("test_cache"){User.last.as_json}
它成功地工作并在两个应用程序上获取了数据,但是我还有一个问题,我该如何访问model methods, associations etc etc...
它。
有什么建议或想法吗?
解决方案
对于缓存 Rails 使用的非字符串值Marshal.dump
(并且还通过 deflate 压缩它以获取大值)。编组数据可以被认为是介于数据和代码之间的东西,因为它引用了类名和内部结构。这就是它有局限性的原因:它只能使用相同的 ruby 版本进行解组(参见ruby 文档),并且应用程序应该具有相同的类。
显然,ActiveRecord::Base
导轨 4 和导轨 6 的结构不同,因此在编组时不兼容。
要获得兼容性,您唯一的选择是仅缓存基本的 ruby 类型和 PORO,它们不引用任何在您的应用程序中不同的类。您的尝试as_json
正是这样做的——存储模型的哈希表示。
但实际上第一步是重新考虑你想要缓存的确切内容和原因,有几个想法需要考虑:
- 当然,Redis/Memcache 很快,但访问它仍然是一个数据库查询,有相应的开销。从 SQL DB(如 )的简单读取
User.find(primary_key_value_here)
几乎一样快。 - AR模型有关联缓存,你可能有一些记忆数据,你可能会遇到这些数据停滞
- 访问非缓存的关联仍然会导致数据库调用
- 很可能您想要缓存的不是模型本身,而是一种更容易找到它的方法(例如,如果它是一些昂贵计算的结果)或一些派生数据。在前一种情况下,存储记录 id 就足够了,在后一种情况下,您可以存储诸如哈希/PORO 之类的内容以及您需要的所有数据,例如:
hash = Rails.cache.fetch("last_registered_user"){
User.last.yield_self{|u|
{
user_id: u.id,
name: u.name,
registered_at: u.created_at,
invited_by: u.invited_by.name
}
}
}
推荐阅读
- asp.net - 我不能使用“this.props.form”
- php - ajax 插入在 codeigniter 中不起作用
- cassandra-3.0 - 墓碑影响 Cassandra 读取
- perl - DBD::mysql: mysql.so: 未定义符号:net_buffer_length
- ios - AVAudioSession 在某些蓝牙设备上不起作用
- java - 如何从 JAR 应用程序中动态加载类以在另一个 JAR 中使用?
- go - 恐慌:运行时错误:makelice:上限超出范围
- java - 对象的数据结构 - 为每个对象运行查询
- laravel - 用户类型限制 - 工作流
- python - 我什么时候可以在 Python 中使用 self 调用基类方法