Mondrian缓存上一些架构的变化。
由于在Mondrian 3.3中引入了外部缓存,我们意识到我们正在给缓存架构带来压力。缓存体系结构需要现代化已经有一段时间了,但外部缓存使情况变得更糟。首先,对外部缓存的调用可能需要相当长的时间:根据缓存的不同,它可能会执行网络I/O,因此所需时间比内存访问长几个数量级。其次,我们引入了外部缓存和缓存内汇总,对于这两种情况,我们都必须改进处理缓存段所需的内存内索引。
以前我们使用了临界区方法:任何想要访问缓存中对象的线程都会锁定整个缓存。 随着缓存数据结构变得更加复杂,这些操作花费的时间也越来越长。 为了提高可扩展性,我们采用了一种完全不同的架构模式,称为 Actor 模型。 基本上,一个称为缓存管理器的线程专门负责管理缓存索引。 任何想要在缓存中查找段、或者向缓存添加段、或者通过计算现有段创建段、或者刷新缓存的查询线程都会向缓存管理器发送消息。
讽刺的是,缓存管理器并不从外部缓存获取段。 正如我之前所说,外部缓存访问可能需要一段时间,并且缓存管理器非常繁忙。 缓存管理器告诉客户端要向外部缓存请求的段键,然后客户端进行请求。 当客户端获取一个段时,它将其存储在其私有存储中(在查询期间有效),因此不需要再次询问缓存管理器。 由于一个段可以包含数千个单元,因此即使是大型查询通常也只会向缓存管理器发出几个请求。
外部缓存不仅速度慢,而且它也是多孔的。 它可能前一分钟还有一个片段,下一分钟就忘记了。 Mondrian的查询线程如果没有命中缓存,它将告诉缓存管理器从其索引中删除该段(因此 Mondrian 不会再次请求它),并制定替代策略去查找它。 也许所需的Cell存在于另一个缓存段中; 也许可以通过在缓存中汇总其他段来获得它(但它们也可能在没有通知的情况下丢失)。 如果一切都失败了,我们可以生成 SQL 从数据库中获取数据填充所需的段(事实表,或者如果可能的话,聚合表)。
由于缓存管理器太忙而无法与外部缓存通信,因此它肯定也太忙而无法执行 SQL 语句。 从缓存管理器的角度来看,SQL 查询需要很长时间(每个查询需要几百万个 CPU 周期),因此它将 SQL 查询分配给工作线程池。 缓存管理器将该段标记为“正在加载”。 如果另一个查询线程向缓存管理器请求该段中的单元,它会收到一个 Future
Actor 模型是一种完全不同的架构。 首先,我们来看看好处。 由于一个线程正在管理整个子系统,因此您可以删除所有锁定。 这是一种解放。 在子系统中,您可以非常简单地编写代码,而不是为了线程安全而破坏数据结构。 您甚至不需要使用像 CopyOnWriteArrayList 这样的并发安全数据结构,您只需使用完成这项工作最快的数据结构即可。 一旦删除并发控制(例如“同步”块)以及仅从一个线程进行访问,数据结构就会奇迹般地变得更快。 怎么可能? 数据结构现在驻留在线程的缓存中,当您删除并发控制时,您还删除了强制将更改通过 L1 和 L2 缓存写入 RAM 的内存障碍,这会慢 200 倍。
迁移到 Actor 模型并非没有挑战。 首先,您需要决定参与者应该拥有哪些数据结构和操作。 我相信我们做对了。 我发现大多数相同的事情需要完成,但是通过与以前不同的线程来完成; 所以我们的任务主要是移动代码。 我们需要细化“查询”、“缓存管理器”和“工作”线程之间传递的数据结构,以确保它们是不可变的。 例如,如果您希望查询线程在等待段时找到其他有用的工作要做,那么它不应该修改放入缓存管理器请求队列中的数据结构。 在未来的一篇博客文章中,我将更详细地描述将复杂软件系统的一个组件迁移到 Actor 模型的挑战和好处。
并非所有缓存都是平等的。 有些(例如 JBoss Infinispan)能够在集群中的节点之间共享缓存项(在我们的例子中是包含Cell Value的段),并使用冗余来确保缓存项永远不会丢失。 Infinispan 将自己称为“数据网格”,起初我认为这只是营销,但后来我确信它确实是一种与常规缓存不同的野兽。 为了支持数据网格,我们添加了钩子,以便缓存可以告诉 Mondrian 已添加到集群中其他节点的段。 这样,Mondrian就成为了一个真正的集群。 如果我在节点 1 上执行查询 X,它会将段放入数据网格中,这将使您要提交的查询、节点 2 上的查询 Y 执行得更快。
正如你从这篇文章的篇幅中可以看出的那样,我对Mondrian架构的这一变化感到非常兴奋。 从表面上看,Mondrian 执行与以前相同的 MDX 查询。 但当在具有多核的现代 CPU 上运行时,内部引擎可以更好地扩展; 由于外部缓存,缓存的行为更加可预测; 您可以创建共享工作和内存的 Mondrian 节点集群。
这些更改将很快以 Mondrian 版本 3.3.1 3.4 的形式发布,但您可以通过从主线(或从 CI)下载、尝试一下并让我们知道您是否发现任何问题来提供帮助。
文章评论