针对未知表模式的策略支持¶
新的分布式架构要求策略引擎能够处理某些数据源驱动程序的模式未知的情况。目前,策略引擎假定在加载时已知所有数据源驱动程序的模式。本文档概述了一种支持未知模式的机制。
问题描述¶
对于新的分布式架构,策略引擎在从数据库加载规则时将不知道所有数据源的模式。目前这存在问题,因为列引用在从数据库加载规则时会被编译掉,而该编译过程需要模式。因此,在新架构中,策略引擎在尝试加载包含列引用的策略规则时会崩溃。
提议的变更¶
解决此问题的办法是启用策略引擎加载包含列引用的规则,而无需编译掉这些列引用。也就是说,编译掉列引用的主要原因是,内部数据结构无法原生表示这些列引用,因此必须在加载时删除这些列引用。第一项任务是扩展 compile.py 中的内部数据结构,使其能够表示命名字段。
编译掉列引用的第二个原因是,在没有模式的情况下无法对其进行评估(甚至语义上无法评估)。第二项任务是扩展策略引擎的运行时能力,以便可以在不删除规则的情况下禁用规则。禁用的规则在回答查询时将完全隐藏在评估引擎中,但用户查看规则时仍将可见,并标记为“禁用”。
每次插入新规则时,如果其模式未知,则必须禁用该规则。此外,每条使用依赖于该规则头部表的表的规则都必须被禁用。对于删除操作也是如此,但删除操作可能会导致其他规则被启用。
每次模式更改时,应检查受该模式更改影响的所有规则的一致性,并且一旦所有模式已知,就必须启用禁用的规则。规则启用后,列引用将被编译掉。
如果到达第二个模式(与第一个模式不相等),策略引擎必须检查一致性并重新编译任何模式可能已更改的规则。
例如,如果以下规则在 nova-servers 和 neutron-networks 的模式已知之前插入,则该规则将被禁用,因为它具有列引用。
p(x, z) :- nova:servers(id=x, network=y), neutron:networks(id=y, status=z)
然后,当 nova 模式已知时,该规则将根据该模式进行验证,但不会启用,因为 neutron 模式未知。
最后,当 neutron 模式已知时,将编译掉列引用,并且该规则将正式启用。
备选方案¶
除了禁用规则之外,另一种选择是修改评估引擎以执行尽最大努力的查询评估。评估算法本身将了解列引用,并且即使模式未知也会尝试运行。
这种替代方案的缺点是规则实际上在语义上是模棱两可的,因此评估结果的语义值未知。
策略¶
N/A
策略动作¶
N/A
数据源¶
N/A
数据模型影响¶
不需要数据库修改。
REST API 影响¶
规则对象将具有一个额外的布尔字段,表示规则是否被禁用。
安全影响¶
N/A
通知影响¶
N/A
其他最终用户影响¶
N/A
性能影响¶
规则插入现在可能会更慢,因为如果插入的规则被禁用,则可能会导致许多其他规则被禁用。
规则删除同样可能会导致许多策略规则被启用。
模式更新成本很高,因为策略引擎必须对所有相关规则进行一致性检查,并可能重新编译规则。
其他部署者影响¶
N/A
开发者影响¶
N/A
实现¶
负责人¶
- 主要负责人
thinrichs
- 其他贡献者
<launchpad-id 或 None>
工作项¶
1. 修改 compile.py 数据结构以原生表示列引用。包括一个“disabled”标志。 2. 修改查询评估引擎以忽略禁用的规则 3. 修改触发器以忽略禁用的表 4. 在插入/删除/设置模式时启用/禁用规则 - 编写依赖分析例程,以计算在禁用给定表后将禁用的规则/表。可能需要一个跟踪禁用表的的数据结构。 - 修改更新例程以执行模式检查并根据依赖分析适当地启用/禁用规则。 - 修改 set-schema 以适当地启用/禁用规则。可能需要在规则中添加一个字段,说明编译依赖于哪些表。
依赖项¶
N/A
文档影响¶
N/A
参考资料¶
在 Liberty 中周期 Sprint 中讨论了对本文档的需求。 https://etherpad.openstack.org/p/congress-liberty-sprint