Zoe

读写分离

缓存:

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)
            };
        }

    }
}

 

posted on 2018-03-27 14:27  口袋里的SKY  阅读(313)  评论(0编辑  收藏  举报