Сериализация списка и большого объекта для Redis Cache - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть приложение ASP. NET для электронной коммерции. У моего приложения большой трафик c, и я должен использовать систему кеширования. Я переключаю свой механизм кэширования с оперативной памяти (memcache) на redis (распределенный кеш), потому что у меня пять серверов.

Не было проблем с memcache, но теперь у меня проблема после переключения redis. Например, я сериализую свой список, и он занимает около 4-5 МБ, но когда я читаю его из redis-cli, он получается очень медленно, около 5 секунд, и поэтому мое приложение вызывает исключение тайм-аута.

Я прочитал это " не храните большие данные в Redis ". С другой стороны, я использую кэш вывода и сессионный кэш с MVC, для redis проблем нет. Должен ли я использовать BinarySerializer или что? Как я могу хранить большие объекты в кэше Redis?

Спасибо за совет.

    public List<ProdFilter> GetAll(int prodFeatureGroupId)
    {
        var cacheKey = string.Format("{0}_{1}_{2}",
                            "ProductRepository",
                            "GetAll",
                            prodFeatureGroupId);
        var isExists = _cache.Contains(cacheKey) && Const.CacheIsActive;

        List<ProdFilter> obj;
        if (isExists)
        {
            obj = _cache.Get<List<ProdFilter>>(cacheKey);
        }
        else
        {
            obj = _db.ProdFilters
                    .Where(x => x.ProdFilterGroupId == prodFeatureGroupId)
                    .ToList();
            _cache.Add(cacheKey, obj);
        }

        return obj;
    }

    //my cache methods
    private void Create()
    {
        if (null == _db)
        {
            ConfigurationOptions option = new ConfigurationOptions();
            option.Ssl = false;
            option.EndPoints.Add(_host, _port);
            var connect = ConnectionMultiplexer.Connect(option);

            _db = connect.GetDatabase();
        }
    }

    public void Add<T>(string key, T obj)
    {
        var data = Serialize(obj);
        _db.StringSet(key, data);
    }

    public void Set<T>(string key, T obj)
    {
        Add(key, obj);
    }

    public T Get<T>(string key)
    {
        var val = _db.StringGet(key);

        return Deserialize<T>(val);
    }

    // my serialize helper
    public static byte[] Serialize(object o)
    {
        if (o == null)
        {
            return null;
        }

        BinaryFormatter binaryFormatter = new BinaryFormatter();

        using (MemoryStream memoryStream = new MemoryStream())
        {
            binaryFormatter.Serialize(memoryStream, o);
            byte[] objectDataAsStream = memoryStream.ToArray();
            return objectDataAsStream;
        }
    }

    public static T Deserialize<T>(byte[] stream)
    {
        if (stream == null)
            return (default(T));

        BinaryFormatter binaryFormatter = new BinaryFormatter();

        using (MemoryStream memoryStream = new MemoryStream(stream))
        {
            T result = (T)binaryFormatter.Deserialize(memoryStream);
            return result;
        }
    }
...