ZODB игнорирует целевое количество кэшированных объектов и размер целевой кэш-памяти.

Я хочу использовать ZODB с минимальным кэшированием. Для этого я создаю экземпляр базы данных ZODB и открываю его следующим образом:

db = DB('/home/me/example.db', cache_size=1, cache_size_bytes=1)
db_conn = db.open_then_close_db_when_connection_closes()

db_conn является единственным соединением db. Я проверяю, установлены ли оба параметра размера целевого кэша, проверяя db_conn._cache.cache_size и db_conn._cache.cache_size_bytes, каждый из которых оценивается как 1.

В базе данных я храню множество (могут быть миллиарды и более) постоянных объектов в одном OOBTree. Когда я читаю их (пакетами) из базы данных, использование моей памяти увеличивается. Вызов db_conn.cacheMinimize() после каждого (пакетного) чтения предотвращает рост использования памяти, но я хочу, чтобы ZODB вообще не кэшировал объекты (в отличие от того, чтобы я заставлял его удалять кэшированные объекты из памяти).

Я отслеживаю состояние кэша базы данных прямо перед и сразу после каждого вызова cacheMinimize(), используя cacheDetail() и cacheDetailSize() следующим образом:

cache_status_before = {'detail': db_conn.db().cacheDetail(),
                       'detail size': db_conn.db().cacheDetailSize()}
db_conn.cacheMinimize()
cache_status_after = {'detail': db_conn.db().cacheDetail(),
                      'detail size': db_conn.db().cacheDetailSize()}
print('{} -> {}'.format(cache_status_before, cache_status_after))

Типичный вывод приведенных выше строк (Simulation — это класс моих объектов, унаследованный от Persistent):

{'detail': [('BTrees.OOBTree.OOBucket', 62), ('boolsi.simulate.Simulation', 1758)],
'detail size': [{'connection': '<Connection at 7fe9340966a0>', 'ngsize': 933, 'size': 1820}]}
->
{'detail': [('BTrees.OOBTree.OOBucket', 3), ('boolsi.simulate.Simulation', 1748)],
'detail size': [{'connection': '<Connection at 7fe9340966a0>', 'ngsize': 0, 'size': 1751}]}

Насколько я понимаю, эти выходные данные показывают, что ZODB игнорирует как целевое количество кэшированных объектов, так и размер целевой кэш-памяти, поскольку он кэширует более 1 объекта (и определенно превышает 1 байт). Есть идеи, почему?


person Vlad Oles    schedule 04.12.2018    source источник


Ответы (1)


Кэш ZODB и дерево объектов — это одно и то же. Когда вы извлекаете объекты, они живут в кеше. Если бы ZODB постоянно устанавливал размер кэша, вы не смогли бы загружать объекты с вашими настройками.

Если вы хотите, чтобы ZODB чаще удалял объекты из кеша, рассмотрите возможность более частого совершения транзакций. Обратите внимание, что если вы загружаете объекты из BTree пакетами, вы хотите, чтобы некоторые объекты были кэшированы, чтобы вам не приходилось перезагружать промежуточные объекты снова и снова.

person j1m    schedule 15.12.2018
comment
Я бы только добавил для полноты информации, что размер целевого кэша применяется на границах транзакций, а не все время. - person Vlad Oles; 17.12.2018
comment
Соответствующая тема из ZODB Google Group: groups.google.com/forum/#!topic /zodb/cExsoJ7OkvI - person Vlad Oles; 17.12.2018