ConnectionMultiplexer

ConnectionMultiplexer 是StackExchange.Redis的核心对象,用这个类的实例来进行Redis的一系列操作,对于一个整个应用程序应该只有一个ConnectionMultiplexer 类的实例。上一章中StackExchangeRedisHelper 的相关代码如下

  private static ConnectionMultiplexer _instance = null;
/// <summary>
/// 使用一个静态属性来返回已连接的实例,如下列中所示。这样,一旦 ConnectionMultiplexer 断开连接,便可以初始化新的连接实例。
/// </summary>
public static ConnectionMultiplexer Instance
{
get
{
if (_instance == null)
{
lock (_locker)
{
if (_instance == null || !_instance.IsConnected)
{
_instance = ConnectionMultiplexer.Connect(Coonstr);
}
}
}
//注册如下事件
_instance.ConnectionFailed += MuxerConnectionFailed;
_instance.ConnectionRestored += MuxerConnectionRestored;
_instance.ErrorMessage += MuxerErrorMessage;
_instance.ConfigurationChanged += MuxerConfigurationChanged;
_instance.HashSlotMoved += MuxerHashSlotMoved;
_instance.InternalError += MuxerInternalError;
return _instance;
}
}

String

 string类型应该是最长用到的了,用法也很简单,下面展示了用Redis来进行基本的字符串数字存储

 public static IDatabase GetDatabase()
{
return Instance.GetDatabase();
}
/// <summary>
/// 设置缓存
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public static void Set(string key, object value, TimeSpan? expiry = default(TimeSpan?), When when = When.Always, CommandFlags flags = CommandFlags.None)
{
key = MergeKey(key);
GetDatabase().StringSet(key, Serialize(value), expiry, when, flags);
}
/// <summary>
/// 根据key获取缓存对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
public static T Get<T>(string key)
{
key = MergeKey(key);
return Deserialize<T>(GetDatabase().StringGet(key));
}
/// <summary>
/// 移除指定key的缓存
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool Remove(string key)
{
key = MergeKey(key);
return GetDatabase().KeyDelete(key);
}

除了基本的string类型操作,Redis同时支持以下几种类型的操作

  • List  列表
  • Set  无序集合
  • SortedSet  有序集合  
  • Hash 哈希表

下面我依次来介绍下这四种类型在StackExchange.Redis中的基本用法

关于代码中的KeyDelete为删除对应的键,我这里是因为测试防止重复才加上的。大家不要误会

List

  • 特点:有序排列,值可以重复。我们可以通过pop,push操作来从头部和尾部删除或者添加元素。这使得list既可以做栈也可以做队列
  • 需求:要求一条微博将最新的10条评论用户名字直接显示在主页上
  • 实现:
 public static void LatestUserTop10()
{
IDatabase db = StackExchangeRedisHelper.GetDatabase();
//模拟有一百名用户
for (int i = ; i <= ; i++)
{
db.ListLeftPush("user", "用户"+i);
//每一名用户插入后都只保留最后的十个用户到redis数据库中
db.ListTrim("user", , );
}
RedisValue[] userStores = db.ListRange("user");
foreach (var item in userStores)
{
Console.Write((string)item + ",");
}
db.KeyDelete("user");
Console.ReadLine();
}

Set

  • 特点:无序排列,值不可重复。增加删除查询都很快。提供了取并集交集差集等一些有用的操作
  • 需求:取两篇文章的评论者的交集并集差集
  • 实现:
 public void RedisSetTest()
{
IDatabase db = StackExchangeRedisHelper.GetDatabase(); for (int i = ; i <= ; i++)
{
db.SetAdd("文章1", i);
}
for (int i = ; i <= ; i++)
{
db.SetAdd("文章2", i);
}
RedisValue[] inter = db.SetCombine(SetOperation.Intersect, "文章1", "文章2");
RedisValue[] union = db.SetCombine(SetOperation.Union, "文章1", "文章2");
RedisValue[] dif1 = db.SetCombine(SetOperation.Difference, "文章1", "文章2");
RedisValue[] dif2 = db.SetCombine(SetOperation.Difference, "文章2", "文章1");
int x = ;
Console.WriteLine("两篇文章都评论过的用户");
foreach (var item in inter.OrderBy(m => m).ToList())
{
Console.Write((string)item + " ");
}
Console.WriteLine("\n评论过两篇文章中任意一篇文章的用户");
foreach (var item in union.OrderBy(m => m).ToList())
{
Console.Write((string)item + " ");
}
Console.WriteLine("\n只评论过其第一篇文章的用户");
foreach (var item in dif1.OrderBy(m => m).ToList())
{
Console.Write((string)item + " ");
}
Console.WriteLine("\n只评论过其第二篇文章的用户");
foreach (var item in dif2.OrderBy(m => m).ToList())
{
Console.Write((string)item + " ");
}
db.KeyDelete("文章1");
db.KeyDelete("文章2");
Console.ReadLine();
}

SortedSet

  • 特点:有序排列,值不可重复。类似Set,不同的是sortedset的每个元素都会关联一个double类型的score,用此元素来进行排序
  • 需求:显示文章被赞最多的十条评论
  • 实现:
public void HotestUserTop10()
{
IDatabase db = StackExchangeRedisHelper.GetDatabase();
//模拟有一百名评论者,开始每个用户被“赞”的次数为1
List<SortedSetEntry> entrys = new List<SortedSetEntry>();
for (int i = ; i <= ; i++)
{
db.SortedSetAdd("文章1", "评论者" + i, );
}
//评论者2又被赞了两次
db.SortedSetIncrement("文章1", "评论者2", ); //对应的值的score+2
//评论者101被赞了4次
db.SortedSetIncrement("文章1", "评论者101", ); //若不存在该值,则插入一个新的
RedisValue[] userStores = db.SortedSetRangeByRank("文章1", , , Order.Descending);
for (int i = ; i < userStores.Length; i++)
{
Console.WriteLine(userStores[i]+":"+ db.SortedSetScore("文章1", userStores[i]));
}
db.KeyDelete("文章1");
Console.ReadLine();
}

Hash

  • 特点:Hash是一个string类型的field和value的对应表,它更适合来存储对象,相比于每个属性进行一次缓存,利用hash来存储整个对象会占用更小的内存。但是存储速度并不会更快
  • 需求:存储一个学生的基本信息
  • 实现:
  public void RedisHashTest()
{
IDatabase db = StackExchangeRedisHelper.GetDatabase();
db.HashSet("student1", "name", "张三");
db.HashSet("student1", "age", );
db.HashSet("student1", "class", "五年级");
Console.WriteLine(db.HashGet("student1", "name"));
RedisValue[] result = db.HashGet("student1", new RedisValue[] { "name", "age","class" });
Console.WriteLine(string.Join(",",result));
db.KeyDelete("student1");
Console.ReadLine();
}

以下代码是我分别用stringset和hash来存储对象进行的时间及内存比较,内存可通过redis的info命令来查看。

最终显示耗时方面stringset稍微快一点点,内存占用stringset却是hash的二倍

 public void RedisHashVsStringSet()
{
IDatabase db = StackExchangeRedisHelper.GetDatabase();
Stopwatch sw = new Stopwatch();
sw.Start();
//for (int i = 0; i < 100000; i++)
//{
// db.HashSet("studenths" + i, "name", "张三" + i);
// db.HashSet("studenths" + i, "age", 12 + i);
// db.HashSet("studenths" + i, "class", "五年级" + i);
//}
//Console.WriteLine(sw.Elapsed.TotalMilliseconds);
//sw.Restart();
for (int i = ; i < ; i++)
{
db.StringSet("studentstr_name" + i, "张三" + i);
db.StringSet("studentstr_age" + i, + i);
db.StringSet("studentstr_class" + i, "五年级" + i);
}
Console.WriteLine(sw.Elapsed.TotalMilliseconds);
//for (int i = 0; i < 100000; i++)
//{
// db.KeyDelete("studenths" + i);
// db.KeyDelete("studentstr_name" + i);
// db.KeyDelete("studentstr_age" + i);
// db.KeyDelete("studentstr_class" + i);
//}
Console.ReadLine();
}

StackExchange.Redis学习笔记(二) Redis查询 五种数据类型的应用的更多相关文章

  1. Redis学习笔记(3)—— 五种数据类型&keys的通用操作

    一.Redis数据结构介绍 redis是一种高级的key-value的存储系统,其中的key是字符串类型,尽可能满足如下几点: 1)key不要太长,最好不要操作1024个字节,这不仅会消耗内存还会降低 ...

  2. Redis学习笔记(一)五种数据类型

    1.字符串(String) 基本操作:SET(设置).GET(获取).DEL(删除)其他操作传送门 root@localhost:~# redis-cli > set msg hello OK ...

  3. Redis学习笔记二 (BitMap算法分析与BitCount语法)

    Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...

  4. Redis学习笔记(二):Redis集群

    集群通过分片(sharding)来进行数据共享,并提供复制和故障转移功能.   1.节点 一个节点就是一个运行在集群模式下的Redis服务器.启动Redis服务器时,通过判断cluster-enabl ...

  5. Redis学习笔记二

    学习Redis添加Object时,由于Redis只能存取字符串String,对于其它数据类型形容:Int,long,double,Date等不提供支持,因而需要设计到对象的序列化和反序列化.java序 ...

  6. StackExchange.Redis学习笔记(一) Redis的使用初探

    Redis Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化. 与其它键值数据存储相比,Redis有一组相对丰富的数据类型. Redis可以将数据复制到任意数量的从机中 Redis的安装 官 ...

  7. redis学习笔记(三)——redis的命令大全总结

    总结了一些redis五种存储类型的常用命令以及一些通用操作命令,不是很全,是在学习的时候将学到的做了个汇总,使用的时候可以查一下. 笔记写在表格里面了,不好粘贴.......后面的直接截图了..... ...

  8. Redis学习笔记(4) Redis事务、生存时间及排序

    1. Redis事务 Redis中的事务(transaction)是一组命令的集合,一个事务中的命令要么都执行,要么都不执行.事务的原理是先将属于一个事务的命令发送给Redis,然后再让Redis依次 ...

  9. Redis学习笔记(1) Redis介绍及基础

    1. Redis的特性 (1) 存储结构 Redis(Remote Dictionary Server,远程字典服务器)是以字典结构存储数据,并允许其他应用通过TCP协议读写字典中的内容.Redis支 ...

随机推荐

  1. [javaSE] GUI(事件监听机制)

    外部动作——>事件源(组件)——>事件对象——>监听器 获取Frame对象,与上节一样 调用Frame对象的addWindowListener()方法,参数:WindowListen ...

  2. sublime text3 JS语法检测插件

    首先ctrl+shift+P用包管理器安装sublimeLinter和sublimeLinter-jshint 前往node官网下载nodejs并安装 安装完node后打开命令行输入npm insta ...

  3. Fill Table Row(it’s an IQ test question)

    Here is a table include the 2 rows. And the cells in the first row have been filled with 0~4. Now yo ...

  4. JDK的安装与卸载

      1.jdk 下载链接:http://www.oracle.com/technetwork/java/javase/downloads/jdk9-downloads-3848520.html 2.在 ...

  5. H5实现拍照上传功能

    <input type="file" capture="camera" accept="image/*" >

  6. css 各种常见布局整理

    在学习各种布局之前我们先来认识各个关键词,理解这些关键词,然后由点到面,这样就简单多了. display属性 页面中每个元素都有一个默认的display属性,它的值与该元素的类型有关,默认值通常是 b ...

  7. [HttpException (0x80004005): 应用程序已预编译,因此不允许使用目录“/App_Code/”。]

    删除网站下的PrecompiledApp.config文件即可.

  8. 爬虫必备—requests

    Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得 ...

  9. Java设计模式—解释器模式&迭代器模式简介

       解释器模式在实际的系统开发中使用得非常少,因为它会引起效率.性能以及维护等问题,一般在大中型的框架型项目能够找到它的身影,如一些数据分析工具.报表设计工具.科学计算工具等,若你确实遇到" ...

  10. 【javascript】javascript设计模式之单例模式

    单例模式: 定义:单例模式之所以这么叫,是因为它限制一个类只能有一个实例化对象. 实现方法:判断实例是否存在,如果存在则直接返回,如果不存在就创建了再返回.(确保一个类只有一个实例对象) 特点: 命名 ...