← Назад к вопросам

Что такое swap в Redis?

2.0 Middle🔥 121 комментариев
#Кэширование и NoSQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое swap в Redis

Swap — это механизм операционной системы, который резервирует место на диске (swap-пространство) для хранения данных оперативной памяти, когда физической RAM недостаточно. Для Redis это проблема, так как использование swap серьёзно деградирует производительность.

Почему swap вредит Redis

Redis — база данных в памяти, оптимизированная для быстрого доступа к RAM. Когда операционная система начинает использовать swap:

  1. Огромное замедление — доступ к диску на 1000+ раз медленнее, чем к памяти
  2. Непредсказуемая задержка — операции, которые занимали микросекунды, займут миллисекунды
  3. Выхода из строя — Redis может зависнуть, обслуживая swap-операции
  4. Потеря преимуществ — почему использовать Redis, если данные на диске?

Пример проблемы

Операция без swap:
GET key → 10 микросекунд (из RAM)

Операция с включенным swap:
GET key → может занять 100-500 миллисекунд
         (OS нужно поменять страницы памяти на диск и обратно)

Как Redis использует память

// Пример структуры данных Redis в памяти
public class RedisMemoryExample {
    // Каждый ключ и значение занимает место в RAM
    Map<String, String> dataStore = new HashMap<>();
    
    public void setKey(String key, String value) {
        dataStore.put(key, value);
        // Память занята!
    }
    
    public String getKey(String key) {
        // Быстрый доступ - всё в RAM
        return dataStore.get(key);
    }
}

Признаки, что Redis использует swap

# Проверить использование swap процессом Redis
ps aux | grep redis
# Посмотреть, какой процесс использует swap
for pid in $(pidof redis-server); do
    echo "PID $pid:"
    cat /proc/$pid/status | grep VmSwap
done

# Если VmSwap не 0, то происходит использование swap!

Java клиент для Redis - пример с мониторингом

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisMemoryMonitoringExample {
    public static void main(String[] args) {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(10);
        config.setMaxIdle(5);
        
        JedisPool pool = new JedisPool(config, "localhost", 6379);
        
        try (Jedis jedis = pool.getResource()) {
            // Добавляем большое количество данных
            for (int i = 0; i < 1000000; i++) {
                jedis.set("key:" + i, "value:" + i);
                
                if (i % 10000 == 0) {
                    // Проверяем информацию о памяти Redis
                    String info = jedis.info("memory");
                    System.out.println("Added " + i + " keys");
                    System.out.println(info);
                    // Ищем:
                    // used_memory: используется ОЗУ
                    // used_memory_rss: всё выделенное ОЗУ (включает фрагментацию)
                }
            }
        }
        
        pool.close();
    }
}

Как избежать swap в Redis

1. Правильная настройка максимального объёма памяти

public class RedisConfigExample {
    // Конфигурация redis.conf
    public static void main(String[] args) {
        // redis.conf:
        // maxmemory 2gb
        // maxmemory-policy allkeys-lru
        // (удалять ключи по LRU при достижении максимума)
        
        // Это предотвратит случайное выхода за пределы памяти
    }
}

2. Отключение swap на уровне ОС

# Отключить swap полностью (не рекомендуется для всей системы)
sudo swapoff -a

# Или заблокировать память Redis процесса
# redis.conf:
# stop-writes-on-bgsave-error yes

3. Использование Redis maxmemory policies

public class RedisMaxMemoryPolicies {
    // redis.conf:
    // maxmemory 2gb
    // maxmemory-policy allkeys-lru    # Удалять ключи по LRU
    // или
    // maxmemory-policy volatile-lru   # Удалять только ключи с TTL
    // или
    // maxmemory-policy allkeys-random # Удалять случайные ключи
}

Мониторинг памяти Redis

import redis.clients.jedis.Jedis;

public class RedisMemoryMonitoring {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        String memoryInfo = jedis.info("memory");
        System.out.println(memoryInfo);
        
        // Ищем строки:
        // used_memory: 1000000 (байт используется)
        // used_memory_human: 976.56K (удобочитаемо)
        // used_memory_rss: 2000000 (выделено ОС)
        // mem_fragmentation_ratio: 1.5 (фрагментация памяти)
        // mem_allocator: jemalloc-5.2.1 (аллокатор памяти)
        
        // Если mem_fragmentation_ratio > 1.5, нужна перезагрузка Redis
    }
}

Примеры неправильной конфигурации

# ❌ Плохо: Redis без ограничения памяти
# maxmemory не установлен
# Redis начнёт использовать всю доступную память и потом swap

# ✅ Хорошо: Redis с ограничением
maxmemory 2gb
maxmemory-policy allkeys-lru

Проблемы и решения

ПроблемаПричинаРешение
Redis очень медленныйИспользуется swapУвеличить RAM, установить maxmemory
Память растёт бесконечноНет ttl на ключахУстановить expire на ключи
Память не освобождаетсяФрагментацияПерезагрузить Redis

Правильная архитектура с Redis

public class ProperRedisArchitecture {
    public static void main(String[] args) {
        // 1. Установить maxmemory
        // 2. Выбрать maxmemory-policy
        // 3. Использовать expire/ttl для автоматической очистки
        // 4. Мониторить используемую память
        // 5. Масштабировать горизонтально при необходимости
        
        Jedis jedis = new Jedis("localhost", 6379);
        
        // Хорошая практика: устанавливать TTL
        jedis.setex("temp_key", 3600, "some_value"); // 1 час TTL
        
        // Проверять здоровье Redis
        String pong = jedis.ping();
        if ("PONG".equals(pong)) {
            System.out.println("Redis is healthy");
        }
    }
}

Вывод

Swap в Redis — это признак серьёзной проблемы конфигурации. Необходимо:

  • Установить правильный maxmemory
  • Выбрать подходящую maxmemory-policy
  • Регулярно мониторить использование памяти
  • Использовать TTL для автоматической очистки данных
  • При необходимости масштабировать Redis кластер

Использование swap означает, что Redis работает неправильно и нужно пересмотреть архитектуру или конфигурацию.