AppFabric缓存独立模式?

发布于 2024-12-01 09:05:21 字数 406 浏览 0 评论 0 原文

作为一名 ISV,我希望能够使用 AppFabric 缓存服务对我的中间层进行编程,然后能够在小型(单服务器)环境中进行部署,而无需部署 AppFabric 缓存服务器。对我来说,“仅内存中”版本的缓存客户端对于独立开发来说是理想的选择,这似乎很自然。

然而,到目前为止我所做的所有研究都意味着我必须加载一个真正的缓存服务器才能使某些 api 正常工作,并且当前的“本地”选项不符合我想要的要求。

在我看来,我正在寻找的功能与 aspx 会话缓存类似,因为开箱即用的机制位于内存中,然后您可以选择配置较旧的外部进程提供程序或 sql 提供程序,现在是 AppFabric 提供商,随着您的升级,可提供越来越好的可扩展性。这对于 aspx 会话非常有效。

我是否正确地认为,在 AppFabric 缓存的“小型”环境中进行编程和部署没有等效的解决方案?

As an ISV I'd like to be able to program my middle tier using the AppFabric Caching Service, but then be able to deploy in small (single server) environments without the need to have AppFabric Cache Server(s) deployed. It also seems natural to me that a "in-memory only" version of the cache client would be ideal for standalone development.

However, all the research I've done so far implies that I have to load a real cache server to make some of the apis work at all, and that the current "Local" option does not fit the bill for what I want.

It seems to me that what I'm looking for would work similarly to aspx session cache, in that the out of the box mechanism is in-memory, and then you can choose to configure the older external process provider, or the sql provider, and now the AppFabric provider, giving better and better scalability as you move up. This works great for aspx session.

Am I correct in thinking that there is no equivalent solution for programming and deploying in a "small" environment for AppFabric caching?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梅倚清风 2024-12-08 09:05:21

这个问题提出了很多问题,让我们看看是否可以解决它们......

首先也是最重要的,如 Frode 正确地指出 您可以在一台服务器上非常愉快地运行 AppFabric 实例 - 这就是我在使用 API 时大部分时间所做的事情。显然,高可用性功能不会可用,但从问题本身来看,我认为您已经接受了这一点。

其次,您不能针对本地缓存使用 AppFabric API - 本地缓存仅用于将 AppFabric 客户端通过线路保存到专用 AppFabric 缓存服务器。

现在,到可配置的缓存,我认为这是最有趣的部分。我认为您想要在这里做的是将缓存上的操作与缓存本身分离到一个通用接口中,然后在设计时针对该接口编写代码,并在运行时根据应用程序中的信息创建缓存.config/web.config。

那么让我们从定义接口开始:

public interface IGenericCache
{
    void Add(string key, object value);
    void Remove(string key);
    Object Get(string key);
    void Update(string key, object value);
}

现在我们可以定义几个实现,一个使用 MemoryCache,一个使用 AppFabric。

using System.Runtime.Caching;

class GenericMemoryCache : IGenericCache
{
    public void Add(string key, object value)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Add(key, value, null, null);
    }

    public void Remove(string key)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Remove(key, null);
    }

    public object Get(string key)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        return cache.Get(key, null);
    }

    public void Update(string key, object value)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Set(key, value, null, null);
    }
}

using Microsoft.ApplicationServer.Caching;

class GenericAppFabricCache : IGenericCache
{
    private DataCacheFactory factory;
    private DataCache cache;

    public GenericAppFabricCache()
    {
        factory = new DataCacheFactory();
        cache = factory.GetCache("GenericAppFabricCache");
    }

    public void Add(string key, object value)
    {
        cache.Add(key, value);
    }

    public void Remove(string key)
    {
        cache.Remove(key);
    }

    public object Get(string key)
    {
        return cache.Get(key);
    }

    public void Update(string key, object value)
    {
        cache.Put(key, value);
    }
}

我们可以继续使用 ASP.NET Cache、NCache、memcached 编写 IGenericCache 实现...

现在我们添加一个工厂类,该工厂类使用反射根据 app.config/web 中的值创建这些缓存之一的实例.config。

class CacheFactory
{
    private static IGenericCache cache;

    public static IGenericCache GetCache()
    {
        if (cache == null)
        {
            // Read the assembly and class names from the config file
            string assemblyName = ConfigurationManager.AppSettings["CacheAssemblyName"];
            string className = ConfigurationManager.AppSettings["CacheClassName"];

            // Load the assembly, and then instantiate the implementation of IGenericCache
            Assembly assembly = Assembly.LoadFrom(assemblyName);
            cache = (IGenericCache) assembly.CreateInstance(className);
        }
        return cache;
    }
}

任何客户端代码需要使用缓存的地方,只需要调用CacheFactory.GetCache,就会返回配置文件中指定的缓存,但客户端不需要知道它是哪个缓存,因为客户端代码都是针对接口编写的。这意味着您只需更改配置文件中的设置即可扩展缓存。

本质上,我们在这里编写的是一个用于缓存的插件模型,但请注意,您正在牺牲灵活性来换取功能。该接口或多或少必须是最低公分母 - 您将失去使用 AppFabric 的并发模型或标记 API 等功能。

这篇文章

There's a number of issues raised in this question, let's see if we can tackle them...

First and foremost, as Frode correctly points out you can run an AppFabric instance quite happily on one server - it's what I do most of the time for playing around with the API. Obviously the High Availability feature isn't going to be, well, available, but from the question itself I think you've already accepted that.

Secondly, you can't use the AppFabric API against the Local cache - the local cache is only there to save an AppFabric client trips across the wire to a dedicated AppFabric cache server.

Now, to configurable caches, which I think is the most interesting part. What I think you want to do here is separate the operations on the cache from the cache itself into a generic interface, and then you write your code against the interface at design time, and at runtime you create a cache based on information from your app.config/web.config.

So let's start by defining our interface:

public interface IGenericCache
{
    void Add(string key, object value);
    void Remove(string key);
    Object Get(string key);
    void Update(string key, object value);
}

And now we can define a couple of implementations, one using the MemoryCache and one using AppFabric.

using System.Runtime.Caching;

class GenericMemoryCache : IGenericCache
{
    public void Add(string key, object value)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Add(key, value, null, null);
    }

    public void Remove(string key)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Remove(key, null);
    }

    public object Get(string key)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        return cache.Get(key, null);
    }

    public void Update(string key, object value)
    {
        MemoryCache cache = new MemoryCache("GenericMemoryCache");

        cache.Set(key, value, null, null);
    }
}

using Microsoft.ApplicationServer.Caching;

class GenericAppFabricCache : IGenericCache
{
    private DataCacheFactory factory;
    private DataCache cache;

    public GenericAppFabricCache()
    {
        factory = new DataCacheFactory();
        cache = factory.GetCache("GenericAppFabricCache");
    }

    public void Add(string key, object value)
    {
        cache.Add(key, value);
    }

    public void Remove(string key)
    {
        cache.Remove(key);
    }

    public object Get(string key)
    {
        return cache.Get(key);
    }

    public void Update(string key, object value)
    {
        cache.Put(key, value);
    }
}

And we could go on and write IGenericCache implementations with the ASP.NET Cache, NCache, memcached...

Now we add a factory class that uses reflection to create an instance of one of these caches based on values from the app.config/web.config.

class CacheFactory
{
    private static IGenericCache cache;

    public static IGenericCache GetCache()
    {
        if (cache == null)
        {
            // Read the assembly and class names from the config file
            string assemblyName = ConfigurationManager.AppSettings["CacheAssemblyName"];
            string className = ConfigurationManager.AppSettings["CacheClassName"];

            // Load the assembly, and then instantiate the implementation of IGenericCache
            Assembly assembly = Assembly.LoadFrom(assemblyName);
            cache = (IGenericCache) assembly.CreateInstance(className);
        }
        return cache;
    }
}

Anywhere the client code needs to use the cache, all that is needed is a call to CacheFactory.GetCache, and the cache specified in the config file will be returned, but the client doesn't need to know which cache it is because the client code is all written against the interface. Which means that you can scale out your caching simply by changing the settings in the config file.

Essentially what we're written here is a plugin model for caching, but be aware that you're trading off flexibility for features. The interface has to be more or less the lowest common denominator - you lose the ability to use, say, AppFabric's concurrency models, or the tagging API.

There's an excellent and more complete discussion of programming against interfaces in this article.

忘羡 2024-12-08 09:05:21

我们有一种设置,仅在一台服务器上运行应用程序结构缓存......

We have one setup where we run app fabric cache on just one server...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文