Подтвердить что ты не робот

Как кэшировать таблицы базы данных для предотвращения многих запросов к базе данных в Asp.net С# mvc

Я создаю свои собственные cms, используя Asp.net mvc 4 (С#), и я хочу кэшировать некоторые данные базы данных, нравится: локализация, категории поиска (это длинный хвост, каждая категория имеет собственные подпункты и подкатегории ) и т.д.

Это будет чрезмерное обращение к базе данных все время, потому что для каждого запроса страницы может быть более 30-100 запросов, однако пользователи редко обновляют эту базу данных

Итак, какой лучший способ (производительность и удобство) сделать это??? (ссылки на руководства и руководства также будут полезны)

Я знаю, как использовать OutputCache для действия, но это не то, что мне нужно в этой ситуации, оно кэширует html, но мне нужно, например, что мой собственный помощник @html.Localization("Newsletter.Tite") примет значение языка, или любой другой помощник, который взаимодействует с данными и т.д.

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

4b9b3361

Ответ 1

Вы можете использовать встроенный MemoryCache для хранения целых результатов, которые вы получили из базы данных.

Типичный шаблон:

MyModel model = MemoryCache.Default["my_model_key"] as MyModel;
if (model == null)
{
    model = GetModelFromDatabase();
    MemoryCache.Default["my_model_key"] = model;
}

// you could use the model here

Ответ 2

Мне пришлось кэшировать общие данные базы данных, такие как данные, которые отображались в раскрывающихся списках. Я использовал MemoryCache. И я использовал Entity Framework code first и Autofac для инъекции зависимостей.

Вот часть того, что я сделал в своем решении, может не сработать для вас, но это сработало для меня, но не идеально, но нужно много сделать, чтобы сделать.

Мой ICacheManager интерфейс:

public interface ICacheManager
{
     T Get<T>(string key);

     void Set(string key, object data, int cacheTime);

     bool IsSet(string key);

     void Remove(string key);

     void Clear();
}

Мой CacheManager класс:

public class CacheManager : ICacheManager
{
     private ObjectCache Cache
     {
          get
          {
               return MemoryCache.Default;
          }
     }

     public T Get<T>(string key)
     {
          return (T)Cache[key];
     }

     public void Set(string key, object data, int cacheTime)
     {
          if (data == null)
          {
               return;
          }

          CacheItemPolicy policy = new CacheItemPolicy();
          policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime);

          Cache.Add(new CacheItem(key, data), policy);
     }

     public bool IsSet(string key)
     {
          return (Cache.Contains(key));
     }

     public void Remove(string key)
     {
          Cache.Remove(key);
     }

     public void Clear()
     {
          foreach (var item in Cache)
          {
               Remove(item.Key);
          }
     }
}

Класс расширения для моего кэширования:

public static class CacheExtensions
{
     public static T Get<T>(this ICacheManager cacheManager, string key, Func<T> acquire)
     {
          return Get(cacheManager, key, 60, acquire);
     }

     public static T Get<T>(this ICacheManager cacheManager, string key, int cacheTime, Func<T> acquire)
     {
          if (cacheManager.IsSet(key))
          {
               return cacheManager.Get<T>(key);
          }
          else
          {
               var result = acquire();

               cacheManager.Set(key, result, cacheTime);

               return result;
          }
     }
}

И вот как я буду использовать его в моем классе репозитория. Этот метод возвращает список всех моих банков, который отображается в раскрывающемся списке.

public class BankRepository : RepositoryBase<Bank>, IBankRepository
{
     private readonly ICacheManager cacheManager;
     private const string BanksAllCacheKey = "banks-all";

     public BankRepository(IDatabaseFactory databaseFactory, ICacheManager cacheManager)
          : base(databaseFactory)
     {
          Check.Argument.IsNotNull(cacheManager, "cacheManager");

          this.cacheManager = cacheManager;
     }

     public IEnumerable<Bank> FindAll()
     {
          string key = string.Format(BanksAllCacheKey);

          return cacheManager.Get(key, () =>
          {
               var query = from bank in DatabaseContext.Banks
                           orderby bank.Name
                           select bank;

               return query.ToList();
          });
     }
}

Надеюсь, это поможет. Это очень простая реализация, но она работает для меня. В Интернете много статей о том, как использовать стратегию кэширования в ASP.NET MVC. Просто Google это.

Ответ 3

Есть несколько вещей, которые следует рассмотреть здесь, прежде чем выбирать свою реализацию кеширования, но одна из основных вещей, которую вы должны решить, - в какой момент вы хотите, чтобы кеширование происходило - при доступе к данным, создании модели или создании пользовательского интерфейса? Одно или все из этих мест?

У вас есть несколько вариантов, но для общего кэширования данных вы можете использовать System.Runtime.Caching.MemoryCache, или для чего-то более гибкого и полезного вы можете посмотреть при реализации с использованием NoSQL, например Redis.

Вы можете использовать MemoryCache для кэширования данных, но используйте Redis для кеширования агрегатов, составляющих ваши модели просмотра. Если вы поедете с Redis, вы можете, конечно, обработать все свои кеширования, используя это. Преимущество состоит в том, что все ваши данные станут постоянными во всех перезапусках приложений. Недостатком является то, что он становится дополнительным требованием для запуска вашей CMS.

Другими факторами, которые могут повлиять, являются согласованность (использование некоторых IoC поможет) и предоставление данных, которые будут отменены после его обновления. Поэтому наличие некоторых средств обновления кеша.

Что касается наилучшего подхода, в вашем случае, если вы создаете новое приложение CMS, начинайте с малого/просто и выполняйте шаги. Вы не можете добиться совершенства в первый раз, но до тех пор, пока вы будете последовательны и понятны в своем подходе, вам будет легко опираться на то, что вы сделали или поменяли, и попробовать что-то другое/лучшее.