Redis 安装 & 配置

本测试环境将在 CentOS 7 x64 上安装最新版本的 Redis。

1. 运行以下命令安装 Redis

$ wget http://download.redis.io/releases/redis-3.2.6.tar.gz
$ tar xzf redis-3.2.6.tar.gz
$ cd redis-3.2.6
$ make install

如果 CentOS 上提示 wget 命令未找到,则先安装 net-tools。

yum install net-tools

2. Redis 配置文件

1)开启守护程序

修改 daemonize 节点为 yes。

2)运行外部IP访问

配置 bind 节点为 0.0.0.0

本次示例只使用 Redis 的缓存 所以配置暂时只修改这两处即可。

3. 设置 Redis 开机自动启动

1)在 Redis 的源码包中找到 utils 目录

2) 将 redis_init_script 文件复制到 /etc/init.d 目录下并重命名为 redisd

cp redis_init_script /etc/init.d/redisd

3) 打开 redisd 修改部分配置。

 #!/bin/sh
 # chkconfig:    2345 90 10
 # Simple Redis init.d script conceived to work on Linux systems
 # as it does use of the /proc filesystem.

 REDISPORT=6379
 EXEC=/usr/local/bin/redis-server
 CLIEXEC=/usr/local/bin/redis-cli

 PIDFILE=/var/run/redis_${REDISPORT}.pid
 CONF="/etc/redis/redis_${REDISPORT}.conf"

其中第二行 # chkconfig: 2345 90 10 需要另行添加。

- REDISPORT Redis 运行端口号;

- EXEC Redis 服务器命令文件路径(根据实际情况修改);

- CLIEXEC Redis 客户端命令文件路径(亦根据实际情况修改);

- CONF Redis 配置文件。

4)设置开机启动 & 启动、停止服务

#设置为开机自启动服务器
chkconfig redisd on
#打开服务
service redisd start
#关闭服务
service redisd stop

主:如果外部机器还访问不到 Redis 服务器,请将 6379 端口号加防火墙例外即可。

代码实现:

Common 包 接口定义 & 分布式缓存实例获取和配置

- IDistributedCache 接口
 using System;

 namespace Wlitsoft.Framework.Common.Core
 {
     /// <summary>
     /// 分布式缓存接口。
     /// </summary>
     public interface IDistributedCache
     {
         /// <summary>
         /// 获取缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <returns>获取到的缓存。</returns>
         T Get<T>(string key);

         /// <summary>
         /// 设置缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="value">要缓存的对象。</param>
         void Set<T>(string key, T value);

         /// <summary>
         /// 设置缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="value">要缓存的对象。</param>
         /// <param name="expiredTime">过期时间。</param>
         void Set<T>(string key, T value, TimeSpan expiredTime);

         /// <summary>
         /// 判断指定键值的缓存是否存在。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <returns>一个布尔值,表示缓存是否存在。</returns>
         bool Exists(string key);

         /// <summary>
         /// 移除指定键值的缓存。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         bool Remove(string key);

         /// <summary>
         /// 获取 Hash 表中的缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">要获取的 hash 字段。</param>
         /// <returns>获取到的缓存。</returns>
         T GetHash<T>(string key, string hashField);

         /// <summary>
         /// 设置 缓存到 Hash 表。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">要设置的 hash 字段。</param>
         /// <param name="hashValue">要设置的 hash 值。</param>
         void SetHash<T>(string key, string hashField, T hashValue);

         /// <summary>
         /// 判断指定键值的 Hash 缓存是否存在。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">hash 字段。</param>
         /// <returns>一个布尔值,表示缓存是否存在。</returns>
         bool ExistsHash(string key, string hashField);

         /// <summary>
         /// 删除 hash 表中的指定字段的缓存。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">hash 字段。</param>
         /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
         bool DeleteHash(string key, string hashField);
     }
 }

- App 类

 /// <summary>
 /// 获取分布式缓存。
 /// </summary>
 public static IDistributedCache DistributedCache { get; internal set; }

- AppBuilder 类

 namespace Wlitsoft.Framework.Common
 {
     /// <summary>
     /// 应用 构造。
     /// </summary>
     public class AppBuilder
     {
         #region 添加序列化者

         /// <summary>
         /// 添加序列化者。
         /// </summary>
         /// <param name="type">序列化类型。</param>
         /// <param name="serializer">序列化者接口。</param>
         public void AddSerializer(SerializeType type, ISerializer serializer)
         {
             #region 参数校验

             if (serializer == null)
                 throw new ObjectNullException(nameof(serializer));

             #endregion

             App.SerializerService.SetSerializer(type, serializer);
         }

         #endregion

         #region 添加日志记录者

         /// <summary>
         /// 添加日志记录者。
         /// </summary>
         /// <param name="name">日志记录者名称。</param>
         /// <param name="logger">日志接口。</param>
         public void AddLogger(string name, ILog logger)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(name))
                 throw new StringNullOrEmptyException(nameof(name));

             if (logger == null)
                 throw new ObjectNullException(nameof(logger));

             #endregion

             App.LoggerService.SetLogger(name, logger);
         }

         #endregion

         #region 设置分布式缓存

         /// <summary>
         /// 设置分布式缓存。
         /// </summary>
         /// <param name="cache">分布式缓存实例。</param>
         /// <returns></returns>
         public AppBuilder SetDistributedCache(IDistributedCache cache)
         {
             #region 参数校验

             if (cache == null)
                 throw new ObjectNullException(nameof(cache));

             #endregion

             App.DistributedCache = cache;
             return this;
         }

         #endregion
     }
 }

分布式缓存 Redis 实现

- RedisCache 类

 using System;
 using System.Linq;
 using System.Threading;
 using StackExchange.Redis;
 using Wlitsoft.Framework.Common.Core;
 using Wlitsoft.Framework.Common.Extension;
 using Wlitsoft.Framework.Common.Exception;

 namespace Wlitsoft.Framework.Caching.Redis
 {
     /// <summary>
     /// Redis 缓存。
     /// </summary>
     public class RedisCache : IDistributedCache
     {
         #region 私有属性

         //redis 连接实例。
         private volatile ConnectionMultiplexer _connection;

         //redis 缓存数据库实例。
         private IDatabase _database;

         //连接实例锁。
         , );

         //Redis 配置。
         internal static RedisCacheConfiguration RedisCacheConfiguration;

         #endregion

         #region IDistributedCache 成员

         /// <summary>
         /// 获取缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <returns>获取到的缓存。</returns>
         public T Get<T>(string key)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             #endregion

             this.Connect();
             string result = this._database.StringGet(key);
             if (string.IsNullOrEmpty(result))
                 return default(T);
             return result.ToJsonObject<T>();
         }

         /// <summary>
         /// 设置缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="value">要缓存的对象。</param>
         public void Set<T>(string key, T value)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (value == null)
                 throw new ObjectNullException(nameof(value));

             #endregion

             this.Connect();
             this._database.StringSet(key, value.ToJsonString());
         }

         /// <summary>
         /// 设置缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="value">要缓存的对象。</param>
         /// <param name="expiredTime">过期时间。</param>
         public void Set<T>(string key, T value, TimeSpan expiredTime)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (value == null)
                 throw new ObjectNullException(nameof(value));

             #endregion

             this.Connect();
             this._database.StringSet(key, value.ToJsonString(), expiredTime);
         }

         /// <summary>
         /// 判断指定键值的缓存是否存在。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <returns>一个布尔值,表示缓存是否存在。</returns>
         public bool Exists(string key)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             #endregion

             this.Connect();
             return this._database.KeyExists(key);
         }

         /// <summary>
         /// 移除指定键值的缓存。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         public bool Remove(string key)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             #endregion

             this.Connect();
             return this._database.KeyDelete(key);
         }

         /// <summary>
         /// 获取 Hash 表中的缓存。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">要获取的 hash 字段。</param>
         /// <returns>获取到的缓存。</returns>
         public T GetHash<T>(string key, string hashField)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (string.IsNullOrEmpty(hashField))
                 throw new StringNullOrEmptyException(nameof(hashField));

             #endregion

             this.Connect();
             string value = this._database.HashGet(key, hashField);
             if (string.IsNullOrEmpty(value))
                 return default(T);
             return value.ToJsonObject<T>();
         }

         /// <summary>
         /// 设置 缓存到 Hash 表。
         /// </summary>
         /// <typeparam name="T">缓存类型。</typeparam>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">要设置的 hash 字段。</param>
         /// <param name="hashValue">要设置的 hash 值。</param>
         public void SetHash<T>(string key, string hashField, T hashValue)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (string.IsNullOrEmpty(hashField))
                 throw new StringNullOrEmptyException(nameof(hashField));

             if (hashValue == null)
                 throw new ObjectNullException(nameof(hashValue));

             #endregion

             this.Connect();
             this._database.HashSet(key, hashField, hashValue.ToJsonString());
         }

         /// <summary>
         /// 判断指定键值的 Hash 缓存是否存在。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">hash 字段。</param>
         /// <returns>一个布尔值,表示缓存是否存在。</returns>
         public bool ExistsHash(string key, string hashField)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (string.IsNullOrEmpty(hashField))
                 throw new StringNullOrEmptyException(nameof(hashField));

             #endregion

             this.Connect();
             return this._database.HashExists(key, hashField);
         }

         /// <summary>
         /// 删除 hash 表中的指定字段的缓存。
         /// </summary>
         /// <param name="key">缓存键值。</param>
         /// <param name="hashField">hash 字段。</param>
         /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
         public bool DeleteHash(string key, string hashField)
         {
             #region 参数校验

             if (string.IsNullOrEmpty(key))
                 throw new StringNullOrEmptyException(nameof(key));

             if (string.IsNullOrEmpty(hashField))
                 throw new StringNullOrEmptyException(nameof(hashField));

             #endregion

             this.Connect();
             return this._database.HashDelete(key, hashField);
         }

         #endregion

         #region 私有方法

         /// <summary>
         /// 连接。
         /// </summary>
         private void Connect()
         {
             if (this._connection != null)
                 return;

             this._connectionLock.Wait();
             try
             {
                 if (this._connection == null)
                 {
                     this._connection = ConnectionMultiplexer.Connect(this.GetConfigurationOptions());
                     this._database = this._connection.GetDatabase();
                 }
             }
             finally
             {
                 this._connectionLock.Release();
             }
         }

         private ConfigurationOptions GetConfigurationOptions()
         {
             #region 校验

             if (RedisCacheConfiguration == null)
                 throw new ObjectNullException(nameof(RedisCacheConfiguration));

             if (!RedisCacheConfiguration.HostAndPoints.Any())
                 throw new Exception("RedisCahce 的 HostAndPoints 不能为空");

             #endregion

             ConfigurationOptions options = new ConfigurationOptions();

             foreach (string item in RedisCacheConfiguration.HostAndPoints)
                 options.EndPoints.Add(item);

             options.ConnectRetry = RedisCacheConfiguration.ConnectRetry;
             options.ConnectTimeout = RedisCacheConfiguration.ConnectTimeout;

             return options;
         }

         #endregion

         #region 析构函数

         /// <summary>
         /// 析构 <see cref="RedisCache"/> 类型的对象。
         /// </summary>
         ~RedisCache()
         {
             _connection?.Close();
         }

         #endregion
     }
 }

一个技术汪的开源梦 —— 公共组件缓存之分布式缓存 Redis 实现篇的更多相关文章

  1. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端

    一个技术汪的开源梦 —— 目录 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 POST 了,那下面开 ...

  2. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之序列化

    一个技术汪的开源梦 —— 目录 想必大家在项目中都接触过 JSON 或者 XML 吧,为了将对象在网络上传输或者将其持久化必须将其序列化为一个字符串然后进行后续操作.常见的就是将其序列化成 JSON ...

  3. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之目录结构

    一个技术汪的开源梦 —— 目录 这篇文章是开源公共组件的开篇那就先说说项目的 Github 目录结构和 .Net Core 的项目结构. 1. GitHub 目录结构和相关文件 - src 源码项目目 ...

  4. 一个技术汪的开源梦 —— 基于 .Net Core 的组件 Nuget 包制作 &amp; 发布

    一个技术汪的开源梦 —— 目录 微软的 ASP.Net Core 强化了 Nuget 的使用,所有的 .Net Core 组件均有 Nuget 管理,所以有必要探讨一下 .Net Core 组件制作 ...

  5. 一个技术汪的开源梦 —— 微信开发工具包(WeixinSDK)

    由于春节的关系 WeixinSDK 这个开源项目的进展比预期推迟了大约一个月的时间,值得高兴的是到目前为止该项目的重要模块已经开发完毕.  - 关于项目 该项目的背景是现在微信公众号.微信服务号乃至微 ...

  6. Net Core 的公共组件之 Http 请求客户端

    Net Core 的公共组件之 Http 请求客户端 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 ...

  7. 开源Word读写组件DocX 的深入研究和问题总结

    一. 前言 前两天看到了asxinyu大神的[原创]开源Word读写组件DocX介绍与入门,正好我也有类似的自动生成word文档得需求,于是便仔细的研究了这个DocX. 我也把它融入到我的项目当中并进 ...

  8. Caf.CMS是一个免费的、 开源,功能齐全的CMS

    Caf.CMS(疯狂蚂蚁CMS) 是一个免费的. 开源,功能全面的CMS(内容管理系统).定位CMS也有点狭义呢,因为Caf.CMS是基于国外SmartStore.NET 开源商城源码的基础上改造而成 ...

  9. dnc开源梦之队2018 开源项目精选集

    dnc开源梦之队2018 dnc开源项目选择标准 dnc = .NET Core.dotnet core 1.支持dnc 2.x,Github star数量100以上,最近2月活跃更新 2.轻量级.示 ...

随机推荐

  1. 2016-2017 ACM-ICPC Asia-Bangkok Regional Contest

    A. WSI Extreme 将人按洗澡时间从大到小排序,那么$ans=\sum_{i=1}^{n}a_i\times\lfloor\frac{i+W-1}{W}\rfloor$. 当$W$比较大时, ...

  2. linux php redis 扩展安装

    安装redis服务端 1 进入软件的下载路径 cd /soft wget http://download.redis.io/redis-stable.tar.gz tar -zxvf redis-st ...

  3. SequoiaDB 笔记

    SequoiaDB 笔记 这几天翻了翻SequoiaDB的代码,记了点笔记.不保证下面内容的正确性(肯定有错的地方) 个人观感 优点 代码还不错,设计也算简洁. EDU和CB的使用让整个系统变得简单很 ...

  4. PHP实现简易blog

    最近,有时间看了点PHP的代码.参考PHP100教程做了简单的blog,网易云课堂2012年的教程,需要的可以找一下,这里面简单的记录一下. 首先是集成环境,这里选用的WAMP:http://www. ...

  5. c10k问题及其解决方案

    本文主要讲述高并发http应用中的c10k瓶颈问题:在很多服务器初始状态下,无法服务1w左右的并发连接.这与每次服务的资源消耗.服务器的硬件配置固然有关,但很多时候是被linux的默认配置以及软件st ...

  6. 名词解释:DRAM, SRAM, SDRAM等

    SRAM:静态RAM,不用刷新,速度可以非常快,像CPU内部的cache,都是静态RAM,缺点是一个内存单元需要的晶体管数量多,因而价格昂贵,容量不大. DRAM:动态RAM,需要刷新,容量大. SD ...

  7. ASP.NET26个性能优化方法

    1.数据库访问性能优化 (1)数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要多次与数据库交换信息以通过身份验证,比较耗费服务器资源. ASP.NET中提供了连 ...

  8. 搭建Spring + SpringMVC + Mybatis框架之三(整合Spring、Mybatis和Spring MVC)

    整合Spring和SpringMVC 之前已经整合了spring和mybatis,现在在此基础上整合SSM. 项目目录: 思路:SpringMVC的配置文件独立,然后在web.xml中配置整合. (1 ...

  9. 约瑟夫圆环的C++实现

    转载请注明出处:点我 昨天参加了企鹅的2015年实习生招聘的笔试,编程题第一道题就是约瑟夫圆环问题,要求用C++来实现. 约瑟夫圆环问题其实是一个很有名的问题:问题的描述为: 设有编号为1,2,……, ...

  10. 理解public,protected 以及 private

    经常看到在类中看到public,protected,private以及它们在继承中表示的一些访问范围,很容易搞糊涂.我们首先要明白下面几点. 1.类的一个特征就是封装,public和private作用 ...