StackExchange.Redis Client
StackExchange.Redis Client
这期我们来看StackExchange.Redis,这是redis 的.net客户端之一。Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务。目前有不少人在使用ServiceStack.Redis这个.net客户端,但是这个的最新版本目前已经变成了商业软件。对于ServiceStack.Redis这种行为,我们没有什么好说的,留给我们的选择是使用低版本的开源版本或者转向其他的客户端。
要说到StackExchange.Redis,就不得不说它和BookSleeve的关系。BookSleeve已经是比较完善的redis sdk,但是为什么 BookSleeve 的作者要重新写一个redis 的客户端sdk呢? 有兴趣的同学可以看这里why i wrote another redis client 归纳起来其实就一句话:觉得不爽就推倒重来。
(╯◕◞౪◟◕‵)╯︵ ┴─┴ (╯-_-)╯╧╧ (╯‵□′)╯︵┴─┴ (╯' - ')╯︵ ┻━┻ ┬─┬ ノ
StackExchange.Redis 安装
直接命令或者手动NuGet。
PM> Install-Package StackExchange.Redis
如果需要强签名的版本走下面的命令,当然作者对于强签名的事也是充满了怨念
PM> Install-Package StackExchange.Redis.StrongName
ConnectionMultiplexer
ConnectionMultiplexer对象是StackExchange.Redis最中枢的对象。这个类的实例需要被整个应用程序域共享和重用的,你不要在每个操作中不停的创建该对象的实例,所以使用单例来创建和存放这个对象是必须的。
public static ConnectionMultiplexer Manager
{
get
{
if (_redis == null)
{
lock (_locker)
{
if (_redis != null) return _redis;
_redis = GetManager();
return _redis;
}
}
return _redis;
}
}
private static ConnectionMultiplexer GetManager(string connectionString = null)
{
if (string.IsNullOrEmpty(connectionString))
{
connectionString = GetDefaultConnectionString();
}
return ConnectionMultiplexer.Connect(connectionString);
}
虽然ConnectionMultiplexer是实现了IDisposable接口的,但是我们基于重用的考虑,一般不需要去释放它。
当作内存数据库使用
IDatabase db = redis.GetDatabase();
这里的GetDatabase() 返回的db对象是很轻量级别的,不需要被缓存起来,每次用每次拿即可。IDatabase 的所有方法都有同步和异步的实现。其中的异步实现都是可以await的。
一些基础的操作的封装。
public bool Remove(string key)
{
key = MergeKey(key);
var db = RedisManager.Manager.GetDatabase(Database);
return db.KeyDelete(key);
}
public string Get(string key)
{
key = this.MergeKey(key);
var db = RedisManager.Manager.GetDatabase(Database);
return db.StringGet(key);
}
public bool Set(string key, string value, int expireMinutes = 0)
{
key = MergeKey(key);
var db = RedisManager.Manager.GetDatabase(Database);
if (expireMinutes > 0)
{
db.StringSet(key, value, TimeSpan.FromMinutes(expireMinutes));
}
else
{
db.StringSet(key, value);
}
return db.StringSet(key, value);
}
public bool HasKey(string key)
{
key = MergeKey(key);
var db = RedisManager.Manager.GetDatabase(Database);
return db.KeyExists(key);
}
这里的MergeKey用来拼接Key的前缀,具体不同的业务模块使用不同的前缀。
这里有个和ServiceStack.Redis大的区别是没有默认的连接池管理了。没有连接池自然有其利弊,最大的好处在于等待获取连接的等待时间没有了,也不会因为连接池里面的连接由于没有正确释放等原因导致无限等待而处于死锁状态。缺点在于一些低质量的代码可能导致服务器资源耗尽。不过提供连接池等阻塞和等待的手段是和作者的设计理念相违背的。StackExchange.Redis这里使用管道和多路复用的技术来实现减少连接,这里后续展开再讨论。
当作消息代理中间件使用
消息组建中,重要的概念便是生产者,消费者,消息中间件。
ISubscriber sub = redis.GetSubscriber();
首先,先拿到一个ISubscriber对象。在生产者端我们发布一条消息:
sub.Publish("messages", "hello");
,在消费者端得到该消息并输出
sub.Subscribe("messages", (channel, message) => {
Console.WriteLine((string)message);
});
一般使用更专业的消息队列来处理这种业务场景,因此这里就略过了。
三种命令模式
Sync vs Async vs Fire-and-Forget
最后,这里有三种命令模式分别对应StackExchange.Redis的三类不同的使用场景。
Sync,同步模式会直接阻塞调用者,但是显然不会阻塞其他线程。
Async,异步模式直接走的是Task模型。
Fire-and-Forget,就是发送命令,然后完全不关心最终什么时候完成命令操作。
db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget);
这里值得注意的是,在Fire-and-Forget模式下,所有命令都会立即得到返回值,当然该值都是该返回值类型的默认值,比如操作返回类型是bool将会立即得到false,因为false = default(bool)。
StackExchange.Redis Client的更多相关文章
- Redis 详解 (一) StackExchange.Redis Client
这期我们来看StackExchange.Redis,这是redis 的.net客户端之一.Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务.目前有不少人在使用ServiceS ...
- [开源精品] .NET Redis Client 又多了一个选择,还在被 StackExchange.Redis Timeout 问题困扰吗?
前言 .NET 下 RedisClient SDK 选择挺多,国人常用免费的有 StackExchange.Redis/CSRedis/Newlife.Redis,收费的有 ServiceStack. ...
- RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...
- StackExchange.Redis 使用-配置
Configurationredis有很多不同的方法来配置连接字符串 , StackExchange.Redis 提供了一个丰富的配置模型,当调用Connect 或者 ConnectAsync 时需要 ...
- StackExchange.Redis的使用
StackExchange.Redis介绍 有需要了解的和基础的使用可以参考:http://www.cnblogs.com/bnbqian/p/4962855.html StackExchange.R ...
- StackExchange.Redis 使用-配置 (四)
Configurationredis有很多不同的方法来配置连接字符串 , StackExchange.Redis 提供了一个丰富的配置模型,当调用Connect 或者 ConnectAsync 时需要 ...
- StackExchange.Redis 官方文档(四) KeysScan
KEYS, SCAN, FLUSHDB 方法在哪? 经常有人问这些问题: 好像并没有看到 Keys(...) 或者 Scan(...)方法?那我要怎么查询数据库里面存有哪些key? 或者 好像没有Fl ...
- StackExchange.Redis 官方文档(二) Configuration
配置 有多种方式可以配置redis,StackExchange.Redis提供了一个丰富的配置模型,在执行Connect (or ConnectAsync) 时被调用: var conn = Conn ...
- c# redis 操作类库推荐:StackExchange.Redis.Extensions
StackExchange是一个优秀的c# redis客户端,但是存在操作略为繁琐的弊端,为了简化操作,使用 StackExchange.Redis.Extensions成为了一个非常值得推荐的选择. ...
随机推荐
- urses.ascii.ispunct(ch):
Nullege: A Search Engine for Python source code urses.ascii.ispunct(ch): TypeError: 'unicode' object ...
- Knockout应用开发指南 第七章:Mapping插件
原文:Knockout应用开发指南 第七章:Mapping插件 Mapping插件 Knockout设计成允许你使用任何JavaScript对象作为view model.必须view model的一些 ...
- Allegro绘制PCB流程
单位换算 1mil = 0.0254 mm 1mm = 39.3701 mil 默认情况下我们更倾向于使用mil单位绘制PCB板. 1 新建工程,File --> New... --> [ ...
- [Django]models定义choices 字典中的页面显示值
问题: 在django的models.py 在.我们定义一些choices元组,类别似一些字典值.通常下拉框或单个复选框,例如 0相应的M 1妇女和其他有关 class Area(models.Mod ...
- 讨论asp.net通过机器cookie仿百度(google)实现搜索input搜索提示弹出框自己主动
为实现自己主动弹出通过用户输入关键词相关的搜索结果,在这里,我举两个解决方案,对于两个不同的方案. 常用的方法是建立一个用户数据库中查找关系表.然后输入用户搜索框keyword异步调用数据表中的相关数 ...
- 从lca到树链剖分 bestcoder round#45 1003
bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...
- HTTP请求响应过程 与HTTPS区别
原文:HTTP请求响应过程 与HTTPS区别 HTTP协议学习笔记,基础,干货 HTTP协议 HTTP协议主要应用是在服务器和客户端之间,客户端接受超文本. 服务器按照一定规则,发送到客户端(一般是浏 ...
- android LinearLayout等view如何获取button效果
我们可以给LinearLayout以及一切继承自View的控件,设置View.onClickListener监听,例如LInearLayout. 但是我们发现LinearLayout可以执行监听方法体 ...
- HDU-3502-Huson's Adventure Island(BFS+如压力DP)
Problem Description A few days ago, Tom was tired of all the PC-games, so he went back to some old F ...
- LightOj 1148 Basic Math
1148 - Mad Counting PDF (English) Statistics Forum Time Limit: 0.5 second(s) Memory Limit: 32 MB Mob ...