zoukankan      html  css  js  c++  java
  • 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类库错误
  • 相关阅读:
    哪怕我变成一个庸俗女子
    硬盘接口的种类
    HTTPS与SHTTP
    Jquery动态加载页面
    iText简介
    TFS offline issue
    VS2008 调试慢的问题
    One error related to msxml4.dll (0x800C0014)
    46 Run Commands for Frequently Used Areas of Your Windows Computer
    快速启动工具入门——以Launchy为例(二)
  • 原文地址:https://www.cnblogs.com/zxtceq/p/7344154.html
Copyright © 2011-2022 走看看