Enhancement: Add a database caching for improved performance (#9784)

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
Antoine Mérino
2025-07-01 07:36:24 +02:00
committed by GitHub
parent 6b248ef140
commit 1671d49d44
7 changed files with 309 additions and 16 deletions

View File

@@ -433,6 +433,7 @@ STORAGES = {
_CELERY_REDIS_URL, _CHANNELS_REDIS_URL = _parse_redis_url(
os.getenv("PAPERLESS_REDIS", None),
)
_REDIS_KEY_PREFIX = os.getenv("PAPERLESS_REDIS_PREFIX", "")
TEMPLATES = [
{
@@ -458,7 +459,7 @@ CHANNEL_LAYERS = {
"hosts": [_CHANNELS_REDIS_URL],
"capacity": 2000, # default 100
"expiry": 15, # default 60
"prefix": os.getenv("PAPERLESS_REDIS_PREFIX", ""),
"prefix": _REDIS_KEY_PREFIX,
},
},
}
@@ -882,7 +883,7 @@ CELERY_SEND_TASK_SENT_EVENT = True
CELERY_BROKER_CONNECTION_RETRY = True
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
CELERY_BROKER_TRANSPORT_OPTIONS = {
"global_keyprefix": os.getenv("PAPERLESS_REDIS_PREFIX", ""),
"global_keyprefix": _REDIS_KEY_PREFIX,
}
CELERY_TASK_TRACK_STARTED = True
@@ -903,22 +904,69 @@ CELERY_BEAT_SCHEDULE = _parse_beat_schedule()
# https://docs.celeryq.dev/en/stable/userguide/configuration.html#beat-schedule-filename
CELERY_BEAT_SCHEDULE_FILENAME = str(DATA_DIR / "celerybeat-schedule.db")
# django setting.
CACHES = {
"default": {
"BACKEND": os.environ.get(
"PAPERLESS_CACHE_BACKEND",
"django.core.cache.backends.redis.RedisCache",
),
"LOCATION": _CHANNELS_REDIS_URL,
"KEY_PREFIX": os.getenv("PAPERLESS_REDIS_PREFIX", ""),
},
}
if DEBUG and os.getenv("PAPERLESS_CACHE_BACKEND") is None:
CACHES["default"]["BACKEND"] = (
"django.core.cache.backends.locmem.LocMemCache" # pragma: no cover
# Cachalot: Database read cache.
def _parse_cachalot_settings():
global INSTALLED_APPS
ttl = __get_int("PAPERLESS_READ_CACHE_TTL", 3600)
ttl = min(ttl, 31536000) if ttl > 0 else 3600
_, redis_url = _parse_redis_url(
os.getenv("PAPERLESS_READ_CACHE_REDIS_URL", None),
)
result = {
"CACHALOT_CACHE": "read-cache",
"CACHALOT_ENABLED": __get_boolean(
"PAPERLESS_DB_READ_CACHE_ENABLED",
default="no",
),
"CACHALOT_FINAL_SQL_CHECK": True,
"CACHALOT_QUERY_KEYGEN": "paperless.db_cache.custom_get_query_cache_key",
"CACHALOT_TABLE_KEYGEN": "paperless.db_cache.custom_get_table_cache_key",
"CACHALOT_REDIS_URL": redis_url,
"CACHALOT_TIMEOUT": ttl,
}
if result["CACHALOT_ENABLED"]:
INSTALLED_APPS.append("cachalot")
return result
_cachalot_settings = _parse_cachalot_settings()
CACHALOT_ENABLED = _cachalot_settings["CACHALOT_ENABLED"]
CACHALOT_CACHE = _cachalot_settings["CACHALOT_CACHE"]
CACHALOT_TIMEOUT = _cachalot_settings["CACHALOT_TIMEOUT"]
CACHALOT_QUERY_KEYGEN = _cachalot_settings["CACHALOT_QUERY_KEYGEN"]
CACHALOT_TABLE_KEYGEN = _cachalot_settings["CACHALOT_TABLE_KEYGEN"]
CACHALOT_FINAL_SQL_CHECK = _cachalot_settings["CACHALOT_FINAL_SQL_CHECK"]
# Django default & Cachalot cache configuration
_CACHE_BACKEND = os.environ.get(
"PAPERLESS_CACHE_BACKEND",
"django.core.cache.backends.locmem.LocMemCache"
if DEBUG
else "django.core.cache.backends.redis.RedisCache",
)
def _parse_caches():
return {
"default": {
"BACKEND": _CACHE_BACKEND,
"LOCATION": _CHANNELS_REDIS_URL,
"KEY_PREFIX": _REDIS_KEY_PREFIX,
},
"read-cache": {
"BACKEND": _CACHE_BACKEND,
"LOCATION": _parse_cachalot_settings()["CACHALOT_REDIS_URL"],
"KEY_PREFIX": _REDIS_KEY_PREFIX,
},
}
CACHES = _parse_caches()
del _cachalot_settings
def default_threads_per_worker(task_workers) -> int: