栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Windows Azure中使用Redis实现进程外缓存

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Windows Azure中使用Redis实现进程外缓存

如果你想 单纯 外的过程,那么它是非常简单的-类似于以下,但指出对于BookSleeve被设计为 共享的 :它完全线程安全的,作为一部多路复用器-
你不应该创建/在每次通话时都要处理它们。还要注意,在这种情况下,我假设您将单独处理序列化,因此我只是公开一个

byte[]
API:

class MyCache : IDisposable{    public void Dispose()    {        var tmp = conn;        conn = null;        if (tmp != null)        { tmp.Close(true); tmp.Dispose();        }    }    private RedisConnection conn;    private readonly int db;    public MyCache(string configuration = "127.0.0.1:6379", int db = 0)    {        conn = ConnectionUtils.Connect(configuration);        this.db = db;        if (conn == null) throw new ArgumentException("It was not possible to connect to redis", "configuration");    }    public byte[] Get(string key)    {        return conn.Wait(conn.Strings.Get(db, key));    }    public void Set(string key, byte[] value, int timeoutSeconds = 60)    {        conn.Strings.Set(db, key, value, timeoutSeconds);    }}

什么变得 有趣 ,即使用本地内存-如果你想有一个2级高速缓存是 进程外的高速缓存,因为现在你需要缓存失效。发布/订阅很方便-
下面显示了这一点。可能并不明显,但这将减少对redis的调用(您可以

monitor
用来查看此信息)-因为大多数请求都是从本地缓存中处理的。

using BookSleeve;using System;using System.Runtime.Caching;using System.Text;using System.Threading;class MyCache : IDisposable{    public void Dispose()    {        var tmp0 = conn;        conn = null;        if (tmp0 != null)        { tmp0.Close(true); tmp0.Dispose();        }        var tmp1 = localCache;        localCache = null;        if (tmp1 != null) tmp1.Dispose();        var tmp2 = sub;        sub = null;        if (tmp2 != null)        { tmp2.Close(true); tmp2.Dispose();        }    }    private RedisSubscriberConnection sub;    private RedisConnection conn;    private readonly int db;    private MemoryCache localCache;    private readonly string cacheInvalidationChannel;    public MyCache(string configuration = "127.0.0.1:6379", int db = 0)    {        conn = ConnectionUtils.Connect(configuration);        this.db = db;        localCache = new MemoryCache("local:" + db.ToString());        if (conn == null) throw new ArgumentException("It was not possible to connect to redis", "configuration");        sub = conn.GetOpenSubscriberChannel();        cacheInvalidationChannel = db.ToString() + ":inval"; // note that pub/sub is server-wide; use      // a channel per DB here        sub.Subscribe(cacheInvalidationChannel, Invalidate);       }    private void Invalidate(string channel, byte[] payload)    {        string key = Encoding.UTF8.GetString(payload);        var tmp = localCache;        if (tmp != null) tmp.Remove(key);    }    private static readonly object nix = new object();    public byte[] Get(string key)    {        // try local, noting the "nix" sentinel value        object found = localCache[key];        if (found != null)        { return found == nix ? null : (byte[])found;        }        // fetch and store locally        byte[] blob = conn.Wait(conn.Strings.Get(db, key));        localCache[key] = blob ?? nix;        return blob;    }    public void Set(string key, byte[] value, int timeoutSeconds = 60, bool broadcastInvalidation = true)    {        localCache[key] = value;        conn.Strings.Set(db, key, value, timeoutSeconds);        if (broadcastInvalidation) conn.Publish(cacheInvalidationChannel, key);    }}static class Program{    static void ShowResult(MyCache cache0, MyCache cache1, string key, string caption)    {        Console.WriteLine(caption);        byte[] blob0 = cache0.Get(key), blob1 = cache1.Get(key);        Console.WriteLine("{0} vs {1}", blob0 == null ? "(null)" : Encoding.UTF8.GetString(blob0), blob1 == null ? "(null)" : Encoding.UTF8.GetString(blob1) );    }    public static void Main()    {        MyCache cache0 = new MyCache(), cache1 = new MyCache();        string someRandomKey = "key" + new Random().Next().ToString();        ShowResult(cache0, cache1, someRandomKey, "Initially");        cache0.Set(someRandomKey, Encoding.UTF8.GetBytes("hello"));        Thread.Sleep(10); // the pub/sub is fast, but not *instant*        ShowResult(cache0, cache1, someRandomKey, "Write to 0");        cache1.Set(someRandomKey, Encoding.UTF8.GetBytes("world"));        Thread.Sleep(10); // the pub/sub is fast, but not *instant*        ShowResult(cache0, cache1, someRandomKey, "Write to 1");    }}

请注意,在完整的实现中,您可能希望处理偶尔断开的连接,稍微延迟的重新连接等。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/394481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号