StackExchange.Redis的基本用法

基本用法

StackExchange.Redis中的中心对象是名称空间中的ConnectionMultiplexer类StackExchange.Redis。这是隐藏多个服务器详细信息的对象。由于ConnectionMultiplexer功能很多,因此可以在调用方之间共享和重用它。您不应该创建ConnectionMultiplexer每个操作。它是完全线程安全的,并且可以用于此用途。在所有后续示例中,将假定您已ConnectionMultiplexer保存一个实例以供重用。但是现在,让我们创建一个。这可以使用ConnectionMultiplexer.Connect或ConnectionMultiplexer.ConnectAsync传入配置字符串或ConfigurationOptions对象来完成。配置字符串可以采用逗号分隔的一系列节点的形式,因此让我们仅通过默认端口(6379)连接到本地计算机上的实例:

  •  
  •  
  •  
  •  
using StackExchange.Redis;...ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("localhost");// ^^^ store and re-use this!!!

 

需要注意的是ConnectionMultiplexer工具IDisposable,可以在不再需要处置。这是故意不显示using语句用法的原因,因为ConnectionMultiplexer要重用此对象非常少见,因此您希望简短地使用它。

更复杂的情况可能涉及主/副本设置。对于此用法,只需指定组成该逻辑Redis层的所有所需节点(它将自动识别主节点):

ConnectionMultiplexer redis = ConnectionMultiplexer.Connect("server1:6379,server2:6379");

如果发现两个节点都是主节点,则可以有选择地指定一个决胜键,该键可用于解决问题,但是幸运的是这种情况很少见。

有了之后ConnectionMultiplexer,您可能需要做以下三件事:

  • 访问redis数据库(请注意,在集群的情况下,单个逻辑数据库可能分布在多个节点上)

  • 利用redis的发布/订阅功能

  • 访问单个服务器以进行维护/监视

    使用redis数据库

  • 访问redis数据库非常简单:

  • IDatabase db = redis.GetDatabase();
    
  • 返回的对象GetDatabase是便宜的直通对象,不需要存储。请注意,redis支持多个数据库(尽管“群集”不支持此功能);您可以在调用中指定此选项GetDatabase。此外,如果您打算使用异步API并要求Task.AsyncState具有一个值,则也可以指定以下值:

  • int databaseNumber = ...
    object asyncState = ...
    IDatabase db = redis.GetDatabase(databaseNumber, asyncState);
    
  • 一旦有了IDatabase,只需使用redis API。请注意,所有方法都具有同步和异步实现。按照Microsoft的命名指南,所有异步方法都结束了...Async(...),并且是完全await可用的,等等。

  • 最简单的操作是存储和检索值:

  • string value = "abcdefg";
    db.StringSet("mykey", value);
    ...
    string value = db.StringGet("mykey");
    Console.WriteLine(value); // writes: "abcdefg"
    
  • 请注意,String...此处的前缀表示String redis类型,尽管它们都可以存储文本数据,但它们在很大程度上与.NET String类型分开。但是,redis允许键和值都使用原始二进制数据-用法是相同的:

  • byte[] key = ..., value = ...;
    db.StringSet(key, value);
    ...
    byte[] value = db.StringGet(key);
    
  • 的整个范围内redis的数据库命令涵盖所有redis的数据类型是可供使用。

     

    使用redis发布订阅

  • Redis的另一种常见用法是作为发布/订阅消息分发工具。这也很简单,并且在连接失败的情况下,ConnectionMultiplexer它将处理重新订阅所请求频道的所有细节。

  • ISubscriber sub = redis.GetSubscriber();
    
  • 同样,从中返回的对象GetSubscriber是便宜的直通对象,无需存储。pub / sub API没有数据库的概念,但是像以前一样,我们可以选择提供异步状态。请注意,所有订阅都是全局的:它们的作用域不限于ISubscriber实例的生存期。Redis中的发布/订阅功能使用命名为“ channels”的通道;不需要在服务器上预先定义通道(这里有趣的用法是每用户通知通道之类的东西,它是驱动Stack Overflow实时更新的一部分)。与.NET中常见的一样,订阅采用回调委托的形式,它们接受通道名称和消息:

  • sub.Subscribe("messages", (channel, message) => {
        Console.WriteLine((string)message);
    });
    
  • 注意:此处的异常由StackExchange.Redis捕获和丢弃,以防止级联失败。要处理失败,请在处理程序中使用try/catch来执行您希望的操作(有任何例外情况)。

  • 在v2中,您可以订阅而无需直接向该Subscribe()方法提供回调,而可以使用return ChannelMessageQueue,它表示有序发布/订阅通知的消息队列。这允许使用ChannelMessageQueue.OnMessage()方法,该方法为接收消息时要执行的同步(Action)和异步(Func)处理程序提供重载。

  • // Synchronous handler
    sub.Subscribe("messages").OnMessage(channelMessage => {
        Console.WriteLine((string) channelMessage.Message);
    });
    
    // Asynchronous handler
    sub.Subscribe("messages").OnMessage(async channelMessage => {
        await Task.Delay(1000);
        Console.WriteLine((string) channelMessage.Message);
    });
    
  • 您可以单独(通常是在单独的计算机上的单独过程中)发布到此频道:

  • sub.Publish("messages", "hello");
    
  • 这将(实际上是瞬时地)写入"hello"已订阅进程的控制台。和以前一样,通道名和消息都可以是二进制的。

  • 另请参阅发布/子消息顺序,以获取有关顺序消息和并发消息处理的指南。

     

    访问单个服务器

  • 出于维护目的,有时有必要发出服务器特定的命令:

  • IServer server = redis.GetServer("localhost", 6379);
    
  • GetServer方法将接受EndPoint唯一标识服务器的或名称/值对。和以前一样,从其返回的对象GetServer是便宜的直通对象,不需要存储,并且可以选择指定异步状态。请注意,可用端点集也可用:

  • EndPoint[] endpoints = redis.GetEndPoints();
    
  • IServer实例中,服务器命令可用;例如:

  • DateTime lastSave = server.LastSave();
    ClientInfo[] clients = server.ClientList();
     

    同步和异步

  • StackExchange.Redis有3种主要使用机制:

  • 同步-操作在方法返回调用者之前完成(请注意,尽管这可能会阻止调用者,但它绝对不会阻止其他线程:StackExchange.Redis中的关键思想是它积极共享并发调用者之间的连接)

  • 异步-该操作将在以后的某个时间完成,并且立即返回TaskTask,以后可以:

    • .Wait()ED(阻塞当前线程,直到响应是可用的)

    • ContinueWith在TPL中添加了一个继续回调

    • 期待已久的(这是一个语言级的功能,简化了后者,同时也继续如果立即答复是已知的)

  • 一劳永逸-您对回复真的不感兴趣,无论回复如何,乐于继续

  • 同步用法已在上面的示例中显示。这是最简单的用法,并且不涉及TPL。

  • 对于异步使用,主要区别在于Async方法的后缀,以及(通常)await语言功能的使用。例如:

  • string value = "abcdefg";
    await db.StringSetAsync("mykey", value);
    ...
    string value = await db.StringGetAsync("mykey");
    Console.WriteLine(value); // writes: "abcdefg"
    
  • 即弃即用用法可通过CommandFlags flags所有方法上的可选参数访问(默认为无)。在这种用法中,该方法立即返回默认值(因此,通常返回a的方法String将始终返回null,而通常返回an的方法Int64将始终返回0)。该操作将在后台继续。一个典型的用例是增加页面浏览量:

  • db.StringIncrement(pageKey, flags: CommandFlags.FireAndForget);

你可能感兴趣的:(.NET)