Удаление данных из кэша с помощью префикса ключа в Django

cache.set("determ_" + str(id), cache_object)

Я работаю с кэшем Django, используя Redis, вот примеры ключей моего кэша

determ_1ba243f3-2eda-4feb-bf24-1aa4c0cd2171 appr_hist_2bfd55e4-22c1-4cc3-a913-8ac2cde3801b appr_act_5a18c351-e172-4369-9a4b-118c3df5b25a

но у меня возникает проблема, когда я хочу удалить кэш, используя часть ключа, например determ_, appr_hist_, appr_act_

Как это удастся сделать?

from django.core.cache import cache

class CacheManager:
    
    @classmethod
    def delete_cache(self, prefixes = []):
        for pattern in prefixes:
            cache.delete(pattern)

        return True
CacheManager.delete_cache(['determ_','appr_hist_', 'det_appr','appr_act_','deter_sect_'])

Я не могу говорить за Django, но в Redis нет функции удаления по шаблону. Способ, которым это обычно делается, работает, но не является производительным.

Это использование команды SCAN для получения всех ключей, соответствующих шаблону. SCAN - это операция O(N), где N - количество ключей в Redis. Затем вы выполняете команду UNLINK для всех полей. UNLINK является переменной, поэтому вы можете передать ей все совпадающие ключи.

Команды KEYS и DEL будут работать также, но они еще менее производительны. KEYS блокирует Redis на время его работы, после чего другие клиенты не могут использовать Redis. DEL блокирует Redis до освобождения памяти, в то время как UNLINK возвращается и затем освобождает память.

Не уверен, что вы можете получить доступ к любой из этих команд из Django, но я надеюсь, что это поможет.

Огромное спасибо @Guy Royse за отличные материалы. Я воспользовался идеей и построил этот метод, и теперь он отлично работает, но мне нужно будет разобраться с моими политиками и производительностью

import redis

class CacheManager:

    
    @classmethod
    def delete_cache(self, prefixes = []):
        redis_client = redis.from_url('redis://127.0.0.1:6379/1')
        keys = redis_client.scan_iter("fcrs_:1:*")
        for key in keys:
            for prefix in prefixes:
                clear_key = str(key.decode('utf-8')).split(":")
                if prefix in clear_key[2]:
                    print(f": Found keys for prefix '{prefix}':", str(key.decode('utf-8')))
                    redis_client.delete(key)
        
        return True
Вернуться на верх