Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍
Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍
目录
- 简介
- 安装
- 入门指令
- GUI 工具
- C# 驱动介绍
简介
ANSI C 编写,开源,基于内存,可持久化,一个键值对的数据库,用法简单。
支持的类型:字符串、散列、列表、集合和有序集合。
因为 Redis 默认将所有数据都存储到内存中,并且内存的读写速度远远高于硬盘,因此,比其他基于硬盘存储的数据库在性能上体现的优势非常明显。不过这样也引发了一个数据安全性的问题,程序异常或退出后数据会出现丢失的情形,现在新的版本已经提供了数据持久化(RDB + AOF)的支持,即可以将内存中的数据异步写入到硬盘上,同时不会影响其它功能的运行。
redis 可以为每个键设置生存时间,到期自动删除,也就是说可以作为缓存系统(这也是企业主要的运用场景)进行使用。
相对于 Memcached,简单的说:Redis 单线程模型,Memcached 支持多线程,但 Redis 支持的功能和数据类型更多,更简单易用,并且 redis 的性能在绝大部分场合下都不会成为系统瓶颈,不过在多核服务器上使用的情况下,理论上 Memcached 比 redis 性能更高。所以,在新项目中,建议使用 redis 代替 Memcached。
Redis 还可以限定数据占用的最大内存空间,在数据达到空间限制后按一定规则自动淘汰不需要的键;也支持构建高性能的队列(不过很多企业会选择第三方的 MQ,如:RabbitMQ)。
安装
它的约定次版本号(即第一个小数点后的数字)为偶数的版本是稳定版(如 v2.8,v3.0)。
为了减少学习成本,我们直接使用 windows 版本的就可以,想学习 Linux 部署的,先搜搜别人的文章吧。
redis-windows-3.0(搜索了一下,最新的正式版是 3.2):下载地址
文件简单说明:
入门指令
1.启动 CMD:
$ redis-server $ redis-server --port //自定义端口
2.停止:
$ redis-cli SHUTDOWN
3.PING 命令:
测试与 redis 的连接是否正常,正常返回 PONG
$ redis-cli PING
GUI 工具
Redis Client:一个基于Java SWT 和 Jedis 编写的 redis 客户端 GUI 工具。可从 https://github.com/caoxinyu/RedisClient 下载。
从图可知,redis 包含了 16 个数据库。上面的每个数据库默认从 0 开始的递增数字命名。
因为该程序打包后的压缩包 >10 M,无法上传到 cnblogs,如有需要的童鞋请加群在群文件中下载压缩包。
补充一下园友(心态要好)推荐的其它 GUI 工具 RedisDeskTopManager:https://redisdesktop.com/download。
C# 驱动
之前在 《使用 StackExchange.Redis 封装属于自己的 RedisHelper》 曾经发布了一篇使用 StackExchange.Redis 进行了简单封装的 RedisHelper,你可以选择查看之前的文章,从中借鉴一些思想或者给出一些建议。
这里是更新后的 Helper 代码(直接展开即可),代码的后续更新在 GitHub 上。
#region using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading.Tasks;
using StackExchange.Redis; #endregion namespace Wen.Helpers.Common.Redis
{
/// <summary>
/// Redis 助手
/// </summary>
public class RedisHelper
{
/// <summary>
/// 获取 Redis 连接对象
/// </summary>
/// <returns></returns>
public IConnectionMultiplexer GetConnectionRedisMultiplexer()
{
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
lock (Locker)
{
if (_connMultiplexer == null || !_connMultiplexer.IsConnected)
_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
} return _connMultiplexer;
} #region 其它 public ITransaction GetTransaction()
{
return _db.CreateTransaction();
} #endregion 其它 #region private field /// <summary>
/// 连接字符串
/// </summary>
private static readonly string ConnectionString; /// <summary>
/// redis 连接对象
/// </summary>
private static IConnectionMultiplexer _connMultiplexer; /// <summary>
/// 默认的 Key 值(用来当作 RedisKey 的前缀)
/// </summary>
private static readonly string DefaultKey; /// <summary>
/// 锁
/// </summary>
private static readonly object Locker = new object(); /// <summary>
/// 数据库
/// </summary>
private readonly IDatabase _db; #endregion private field #region 构造函数 static RedisHelper()
{
ConnectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
DefaultKey = ConfigurationManager.AppSettings["Redis.DefaultKey"];
AddRegisterEvent();
} public RedisHelper(int db = )
{
_db = _connMultiplexer.GetDatabase(db);
} #endregion 构造函数 #region String 操作 /// <summary>
/// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public bool StringSet(string key, string value, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
return _db.StringSet(key, value, expiry);
} /// <summary>
/// 保存多个 Key-value
/// </summary>
/// <param name="keyValuePairs"></param>
/// <returns></returns>
public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
{
var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
return _db.StringSet(pairs.ToArray());
} /// <summary>
/// 获取字符串
/// </summary>
/// <param name="redisKey"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public string StringGet(string redisKey)
{
redisKey = AddKeyPrefix(redisKey);
return _db.StringGet(redisKey);
} /// <summary>
/// 存储一个对象(该对象会被序列化保存)
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public bool StringSet<T>(string key, T value, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
var json = Serialize(value); return _db.StringSet(key, json, expiry);
} /// <summary>
/// 获取一个对象(会进行反序列化)
/// </summary>
/// <param name="key"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public T StringGet<T>(string key, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
return Deserialize<T>(_db.StringGet(key));
} /// <summary>
/// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public double StringIncrement(string key, double value = )
{
key = AddKeyPrefix(key);
return _db.StringIncrement(key, value);
} /// <summary>
/// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public double StringDecrement(string key, double value = )
{
key = AddKeyPrefix(key);
return _db.StringDecrement(key, value);
} #region async /// <summary>
/// 保存一个字符串值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync(string key, string value, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
return await _db.StringSetAsync(key, value, expiry);
} /// <summary>
/// 保存一组字符串值
/// </summary>
/// <param name="keyValuePairs"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs)
{
var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
return await _db.StringSetAsync(pairs.ToArray());
} /// <summary>
/// 获取单个值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public async Task<string> StringGetAsync(string key, string value, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
return await _db.StringGetAsync(key);
} /// <summary>
/// 存储一个对象(该对象会被序列化保存)
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
var json = Serialize(value);
return await _db.StringSetAsync(key, json, expiry);
} /// <summary>
/// 获取一个对象(会进行反序列化)
/// </summary>
/// <param name="key"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public async Task<T> StringGetAsync<T>(string key, TimeSpan? expiry = null)
{
key = AddKeyPrefix(key);
return Deserialize<T>(await _db.StringGetAsync(key));
} /// <summary>
/// 在指定 key 处实现增量的递增,如果该键不存在,则在执行前将其设置为 0
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<double> StringIncrementAsync(string key, double value = )
{
key = AddKeyPrefix(key);
return await _db.StringIncrementAsync(key, value);
} /// <summary>
/// 在指定 key 处实现增量的递减,如果该键不存在,则在执行前将其设置为 0
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<double> StringDecrementAsync(string key, double value = )
{
key = AddKeyPrefix(key);
return await _db.StringDecrementAsync(key, value);
} #endregion async #endregion String 操作 #region Hash 操作 /// <summary>
/// 判断该字段是否存在 hash 中
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public bool HashExists(string key, string hashField)
{
key = AddKeyPrefix(key);
return _db.HashExists(key, hashField);
} /// <summary>
/// 从 hash 中移除指定字段
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public bool HashDelete(string key, string hashField)
{
key = AddKeyPrefix(key);
return _db.HashDelete(key, hashField);
} /// <summary>
/// 从 hash 中移除指定字段
/// </summary>
/// <param name="key"></param>
/// <param name="hashFields"></param>
/// <returns></returns>
public long HashDelete(string key, IEnumerable<string> hashFields)
{
key = AddKeyPrefix(key);
var fields = hashFields.Select(x => (RedisValue) x); return _db.HashDelete(key, fields.ToArray());
} /// <summary>
/// 在 hash 设定值
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool HashSet(string key, string hashField, string value)
{
key = AddKeyPrefix(key);
return _db.HashSet(key, hashField, value);
} /// <summary>
/// 在 hash 中设定值
/// </summary>
/// <param name="key"></param>
/// <param name="hashFields"></param>
public void HashSet(string key, IEnumerable<KeyValuePair<string, string>> hashFields)
{
key = AddKeyPrefix(key);
var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value)); _db.HashSet(key, entries.ToArray());
} /// <summary>
/// 在 hash 中获取值
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public string HashGet(string key, string hashField)
{
key = AddKeyPrefix(key);
return _db.HashGet(key, hashField);
} /// <summary>
/// 在 hash 中获取值
/// </summary>
/// <param name="key"></param>
/// <param name="hashFields"></param>
/// <returns></returns>
public IEnumerable<string> HashGet(string key, IEnumerable<string> hashFields)
{
key = AddKeyPrefix(key);
var fields = hashFields.Select(x => (RedisValue) x); return ConvertStrings(_db.HashGet(key, fields.ToArray()));
} /// <summary>
/// 从 hash 返回所有的字段值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public IEnumerable<string> HashKeys(string key)
{
key = AddKeyPrefix(key);
return ConvertStrings(_db.HashKeys(key));
} /// <summary>
/// 返回 hash 中的所有值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public IEnumerable<string> HashValues(string key)
{
key = AddKeyPrefix(key);
return ConvertStrings(_db.HashValues(key));
} /// <summary>
/// 在 hash 设定值(序列化)
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="redisValue"></param>
/// <returns></returns>
public bool HashSet<T>(string key, string hashField, T redisValue)
{
key = AddKeyPrefix(key);
var json = Serialize(redisValue); return _db.HashSet(key, hashField, json);
} /// <summary>
/// 在 hash 中获取值(反序列化)
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public T HashGet<T>(string key, string hashField)
{
key = AddKeyPrefix(key);
return Deserialize<T>(_db.HashGet(key, hashField));
} /// <summary>
/// 指定键递增
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public double HashIncrement(string key, string hashField, double value = )
{
key = AddKeyPrefix(key);
return _db.HashIncrement(key, hashField, value);
} /// <summary>
/// 指定键递减
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public double HashDecrement(string key, string hashField, double value = )
{
key = AddKeyPrefix(key);
return _db.HashDecrement(key, hashField, value);
} #region async /// <summary>
/// 判断该字段是否存在 hash 中
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public async Task<bool> HashExistsAsync(string redisKey, string hashField)
{
redisKey = AddKeyPrefix(redisKey);
return await _db.HashExistsAsync(redisKey, hashField);
} /// <summary>
/// 从 hash 中移除指定字段
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public async Task<bool> HashDeleteAsync(string redisKey, string hashField)
{
redisKey = AddKeyPrefix(redisKey);
return await _db.HashDeleteAsync(redisKey, hashField);
} /// <summary>
/// 从 hash 中移除指定字段
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashFields"></param>
/// <returns></returns>
public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields)
{
redisKey = AddKeyPrefix(redisKey);
var fields = hashFields.Select(x => (RedisValue) x); return await _db.HashDeleteAsync(redisKey, fields.ToArray());
} /// <summary>
/// 在 hash 设定值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<bool> HashSetAsync(string redisKey, string hashField, string value)
{
redisKey = AddKeyPrefix(redisKey);
return await _db.HashSetAsync(redisKey, hashField, value);
} /// <summary>
/// 在 hash 中设定值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashFields"></param>
public async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields)
{
redisKey = AddKeyPrefix(redisKey);
var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value));
await _db.HashSetAsync(redisKey, entries.ToArray());
} /// <summary>
/// 在 hash 中获取值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public async Task<string> HashGetAsync(string redisKey, string hashField)
{
redisKey = AddKeyPrefix(redisKey);
return await _db.HashGetAsync(redisKey, hashField);
} /// <summary>
/// 在 hash 中获取值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashFields"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields,
string value)
{
redisKey = AddKeyPrefix(redisKey);
var fields = hashFields.Select(x => (RedisValue) x); return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray()));
} /// <summary>
/// 从 hash 返回所有的字段值
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> HashKeysAsync(string redisKey)
{
redisKey = AddKeyPrefix(redisKey);
return ConvertStrings(await _db.HashKeysAsync(redisKey));
} /// <summary>
/// 返回 hash 中的所有值
/// </summary>
/// <param name="redisKey"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> HashValuesAsync(string redisKey)
{
redisKey = AddKeyPrefix(redisKey);
return ConvertStrings(await _db.HashValuesAsync(redisKey));
} /// <summary>
/// 在 hash 设定值(序列化)
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value)
{
redisKey = AddKeyPrefix(redisKey);
var json = Serialize(value);
return await _db.HashSetAsync(redisKey, hashField, json);
} /// <summary>
/// 在 hash 中获取值(反序列化)
/// </summary>
/// <param name="redisKey"></param>
/// <param name="hashField"></param>
/// <returns></returns>
public async Task<T> HashGetAsync<T>(string redisKey, string hashField)
{
redisKey = AddKeyPrefix(redisKey);
return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));
} /// <summary>
/// 指定键递增
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<double> HashIncrementAsync(string key, string hashField, double value = )
{
key = AddKeyPrefix(key);
return await _db.HashIncrementAsync(key, hashField, value);
} /// <summary>
/// 指定键递减
/// </summary>
/// <param name="key"></param>
/// <param name="hashField"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<double> HashDecrementAsync(string key, string hashField, double value = )
{
key = AddKeyPrefix(key);
return await _db.HashDecrementAsync(key, hashField, value);
} #endregion async #endregion Hash 操作 #region List 操作 /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string ListLeftPop(string key)
{
key = AddKeyPrefix(key);
return _db.ListLeftPop(key);
} /// <summary>
/// 出列,移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string ListRightPop(string key)
{
key = AddKeyPrefix(key);
return _db.ListRightPop(key);
} /// <summary>
/// 移除列表指定键上与该值相同的元素
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRemove(string key, string value)
{
key = AddKeyPrefix(key);
return _db.ListRemove(key, value);
} /// <summary>
/// 入列,在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRightPush(string key, string value)
{
key = AddKeyPrefix(key);
return _db.ListRightPush(key, value);
} /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListLeftPush(string key, string value)
{
key = AddKeyPrefix(key);
return _db.ListLeftPush(key, value);
} /// <summary>
/// 返回列表上该键的长度,如果不存在,返回 0
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long ListLength(string key)
{
key = AddKeyPrefix(key);
return _db.ListLength(key);
} /// <summary>
/// 返回在该列表上键所对应的元素
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public IEnumerable<string> ListRange(string key, long start = 0L, long stop = -1L)
{
key = AddKeyPrefix(key);
return ConvertStrings(_db.ListRange(key, start, stop));
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public T ListLeftPop<T>(string key)
{
key = AddKeyPrefix(key);
return Deserialize<T>(_db.ListLeftPop(key));
} /// <summary>
/// 出队,移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public T ListRightPop<T>(string key)
{
key = AddKeyPrefix(key);
return Deserialize<T>(_db.ListRightPop(key));
} /// <summary>
/// 入队,在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListRightPush<T>(string key, T value)
{
key = AddKeyPrefix(key);
return _db.ListRightPush(key, Serialize(value));
} /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public long ListLeftPush<T>(string key, T value)
{
key = AddKeyPrefix(key);
return _db.ListLeftPush(key, Serialize(value));
} #region List-async /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<string> ListLeftPopAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.ListLeftPopAsync(key);
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<string> ListRightPopAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.ListRightPopAsync(key);
} /// <summary>
/// 移除列表指定键上与该值相同的元素
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRemoveAsync(string key, string value)
{
key = AddKeyPrefix(key);
return await _db.ListRemoveAsync(key, value);
} /// <summary>
/// 在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRightPushAsync(string key, string value)
{
key = AddKeyPrefix(key);
return await _db.ListRightPushAsync(key, value);
} /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListLeftPushAsync(string key, string value)
{
key = AddKeyPrefix(key);
return await _db.ListLeftPushAsync(key, value);
} /// <summary>
/// 返回列表上该键的长度,如果不存在,返回 0
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<long> ListLengthAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.ListLengthAsync(key);
} /// <summary>
/// 返回在该列表上键所对应的元素
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> ListRangeAsync(string key, long start = 0L, long stop = -1L)
{
key = AddKeyPrefix(key);
var query = await _db.ListRangeAsync(key, start, stop);
return query.Select(x => x.ToString());
} /// <summary>
/// 移除并返回存储在该键列表的第一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> ListLeftPopAsync<T>(string key)
{
key = AddKeyPrefix(key);
return Deserialize<T>(await _db.ListLeftPopAsync(key));
} /// <summary>
/// 移除并返回存储在该键列表的最后一个元素
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<T> ListRightPopAsync<T>(string key)
{
key = AddKeyPrefix(key);
return Deserialize<T>(await _db.ListRightPopAsync(key));
} /// <summary>
/// 在列表尾部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListRightPushAsync<T>(string key, T value)
{
key = AddKeyPrefix(key);
return await _db.ListRightPushAsync(key, Serialize(value));
} /// <summary>
/// 在列表头部插入值。如果键不存在,先创建再插入值
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public async Task<long> ListLeftPushAsync<T>(string key, T value)
{
key = AddKeyPrefix(key);
return await _db.ListLeftPushAsync(key, Serialize(value));
} #endregion List-async #endregion List 操作 #region SortedSet 操作 /// <summary>
/// SortedSet 新增
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="score"></param>
/// <returns></returns>
public bool SortedSetAdd(string key, string member, double score)
{
key = AddKeyPrefix(key);
return _db.SortedSetAdd(key, member, score);
} /// <summary>
/// 在有序集合中返回指定范围的元素,默认情况下从低到高。
/// </summary>
/// <param name="key"></param>
/// <param name="start"></param>
/// <param name="stop"></param>
/// <param name="order"></param>
/// <returns></returns>
public IEnumerable<string> SortedSetRangeByRank(string key, long start = 0L, long stop = -1L,
OrderType order = OrderType.Ascending)
{
key = AddKeyPrefix(key);
return _db.SortedSetRangeByRank(key, start, stop, (Order) order).Select(x => x.ToString());
} /// <summary>
/// 返回有序集合的元素个数
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public long SortedSetLength(string key)
{
key = AddKeyPrefix(key);
return _db.SortedSetLength(key);
} /// <summary>
/// 返回有序集合的元素个数
/// </summary>
/// <param name="key"></param>
/// <param name="memebr"></param>
/// <returns></returns>
public bool SortedSetRemove(string key, string memebr)
{
key = AddKeyPrefix(key);
return _db.SortedSetRemove(key, memebr);
} /// <summary>
/// SortedSet 新增
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="score"></param>
/// <returns></returns>
public bool SortedSetAdd<T>(string key, T member, double score)
{
key = AddKeyPrefix(key);
var json = Serialize(member); return _db.SortedSetAdd(key, json, score);
} /// <summary>
/// 增量的得分排序的集合中的成员存储键值键按增量
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="value"></param>
/// <returns></returns>
public double SortedSetIncrement(string key, string member, double value = )
{
key = AddKeyPrefix(key);
return _db.SortedSetIncrement(key, member, value);
} #region SortedSet-Async /// <summary>
/// SortedSet 新增
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="score"></param>
/// <returns></returns>
public async Task<bool> SortedSetAddAsync(string key, string member, double score)
{
key = AddKeyPrefix(key);
return await _db.SortedSetAddAsync(key, member, score);
} /// <summary>
/// 在有序集合中返回指定范围的元素,默认情况下从低到高。
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string key)
{
key = AddKeyPrefix(key);
return ConvertStrings(await _db.SortedSetRangeByRankAsync(key));
} /// <summary>
/// 返回有序集合的元素个数
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<long> SortedSetLengthAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.SortedSetLengthAsync(key);
} /// <summary>
/// 返回有序集合的元素个数
/// </summary>
/// <param name="key"></param>
/// <param name="memebr"></param>
/// <returns></returns>
public async Task<bool> SortedSetRemoveAsync(string key, string memebr)
{
key = AddKeyPrefix(key);
return await _db.SortedSetRemoveAsync(key, memebr);
} /// <summary>
/// SortedSet 新增
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="score"></param>
/// <returns></returns>
public async Task<bool> SortedSetAddAsync<T>(string key, T member, double score)
{
key = AddKeyPrefix(key);
var json = Serialize(member); return await _db.SortedSetAddAsync(key, json, score);
} /// <summary>
/// 增量的得分排序的集合中的成员存储键值键按增量
/// </summary>
/// <param name="key"></param>
/// <param name="member"></param>
/// <param name="value"></param>
/// <returns></returns>
public Task<double> SortedSetIncrementAsync(string key, string member, double value = )
{
key = AddKeyPrefix(key);
return _db.SortedSetIncrementAsync(key, member, value);
} #endregion SortedSet-Async #endregion SortedSet 操作 #region key 操作 /// <summary>
/// 移除指定 Key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool KeyDelete(string key)
{
key = AddKeyPrefix(key);
return _db.KeyDelete(key);
} /// <summary>
/// 移除指定 Key
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
public long KeyDelete(IEnumerable<string> keys)
{
var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
return _db.KeyDelete(redisKeys.ToArray());
} /// <summary>
/// 校验 Key 是否存在
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public bool KeyExists(string key)
{
key = AddKeyPrefix(key);
return _db.KeyExists(key);
} /// <summary>
/// 重命名 Key
/// </summary>
/// <param name="key"></param>
/// <param name="newKey"></param>
/// <returns></returns>
public bool KeyRename(string key, string newKey)
{
key = AddKeyPrefix(key);
return _db.KeyRename(key, newKey);
} /// <summary>
/// 设置 Key 的时间
/// </summary>
/// <param name="key"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public bool KeyExpire(string key, TimeSpan? expiry)
{
key = AddKeyPrefix(key);
return _db.KeyExpire(key, expiry);
} #region key-async /// <summary>
/// 移除指定 Key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<bool> KeyDeleteAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.KeyDeleteAsync(key);
} /// <summary>
/// 移除指定 Key
/// </summary>
/// <param name="keys"></param>
/// <returns></returns>
public async Task<long> KeyDeleteAsync(IEnumerable<string> keys)
{
var redisKeys = keys.Select(x => (RedisKey) AddKeyPrefix(x));
return await _db.KeyDeleteAsync(redisKeys.ToArray());
} /// <summary>
/// 校验 Key 是否存在
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public async Task<bool> KeyExistsAsync(string key)
{
key = AddKeyPrefix(key);
return await _db.KeyExistsAsync(key);
} /// <summary>
/// 重命名 Key
/// </summary>
/// <param name="key"></param>
/// <param name="newKey"></param>
/// <returns></returns>
public async Task<bool> KeyRenameAsync(string key, string newKey)
{
key = AddKeyPrefix(key);
return await _db.KeyRenameAsync(key, newKey);
} /// <summary>
/// 设置 Key 的时间
/// </summary>
/// <param name="key"></param>
/// <param name="expiry"></param>
/// <returns></returns>
public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
{
key = AddKeyPrefix(key);
return await _db.KeyExpireAsync(key, expiry);
} #endregion key-async #endregion key 操作 #region 发布订阅 /// <summary>
/// 订阅
/// </summary>
/// <param name="channel"></param>
/// <param name="handle"></param>
public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
{
var sub = _connMultiplexer.GetSubscriber();
sub.Subscribe(channel, handle);
} /// <summary>
/// 发布
/// </summary>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public long Publish(RedisChannel channel, RedisValue message)
{
var sub = _connMultiplexer.GetSubscriber();
return sub.Publish(channel, message);
} /// <summary>
/// 发布(使用序列化)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public long Publish<T>(RedisChannel channel, T message)
{
var sub = _connMultiplexer.GetSubscriber();
return sub.Publish(channel, Serialize(message));
} #region 发布订阅-async /// <summary>
/// 订阅
/// </summary>
/// <param name="channel"></param>
/// <param name="handle"></param>
public async Task SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handle)
{
var sub = _connMultiplexer.GetSubscriber();
await sub.SubscribeAsync(channel, handle);
} /// <summary>
/// 发布
/// </summary>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public async Task<long> PublishAsync(RedisChannel channel, RedisValue message)
{
var sub = _connMultiplexer.GetSubscriber();
return await sub.PublishAsync(channel, message);
} /// <summary>
/// 发布(使用序列化)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="channel"></param>
/// <param name="message"></param>
/// <returns></returns>
public async Task<long> PublishAsync<T>(RedisChannel channel, T message)
{
var sub = _connMultiplexer.GetSubscriber();
return await sub.PublishAsync(channel, Serialize(message));
} #endregion 发布订阅-async #endregion 发布订阅 #region private method /// <summary>
/// 添加 Key 的前缀
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static string AddKeyPrefix(string key)
{
return $"{DefaultKey}:{key}";
} /// <summary>
/// 转换为字符串
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
private static IEnumerable<string> ConvertStrings<T>(IEnumerable<T> list) where T : struct
{
if (list == null) throw new ArgumentNullException(nameof(list));
return list.Select(x => x.ToString());
} #region 注册事件 /// <summary>
/// 添加注册事件
/// </summary>
private static void AddRegisterEvent()
{
_connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;
_connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;
_connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;
_connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;
_connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;
_connMultiplexer.InternalError += ConnMultiplexer_InternalError;
_connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;
} /// <summary>
/// 重新配置广播时(通常意味着主从同步更改)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");
} /// <summary>
/// 发生内部错误时(主要用于调试)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");
} /// <summary>
/// 更改集群时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e)
{
Console.WriteLine(
$"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");
} /// <summary>
/// 配置更改时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");
} /// <summary>
/// 发生错误时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");
} /// <summary>
/// 物理连接失败时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");
} /// <summary>
/// 建立物理连接时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e)
{
Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");
} #endregion 注册事件 /// <summary>
/// 序列化
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private static byte[] Serialize(object obj)
{
if (obj == null)
return null; var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
var data = memoryStream.ToArray();
return data;
}
} /// <summary>
/// 反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="data"></param>
/// <returns></returns>
private static T Deserialize<T>(byte[] data)
{
if (data == null)
return default(T); var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream(data))
{
var result = (T) binaryFormatter.Deserialize(memoryStream);
return result;
}
} #endregion private method
}
}
RedisHelper.cs
下期将分析 redis 的五大类型,及介绍他们常用的指令。
系列
《Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍》
《Redis 小白指南(二)- 聊聊五大类型:字符串、散列、列表、集合和有序集合》
《Redis 小白指南(三)- 事务、过期、消息通知、管道、优化内存空间》
【博主】反骨仔
【原文】http://www.cnblogs.com/liqingwen/p/6917426.html
【GitHub】https://github.com/liqingwen2015/Wen.Helpers/blob/master/Wen.Helpers.Common/Redis/RedisHelper.cs
【参考】《redis 入门指南》
Redis 小白指南(一)- 简介、安装、GUI 和 C# 驱动介绍的更多相关文章
- Redis 小白指南(二)- 基础命令和五大类型:字符串、散列、列表、集合和有序集合
Redis 小白指南(二)- 基础命令和五大类型:字符串.散列.列表.集合和有序集合 引言 目录 基础命令 字符串类型 散列类型 列表类型 集合类型 有序集合类型 基础命令 1.获得符合规则的键名列表 ...
- Redis 小白指南(三)- 事务、过期、消息通知、管道和优化内存空间
Redis 小白指南(三)- 事务.过期.消息通知.管道和优化内存空间 简介 <Redis 小白指南(一)- 简介.安装.GUI 和 C# 驱动介绍> 讲的是 Redis 的介绍,以及如何 ...
- Redis 小白指南(二)- 聊聊五大类型:字符串、散列、列表、集合和有序集合
Redis 小白指南(二)- 聊聊五大类型:字符串.散列.列表.集合和有序集合 引言 开篇<Redis 小白指南(一)- 简介.安装.GUI 和 C# 驱动介绍>已经介绍了 Redis 的 ...
- Redis 小白指南(四)- 数据的持久化保存(草稿)
Redis 小白指南(四)- 数据的持久化保存 简介 因为 redis 将数据保存在内存中,很容易诱发的一个问题就是,程序崩溃或服务器重启等情况如何保证数据的正常存储. 当我们以 redis 作为主数 ...
- Redis入门指南之一(简介)
1. 简介 Redis是一个开源的.高性能的.基于键值对的缓存与存储系统,通过提供多种键值数据类型来适应不同的场景下的缓存与存储需求.同时Redis的诸多高级功能使其可以胜任消息队列.任务队列等不同的 ...
- Redis入门指南之二(安装及配置)
本节主要内容 1. 前言2. redis安装3. 启动和停止Redis 1. 前言 安装Redis需要知道自己需要哪个版本,有针对性的安装,比如如果需要redis GEO这个地理集合的特性,那么red ...
- redis系列之1----redis简介以及linux上的安装
redis简介 redis是NoSQL(No Only SQL,非关系型数据库)的一种,NoSQL是以Key-Value的形式存储数据.当前主流的分布式缓存技术有redis,memcached,ssd ...
- Redis(一)简介及安装、测试
一.Redis简介: 关于关系型数据库和nosql数据库 关系型数据库是基于关系表的数据库,最终会将数据持久化到磁盘上,而nosql数据 库是基于特殊的结构,并将数据存储到内存的数据库.从性能上而言, ...
- Redis Cluster搭建方法简介22211111
Redis Cluster搭建方法简介 (2013-05-29 17:08:57) 转载▼ Redis Cluster即Redis的分布式版本,将是Redis继支持Lua脚本之后的又一重磅 ...
随机推荐
- JavaScript高级内容:原型链、继承、执行上下文、作用域链、闭包
了解这些问题,我先一步步来看,先从基础说起,然后引出这些概念. 本文只用实例验证结果,并做简要说明,给大家增加些印象,因为单独一项拿出来都需要大篇幅讲解. 1.值类型 & 引用类型 funct ...
- 关于下拉框列表不可选择相同值的设置一:当前DOM不可选
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...
- Windows下JIRA6.3.6安装、汉化、破解
一.MySQL建库和建账号 1. mysql中创建数据库jiradb create database jiradb character set 'UTF8'; 2.创建数据库用户并赋于权限 creat ...
- asp.net core 编译mvc,routing,security源代码进行本地调试
因为各种原因,需要查看asp.net core mvc的源代码来理解运行机制等等,虽说源代码查看已经能很好的理解了.但是能够直接调试还是最直观的.所有就有了本次尝试. 因调试设置源代码调试太辍笔,所以 ...
- 基于jquery 的分页插件,前端实现假分页效果
上次分享了一款jquery插件,现在依旧分享这个插件,不过上一次分享主要是用于regular框件,且每一页数据都是从后端获取过来的,这一次的分享主要是讲一次性获取完数据 然后手动进行分页.此需求基本上 ...
- java复习(7)---集合类、泛型
本节主要结合用例讲述Java中Map类.Set类.List类如何使用. Java中有封装好的集合类,常用的有Map类.Set类.List类,简单说明一下他们的用法. List类,常用有ArrayLis ...
- ob缓存
ob的基本原则:如果ob缓存打开,则echo的数据首先放在ob缓存.如果是header信息,直接放在程序缓存.当页面执行到最后,会把ob缓存的数据放到程序缓存,然后依次返回给浏览器.下面我说说ob的基 ...
- 使用Java语言开发微信公众平台(六)
在上一节课程中,我们来学习了微信公众平台最基础的一个接口--access_token,并且能够从微信公众平台中取到access_token. 那么,在本节课程中,我们要以上节课获取到的access_t ...
- 【openstack N版】——摘除一个计算节点
1.查看计算节点 #查看所有计算节点 [root@open-control01 ~]# nova service-list+----+------------------+-------------- ...
- npm install fetchmatedata慢的解决办法
最近在开发webpack工程时,第一步npm install这里超级慢,一直停着,显示:"fetchMetadata: sill mapToRegistry uri https://regi ...