StackExchange.Redis 使用资料
在StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.redis命名空间中。
这个类隐藏了Redis服务的操作细节,ConnectionMultiplexer类做了很多东西, 在所有调用之间它被设计为共享和重用的。
不应该为每一个操作都创建一个ConnectionMultiplexer 。 ConnectionMultiplexer是线程安全的 , 推荐使用下面的方法。
在所有后续示例中 , 都假定你已经实例化好了一个ConnectionMultiplexer类,它将会一直被重用 ,
现在我们来创建一个ConnectionMultiplexer实例。它是通过ConnectionMultiplexer.Connect 或者 ConnectionMultiplexer.ConnectAsync,
传递一个连接字符串或者一个ConfigurationOptions 对象来创建的。
连接字符串可以是以逗号分割的多个服务的节点, 我们仅仅需要连接一个在本地计算机中的redis服务,redis服务的默认端口是6379.
using StackExchange.Redis;
...
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");
// ^^^ store and re-use this!!!
注意 : ConnectionMultiplexer 实现了IDisposable接口当我们不再需要是可以将其释放的 , 这里我故意不使用 using 来释放他。 简单来讲创建一个ConnectionMultiplexer是十分昂贵的 , 一个好的主意是我们一直重用一个ConnectionMultiplexer对象。
一个复杂的的场景中可能包含有主从复制 , 对于这种情况,只需要指定所有地址在连接字符串中(它将会自动识别出主服务器)
ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379");
假设这里找到了两台主服务器,将会对两台服务进行裁决选出一台作为主服务器来解决这个问题 , 这种情况是非常罕见的 ,我们也应该避免这种情况的发生。
现在你已经拥有了一个 ConnectionMultiplexer , 下面三件事情可能是你想要做的。
1. 访问数据库。(注意在使用集群的情况下,一个数据库可能会分部在多个节点中)
2. 使用redis的发布订阅功能
3. 维护和监控一台服务器
访问数据库
访问数据库的操作非常简单:
IDatabase db = redis.GetDatabase();
GetDatabase 返回一个IDatabase接口。 注意 redis允许配置多个数据库,可以在调用GetDatabase() 时候指定数据库.另外,如果你计划使用异步的api , Task.AsyncState 必须拥有一个值 ,也可以这样指定。
int databaseNumber = ...
object asyncState = ...
IDatabase db = redis.GetDatabase(databaseNumber, asyncState);
现在你已经拥有了一个 IDatabase 对象 , 他可以对redis数据库进行操作。所有的方法都有同步和异步两个版本 , 按照微软的命名约定 ,所有的异步方法都以Async结尾。
最简单的操作 存储和获取一个值 。
string value = "abcdefg";
db.StringSet("mykey", value);
...
string value = db.StringGet("mykey");
Console.WriteLine(value); // writes: "abcdefg"
String前缀这里代表的是Redis中的String类型 , 和.net中的String类型有很大的区别 , 尽管两者都可以保存字符串类型。然后 ,Redis允许键值为二进制数据 , 示例如下:
byte[] key = ..., value = ...;
db.StringSet(key, value);
...
byte[] value = db.StringGet(key);
StackExchange.Redis 支持所有的 redis shell命令, 具体可以参考redis官网。
使用Redis的发布订阅功能
redis另一个常见的用途是发布订阅功能 。 它非常的简单 ,当连接失败时 ConnectionMultiplexer 会自动重新进行订阅 。
ISubscriber sub = redis.GetSubscriber();
GetSubscriber 方法返回一个 ISubscriber 类型的实例 。发布订阅功能没有数据库的概念,我们可以为其提供一个 async-state 。所有的订阅都是全局的:
ISubscriber 实例不是他们的生命周期 , 发布订阅的特性在redis中被定义为 “channels” , 渠道不需要预先定义在数据库中 。 订阅操作需要一个渠道
名称和一个回调函数来处理发布的消息。
sub.Subscribe("messages", (channel, message) => {
Console.WriteLine((string)message);
});
你可以发布一个消息到指定的渠道中:
sub.Publish("messages", "hello");
他将会将 “hello” 这个消息发布到所有订阅了messages渠道的客户端(几乎是实时的)。 和之前一样渠道的名称和消息也可以是二进制的。
指定消息发布的顺序(Message Order)
当使用 pub/sub API 时,你可以指定消息是并行还是有序的。
有序的意味着你不需要考虑线程安全的问题 ,同时也意味着消息会通过队列完全按照你发布的顺序来进行传递,这必然导致消息的延迟。
并行处理,不能保证消息是按照发布的顺序来进行处理的,你的代码也要保证当存在并发时程序运行正常,
消息的顺序通常是无关紧要的, 并行处理可以获得更好的性能和扩展性。
为确保安全,消息的传递默认是有序的。为获得更好的性能强烈建议你使用并行操作 。 这是非常简单的。
multiplexer.PreserveAsyncOrder = false;
建议并非是你配置该选项的理由, 是否适合完全取决与你订阅消息的代码。
访问单个服务器
有时候需要为单个服务器指定特定的命令 。
IServer server = redis.GetServer("localhost", 6379);
GetServer方法会接收一个EndPoint类或者一个唯一标识一台服务器的键值对。GetServer 方法返回一个IServer对象。 方法也可以是异步的只需要传入一个async-state
可以使用如下方法获取所有可用的终结点:
EndPoint[] endpoints = redis.GetEndPoints();
使用IServer可以使用所有的shell命令,比如:
DateTime lastSave = server.LastSave();
ClientInfo[] clients = server.ClientList();
如果报错在连接字符串后加 ,allowAdmin=true;
同步 、异步、即发即弃
这是StackExchange.Redis的三种主要使用机制:
同步-在方法返回之前阻塞调用方(虽然会阻塞调用方,但绝不会阻塞其他线程 ,StackExchange.Redis中的关键点是共享调用者之间的连接)
异步-在未来的某个时间点操作完成,会立刻返回一个 Task 或者 Task<T> : 之后可以调用
.Wait() 阻塞当前线程,直到处理完成。
ContinueWith 添加一个回调函数
使用 await 这是一个高级特性简化了操作
即发即弃-
在上面的示例中已经演示同步调用的方法 。
异步调用:
string value = "abcdefg";
await db.StringSetAsync("mykey", value);
...
string value = await db.StringGetAsync("mykey");
Console.WriteLine(value); // writes: "abcdefg"
即发即弃:通过配置 CommandFlags 来实现即发即弃功能,在该实例中该方法会立即返回,如果是string则返回null 如果是int则返回0.这个操作将会继续在后台运行,一个典型的用法页面计数器的实现:
db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget);
Configuration
redis有很多不同的方法来配置连接字符串 , StackExchange.Redis 提供了一个丰富的配置模型,当调用Connect 或者 ConnectAsync 时需要传入。
var conn = ConnectionMultiplexer.Connect(configuration);
这里的 configuration 参数可以是:
1. 一个 ConfigurationOptions 实例
2. 一个字符串
第二种方式从根本上来说也是ConfigurationOptions。
通过字符串配置连接
最简单的配置方式只需要一个主机名
var conn = ConnectionMultiplexer.Connect("localhost");
它将会连接到本地的redis服务器 , 默认6379端口 ,多个连接通过逗号分割 。 其他选项在名称的后面包含了一个 “= ”。 例如
var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,allowAdmin=true");
可以将一个字符串转换为ConfigurationOptions 或者 将一个ConfigurationOptions转换为字符串 。
ConfigurationOptions options = ConfigurationOptions.Parse(configString);
OR
string configString = options.ToString();
推荐的用法是将基础信息保存在一个字符串中,然后在运行是通过ConfigurationOptions改变其他信息。
string configString = GetRedisConfiguration();
var options = ConfigurationOptions.Parse(configString);
options.ClientName = GetAppName(); // only known at runtime
options.AllowAdmin = true;
conn = ConnectionMultiplexer.Connect(options);
也可以指定密码
var conn = ConnectionMultiplexer.Connect("contoso5.redis.cache.windows.NET,ssl=true,password=...");
配置选项
ConfigurationOptions 包含大量的配置选项,一些常用的配置如下:
abortConnect : 当为true时,当没有可用的服务器时则不会创建一个连接
allowAdmin : 当为true时 ,可以使用一些被认为危险的命令
channelPrefix:所有pub/sub渠道的前缀
connectRetry :重试连接的次数
connectTimeout:超时时间
configChannel: Broadcast channel name for communicating configuration changes
defaultDatabase : 默认0到-1
keepAlive : 保存x秒的活动连接
name:ClientName
password:password
proxy:代理 比如 twemproxy
resolveDns : 指定dns解析
serviceName : Not currently implemented (intended for use with sentinel)
ssl={bool} : 使用sll加密
sslHost={string} : 强制服务器使用特定的ssl标识
syncTimeout={int} : 异步超时时间
tiebreaker={string}:Key to use for selecting a server in an ambiguous master scenario
version={string} : Redis version level (useful when the server does not make this available)
writeBuffer={int} : 输出缓存区的大小
各配置项用逗号分割
自动和手动配置
在大部分的情况下StackExchange.Redis 会自动的帮我们配置很多选项。 比如 服务器类型,版本, 超时时间 , 主从服务器等..
尽管如此,有时候我们需要在服务器上面排除一些命令, 这种情况下有必要提供更多信息
ConfigurationOptions config = new ConfigurationOptions
{
EndPoints =
{
{ "redis0", 6379 },
{ "redis1", 6380 }
},
CommandMap = CommandMap.Create(new HashSet<string>
{ // EXCLUDE a few commands
"INFO", "CONFIG", "CLUSTER",
"PING", "ECHO", "CLIENT"
}, available: false),
KeepAlive = 180,
DefaultVersion = new Version(2, 8, 8),
Password = "changeme"
};
也可以使用下面的字符串来设置:
redis0:6379,redis1:6380,keepAlive=180,version=2.8.8,$CLIENT=,$CLUSTER=,$CONFIG=,$ECHO=,$INFO=,$PING=
重命名命令
你可以禁用或者重命名一个命令。 按照前面的示例这是通过 CommandMap 来完成的,不过上面使用Create( new HashSet<string> )来进行配置,我们使用Dictionary<string,string>。设置null时代表禁用该命令
var commands = new Dictionary<string,string> {
{ "info", null }, // disabled
{ "select", "use" }, // renamed to SQL equivalent for some reason
};
var options = new ConfigurationOptions {
// ...
CommandMap = CommandMap.Create(commands),
// ...
}
也可以使用下面的字符串来设置:
$INFO=,$SELECT=use
ConnectionMultiplexer 可以注册如下事件
ConfigurationChanged
- 配置更改时ConfigurationChangedBroadcast
- 通过发布订阅更新配置时ConnectionFailed
- 连接失败 , 如果重新连接成功你将不会收到这个通知ConnectionRestored
- 重新建立连接之前的错误ErrorMessage
- 发生错误HashSlotMoved
- 更改集群InternalError
- redis类库错误
StackExchange.Redis 使用资料的更多相关文章
- Lind.DDD.RedisClient~对StackExchange.Redis调用者的封装及多路复用技术
回到目录 两雄争霸 使用StackExchange.Redis的原因是因为它开源,免费,而对于商业化的ServiceStack.Redis,它将一步步被前者取代,开源将是一种趋势,商业化也值得被我们尊 ...
- StackExchange.Redis 访问封装类
最近需要在C#中使用Redis,在Redis的官网找到了ServiceStack.Redis,最后在测试的时候发现这是个坑,4.0已上已经收费,后面只好找到3系列的最终版本,最后测试发现还是有BUG或 ...
- StackExchange Redis如何实现BRPOP/BLPOP
今天在使用StackExchange Redis客户端时.我想要使用BRPOP,但是我发现StackExchange Redis并没有提供API,没办法只好找资料看文档了. 原来StackExchan ...
- c#使用 StackExchange.Redis 封装 RedisHelper
公司一直在用.net自带的缓存,大家都知道.net自带缓存的缺点,就不多说了,不知道的可以查一查,领导最近在说分布式缓存,我们选的是redis,领导让我不忙的时候封装一下,搜索了两天,选了选第三方的插 ...
- Windows下Redis缓存服务器的使用 .NET StackExchange.Redis Redis Desktop Manager
Redis缓存服务器是一款key/value数据库,读110000次/s,写81000次/s,因为是内存操作所以速度飞快,常见用法是存用户token.短信验证码等 官网显示Redis本身并没有Wind ...
- 怎样在Redis通过StackExchange.Redis 存储集合类型List
StackExchange 是由StackOverFlow出品, 是对Redis的.NET封装,被越来越多的.NET开发者使用在项目中. 绝大部分原先使用ServiceStack的开发者逐渐都转了过来 ...
- StackExchange.Redis帮助类解决方案RedisRepository封装(基础配置)
本文版权归博客园和作者吴双本人共同所有,转载和爬虫,请注明原文地址.http://www.cnblogs.com/tdws/p/5815735.html 写在前面 这不是教程,分享而已,也欢迎园友们多 ...
- StackExchange.Redis客户端读写主从配置,以及哨兵配置。
今天简单分享一下StackExchange.Redis客户端中配置主从分离以及哨兵的配置. 关于哨兵如果有不了解的朋友,可以看我之前的一篇分享,当然主从复制文章也可以找到.http://www.cnb ...
- RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用
本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...
随机推荐
- es6常用的语法
刚开始用vue或者react,很多时候我们都会把ES6这个大兄弟加入我们的技术栈中.但是ES6那么多那么多特性,我们需要全部都掌握吗?秉着二八原则,掌握好常用的,有用的这个可以让我们快速起飞. 接下来 ...
- JAVA程序员面试笔试宝典3
1.什么是线程?它与进程有什么区别?为什么要使用多线程 线程是指程序在执行过程中,能够执行程序代码的一个执行单元.进程是指一段正在执行的程序. 使用多线程可以减少程序的相应时间 与进程相比,线程的创建 ...
- SpringBoot项目编译后没有xxxmapper.xml文件解决方法
在pom.xml文件中添加如下代码 <build> <plugins> <plugin> <groupId>org.springframework.bo ...
- Chrome升级后打开新的标签页变样了……
最近更新Chrome后,打开新的标签页完全变样了,让人不知所措,特别是没有了那个“最近关闭标签页”按钮,这让我抓狂…… PS:Chrome版本号为:29.0.1547.76 m PPS:最新版已无法修 ...
- World Cup(The 2016 ACM-ICPC Asia China-Final Contest dfs搜索)
题目: Here is World Cup again, the top 32 teams come together to fight for the World Champion. The tea ...
- [bzoj4567][Scoi2016][背单词] (贪心+trie树)
Description Lweb 面对如山的英语单词,陷入了深深的沉思,“我怎么样才能快点学完,然后去玩三国杀呢?”.这时候睿智 的凤老师从远处飘来,他送给了 Lweb 一本计划册和一大缸泡椒,他的计 ...
- 被 idea 坑了的记录篇
这个星期真的是波折的一周~~~~ 不得不吐槽下无敌坑的自己了,社会我娜姐,坑起来连自己都坑~~ 其实这也不全算我自己的坑,我只是卸载了idea,重新装了一下而已,很神奇的把idea的几个坑全撞了一遍( ...
- CRC校验算法学习
原文:http://www.repairfaq.org/filipg/LINK/F_crc_v31.html 本文根据上述链接原文翻译而来,如有错误,忘广大网友互相帮忙纠正,谢谢! 1.前言: 1.0 ...
- poj 1364 查分约束
#include<stdio.h> #include<iostream> #include<stack> #include<string.h> usin ...
- poj 2823 二分法+单调队列
#include<stdio.h> #include<string.h> #define N 1100000 int a[N]; int fmin[N],fmax[N]; i ...