當(dāng)前位置:首頁(yè) > IT技術(shù) > Windows編程 > 正文

C#redis緩存應(yīng)用
2021-09-16 11:39:29

Redis

  redis是一種非關(guān)系型數(shù)據(jù)庫(kù)(關(guān)系型數(shù)據(jù)庫(kù)即SQL server,MySQL等),但多用于緩存技術(shù).因?yàn)樗且环N內(nèi)存告訴緩存數(shù)據(jù)庫(kù),存儲(chǔ)數(shù)據(jù)的方式為Key-value,即鍵值對(duì).而且redis還支持多種數(shù)據(jù)類型,如:string、list、set、zset(sorted set)、hash。

  redis特點(diǎn):

①redis以內(nèi)存作為存儲(chǔ)的介質(zhì),讀寫速率極高,遠(yuǎn)超過數(shù)據(jù)庫(kù),

②redis跟memcache不同,redis存儲(chǔ)的數(shù)據(jù)是持久化的,不會(huì)因?yàn)閿嚯娭貑⒃斐傻臄?shù)據(jù)丟失.(reids的存儲(chǔ)分為內(nèi)存存儲(chǔ),磁盤存儲(chǔ)和log文件三部分,重啟后,redis從磁盤重新將數(shù)據(jù)加載到內(nèi)存中,再通過配置文件對(duì)其進(jìn)行配置,持久化的原因)

③redis可以配置集群,就像一些大公司的服務(wù)器一樣,它可以建立多個(gè)redis用來(lái)緩存,而且redis不在客戶端,也不再服務(wù)端,是一個(gè)獨(dú)立的部分

  redis兩種文件格式:

①全量數(shù)據(jù):是把內(nèi)存中的數(shù)據(jù)寫入磁盤,便于下次讀取文件進(jìn)行夾雜

②增量請(qǐng)求:是將內(nèi)存中的數(shù)據(jù)序列化為操作請(qǐng)求,用于讀取文件進(jìn)行replay得到數(shù)據(jù),序列化的操作包括SET,RPUSH,SADD,ZADD

1. 要進(jìn)行Master-slave配置,出現(xiàn)服務(wù)故障時(shí)可以支持切換。
2. 在master側(cè)禁用數(shù)據(jù)持久化,只需在slave上配置數(shù)據(jù)持久化。
3. 物理內(nèi)存+虛擬內(nèi)存不足,這個(gè)時(shí)候dump一直死著,時(shí)間久了機(jī)器掛掉。這個(gè)情況就是災(zāi)難!
4. 當(dāng)Redis物理內(nèi)存使用超過內(nèi)存總?cè)萘康?/5時(shí)就會(huì)開始比較危險(xiǎn)了,就開始做swap,內(nèi)存碎片大
5. 當(dāng)達(dá)到最大內(nèi)存時(shí),會(huì)清空帶有過期時(shí)間的key,即使key未到過期時(shí)間.
6. redis與DB同步寫的問題,先寫DB,后寫redis,因?yàn)閷憙?nèi)存基本上沒有問題

Redis的安裝:

  包地址:https://files.cnblogs.com/files/lbjlbj/Redis3.7z

運(yùn)行->cmd->CD C: edis(C: edis CD 進(jìn)入到盤符(記得有空格),上面那個(gè)解壓后把它改名為redis,放到了C盤,也可以放其他盤)

?

?redis-server.exe?redis.windows.conf,等出現(xiàn)如圖的實(shí)例,就證明成功了(這個(gè)控制臺(tái)先不要關(guān))

?

再開一個(gè)控制臺(tái),同樣:CD C: edis?
?redis-cli.exe?-h?127.0.0.1?-p?6379
?set?myKey?abc(myKey即Key,abc即value,set存)
?get?myKey(get讀)

set auth 密碼名,是用來(lái)設(shè)置密碼.(如果忘記了密碼:redis文件夾下redis.windows-service.conf記事本打開CTRL+F requirepass 即可)

?

redis在C#中的實(shí)際用法:

******在使用redis緩存時(shí),須先啟動(dòng)服務(wù)器,CD C: edis redis-server.exe?redis.windows.conf

dll文件:https://files.cnblogs.com/files/lbjlbj/dll.7z

可能會(huì)存在ConfigurationManager會(huì)報(bào)錯(cuò),還需自行搜索添加引用,

?

  奉上一個(gè)封裝好的Helper類

復(fù)制代碼
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace ConsoleApp1
{
    /// <summary>
    /// Redis 操作類
    /// </summary>
    public class RedisHelper
    {
        /// <summary>
        /// 連接字符串
        /// </summary>
        private static readonly string ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
        /// <summary>
        /// 鎖
        /// </summary>
        private readonly object _lock = new object();
        /// <summary>
        /// 連接對(duì)象
        /// </summary>
        private volatile IConnectionMultiplexer _connection;
        /// <summary>
        /// 數(shù)據(jù)庫(kù)
        /// </summary>
        private IDatabase _db;
        public RedisHelper()
        {
            _connection = ConnectionMultiplexer.Connect(ConnectionString);
            _db = GetDatabase();
        }
        /// <summary>
        /// 獲取連接
        /// </summary>
        /// <returns></returns>
        protected IConnectionMultiplexer GetConnection()
        {
            if (_connection != null && _connection.IsConnected)
            {
                return _connection;
            }
            lock (_lock)
            {
                if (_connection != null && _connection.IsConnected)
                {
                    return _connection;
                }

                if (_connection != null)
                {
                    _connection.Dispose();
                }
                _connection = ConnectionMultiplexer.Connect(ConnectionString);
            }

            return _connection;
        }
        /// <summary>
        /// 獲取數(shù)據(jù)庫(kù)
        /// </summary>
        /// <param name="db"></param>
        /// <returns></returns>
        public IDatabase GetDatabase(int? db = null)
        {
            return GetConnection().GetDatabase(db ?? -1);
        }
        /// <summary>
        /// 設(shè)置
        /// </summary>
        /// <param name="key">鍵</param>
        /// <param name="data">值</param>
        /// <param name="cacheTime">時(shí)間</param>
        public virtual void Set(string key, object data, int cacheTime)
        {
            if (data == null)
            {
                return;
            }
            var entryBytes = Serialize(data);
            var expiresIn = TimeSpan.FromMinutes(cacheTime);

            _db.StringSet(key, entryBytes, expiresIn);
        }
        /// <summary>
        /// 根據(jù)鍵獲取值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <returns></returns>
        public virtual T Get<T>(string key)
        {

            var rValue = _db.StringGet(key);
            if (!rValue.HasValue)
            {
                return default(T);
            }

            var result = Deserialize<T>(rValue);

            return result;
        }
        /// <summary>
        /// 反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serializedObject"></param>
        /// <returns></returns>
        protected virtual T Deserialize<T>(byte[] serializedObject)
        {
            if (serializedObject == null)
            {
                return default(T);
            }
            var json = Encoding.UTF8.GetString(serializedObject);
            return JsonConvert.DeserializeObject<T>(json);
        }
        /// <summary>
        /// 判斷是否已經(jīng)設(shè)置
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public virtual bool IsSet(string key)
        {
            return _db.KeyExists(key);
        }
        /// <summary>
        /// 序列化
        /// </summary>
        /// <param name="data"></param>
        /// <returns>byte[]</returns>
        private byte[] Serialize(object data)
        {
            var json = JsonConvert.SerializeObject(data);
            return Encoding.UTF8.GetBytes(json);
        }
    }
}
復(fù)制代碼

AppConfig中配置:

 <connectionStrings>
    <add name="RedisConnectionString" connectionString="localhost"/>
  </connectionStrings>

最后功能實(shí)現(xiàn):

復(fù)制代碼
class Program
    {
        static void Main(string[] args)
        {
            var s = "a";
            //RedisCacheHelper.Add("abc",s,DateTime.Now.AddDays(1));

            //Console.WriteLine("ok");

            //Console.WriteLine(RedisCacheHelper.Get<string>("abc"));
            new RedisHelper().Set("abc", s, 10);
            Console.WriteLine("ok");
            Console.ReadKey();
        }
    }
復(fù)制代碼

?

?

本文摘自 :https://www.cnblogs.com/

開通會(huì)員,享受整站包年服務(wù)立即開通 >