读写分离
缓存:
using Common; using Ruanmou.BLL; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CacheDemo { /// <summary> /// 1 读写分离、分库分表、表分区 /// 2 各种缓存 /// 3 本地缓存原理和实现 /// 4 作业 /// /// 本地缓存用在哪里: /// 1 查询多,修改少 /// 2 不是要求很即时,容忍延迟 /// 3 数据不是很多,,太多的话,,就得用分布式缓存 /// 4 复杂计算(分析报表)后、远程接口、长时间的查询,数据多次查询,也该缓存 /// 5 缓存可以读写,但是不能保存,因为不是硬盘(服务器重启 IIS死掉) /// 6 大批量数据操作,可以缓存后,多次一起操作(比如计数器) /// /// /// 缓存更新的问题: /// 首先 数据更新途径要统一,在这里可以更新缓存 /// 然后 如果有不同的途径,得提供清理缓存的方式 /// 其他 文件依赖、监听 /// 最后,依赖时间过期,得容忍延迟 /// /// </summary> class Program { static void Main(string[] args) { try { Console.WriteLine("今天是缓存的学习"); { //for (int i = 0; i < 5; i++) //{ // List<Program> programList = DBHelper.Query<Program>(); //} } { for (int i = 0; i < 5; i++) { //List<Program> programList = RemoteHelper.Query<Program>(); List<Program> programList = null; if (CacheManager.Contains("RemoteHelper")) { programList = CacheManager.GetData<List<Program>>("RemoteHelper"); } else { programList = RemoteHelper.Query<Program>(); CacheManager.Add("RemoteHelper", programList); } } } //{ // List<Program> programList = DBHelper.Query<Program>(); //} } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.Read(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Common { public class CacheManager { #region Identity private CacheManager() { } private static ICache cache = null; static CacheManager() { //可以创建不同的cache对象 //cache = (ICache)Activator.CreateInstance(typeof(MemoryCacheCache));// 这里可以根据配置文件来选择 cache = (ICache)Activator.CreateInstance(typeof(CustomerCache)); } #endregion Identity #region ICache /// <summary> /// 当前缓存数据项的个数 /// </summary> public static int Count { get { return cache.Count; } } /// <summary> /// 如果缓存中已存在数据项键值,则返回true /// </summary> /// <param name="key">数据项键值</param> /// <returns>数据项是否存在</returns> public static bool Contains(string key) { return cache.Contains(key); } /// <summary> /// 获取缓存数据 /// </summary> /// <param name="key"></param> /// <returns></returns> public static T GetData<T>(string key) { return cache.Get<T>(key); } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="key">缓存的项</param> /// <param name="acquire">没有缓存的时候获取数据的方式</param> /// <param name="cacheTime">单位分钟 默认30</param> /// <returns></returns> public static T Get<T>(string key, Func<T> acquire, int cacheTime = 30) { if (cache.Contains(key)) { return GetData<T>(key); } else { T result = acquire.Invoke();//执行委托 获取委托结果 作为缓存值 cache.Add(key, result, cacheTime); return result; } } /// <summary> /// 添加缓存数据。 /// 如果另一个相同键值的数据已经存在,原数据项将被删除,新数据项被添加。 /// </summary> /// <param name="key">缓存数据的键值</param> /// <param name="value">缓存的数据,可以为null值</param> /// <param name="expiratTime">缓存过期时间间隔(单位:分钟)</param> public static void Add(string key, object value, int expiratTime = 30) { if (Contains(key)) cache.Remove(key); cache.Add(key, value, expiratTime); } /// <summary> /// 删除缓存数据项 /// </summary> /// <param name="key"></param> public static void Remove(string key) { cache.Remove(key); } /// <summary> /// 删除所有缓存数据项 /// </summary> public static void RemoveAll() { cache.RemoveAll(); } #endregion } }
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Common { /// <summary> /// 自定义实现的缓存 /// /// 非线程安全 /// 过期清除 /// </summary> public class CustomerCache : ICache { /// <summary> /// 过期问题 /// </summary> private static Dictionary<string, KeyValuePair<object, DateTime>> _Dictionary = new Dictionary<string, KeyValuePair<object, DateTime>>(); static CustomerCache() { new Action(() => { while (true) { Thread.Sleep(100); foreach (var item in _Dictionary.Where(t => t.Value.Value < DateTime.Now)) { _Dictionary.Remove(item.Key); } } }).BeginInvoke(null, null); } public T Get<T>(string key) { if (_Dictionary.ContainsKey(key))//有没有key { KeyValuePair<object, DateTime> keyValue = _Dictionary[key]; if (keyValue.Value > DateTime.Now)//有没有过期 { return (T)keyValue.Key; } else { _Dictionary.Remove(key);//过期清除 return default(T); } } else { return default(T); } } /// <summary> /// KEY-VALUE-Time /// </summary> /// <param name="key"></param> /// <param name="data"></param> /// <param name="cacheTime">分钟</param> public void Add(string key, object data, int cacheTime = 30 ) { KeyValuePair<object, DateTime> keyValue = new KeyValuePair<object, DateTime>(data, DateTime.Now.AddMinutes(30)); _Dictionary[key] = keyValue; } public bool Contains(string key) { if (_Dictionary.ContainsKey(key))//有没有key { KeyValuePair<object, DateTime> keyValue = _Dictionary[key]; if (keyValue.Value > DateTime.Now)//有没有过期 { return true; } else { _Dictionary.Remove(key);//过期清除 return false; } } else return false; } public void Remove(string key) { if (_Dictionary.ContainsKey(key))//有没有key { _Dictionary.Remove(key); } } public void RemoveAll() { _Dictionary = new Dictionary<string, KeyValuePair<object, DateTime>>(); } public object this[string key] { get { return this.Get<object>(key); } set { this.Add(key, value); } } public int Count { get { return _Dictionary.Values.Count(t => t.Value > DateTime.Now); } } } }
namespace Common { /// <summary> /// Cache manager interface /// </summary> public interface ICache { /// <summary> /// Gets or sets the value associated with the specified key. /// </summary> /// <typeparam name="T">Type</typeparam> /// <param name="key">The key of the value to get.</param> /// <returns>The value associated with the specified key.</returns> T Get<T>(string key); /// <summary> /// Adds the specified key and object to the cache. /// </summary> /// <param name="key">key</param> /// <param name="data">Data</param> /// <param name="cacheTime">Cache time</param> void Add(string key, object data, int cacheTime = 30); /// <summary> /// Gets a value indicating whether the value associated with the specified key is cached /// </summary> /// <param name="key">key</param> /// <returns>Result</returns> bool Contains(string key); /// <summary> /// Removes the value with the specified key from the cache /// </summary> /// <param name="key">/key</param> void Remove(string key); /// <summary> /// Clear all cache data /// </summary> void RemoveAll(); object this[string key] { get; set; } int Count { get; } } }
using System; using System.Collections.Generic; using System.Runtime.Caching; using System.Text.RegularExpressions; namespace Common { /// <summary> /// Represents a MemoryCacheCache /// </summary> public partial class MemoryCacheCache : ICache { public MemoryCacheCache() { } protected ObjectCache Cache { get { return MemoryCache.Default; } } /// <summary> /// Gets or sets the value associated with the specified key. /// </summary> /// <typeparam name="T">Type</typeparam> /// <param name="key">The key of the value to get.</param> /// <returns>The value associated with the specified key.</returns> public T Get<T>(string key) { if (Cache.Contains(key)) { return (T)Cache[key]; } else { return default(T); } } public object Get(string key) { //int iResult= Get<Int16>("123"); return Cache[key]; } /// <summary> /// Adds the specified key and object to the cache. /// </summary> /// <param name="key">key</param> /// <param name="data">Data</param> /// <param name="cacheTime">Cache time(unit:minute)</param> public void Add(string key, object data, int cacheTime = 30) { if (data == null) return; var policy = new CacheItemPolicy(); policy.AbsoluteExpiration = DateTime.Now + TimeSpan.FromMinutes(cacheTime); Cache.Add(new CacheItem(key, data), policy); } /// <summary> /// Gets a value indicating whether the value associated with the specified key is cached /// </summary> /// <param name="key">key</param> /// <returns>Result</returns> public bool Contains(string key) { return Cache.Contains(key); } public int Count { get { return (int)(Cache.GetCount()); } } /// <summary> /// Removes the value with the specified key from the cache /// </summary> /// <param name="key">/key</param> public void Remove(string key) { Cache.Remove(key); } /// <summary> /// Removes items by pattern /// </summary> /// <param name="pattern">pattern</param> public void RemoveByPattern(string pattern) { var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); var keysToRemove = new List<String>(); foreach (var item in Cache) if (regex.IsMatch(item.Key)) keysToRemove.Add(item.Key); foreach (string key in keysToRemove) { Remove(key); } } /// <summary> /// 根据键值返回缓存数据 /// </summary> /// <param name="key"></param> /// <returns></returns> public object this[string key] { get { return Cache.Get(key); } set { Add(key, value); } } /// <summary> /// Clear all cache data /// </summary> public void RemoveAll() { foreach (var item in Cache) Remove(item.Key); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Ruanmou.BLL { /// <summary> /// 数据库查询 /// </summary> public class DBHelper { public static List<T> Query<T>() { Console.WriteLine("This is {0} Query", typeof(DBHelper)); long lResult = 0; for (int i = 0; i < 1000000000; i++) { lResult += i; } return new List<T>() { default(T),default(T),default(T),default(T) }; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Ruanmou.BLL { /// <summary> /// 读硬盘文件 /// </summary> public class FileHelper { public static List<T> Query<T>() { Console.WriteLine("This is {0} Query", typeof(FileHelper)); long lResult = 0; for (int i = 0; i < 10000000000; i++) { lResult += i; } return new List<T>() { default(T),default(T),default(T),default(T) }; } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Ruanmou.BLL { /// <summary> /// 远程接口 /// </summary> public class RemoteHelper { public static List<T> Query<T>() { Console.WriteLine("This is {0} Query", typeof(RemoteHelper)); long lResult = 0; for (int i = 0; i < 1000000000; i++) { lResult += i; } return new List<T>() { default(T),default(T),default(T),default(T) }; } } }