Session的缺点

众所周知Asp.net Session默认存储在IIS中,IIS的重启会导致Session丢失。

如果你的网站使用了session,当网站并发过大时可能引起溢出。

配置Redis 集群


安装Redis

创建一个文件,进入该文件夹

下载Redis 地址:http://download.redis.io/releases/redis-3.0.4.tar.gz

tar -xvf redis-3.0.4.tar.gz 解压文件

cd redis-3.0.4 进入解压的文件

make && make install 安装

创建三个文件夹

把redis.conf文件分别复制到这三个文件夹

然后分别进入这三个文件夹修改配置文件和指定不同的端口

1.daemonize yes  (开启后台运行)

2.port 6379 (端口)

3.pidfile /var/run/redis-6379.pid (Redis 以守护进程的方式运行的时候,Redis 默认会把 pid 文件放在/var/run/redis.pid,你可以配置到其他地址。当运行多个 redis 服务时,需要指定不同的 pid 文件和端口)

4.cluster-enabled yes (是否启用集群)

5.cluster-config-file "nodes-6379.conf" (nodes 节点文件)

安装ruby环境

yum -y install zlib ruby rubygems

gem install redis

开启服务

分别开启这三个实例

查看是否开启

创建集群

首先,进入redis的安装包路径下:

cd /usr/local/src/redis/redis-3.0.1/src/

执行命令:

./redis-trib.rb create --replicas 0 ./redis-trib.rb create --replicas 0 192.168.1.108:6379 192.168.1.108:6380 192.168.1.108:6381

进入redis-cli -p 6379 -c

Cluster nodes 查看集群信息

配置完成

使用 StackExchange.Redis驱动连接到redis


代码是我从Asp.net vnext Caching 程序集中copy下来的

配置类型

 public class RedisCacheOptions
{
/// <summary>
/// 连接配置
/// </summary>
public string Configuration { get; set; }
/// <summary>
/// 实例名字
/// </summary>
public string InstanceName { get; set; } }
  static void Main(string[] args)
{ string key = "myKey";
object state = null;
string value1 = "yyyyyyyyyyyyyy";
byte[] value = Encoding.Default.GetBytes(value1);
Stream valueStream; Console.WriteLine("Connecting to cache");
var cache = new RedisCache(new RedisCacheOptions
{
InstanceName = "sessionId",
Configuration = "192.168.1.108:6379,192.168.1.108:6380,192.168.1.108:6381"
});
Console.WriteLine("Connected"); Console.WriteLine("Setting");
valueStream = cache.Set(key, state, context =>
{
context.Data.Write(value, , value.Length);
});

RedisCache 集体实现

   public class RedisCache : IDistributedCache
{
//Lua 脚本
private const string SetScript = (@"
redis.call('HMSET', KEYS[1], 'absexp', ARGV[1], 'sldexp', ARGV[2], 'data', ARGV[4])
if ARGV[3] ~= '-1' then
redis.call('EXPIRE', KEYS[1], ARGV[3])
end
return 1");
//key
private const string AbsoluteExpirationKey = "absexp";
//key
private const string SlidingExpirationKey = "sldexp";
//key
private const string DataKey = "data";
private const long NotPresent = -;
private ConnectionMultiplexer _connection;
private IDatabase _cache;
private readonly RedisCacheOptions _options;
private readonly string _instance;
/// <summary>
/// 初始化配置
/// </summary>
/// <param name="optionsAccessor"></param>
public RedisCache(RedisCacheOptions optionsAccessor)
{
_options = optionsAccessor;
_instance = optionsAccessor.InstanceName;
}
public void Connect()
{
if (_connection == null)
{
_connection = ConnectionMultiplexer.Connect(_options.Configuration);
_cache = _connection.GetDatabase();
}
} /// <summary>
/// set到Redis中
/// </summary>
/// <param name="key"></param>
/// <param name="state"></param>
/// <param name="create"></param>
/// <returns></returns>
public Stream Set(string key, object state, Action<ICacheContext> create)
{
Connect(); var context = new CacheContext(key) { State = state };
//设置绝对过期时间
//context.SetAbsoluteExpiration(DateTimeOffset.Now.AddMilliseconds(22222));
//设置滑动过期时间
context.SetSlidingExpiration(TimeSpan.FromSeconds());
create(context);
var value = context.GetBytes();
//Lua脚本赋值
var result = _cache.ScriptEvaluate(SetScript, new RedisKey[] { _instance + key },
new RedisValue[]
{
context.AbsoluteExpiration?.Ticks ?? NotPresent,
context.SlidingExpiration?.Ticks ?? NotPresent,
context.GetExpirationInSeconds() ?? NotPresent,
value
});
return new MemoryStream(value, writable: false);
} public bool TryGetValue(string key, out Stream value)
{
value = GetAndRefresh(key, getData: true);
return value != null;
} public void Refresh(string key)
{
var ignored = GetAndRefresh(key, getData: false);
} private Stream GetAndRefresh(string key, bool getData)
{
Connect(); RedisValue[] results;
if (getData)
{
results = _cache.HashMemberGet(_instance + key, AbsoluteExpirationKey, SlidingExpirationKey, DataKey);
}
else
{
results = _cache.HashMemberGet(_instance + key, AbsoluteExpirationKey, SlidingExpirationKey);
} if (results.Length >= )
{
DateTimeOffset? absExpr;
TimeSpan? sldExpr;
MapMetadata(results, out absExpr, out sldExpr);
Refresh(key, absExpr, sldExpr);
}
if (results.Length >= && results[].HasValue)
{
return new MemoryStream(results[], writable: false);
}
return null;
}
private void MapMetadata(RedisValue[] results, out DateTimeOffset? absoluteExpiration, out TimeSpan? slidingExpiration)
{
absoluteExpiration = null;
slidingExpiration = null;
var absoluteExpirationTicks = (long?)results[];
if (absoluteExpirationTicks.HasValue && absoluteExpirationTicks.Value != NotPresent)
{
absoluteExpiration = new DateTimeOffset(absoluteExpirationTicks.Value, TimeSpan.Zero);
}
var slidingExpirationTicks = (long?)results[];
if (slidingExpirationTicks.HasValue && slidingExpirationTicks.Value != NotPresent)
{
slidingExpiration = new TimeSpan(slidingExpirationTicks.Value);
}
} /// <summary>
/// 刷新缓存过期时间
/// </summary>
/// <param name="key"></param>
/// <param name="absExpr"></param>
/// <param name="sldExpr"></param>
private void Refresh(string key, DateTimeOffset? absExpr, TimeSpan? sldExpr)
{
TimeSpan? expr = null;
if (sldExpr.HasValue)
{
if (absExpr.HasValue)
{
var relExpr = absExpr.Value - DateTimeOffset.Now;
expr = relExpr <= sldExpr.Value ? relExpr : sldExpr;
}
else
{
expr = sldExpr;
}
_cache.KeyExpire(_instance + key, expr);
// TODO: Error handling
}
}
/// <summary>
/// 移除指定key
/// </summary>
/// <param name="key"></param>
public void Remove(string key)
{
Connect();
_cache.KeyDelete(_instance + key); }
}

运行结果

源码:http://pan.baidu.com/s/1gdm8F9h

最新文章

  1. 记一次Redis被攻击的事件
  2. centos 编程环境
  3. Raspberry pi之wifi设置-3
  4. 9.27js拓展、bootstrap菜鸟教程
  5. OCJP(1Z0-851) 模拟题分析(三)over
  6. 字节流和字符流(BufferedReader类和BufferedWriter类)
  7. 合并excel-MergeExcel
  8. iOS RSA 加密解密及签名验证
  9. 什么是SPI通信?
  10. 黑马程序员_Java面向对象1_封装
  11. Objective-C——判断对象等同性
  12. C++/C# 最基本的Marshal和Ptr
  13. sqlite3编译
  14. RabbitMQ-从基础到实战(1)— Hello RabbitMQ
  15. linux jpg文件查找木马
  16. DSSM:深度语义匹配模型(及其变体CLSM、LSTM-DSSM)
  17. eclipse中的yaml插件
  18. 译:9.使用Redis进行消息传递
  19. ABP 邮箱设置
  20. JS获取整个网页html代码

热门文章

  1. Janus WinForms Controls
  2. JavaScript实现,判断一个点是否在多边形内
  3. CentOS安装Git
  4. UINavagationController页面跳转
  5. SuSE Apache2 VirtualHost Build
  6. Canopy算法聚类
  7. poj1703 Find them, Catch them 并查集
  8. [原创]java WEB学习笔记84:Hibernate学习之路-- -映射 一对一关系 ,基外键的方式实现
  9. [原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程
  10. Android 优秀UI控件 ---- FlowingDrawer