STACKEXCHANGE.REDIS Larry Nung
AGENDA Introduction Features Installation Usage Configuration Transaction Scripting Demo Reference Q & A 2
INTRODUCTION 3
INTRODUCTION  High performance general purpose redis client for .NET languages 4
FEATURES 5
FEATURES  High performance multiplexed design, allowing for efficient use of shared connections from multiple calling threads  Abstraction over redis node configuration: the client can silently negotiate multiple redis servers for robustness and availability  Convenient access to the full redis feature-set  Full dual programming model both synchronous and asynchronous usage, without requiring "sync over async" usage of the TPL  Support for redis "cluster" 6
INSTALLATION 7
INSTALLATION  PM> Install-Package StackExchange.Redis  PM> Install-Package StackExchange.Redis.StrongName 8
INSTALLATION 9
USAGE 10
BASIC USAGE using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 11
USING A REDIS DATABASE using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); ... } ... 12
USING REDIS PUB/SUB using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var sub = conn.GetSubscriber(); var channelName = GetChannelName(); var handler = GetChannelHandler(); //conn.PreserveAsyncOrder = false; sub.Subscribe(channelName, handler); ... var message = GetMessage(); sub.Publish(channelName, message); ... } ... 13
ACCESSING INDIVIDUAL SERVERS using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); //var host = GetHost(); //var port = GetPort(); //var server = conn.GetServer(host, port); ... } ... 14
SYNC VS ASYNC VS FIRE-AND-FORGET  Synchronous - where the operation completes before the methods returns to the caller (note that while this may block the caller, it absolutely does not block other threads: the key idea in StackExchange.Redis is that it aggressively shares the connection between concurrent callers).  Asynchronous - where the operation completes some time in the future, and a Task or Task<T> is returned immediately.  Fire-and-Forget - where you really aren't interested in the reply, and are happy to continue irrespective of the response. 15
CONFIGURATION 16
CONFIGURATION using StackExchange.Redis; ... var configuration = new ConfigurationOptions() { EndPoints = { {"localhost", 6379}, {"localhost", 6380} }, Password = "LarryNung" }; using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 17
CONFIGURATION using StackExchange.Redis; ... var configuration = "localhost:6379,localhost:6380,password=LarryNun g"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 18
CONFIGURATION 19
CONFIGURATION 20
TRANSACTION 21
TRANSACTION using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var tran = db.CreateTransaction(); ... var committed = tran.Execute(); } ... 22
SCRIPTING 23
SCRIPTING using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = GetScript(); var keys = GetKeys(); var values = GetValues(); var result = db.ScriptEvaluate(script, keys, values); ... } ... 24
SCRIPTING using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = GetScript(); var preparedScript = LuaScript.Prepare(script); var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); var loadedScript = preparedScript.Load(server); var result = db.ScriptEvaluate(loadedScript, new {Param1 = "LarryNung", Param2= "http://larrynung.github.io"}); ... } ... 25
DEMO 26
STRING TYPE DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.StringSetAsync("Blog:Author", "LarryNung", flags:CommandFlags.FireAndForget); db.StringSetAsync("Blog:Name", "LevelUp", flags: CommandFlags.FireAndForget); db.StringSetAsync("Blog:Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 27
HASH TYPE DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.HashSetAsync("Blog", "Author", "LarryNung", flags:CommandFlags.FireAndForget); db.HashSetAsync("Blog", "Name", "LevelUp", flags: CommandFlags.FireAndForget); db.HashSetAsync("Blog", "Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.HashGet("Blog", "Author", CommandFlags.PreferSlave)); Console.WriteLine(db.HashGet("Blog", "Name", CommandFlags.PreferSlave)); Console.WriteLine(db.HashGet("Blog", "Url", CommandFlags.PreferSlave)); } } } } 28
LIST TYPE DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.ListLeftPushAsync("Data", "LarryNung", flags:CommandFlags.FireAndForget); db.ListLeftPushAsync("Data", "LevelUp", flags: CommandFlags.FireAndForget); db.ListLeftPushAsync("Data", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.ListRightPop("Data")); Array.ForEach(db.ListRange("Data").Reverse().ToArray(), item => Console.WriteLine(item)); } } } } 29
SET TYPE DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.SetAddAsync("Data1", "LarryNung", flags:CommandFlags.FireAndForget); db.SetAddAsync("Data1", "LevelUp", flags: CommandFlags.FireAndForget); db.SetAddAsync("Data2", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); db.SetCombineAndStore(SetOperation.Union, "Data", "Data1", "Data2", flags: CommandFlags.FireAndForget); Array.ForEach(db.SetMembers("Data"), item => Console.WriteLine(item)); } } } } 30
SORTED SET TYPE DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.SortedSetAdd("Data1", "LarryNung", 0, flags: CommandFlags.FireAndForget); db.SortedSetAdd("Data1", "LevelUp", 1, flags: CommandFlags.FireAndForget); db.SortedSetAdd("Data2", "http://larrynung.github.io/", 2, flags: CommandFlags.FireAndForget); db.SortedSetCombineAndStore(SetOperation.Union, "Data", "Data1", "Data2", flags: CommandFlags.FireAndForget); Array.ForEach(db.SortedSetRangeByScore("Data"), item => Console.WriteLine(item)); } } } } 31
SERVER COMMAND DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var endPoints = conn.GetEndPoints(); foreach (var endPoint in endPoints) { var server = conn.GetServer(endPoint); Console.WriteLine("Server: {0}", server.Multiplexer); Console.WriteLine("IsSlave: {0}", server.IsSlave); Console.WriteLine("AllowSlaveWrites: {0}", server.AllowSlaveWrites); Console.WriteLine("ServerType: {0}", server.ServerType); Console.WriteLine("Version: {0}", server.Version); Console.WriteLine("ServerTime: {0}", server.Time()); Console.WriteLine("Latency: {0}", server.Ping()); Console.WriteLine("OperationCount: {0}", server.Multiplexer.OperationCount); Console.WriteLine("Keys: {0}", string.Join(",", server.Keys().ToArray())); Console.WriteLine(new string('=', 78)); } } } } } 32
PUB/SUB DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var sub = conn.GetSubscriber(); var key = "MemberOnLine"; sub.Subscribe(key, (c, v) => { Console.WriteLine("{0} Online...", v); }); sub.PublishAsync(key, "LarryNung", CommandFlags.FireAndForget); } } } } 33
TRANSACTION DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var tran = db.CreateTransaction(); tran.StringSetAsync("Blog:Author", "LarryNung", flags: CommandFlags.FireAndForget); tran.StringSetAsync("Blog:Name", "LevelUp", flags: CommandFlags.FireAndForget); tran.Execute(); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); tran.StringSetAsync("Blog:Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 34
SCRIPTING DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = @“ redis.call('set', KEYS[1], ARGV[1]) redis.call('set', KEYS[2], ARGV[2]) redis.call('set', KEYS[3], ARGV[3])"; var keys = new RedisKey[] {"Blog:Author", "Blog:Name", "Blog:Url"}; var values = new RedisValue[] { "LarryNung", "LevelUp", "http://larrynung.github.io" }; db.ScriptEvaluateAsync(script, keys, values, CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 35
SCRIPTING DEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = @" redis.call('set', @AuthorKey, @AuthorValue) redis.call('set', @NameKey, @NameValue) redis.call('set', @UrlKey, @UrlValue)"; var preparedScript = LuaScript.Prepare(script); var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); var loadedScript = preparedScript.Load(server); db.ScriptEvaluate(loadedScript, new { AuthorKey = "Blog:Author", NameKey = "Blog:Name", UrlKey = "Blog:Url", AuthorValue = "LarryNung", NameValue = "LevelUp", UrlValue = "http://larrynung.github.io" }); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 36
REFERENCE 37
REFERENCE  StackExchange/StackExchange.Redis: General purpose redis client  https://github.com/StackExchange/StackExchange.Redi s 38
Q&A 39
QUESTION & ANSWER 40

StackExchange.redis

  • 1.
  • 2.
  • 3.
  • 4.
    INTRODUCTION  High performancegeneral purpose redis client for .NET languages 4
  • 5.
  • 6.
    FEATURES  High performancemultiplexed design, allowing for efficient use of shared connections from multiple calling threads  Abstraction over redis node configuration: the client can silently negotiate multiple redis servers for robustness and availability  Convenient access to the full redis feature-set  Full dual programming model both synchronous and asynchronous usage, without requiring "sync over async" usage of the TPL  Support for redis "cluster" 6
  • 7.
  • 8.
    INSTALLATION  PM> Install-PackageStackExchange.Redis  PM> Install-Package StackExchange.Redis.StrongName 8
  • 9.
  • 10.
  • 11.
    BASIC USAGE using StackExchange.Redis; ... varconfiguration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 11
  • 12.
    USING A REDISDATABASE using StackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); ... } ... 12
  • 13.
    USING REDIS PUB/SUB usingStackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var sub = conn.GetSubscriber(); var channelName = GetChannelName(); var handler = GetChannelHandler(); //conn.PreserveAsyncOrder = false; sub.Subscribe(channelName, handler); ... var message = GetMessage(); sub.Publish(channelName, message); ... } ... 13
  • 14.
    ACCESSING INDIVIDUAL SERVERS usingStackExchange.Redis; ... var configuration = GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); //var host = GetHost(); //var port = GetPort(); //var server = conn.GetServer(host, port); ... } ... 14
  • 15.
    SYNC VS ASYNCVS FIRE-AND-FORGET  Synchronous - where the operation completes before the methods returns to the caller (note that while this may block the caller, it absolutely does not block other threads: the key idea in StackExchange.Redis is that it aggressively shares the connection between concurrent callers).  Asynchronous - where the operation completes some time in the future, and a Task or Task<T> is returned immediately.  Fire-and-Forget - where you really aren't interested in the reply, and are happy to continue irrespective of the response. 15
  • 16.
  • 17.
    CONFIGURATION using StackExchange.Redis; ... var configuration= new ConfigurationOptions() { EndPoints = { {"localhost", 6379}, {"localhost", 6380} }, Password = "LarryNung" }; using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 17
  • 18.
    CONFIGURATION using StackExchange.Redis; ... var configuration= "localhost:6379,localhost:6380,password=LarryNun g"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { ... } ... 18
  • 19.
  • 20.
  • 21.
  • 22.
    TRANSACTION using StackExchange.Redis; ... var configuration= GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var tran = db.CreateTransaction(); ... var committed = tran.Execute(); } ... 22
  • 23.
  • 24.
    SCRIPTING using StackExchange.Redis; ... var configuration= GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = GetScript(); var keys = GetKeys(); var values = GetValues(); var result = db.ScriptEvaluate(script, keys, values); ... } ... 24
  • 25.
    SCRIPTING using StackExchange.Redis; ... var configuration= GetConfiguration(); using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = GetScript(); var preparedScript = LuaScript.Prepare(script); var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); var loadedScript = preparedScript.Load(server); var result = db.ScriptEvaluate(loadedScript, new {Param1 = "LarryNung", Param2= "http://larrynung.github.io"}); ... } ... 25
  • 26.
  • 27.
    STRING TYPE DEMO usingSystem; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.StringSetAsync("Blog:Author", "LarryNung", flags:CommandFlags.FireAndForget); db.StringSetAsync("Blog:Name", "LevelUp", flags: CommandFlags.FireAndForget); db.StringSetAsync("Blog:Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 27
  • 28.
    HASH TYPE DEMO usingSystem; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.HashSetAsync("Blog", "Author", "LarryNung", flags:CommandFlags.FireAndForget); db.HashSetAsync("Blog", "Name", "LevelUp", flags: CommandFlags.FireAndForget); db.HashSetAsync("Blog", "Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.HashGet("Blog", "Author", CommandFlags.PreferSlave)); Console.WriteLine(db.HashGet("Blog", "Name", CommandFlags.PreferSlave)); Console.WriteLine(db.HashGet("Blog", "Url", CommandFlags.PreferSlave)); } } } } 28
  • 29.
    LIST TYPE DEMO usingSystem; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.ListLeftPushAsync("Data", "LarryNung", flags:CommandFlags.FireAndForget); db.ListLeftPushAsync("Data", "LevelUp", flags: CommandFlags.FireAndForget); db.ListLeftPushAsync("Data", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.ListRightPop("Data")); Array.ForEach(db.ListRange("Data").Reverse().ToArray(), item => Console.WriteLine(item)); } } } } 29
  • 30.
    SET TYPE DEMO usingSystem; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.SetAddAsync("Data1", "LarryNung", flags:CommandFlags.FireAndForget); db.SetAddAsync("Data1", "LevelUp", flags: CommandFlags.FireAndForget); db.SetAddAsync("Data2", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); db.SetCombineAndStore(SetOperation.Union, "Data", "Data1", "Data2", flags: CommandFlags.FireAndForget); Array.ForEach(db.SetMembers("Data"), item => Console.WriteLine(item)); } } } } 30
  • 31.
    SORTED SET TYPEDEMO using System; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); db.SortedSetAdd("Data1", "LarryNung", 0, flags: CommandFlags.FireAndForget); db.SortedSetAdd("Data1", "LevelUp", 1, flags: CommandFlags.FireAndForget); db.SortedSetAdd("Data2", "http://larrynung.github.io/", 2, flags: CommandFlags.FireAndForget); db.SortedSetCombineAndStore(SetOperation.Union, "Data", "Data1", "Data2", flags: CommandFlags.FireAndForget); Array.ForEach(db.SortedSetRangeByScore("Data"), item => Console.WriteLine(item)); } } } } 31
  • 32.
    SERVER COMMAND DEMO usingSystem; using StackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var endPoints = conn.GetEndPoints(); foreach (var endPoint in endPoints) { var server = conn.GetServer(endPoint); Console.WriteLine("Server: {0}", server.Multiplexer); Console.WriteLine("IsSlave: {0}", server.IsSlave); Console.WriteLine("AllowSlaveWrites: {0}", server.AllowSlaveWrites); Console.WriteLine("ServerType: {0}", server.ServerType); Console.WriteLine("Version: {0}", server.Version); Console.WriteLine("ServerTime: {0}", server.Time()); Console.WriteLine("Latency: {0}", server.Ping()); Console.WriteLine("OperationCount: {0}", server.Multiplexer.OperationCount); Console.WriteLine("Keys: {0}", string.Join(",", server.Keys().ToArray())); Console.WriteLine(new string('=', 78)); } } } } } 32
  • 33.
    PUB/SUB DEMO using System; usingStackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var sub = conn.GetSubscriber(); var key = "MemberOnLine"; sub.Subscribe(key, (c, v) => { Console.WriteLine("{0} Online...", v); }); sub.PublishAsync(key, "LarryNung", CommandFlags.FireAndForget); } } } } 33
  • 34.
    TRANSACTION DEMO using System; usingStackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var tran = db.CreateTransaction(); tran.StringSetAsync("Blog:Author", "LarryNung", flags: CommandFlags.FireAndForget); tran.StringSetAsync("Blog:Name", "LevelUp", flags: CommandFlags.FireAndForget); tran.Execute(); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); tran.StringSetAsync("Blog:Url", "http://larrynung.github.io/", flags: CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 34
  • 35.
    SCRIPTING DEMO using System; usingStackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = @“ redis.call('set', KEYS[1], ARGV[1]) redis.call('set', KEYS[2], ARGV[2]) redis.call('set', KEYS[3], ARGV[3])"; var keys = new RedisKey[] {"Blog:Author", "Blog:Name", "Blog:Url"}; var values = new RedisValue[] { "LarryNung", "LevelUp", "http://larrynung.github.io" }; db.ScriptEvaluateAsync(script, keys, values, CommandFlags.FireAndForget); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 35
  • 36.
    SCRIPTING DEMO using System; usingStackExchange.Redis; namespace ConsoleApplication4 { class Program { static void Main(string[] args) { var configuration = "localhost:6379"; using (var conn = ConnectionMultiplexer.Connect(configuration)) { var db = conn.GetDatabase(); var script = @" redis.call('set', @AuthorKey, @AuthorValue) redis.call('set', @NameKey, @NameValue) redis.call('set', @UrlKey, @UrlValue)"; var preparedScript = LuaScript.Prepare(script); var endPoint = conn.GetEndPoints().First(); var server = conn.GetServer(endPoint); var loadedScript = preparedScript.Load(server); db.ScriptEvaluate(loadedScript, new { AuthorKey = "Blog:Author", NameKey = "Blog:Name", UrlKey = "Blog:Url", AuthorValue = "LarryNung", NameValue = "LevelUp", UrlValue = "http://larrynung.github.io" }); Console.WriteLine(db.StringGet("Blog:Author", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Name", CommandFlags.PreferSlave)); Console.WriteLine(db.StringGet("Blog:Url", CommandFlags.PreferSlave)); } } } } 36
  • 37.
  • 38.
    REFERENCE  StackExchange/StackExchange.Redis: General purposeredis client  https://github.com/StackExchange/StackExchange.Redi s 38
  • 39.
  • 40.