Redis
 sql >> Teknologi Basis Data >  >> NoSQL >> Redis

Pegangan Kesalahan Redis Musim Semi

Saya memiliki masalah yang sama. Saya sedang mengembangkan beberapa layanan data terhadap database, menggunakan Redis sebagai penyimpanan cache melalui anotasi Spring Caching. Jika server Redis menjadi tidak tersedia, saya ingin layanan terus beroperasi seolah-olah tidak di-cache, daripada membuang pengecualian.

Awalnya saya mencoba CacheErrorHandler khusus, mekanisme yang disediakan oleh Spring. Itu tidak cukup berhasil, karena hanya menangani RuntimeExceptions, dan masih memungkinkan hal-hal seperti java.net.ConnectException meledakkan segalanya.

Pada akhirnya yang saya lakukan adalah memperluas RedisTemplate, mengganti beberapa metode execute() sehingga mereka mencatat peringatan alih-alih menyebarkan pengecualian. Sepertinya sedikit peretasan, dan saya mungkin telah mengganti terlalu sedikit metode execute() atau terlalu banyak, tetapi ini berfungsi seperti pesona di semua kasus pengujian saya.

Ada aspek operasional yang penting untuk pendekatan ini. Jika server Redis menjadi tidak tersedia, Anda harus menghapusnya (membersihkan entri) sebelum membuatnya tersedia lagi. Jika tidak, ada kemungkinan Anda mulai mengambil entri cache yang memiliki data yang salah karena pembaruan yang terjadi sementara itu.

Di bawah ini adalah sumbernya. Jangan ragu untuk menggunakannya. Semoga membantu.

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;


/**
 * An extension of RedisTemplate that logs exceptions instead of letting them propagate.
 * If the Redis server is unavailable, cache operations are always a "miss" and data is fetched from the database.
 */
public class LoggingRedisTemplate<K, V> extends RedisTemplate<K, V> {

    private static final Logger logger = LoggerFactory.getLogger(LoggingRedisTemplate.class);


    @Override
    public <T> T execute(final RedisCallback<T> action, final boolean exposeConnection, final boolean pipeline) {
        try {
            return super.execute(action, exposeConnection, pipeline);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final RedisScript<T> script, final List<K> keys, final Object... args) {
        try {
            return super.execute(script, keys, args);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final RedisScript<T> script, final RedisSerializer<?> argsSerializer, final RedisSerializer<T> resultSerializer, final List<K> keys, final Object... args) {
        try {
            return super.execute(script, argsSerializer, resultSerializer, keys, args);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }


    @Override
    public <T> T execute(final SessionCallback<T> session) {
        try {
            return super.execute(session);
        }
        catch(final Throwable t) {
            logger.warn("Error executing cache operation: {}", t.getMessage());
            return null;
        }
    }
}


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Cache dalam memori dengan masa berlaku LRU

  2. Python - Cara memeriksa apakah server Redis tersedia

  3. Ruang nama di Redis?

  4. Performa SCAN vs KEYS di Redis

  5. Apakah perintah redis incr dapat dibatasi untuk nomor tertentu?