C# redis使用之ServiceStack
需要注意的是:ServiceStack.Redis 中GetClient()方法,只能拿到Master redis中获取连接,而拿不到slave 的readonly连接。这样 slave起到了冗余备份的作用,读的功能没有发挥出来,如果并发请求太多的话,则Redis的性能会有影响。
所以,我们需要的写入和读取的时候做一个区分,写入的时候,调用client.GetClient() 来获取writeHosts的Master的redis 链接。读取,则调用client.GetReadOnlyClient()来获取的readonlyHost的 Slave的redis链接。
或者可以直接使用client.GetCacheClient() 来获取一个连接,他会在写的时候调用GetClient获取连接,读的时候调用GetReadOnlyClient获取连接,这样可以做到读写分离,从而利用redis的主从复制功能。
1. 配置文件 app.config
<!-- redis Start -->
<add key="SessionExpireMinutes" value="180" />
<add key="redis_server_master_session" value="127.0.0.1:6379" />
<add key="redis_server_slave_session" value="127.0.0.1:6380" />
<add key="redis_max_read_pool" value="300" />
<add key="redis_max_write_pool" value="100" />
<!--redis end-->
2. Redis操作的公用类RedisCacheHelper
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Web;
using ServiceStack.Common.Extensions;
using ServiceStack.Redis;
using ServiceStack.Logging;
namespace Weiz.Redis.Common
{
public class RedisCacheHelper
{
private static readonly PooledRedisClientManager pool = null;
private static readonly string[] writeHosts = null;
private static readonly string[] readHosts = null;
public static int RedisMaxReadPool = int.Parse(ConfigurationManager.AppSettings["redis_max_read_pool"]);
public static int RedisMaxWritePool = int.Parse(ConfigurationManager.AppSettings["redis_max_write_pool"]);
static RedisCacheHelper()
{
var redisMasterHost = ConfigurationManager.AppSettings["redis_server_master_session"];
var redisSlaveHost = ConfigurationManager.AppSettings["redis_server_slave_session"];
if (!string.IsNullOrEmpty(redisMasterHost))
{
writeHosts = redisMasterHost.Split(',');
readHosts = redisSlaveHost.Split(',');
if (readHosts.Length > 0)
{
pool = new PooledRedisClientManager(writeHosts, readHosts,
new RedisClientManagerConfig()
{
MaxWritePoolSize = RedisMaxWritePool,
MaxReadPoolSize = RedisMaxReadPool,
AutoStart = true
});
}
}
}
public static void Add<T>(string key, T value, DateTime expiry)
{
if (value == null)
{
return;
}
if (expiry <= DateTime.Now)
{
Remove(key);
return;
}
try
{
if (pool != null)
{
using (var r = pool.GetClient())
{
if (r != null)
{
r.SendTimeout = 1000;
r.Set(key, value, expiry - DateTime.Now);
}
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "存储", key);
}
}
public static void Add<T>(string key, T value, TimeSpan slidingExpiration)
{
if (value == null)
{
return;
}
if (slidingExpiration.TotalSeconds <= 0)
{
Remove(key);
return;
}
try
{
if (pool != null)
{
using (var r = pool.GetClient())
{
if (r != null)
{
r.SendTimeout = 1000;
r.Set(key, value, slidingExpiration);
}
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "存储", key);
}
}
public static T Get<T>(string key)
{
if (string.IsNullOrEmpty(key))
{
return default(T);
}
T obj = default(T);
try
{
if (pool != null)
{
using (var r = pool.GetClient())
{
if (r != null)
{
r.SendTimeout = 1000;
obj = r.Get<T>(key);
}
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "获取", key);
}
return obj;
}
public static void Remove(string key)
{
try
{
if (pool != null)
{
using (var r = pool.GetClient())
{
if (r != null)
{
r.SendTimeout = 1000;
r.Remove(key);
}
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "删除", key);
}
}
public static bool Exists(string key)
{
try
{
if (pool != null)
{
using (var r = pool.GetClient())
{
if (r != null)
{
r.SendTimeout = 1000;
return r.ContainsKey(key);
}
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "是否存在", key);
}
return false;
}
public static IDictionary<string, T> GetAll<T>(IEnumerable<string> keys) where T : class
{
if (keys == null)
{
return null;
}
keys = keys.Where(k => !string.IsNullOrWhiteSpace(k));
if (keys.Count() == 1)
{
T obj = Get<T>(keys.Single());
if (obj != null)
{
return new Dictionary<string, T>() { { keys.Single(), obj } };
}
return null;
}
if (!keys.Any())
{
return null;
}
IDictionary<string, T> dict = null;
if (pool != null)
{
keys.Select(s => new
{
Index = Math.Abs(s.GetHashCode()) % readHosts.Length,
KeyName = s
})
.GroupBy(p => p.Index)
.Select(g =>
{
try
{
using (var r = pool.GetClient(g.Key))
{
if (r != null)
{
r.SendTimeout = 1000;
return r.GetAll<T>(g.Select(p => p.KeyName));
}
}
}
catch (Exception ex)
{
string msg = string.Format("{0}:{1}发生异常!{2}", "cache", "获取", keys.Aggregate((a, b) => a + "," + b));
}
return null;
})
.Where(x => x != null)
.ForEach(d =>
{
d.ForEach(x =>
{
if (dict == null || !dict.Keys.Contains(x.Key))
{
if (dict == null)
{
dict = new Dictionary<string, T>();
}
dict.Add(x);
}
});
});
}
IEnumerable<Tuple<string, T>> result = null;
if (dict != null)
{
result = dict.Select(d => new Tuple<string, T>(d.Key, d.Value));
}
else
{
result = keys.Select(key => new Tuple<string, T>(key, Get<T>(key)));
}
return result
.Select(d => new Tuple<string[], T>(d.Item1.Split('_'), d.Item2))
.Where(d => d.Item1.Length >= 2)
.ToDictionary(x => x.Item1[1], x => x.Item2);
}
}
}
C# redis使用之ServiceStack的更多相关文章
- Redis分布式锁(ServiceStack.Redis实现)
1.设计思路 由于Redis是单线程模型,命令操作原子性,所以利用这个特性可以很容易的实现分布式锁.A用户端在Resdis写入1个KEY,其他的用户无法写入这个KEY,实现锁的效果.A用户使用完成后释 ...
- ServiceStack.Redis订阅发布服务的调用(Z)
1.Redis订阅发布介绍Redis订阅发布是一种消息通信模式:发布者(publisher)发送消息,订阅者(Subscriber)接受消息.类似于设计模式中的观察者模式.发布者和订阅者之间使用频 ...
- ServiceStack.Redis订阅发布服务的调用
1.Redis订阅发布介绍 Redis订阅发布是一种消息通信模式:发布者(publisher)发送消息,订阅者(Subscriber)接受消息.类似于设计模式中的观察者模式. 发布者和订阅者之间使用频 ...
- ServiceStack.Redis 使用
Redis官网提供了很多开源的C#客户端.例如,Nhiredis ,ServiceStack.Redis ,StackExchange.Redis等.其中ServiceStack.Redis应该算是比 ...
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
ASP.NET MVC 学习笔记-2.Razor语法 1. 表达式 表达式必须跟在“@”符号之后, 2. 代码块 代码块必须位于“@{}”中,并且每行代码必须以“: ...
- 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用
责任链模式的具体应用 1.业务场景 生产车间中使用的条码扫描,往往一把扫描枪需要扫描不同的条码来处理不同的业务逻辑,比如,扫描投入料工位条码.扫描投入料条码.扫描产出工装条码等,每种类型的条码位数 ...
- 使用ServiceStack构建Web服务
提到构建WebService服务,大家肯定第一个想到的是使用WCF,因为简单快捷嘛.首先要说明的是,本人对WCF不太了解,但是想快速建立一个WebService,于是看到了MSDN上的这一篇文章 Bu ...
- ASP.NET Redis 开发
文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据库系统,特点是高性能,持久存储,适应高 ...
- StackExchange.Redis通用封装类分享(转)
阅读目录 ConnectionMultiplexer 封装 RedisHelper 通用操作类封 String类型的封装 List类型的封装 Hash类型的封装 SortedSet 类型的封装 key ...
随机推荐
- 缓存篇~第七回 Redis实现基于方法签名的数据集缓存(可控更新,分布式数据缓存)
返回目录 本篇文章可以说是第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存(可控更新,WEB端数据缓存)的续篇,事实上,有 ...
- MVVM架构~Knockoutjs系列之js接收C#数据集合的方式
返回目录 在controller里将数据拿到,并且存储到ViewBag对象里,最后在View上显示出来,这是传统的MVC开发方式,事实上引入Knockoutjs以后,这种方式还是适合的,Knockou ...
- C#设计模式-单例模式
单例模式三种写法: 第一种最简单,但没有考虑线程安全,在多线程时可能会出问题…… public class Singleton { private static Singleton _instance ...
- jquery的html,text,val
.html()用为读取和修改元素的HTML标签 .text()用来读取或修改元素的纯文本内容 .val()用来读取或修改表单元素的value值. 这三个方法功能上的对比 .html(),.text() ...
- Java基本特征 - 多态
多态的实现方式: 1. 重载(overload):实现编译时的多态性,前绑定 同一个类中.方法名相同.参数类型或者参数数量不相同 重写(override):运行时的多态性,后绑定.运行时的多态,是面向 ...
- 快速入门系列--MVC--03控制器和IOC应用
Asp.net MVC也接触好久了,但由于自己一直主要负责后台,尤其是数据库方面的工作对于该框架并没有一个很好的了解,尤其是蒋金楠大师的ASP.NET MVC4框架剖析一书都买了2年多了,真正认真看过 ...
- 基于Metronic的Bootstrap开发框架经验总结(7)--数据的导入、导出及附件的查看处理
在很多系统模块里面,我们可能都需要进行一定的数据交换处理,也就是数据的导入或者导出操作,这样的批量处理能给系统用户更好的操作体验,也提高了用户录入数据的效率.我在较早时期的EasyUI的Web框架上, ...
- 可视化工具gephi源码探秘(二)---导入netbeans
在上篇<可视化工具gephi源码探秘(一)>中主要介绍了如何将gephi的源码导入myeclipse中遇到的一些问题,此篇接着上篇而来,主要讲解当下通过myeclipse导入gephi源码 ...
- 配置Hibernate二级缓存时,不能初始化RegionFactory的解决办法
配置Hibernate 二级缓存时,出现以下bug提示: SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&quo ...
- [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3
[java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 // */ // ]]> [java] 注释以及javadoc使用简介-汇率换算器的实现-插曲3 Table of C ...