如何在有状态服务中缓存数据?

时间:2017-11-01 03:45:13

标签: c# .net visual-studio-2017 azure-service-fabric

群集需要访问位于群集外部的sql server中的数据集。

我想创建一个有状态的服务,它会定期使用来自远程数据库的数据刷新其缓存,而不是强制对每个请求远程调用数据库。

我们会看下面这样的事情吗?

    internal sealed class StatefulBackendService : StatefulService
{
    public StatefulBackendService(StatefulServiceContext context)
        : base(context)
    {
    }

    /// <summary>
    /// Optional override to create listeners (like tcp, http) for this service instance.
    /// </summary>
    /// <returns>The collection of listeners.</returns>
    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        return new ServiceReplicaListener[]
        {
            new ServiceReplicaListener(
                serviceContext =>
                    new KestrelCommunicationListener(
                        serviceContext,
                        (url, listener) =>
                        {
                            ServiceEventSource.Current.ServiceMessage(serviceContext, $"Starting Kestrel on {url}");

                            return new WebHostBuilder()
                                .UseKestrel()
                                .ConfigureServices(
                                    services => services
                                        .AddSingleton<IReliableStateManager>(this.StateManager)
                                        .AddSingleton<StatefulServiceContext>(serviceContext))
                                .UseContentRoot(Directory.GetCurrentDirectory())
                                .UseServiceFabricIntegration(listener, ServiceFabricIntegrationOptions.UseUniqueServiceUrl)
                                .UseStartup<Startup>()
                                .UseUrls(url)
                                .Build();
                        }))
        };
    }
}

在此有状态服务中,如何从远程数据库加载数据并通过控制器提供服务?

我们假设我们有一个简单的模型:

Create table Account (varchar name, int key)

我想这些操作将按以下顺序进行:

  1. 将帐户表加载到内存
  2. 回复http://statefulservice/account?$ top = 10
  3. 等请求
  4. 以时间间隔刷新服务中的数据
  5. 为了缓存这些数据,我应该使用哪些数据类型?将数据从sql server数据库加载到有状态服务的过程是什么?

2 个答案:

答案 0 :(得分:3)

恕我直言,即使可以将Statefull服务用作某些数据库备份的缓存,只有将数据保存在可靠的集合中才能实现真正的强大功能。使用Service Fabric和Reliable Collections,您可以直接在服务中存储数据,而无需外部持久存储。见Application scenarios。除了提供高可用性和低延迟之外,状态可以在多个节点上可靠地复制,因此它可以在节点故障中存活,而且,还有Back up and restore功能,可以让您处理整个群集中断。

在处理可靠服务时,您应该了解许多事项。 Service partiotioningTransactions and lock modesGuidelines and recommendations

对于数据类型,请探索Reliable Collection object serializationSerialization and Upgrade

您还应该注意的另一件事是,Reliable Dictionary定期从内存中删除最近最少使用的值,这可能会增加某些情况下的读取延迟。点击此处 - Service fabric reliable dictionary linq query very slow

集成控制器和StateManager的简单示例,您可以找到in this article

答案 1 :(得分:1)

升--''''''--------- '' '' '' '' '' ''
以下是与您的评论相关的更多信息...... 嘿m8 ......可靠的集合被设计为运行多个实例(一次在多个节点上运行)...在每个实例中,数据被分区为一个或多个组(你如何决定分区完全是对你来说)...所以有负载分配和故障转移,还有更多要说...但我不想让水混乱,所以我试图保持高水平。可靠集合中的这种类型的服务数据存在于内存中并且可以“备份”...如果您希望将数据正式写入光盘并且可以更好地控制何时将其写入光盘,则需要查看Actors 。这是一个很好的(非常简单的)服务结构,可靠集合和内部通信连接示例的集合。只考虑看这个问题的时候,有很多不同的“食谱”用于促进从后端到公共(无状态)方面的后端和通信。

我看到你添加了你的问题并稍微改变了意图......我会有针对性地告诉你我认为你需要什么,你真正想要的......你想要一个或多个'有状态服务'(这个是您的数据服务层,如果您需要,可以将其抽象为3个组件......有状态服务本身,2个类库,一个用于服务接口,一个用于合同......或者更确切地说是数据模型...基本上这是一个POCO),您将在您的有状态服务中包含2个类库并使用它们来创建字典条目(可能类似于新的IReliableDictionary ...并绑定接口。您将要使用(添加到)IService接口(您需要为您为服务界面创建的界面项目获取一个nuget包'Service Fabric Remoting',有很多关于如何在服务结构中实现远程处理的信息,因为它是一种标准的通信方法。更多,但只是建立这个是一个可行的实验,并将有效地取代或数据库。您可以使用Actors或使用服务结构封装的简单备份方法将数据正式保存到光盘。基本上我建议你构建这个以便确定你可以从这个场景中完全删除数据库的事实......你真的不需要它。我上面所描述的仅取代了db ...而没有为此编写前端(使用远程处理与后端通信),这对公众来说是不可访问的......至少不容易。登记/> TL; DR - 基本上我同意你的其他贡献者所说的话......我的观点不那么谦虚,所以我会简单说明一下。如果您在服务结构中处理数据,您的应用程序将不那么复杂,更快速,更可靠...仍然TL; DR? - 抛弃db我的男人。如果你真的很担心它只存在于内存中,请使用Actors