沙尘暴/optimizedrediscachebackend

此包已被放弃且不再维护。未建议替代包。

1.1.5 2022-02-23 14:17 UTC

This package is auto-updated.

Last update: 2022-09-07 06:44:48 UTC


README

已过时自Neos 8.0以来

注意:OptimizedRedisCacheBackend在Neos 8.0及更高版本中已过时,因为其功能已被集成到核心,并进一步改进。感谢Sebastian Helzle以及所有参与此项目的人 :- :-) )

如何从OptimizedRedisCacheBackend迁移到Neos 8.x

Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend的功能已被集成并进一步改进到核心类Neos\Cache\Backend\RedisBackend。

因此,要更新,您需要进入您的Caches.yaml文件,并将所有出现的Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend替换为Neos\Cache\Backend\RedisBackend。

Neos < 8.0的原始README

  • 用作内容缓存
  • 如果许多元素具有相同的标签,则需要此功能

安装

composer require sandstorm/optimizedrediscachebackend

版本兼容性

  • = 1.1.4: 支持在Settings.yaml中Neos.Flow.cache.applicationIdentifier - 这仅支持以下Flow版本,因为我们依赖于此核心错误修复

    • 6.3.14或更高版本(且小于7.0)
    • 7.0.11或更高版本(且小于7.1)
    • 7.1.5或更高版本(且小于7.2)
    • 7.2.2或更高版本
    • 7.3.0或更高版本(以及所有未来版本)
  • <= 1.1.3 - Flow 6和7(所有版本)

使用

在Caches.yaml中,执行以下操作

Neos_Fusion_Content:
  backend: Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend
  
Neos_Media_ImageSize:
  backend: Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend
  
Flow_Mvc_Routing_Route:
  backend: Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend
  
Flow_Mvc_Routing_Resolve:
  backend: Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend

如果您使用基于符号链接的部署,您应按如下方式设置flushRedisDatabaseCompletely选项,以删除旧版本中的旧数据(并确保您为每个缓存使用一个redis DB)

Neos_Fusion_Content:
  backend: Sandstorm\OptimizedRedisCacheBackend\OptimizedRedisCacheBackend
  backendOptions:
    flushRedisDatabaseCompletely: true

当前Redis缓存实现的问题

  • 当执行flushByTag时,我们执行以下操作(伪代码)

    • 迭代此标签的所有条目
      • "取消链接"条目从所有此条目额外标记的标签中
        • 迭代当前条目的所有标签
      • 删除条目
      • 删除条目-标签关系
    • 删除标签
  • 您可以看到,我们在这里有一个双层迭代。在一个大客户项目中,有时在单个标签刷新过程中,内部循环被调用超过100,000次;这使得Redis服务器在脚本运行期间无响应。

此缓存后端的优化

优化后的 FlushByTag

在执行 flushByTag 时,我们只需做以下操作

- *iterate* over all entries for this tag
  - remove the entry
  - remove the entry->tags relation
- remove the tag

这意味着不会删除缓存条目中其他标签.

  • 这会在 Redis 缓存中留下一些“冗余”数据;即那些分配的条目已经不存在但标签仍然存在的数据。这不是一个大问题,因为条目可能只是因为超时(因为它们有 TTL)而消失。

  • 我唯一能想到的可能会成为问题的情况是

    • entry1 插入并带有标签 A,B
    • 执行 flushByTag(A) -> entry1 被删除,标签 A 被删除,标签 B 仍然存在,指向(不存在的)entry1
    • 带有标签 A 的 entry1 被插入 (标签关联已更改!)
    • -> 仍然存在标签 B(尚未被删除)和 entry1 之间的连接。
  • 当依赖于 TaggableBackendInterface 的 findIdentifiersByTag() 时,这可能会成为问题 -- 但内容缓存中从未使用过这个功能。

  • 除了 findIdentifiersByTag() 之外,标签仅用于 清除 缓存的某些部分。因此,标签 B -> entry1 的过时边缘可能导致 entry1 被频繁刷新我们假设这对于内容缓存来说并不重要。

  • 如果用户想要完全删除冗余数据,应该调用 flush(),这将完全重置缓存。

  • 上述整个场景不太可能发生,因为缓存标签主要受 Fusion 控制;只要这一点没有改变,缓存标签就会保持稳定。

标准缓存后端的条目列表的删除

默认的 Redis 缓存后端有一个 entries 列表,用于存储所有缓存条目(在旧版 Redis 版本上需要用于迭代)。在列表中查找元素的时间复杂度为 O(n),即列表条目数量。

今天,人们可以使用 KEYS 来迭代条目;但我们的内容缓存不依赖于 IterableBackendInterface。因此,我们完全删除了 entries

更简单的 flush() 实现

在实现 flush() 时,我们只需遍历键空间的相关部分并删除所有元素。之前,这是通过类似于 FlushByTag 中解释的逻辑来完成的,因为 Redis 后端是可以冻结的(但我们不需要 Neos 内容缓存中的这一点)。