ODOO集群模式下模块加载问题

ODOO集群模式下模块加载问题

在odoo及postgresql(主从模式)皆为集群模式下,系统出现频繁加载模块及模块更新不及时的问题。系统频繁加载模块,会导致缓存失效,严重影响系统性能。

odoo控制台输出日志如下:

odoo.modules.registry: Reloading the model registry after database signaling.
odoo.modules.loading: loading 1 modules…
odoo.modules.loading: 1 modules loaded in 0.01s, 0 queries
odoo_input_test odoo.modules.loading: loading 69 modules…

翻看odoo13的源码,涉及到上述错误的代码如下:

with closing(self.cursor()) as cr:
    cr.execute(""" SELECT base_registry_signaling.last_value,
                          base_cache_signaling.last_value
                   FROM base_registry_signaling, base_cache_signaling""")
    r, c = cr.fetchone()
    _logger.debug("Multiprocess signaling check: [Registry - %s -> %s] [Cache - %s -> %s]",
                  self.registry_sequence, r, self.cache_sequence, c)
    # Check if the model registry must be reloaded
    if self.registry_sequence != r:
        _logger.info("Reloading the model registry after database signaling.")
        self = Registry.new(self.db_name)
    # Check if the model caches must be invalidated.
    elif self.cache_sequence != c:
        _logger.info("Invalidating all model caches after database signaling.")
        # Bypass self.clear_caches() to avoid invalidation loops in multi-threaded
        # configs due to the `cache_invalidated` flag being set, causing more signaling.
        self.cache.clear()
    self.registry_sequence = r
    self.cache_sequence = c

modules指的是odoo的model元数据部分,odoo启动时加载所有modules。如果modules发生了更新或卸载,odoo则需要重新加载modules。重新加载并不是实时的,odoo内部维护了两个序列:base_registry_signaling和base_cache_signaling。并且odoo内存中保存了当前的序列值:registry_sequence和cache_sequence。modules发生变更,数据库中的序列值加一处理,应用内存中的序列值维持不变。当有新的请求进来的时候,系统将判断数据库中和内存中的序列值是否一致。不一致的话将重新加载modules,并用数据库的序列值刷新内存的序列值。以上是odoo的处理逻辑。

但是考虑集群模式下,问题就变的复杂起来。

一、odoo集群、postgresql单节点方式

odoo的默认处理逻辑可以支持这种方式。由于数据库是单节点,odoo集群中的各个结点的modules最终都能保证是最新的。

二、odoo集群、postgresql集群方式

这种方式的话就杯具了。大家知道对于序列,postgresql主从同步是不能保证一致性的。序列值不一致,在数据库读写分离的情况下就会导致部分结点的modules是旧的或者发生重复加载的问题。

解决方案:

1、替换odoo的序列方案,采用数据库表或者Redis的方式,只要保证变更的序号在集群模式下是一致的即可。该种方案可以根本性的解决加载modules的问题。

2、注释掉odoo默认的元数据变更处理逻辑(不推荐),此种解决方案适用于odoo的非实施模式,即开发模式。只要modules发生了变更,就需要重启odoo的集群服务。

One thought on “ODOO集群模式下模块加载问题

发表评论