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 修改部分配置。

 1 #!/bin/sh
 2 # chkconfig:    2345 90 10
 3 # Simple Redis init.d script conceived to work on Linux systems
 4 # as it does use of the /proc filesystem.
 5
 6 REDISPORT=6379
 7 EXEC=/usr/local/bin/redis-server
 8 CLIEXEC=/usr/local/bin/redis-cli
 9
10 PIDFILE=/var/run/redis_${REDISPORT}.pid
11 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 接口
 1 using System;
 2
 3 namespace Wlitsoft.Framework.Common.Core
 4 {
 5     /// <summary>
 6     /// 分布式缓存接口。
 7     /// </summary>
 8     public interface IDistributedCache
 9     {
10         /// <summary>
11         /// 获取缓存。
12         /// </summary>
13         /// <typeparam name="T">缓存类型。</typeparam>
14         /// <param name="key">缓存键值。</param>
15         /// <returns>获取到的缓存。</returns>
16         T Get<T>(string key);
17
18         /// <summary>
19         /// 设置缓存。
20         /// </summary>
21         /// <typeparam name="T">缓存类型。</typeparam>
22         /// <param name="key">缓存键值。</param>
23         /// <param name="value">要缓存的对象。</param>
24         void Set<T>(string key, T value);
25
26         /// <summary>
27         /// 设置缓存。
28         /// </summary>
29         /// <typeparam name="T">缓存类型。</typeparam>
30         /// <param name="key">缓存键值。</param>
31         /// <param name="value">要缓存的对象。</param>
32         /// <param name="expiredTime">过期时间。</param>
33         void Set<T>(string key, T value, TimeSpan expiredTime);
34
35         /// <summary>
36         /// 判断指定键值的缓存是否存在。
37         /// </summary>
38         /// <param name="key">缓存键值。</param>
39         /// <returns>一个布尔值,表示缓存是否存在。</returns>
40         bool Exists(string key);
41
42         /// <summary>
43         /// 移除指定键值的缓存。
44         /// </summary>
45         /// <param name="key">缓存键值。</param>
46         bool Remove(string key);
47
48         /// <summary>
49         /// 获取 Hash 表中的缓存。
50         /// </summary>
51         /// <typeparam name="T">缓存类型。</typeparam>
52         /// <param name="key">缓存键值。</param>
53         /// <param name="hashField">要获取的 hash 字段。</param>
54         /// <returns>获取到的缓存。</returns>
55         T GetHash<T>(string key, string hashField);
56
57         /// <summary>
58         /// 设置 缓存到 Hash 表。
59         /// </summary>
60         /// <typeparam name="T">缓存类型。</typeparam>
61         /// <param name="key">缓存键值。</param>
62         /// <param name="hashField">要设置的 hash 字段。</param>
63         /// <param name="hashValue">要设置的 hash 值。</param>
64         void SetHash<T>(string key, string hashField, T hashValue);
65
66         /// <summary>
67         /// 判断指定键值的 Hash 缓存是否存在。
68         /// </summary>
69         /// <param name="key">缓存键值。</param>
70         /// <param name="hashField">hash 字段。</param>
71         /// <returns>一个布尔值,表示缓存是否存在。</returns>
72         bool ExistsHash(string key, string hashField);
73
74         /// <summary>
75         /// 删除 hash 表中的指定字段的缓存。
76         /// </summary>
77         /// <param name="key">缓存键值。</param>
78         /// <param name="hashField">hash 字段。</param>
79         /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
80         bool DeleteHash(string key, string hashField);
81     }
82 }

- App 类

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

- AppBuilder 类

 1 namespace Wlitsoft.Framework.Common
 2 {
 3     /// <summary>
 4     /// 应用 构造。
 5     /// </summary>
 6     public class AppBuilder
 7     {
 8         #region 添加序列化者
 9
10         /// <summary>
11         /// 添加序列化者。
12         /// </summary>
13         /// <param name="type">序列化类型。</param>
14         /// <param name="serializer">序列化者接口。</param>
15         public void AddSerializer(SerializeType type, ISerializer serializer)
16         {
17             #region 参数校验
18
19             if (serializer == null)
20                 throw new ObjectNullException(nameof(serializer));
21
22             #endregion
23
24             App.SerializerService.SetSerializer(type, serializer);
25         }
26
27         #endregion
28
29         #region 添加日志记录者
30
31         /// <summary>
32         /// 添加日志记录者。
33         /// </summary>
34         /// <param name="name">日志记录者名称。</param>
35         /// <param name="logger">日志接口。</param>
36         public void AddLogger(string name, ILog logger)
37         {
38             #region 参数校验
39
40             if (string.IsNullOrEmpty(name))
41                 throw new StringNullOrEmptyException(nameof(name));
42
43             if (logger == null)
44                 throw new ObjectNullException(nameof(logger));
45
46             #endregion
47
48             App.LoggerService.SetLogger(name, logger);
49         }
50
51         #endregion
52
53         #region 设置分布式缓存
54
55         /// <summary>
56         /// 设置分布式缓存。
57         /// </summary>
58         /// <param name="cache">分布式缓存实例。</param>
59         /// <returns></returns>
60         public AppBuilder SetDistributedCache(IDistributedCache cache)
61         {
62             #region 参数校验
63
64             if (cache == null)
65                 throw new ObjectNullException(nameof(cache));
66
67             #endregion
68
69             App.DistributedCache = cache;
70             return this;
71         }
72
73         #endregion
74     }
75 }

分布式缓存 Redis 实现

- RedisCache 类

  1 using System;
  2 using System.Linq;
  3 using System.Threading;
  4 using StackExchange.Redis;
  5 using Wlitsoft.Framework.Common.Core;
  6 using Wlitsoft.Framework.Common.Extension;
  7 using Wlitsoft.Framework.Common.Exception;
  8
  9 namespace Wlitsoft.Framework.Caching.Redis
 10 {
 11     /// <summary>
 12     /// Redis 缓存。
 13     /// </summary>
 14     public class RedisCache : IDistributedCache
 15     {
 16         #region 私有属性
 17
 18         //redis 连接实例。
 19         private volatile ConnectionMultiplexer _connection;
 20
 21         //redis 缓存数据库实例。
 22         private IDatabase _database;
 23
 24         //连接实例锁。
 25         private readonly SemaphoreSlim _connectionLock = new SemaphoreSlim(1, 1);
 26
 27         //Redis 配置。
 28         internal static RedisCacheConfiguration RedisCacheConfiguration;
 29
 30         #endregion
 31
 32         #region IDistributedCache 成员
 33
 34         /// <summary>
 35         /// 获取缓存。
 36         /// </summary>
 37         /// <typeparam name="T">缓存类型。</typeparam>
 38         /// <param name="key">缓存键值。</param>
 39         /// <returns>获取到的缓存。</returns>
 40         public T Get<T>(string key)
 41         {
 42             #region 参数校验
 43
 44             if (string.IsNullOrEmpty(key))
 45                 throw new StringNullOrEmptyException(nameof(key));
 46
 47             #endregion
 48
 49             this.Connect();
 50             string result = this._database.StringGet(key);
 51             if (string.IsNullOrEmpty(result))
 52                 return default(T);
 53             return result.ToJsonObject<T>();
 54         }
 55
 56         /// <summary>
 57         /// 设置缓存。
 58         /// </summary>
 59         /// <typeparam name="T">缓存类型。</typeparam>
 60         /// <param name="key">缓存键值。</param>
 61         /// <param name="value">要缓存的对象。</param>
 62         public void Set<T>(string key, T value)
 63         {
 64             #region 参数校验
 65
 66             if (string.IsNullOrEmpty(key))
 67                 throw new StringNullOrEmptyException(nameof(key));
 68
 69             if (value == null)
 70                 throw new ObjectNullException(nameof(value));
 71
 72             #endregion
 73
 74             this.Connect();
 75             this._database.StringSet(key, value.ToJsonString());
 76         }
 77
 78         /// <summary>
 79         /// 设置缓存。
 80         /// </summary>
 81         /// <typeparam name="T">缓存类型。</typeparam>
 82         /// <param name="key">缓存键值。</param>
 83         /// <param name="value">要缓存的对象。</param>
 84         /// <param name="expiredTime">过期时间。</param>
 85         public void Set<T>(string key, T value, TimeSpan expiredTime)
 86         {
 87             #region 参数校验
 88
 89             if (string.IsNullOrEmpty(key))
 90                 throw new StringNullOrEmptyException(nameof(key));
 91
 92             if (value == null)
 93                 throw new ObjectNullException(nameof(value));
 94
 95             #endregion
 96
 97             this.Connect();
 98             this._database.StringSet(key, value.ToJsonString(), expiredTime);
 99         }
100
101         /// <summary>
102         /// 判断指定键值的缓存是否存在。
103         /// </summary>
104         /// <param name="key">缓存键值。</param>
105         /// <returns>一个布尔值,表示缓存是否存在。</returns>
106         public bool Exists(string key)
107         {
108             #region 参数校验
109
110             if (string.IsNullOrEmpty(key))
111                 throw new StringNullOrEmptyException(nameof(key));
112
113             #endregion
114
115             this.Connect();
116             return this._database.KeyExists(key);
117         }
118
119         /// <summary>
120         /// 移除指定键值的缓存。
121         /// </summary>
122         /// <param name="key">缓存键值。</param>
123         public bool Remove(string key)
124         {
125             #region 参数校验
126
127             if (string.IsNullOrEmpty(key))
128                 throw new StringNullOrEmptyException(nameof(key));
129
130             #endregion
131
132             this.Connect();
133             return this._database.KeyDelete(key);
134         }
135
136         /// <summary>
137         /// 获取 Hash 表中的缓存。
138         /// </summary>
139         /// <typeparam name="T">缓存类型。</typeparam>
140         /// <param name="key">缓存键值。</param>
141         /// <param name="hashField">要获取的 hash 字段。</param>
142         /// <returns>获取到的缓存。</returns>
143         public T GetHash<T>(string key, string hashField)
144         {
145             #region 参数校验
146
147             if (string.IsNullOrEmpty(key))
148                 throw new StringNullOrEmptyException(nameof(key));
149
150             if (string.IsNullOrEmpty(hashField))
151                 throw new StringNullOrEmptyException(nameof(hashField));
152
153             #endregion
154
155             this.Connect();
156             string value = this._database.HashGet(key, hashField);
157             if (string.IsNullOrEmpty(value))
158                 return default(T);
159             return value.ToJsonObject<T>();
160         }
161
162         /// <summary>
163         /// 设置 缓存到 Hash 表。
164         /// </summary>
165         /// <typeparam name="T">缓存类型。</typeparam>
166         /// <param name="key">缓存键值。</param>
167         /// <param name="hashField">要设置的 hash 字段。</param>
168         /// <param name="hashValue">要设置的 hash 值。</param>
169         public void SetHash<T>(string key, string hashField, T hashValue)
170         {
171             #region 参数校验
172
173             if (string.IsNullOrEmpty(key))
174                 throw new StringNullOrEmptyException(nameof(key));
175
176             if (string.IsNullOrEmpty(hashField))
177                 throw new StringNullOrEmptyException(nameof(hashField));
178
179             if (hashValue == null)
180                 throw new ObjectNullException(nameof(hashValue));
181
182             #endregion
183
184             this.Connect();
185             this._database.HashSet(key, hashField, hashValue.ToJsonString());
186         }
187
188         /// <summary>
189         /// 判断指定键值的 Hash 缓存是否存在。
190         /// </summary>
191         /// <param name="key">缓存键值。</param>
192         /// <param name="hashField">hash 字段。</param>
193         /// <returns>一个布尔值,表示缓存是否存在。</returns>
194         public bool ExistsHash(string key, string hashField)
195         {
196             #region 参数校验
197
198             if (string.IsNullOrEmpty(key))
199                 throw new StringNullOrEmptyException(nameof(key));
200
201             if (string.IsNullOrEmpty(hashField))
202                 throw new StringNullOrEmptyException(nameof(hashField));
203
204             #endregion
205
206             this.Connect();
207             return this._database.HashExists(key, hashField);
208         }
209
210         /// <summary>
211         /// 删除 hash 表中的指定字段的缓存。
212         /// </summary>
213         /// <param name="key">缓存键值。</param>
214         /// <param name="hashField">hash 字段。</param>
215         /// <returns>一个布尔值,表示缓存是否删除成功。</returns>
216         public bool DeleteHash(string key, string hashField)
217         {
218             #region 参数校验
219
220             if (string.IsNullOrEmpty(key))
221                 throw new StringNullOrEmptyException(nameof(key));
222
223             if (string.IsNullOrEmpty(hashField))
224                 throw new StringNullOrEmptyException(nameof(hashField));
225
226             #endregion
227
228             this.Connect();
229             return this._database.HashDelete(key, hashField);
230         }
231
232         #endregion
233
234         #region 私有方法
235
236         /// <summary>
237         /// 连接。
238         /// </summary>
239         private void Connect()
240         {
241             if (this._connection != null)
242                 return;
243
244             this._connectionLock.Wait();
245             try
246             {
247                 if (this._connection == null)
248                 {
249                     this._connection = ConnectionMultiplexer.Connect(this.GetConfigurationOptions());
250                     this._database = this._connection.GetDatabase();
251                 }
252             }
253             finally
254             {
255                 this._connectionLock.Release();
256             }
257         }
258
259         private ConfigurationOptions GetConfigurationOptions()
260         {
261             #region 校验
262
263             if (RedisCacheConfiguration == null)
264                 throw new ObjectNullException(nameof(RedisCacheConfiguration));
265
266             if (!RedisCacheConfiguration.HostAndPoints.Any())
267                 throw new Exception("RedisCahce 的 HostAndPoints 不能为空");
268
269             #endregion
270
271             ConfigurationOptions options = new ConfigurationOptions();
272
273             foreach (string item in RedisCacheConfiguration.HostAndPoints)
274                 options.EndPoints.Add(item);
275
276             options.ConnectRetry = RedisCacheConfiguration.ConnectRetry;
277             options.ConnectTimeout = RedisCacheConfiguration.ConnectTimeout;
278
279             return options;
280         }
281
282         #endregion
283
284         #region 析构函数
285
286         /// <summary>
287         /// 析构 <see cref="RedisCache"/> 类型的对象。
288         /// </summary>
289         ~RedisCache()
290         {
291             _connection?.Close();
292         }
293
294         #endregion
295     }
296 }

转载于:https://www.cnblogs.com/wlitsoft/p/6242765.html

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

  1. java 公共组件_【JAVA语言程序设计基础篇】--Swing GUI组件的公共特性

    package chapter12; import java.awt.Color; import java.awt.FlowLayout; import java.awt.Font; import j ...

  2. 【分布式缓存】分布式缓存-缓存技术

    目录 从数据的使用说起 本地缓存 远程缓存 缓存策略 缓存常见问题 总结回顾与作业实践 1. 从数据的使用说起 我们把数据的使用频率和方式分个类 静态数据:一般不变,类似于字典表 准静态数据:变化频率 ...

  3. 电商技术架构演进过程——具体到每一个技术

    我想,不管你是一个开发人员,或者正在走向开发路上的人,都和我一样,都想了解那些电商平台,究竟是如何一步一步从孤舟称为航空母舰的!他们都经历的哪些技术革新.我们正在做的,在哪一个节点上. 以下是我的几个 ...

  4. 大厂都咋用平台、分布式缓存?起码你要懂技术,高级还得懂业务

    所有程序猿都对那缓存并不陌生,好似那风一样的女子只为你独自而舞.只见那回眸一笑百媚生,让你甚是吝惜,惹人怜爱. 但随着项目规模不断增大变强,光是单个缓存就难以招架,优而显得力不从心. 这时伴随着多级缓 ...

  5. java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)...

    一.缓存 当系统的并发量上来了,如果我们频繁地去访问数据库,那么会使数据库的压力不断增大,在高峰时甚至可以出现数据库崩溃的现象.所以一般我们会使用缓存来解决这个数据库并发访问问题,用户访问进来,会先从 ...

  6. 通用社区登陆组件技术分享(开源)下篇:OAuth 源码下载及原理解说

    原文http://www.cnblogs.com/cyq1162/archive/2012/11/07/2756848.html 上节内容: 1:通用社区登陆组件技术分享(开源)上篇:OAuth 授权 ...

  7. 路由到另外一个页面_如何在多个页面中,引入一个公共组件

    应用场景 在前端开发的过程中,时常有这样的一个需求,需要将某个组件,展示在不同的页面中.常见的有,头部菜单栏.底部版权,如下图中的菜单,就需要在不同页面中进行显示. 解决方法 假设有这样一个需求,希望 ...

  8. 第十一篇: 使用ElementUi 卡片封装一个季度选择器公共组件,可直接使用

    本篇主要内容:ElementUi 只提供了时间.日历等选择器,没有提供季度选择器,但在开发中报表的时候用到了季度选择器.需要换切换多种类型(年报.月报.季报), 于是封装一个季度公共组件,大家可按需修 ...

  9. 重磅!GitHub 开源负载均衡组件 GLB Director

    8 日,GitHub 发布了开源负载均衡组件 GitHub Load Balancer Director(GLB) Director,GLB 是 GitHub 针对裸机数据中心的可扩展负载均衡解决方案 ...

  10. .NET 开源免费图表组件库,Winform,WPF 通用

    大家好, 我是等天黑, 今天给大家介绍一个功能完善, 性能强悍的图表组件库 ScottPlot, 当我第一次在 github 上看到这个库, 我看不懂,但我大受震撼, 这么好的项目当然要分享出来了. ...

最新文章

  1. Codeforces Beta Round #95 (Div. 2) 部分解题报告 (dp,组合数,)
  2. POJ 3046 Ant Counting(递推,和号优化)
  3. ArcMap导出属性表为Excel文件
  4. mysql中的get_lock锁机制解析
  5. 如何让apache支持.htaccess 解决Internal Server Error The server …错误
  6. leetcode98. 验证二叉搜索树
  7. 动态代理原理源码分析
  8. ERROR: Could not install packages due to an EnvironmentError: [Errno 13] 权限不够的解决办法
  9. Unity3D之Json序列化
  10. SAS安装时出现的问题:Diagram Control
  11. UI中经常出现的下拉框下拉自动筛选效果的实现
  12. React-pdf:pdf预览插件实践
  13. U盘插入电脑提示未能成功安装设备驱动程序,这个要怎么处理呢
  14. K8s中Secrets
  15. This may be due to a lack of SYSV IPC support
  16. 1.静态方法只能访问静态成员(包括变量和方法不能直接访问实例成员,除非使用对象调用2.实例方法既可以访问静态成员,也可以访问实例成员
  17. proc*c/c++简介
  18. hdu 4607 Park Visit(树上最长链)
  19. iOS 火星坐标相关整理及解决方案汇总
  20. 百度地图离线开发demo(热力图)

热门文章

  1. mysql必要的监控项目--转自土豆大神的博客
  2. Linux 高性能服务器编程——多进程编程
  3. 题目1544:数字序列区间最小值
  4. NET开发资源站点和部分优秀.NET开源项目
  5. Linux 内存管理之 SLUB分配器(2) :kmalloc_cache 结构
  6. linux上禅道源码安装步骤
  7. Linux_I2C读写流程
  8. c语言log_C语言最大难点揭秘~!
  9. python中lock锁和阻塞_Python的锁源码剖析
  10. 思科网院Packet Tracer实验(二)IOS基本配置