Задать вопрос

Redis спустя время теряет данные, с чем это связано и как исправить?

На сколько я знаю, по умолчанию TTL бессрочный, так что дело не в нем, я не ставил никакой TTL.
Попробовал хранить физически, а не в оперативной памяти, так я ловлю ошибку - Background saving error
Failed opening the RDB file crontab (in server root dir /etc) for saving: Permission denied
Вот redis.conf
# RDB настройка
save 900 1
save 300 10
save 60 10000
dir /data
# AOF настройка
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec

Вот часть в docker-compose
redis:
    container_name: redis
    image: redis:6.2 
    ports:
      - "6379:6379"
    restart: always
    networks:
      - postgres
    volumes:
      - redis-data:/data
      - ~/telegrambot/redis.conf:/usr/local/etc/redis/redis.conf # Подключение конфигурационного файла
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"] # Использование конфигурационного файла


volumes:
  pgdata:
  pgadmin-data:
  redis-data:

networks:
  postgres:
    driver: bridge

Вот класс отвечающий за взаимодействие с редисом
import aioredis
import json

class RedisClient:
    def __init__(self, host='redis', port=6379, db=0):
        self.host = host
        self.port = port
        self.db = db
        self.redis = None

    async def connect(self):
        self.redis = await aioredis.from_url(f'redis://{self.host}:{self.port}/{self.db}', decode_responses=True)

    async def close(self):
        if self.redis:
            await self.redis.close()

    async def set_user_data(self, user_id, data):
        if self.redis is None:
            raise ConnectionError("Redis connection is not established.")
        
        # Проходим по элементам словаря
        for key, value in data.items():
            if value is not None:
                if isinstance(value, (list, dict)):  # Если значение является списком или словарем
                    value_str = json.dumps(value)  # Преобразуем его в строку JSON
                else:
                    value_str = str(value)  # Иначе просто преобразуем его в строку
            else:
                value_str = 'None'  # Если значение None, оставляем его как есть
            
            # Устанавливаем каждый элемент словаря в Redis
            await self.redis.hset(f'user:{user_id}', key, value_str)

    async def get_user_data(self, user_id):
        if self.redis is None:
            raise ConnectionError("Redis connection is not established.")
        data = await self.redis.hgetall(f'user:{user_id}')
        
        # Преобразуем строки JSON обратно в оригинальные типы данных
        for key, value in data.items():
            if value == 'None':
                data[key] = None
            else:
                try:
                    data[key] = json.loads(value)
                except json.JSONDecodeError:
                    pass  # Если ошибка, значит значение не было JSON строкой и оставляем его как есть
        return data

    async def user_data_exists(self, user_id):
        if self.redis is None:
            raise ConnectionError("Redis connection is not established.")
        return await self.redis.exists(f'user:{user_id}')

Проблема в том, что он добавляет данные, держит какое-то время и данные для юзера становятся пустыми спустя какое-то время.
  • Вопрос задан
  • 658 просмотров
Подписаться 3 Простой 3 комментария
Решения вопроса 1
@gidwin Автор вопроса
В общем, почитав англоязычные форумы, то что я называл "странным" явлением, считается скомпрометированным сервером. Редис сервер был ничем не защищен и подвергся атаке(буквально в течении полу часа после раската). Единственное решение этого вопроса является защита, а именно необходимо установить юзера/пароль и сменить порты. Все это помогло мне в моей проблеме. Мораль сей басни такова, необходимо делать сразу защищенный доступ и будет вам счастье!
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
AshBlade
@AshBlade
Просто хочу быть счастливым
Тебе прямым текстом пишут Permission denied при попытке доступа к RDB файлу - он не может загрузить файл БД.
Исправить доступ к /etc
Ответ написан
@qid00000000
Мало что знаю, но информацию найду в гугле
А у вас какой key eviction стоит и memory limit?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы