Ruby on rails 对于Ruby,可能会使整个对象的内容在Ohm中过期吗?

Ruby on rails 对于Ruby,可能会使整个对象的内容在Ohm中过期吗?,ruby-on-rails,ruby,redis,ohm,Ruby On Rails,Ruby,Redis,Ohm,一旦我的某个特定事件发生,我希望能够使Ruby on Rails应用程序中基于Ohm的对象的全部内容过期。目前是否可以将Redis+expire与之配合使用?当使用Ohm时,对象有多个与之关联的键,包括索引等。我想确保所有的东西都得到了正确的清理——这就是为什么我想知道是否有官方支持的方法来做到这一点。我为Ohm开发了一个gem来处理它 请看:不幸的是,没有。已经有好几次尝试来解决这个难题,但我所看到的每一次都会在Ohm数据集中留下瑕疵。它们都不能使用唯一的属性,据我所知,它们都使欧姆数据处于不

一旦我的某个特定事件发生,我希望能够使Ruby on Rails应用程序中基于Ohm的对象的全部内容过期。目前是否可以将Redis+expire与之配合使用?当使用Ohm时,对象有多个与之关联的键,包括索引等。我想确保所有的东西都得到了正确的清理——这就是为什么我想知道是否有官方支持的方法来做到这一点。

我为Ohm开发了一个gem来处理它


请看:

不幸的是,没有。已经有好几次尝试来解决这个难题,但我所看到的每一次都会在Ohm数据集中留下瑕疵。它们都不能使用唯一的属性,据我所知,它们都使欧姆数据处于不一致的状态

一些例子:

例如,当一个Ohm模型保存时,有几个字段被添加到Redis散列中,还有一些成员被添加到Redis集合中。虽然可以对整个哈希或集合设置过期,但不能使Redis哈希的单个字段或集合的单个成员过期。整个散列或集合过期

主要问题是:如果这些集合和散列过期,您将丢失模型上的整个索引,或唯一属性的完整记录。因此,使用Ohm expire Mixin时的一个常见问题是,即使主数据键过期,调用
find
仍将从索引返回一条记录,但哈希值为零。如果在模型中指定了唯一属性,则即使数据本身已过期,也不能再次使用过期值调用该模型上的
create
,而不会引发异常

Redis中没有过期回调,因此无法在特定密钥过期时触发删除哈希字段或集合成员。有几个人要求允许散列字段或集合成员在Redis问题列表中使用TTL,但他们都(相当合理地)给出了答案:

嗨,这将不会由原始设计实现:

键中没有嵌套类型。单个字段中没有复杂的特征 聚合数据类型。推理要复杂得多,而且复杂得多 受个人感情、偏好和敏感性的影响,因此没有 以客观的方式向您展示这一点更好;)

结束。谢谢你的报道

例如,以下是Ohm源代码()中的一些注释:


总之,在Redis中对数据过期进行细粒度控制的最佳方法是使用低级接口设计自己的存储方法,例如。

而不是使用Redis使Ohm对象过期,更可靠的方法是直接检查和删除对象,例如通过使用单独的过期线程。这可以检查模型对象,检测那些已过期的对象,并通过Ohm请求删除

Ohm使用a以原子方式执行删除,这将正确地清除与对象关联的所有键,并从其他Ohm结构中删除对对象的引用。使用欧姆删除是清洁过期的最佳选择

通过使用这样的设计,您可能需要在性能和可靠性之间进行权衡:您的程序实际上是在所有已知对象上执行垃圾收集,这可能涉及大量内存访问和/或Redis查询

以下是清理线程如何工作的示例:

def start_expiry_thread expiry_cycle

  Thread.new {

    while (true) do

      MyOhmModel.all.each do |object|
        object.delete if object.expired
      end

      sleep expiry_cycle

    end

  }

end
其中,在Ohm model类中(通过继承或mixin),通过Ohm::Timestaps模块的支持,可以沿以下线路实现过期函数:

@max_life = 3600

def expired            
    (time_since_update > @max_life)
end

def time_since_update
    updated_secs = self.updated_at.to_i
    (Time.now.to_i - updated_secs)
end
注:

  • 引入螺纹时要小心-使用锁定以防止 通过两个线程同时访问同一对象,或者 避免共享对象,让过期线程直接转到 雷迪斯

  • 如果应用程序进程有一个定期的计划重新启动, 另一种方法是在启动过程中进行清理, 在启动任何其他工作线程之前

  • 确保你的另一半 应用程序代码优雅地处理到期-底层Redis 对象将消失,这意味着 应用程序代码将无效

  • 以上是生产系统代码的简化版本,因此在简化过程中可能会出现bug

  • 更一般地说:请检查您是否真的需要欧姆。如果您正在考虑在键值存储之上添加关系层,那么您应该认真考虑系统的技术设计


我正在尝试使用您的gem,但我在使用唯一索引时遇到问题。当具有唯一密钥的记录过期时,我仍然可以通过该密钥找到它,但该记录的属性为空。如何使记录过期并在过期后自动删除?因为当我试图在过期后创建具有相同(已删除)唯一密钥的记录时,我遇到了Ohm唯一性异常。我也遇到了这个问题。不确定这是否是实现中的一个bug(因此我没有在GitHub上打开一个问题),或者Redis处理这个问题的方式。需要更多的研究!gem ohm expire已被放弃,目前无法工作。不要再使用这个宝石了。
def start_expiry_thread expiry_cycle

  Thread.new {

    while (true) do

      MyOhmModel.all.each do |object|
        object.delete if object.expired
      end

      sleep expiry_cycle

    end

  }

end
@max_life = 3600

def expired            
    (time_since_update > @max_life)
end

def time_since_update
    updated_secs = self.updated_at.to_i
    (Time.now.to_i - updated_secs)
end