5

Secondaries=1除了在集群配置中设置以启用 HighAvailability之外,还有什么其他的,特别是在缓存客户端配置上?

我们的配置:

通过 about 配置,我们看到在三台主机上创建了主要和次要区域,但是当其中一台主机停止时,会发生以下异常:

  • ErrorCode<ERRCA0018>:SubStatus<ES0001>:The request timed out.
  • An existing connection was forcibly closed by the remote host
  • No connection could be made because the target machine actively refused it 192.22.0.34:22233
  • An existing connection was forcibly closed by the remote host

高可用性的重点不是能够在不中断服务的情况下处理主机宕机吗?我们正在使用命名区域 - 这会破坏高可用性吗?我在某处读到命名区域只能存在于一个主机上(我确实验证了另一个主机上确实存在辅助节点)。我觉得我们缺少一些缓存客户端配置可以启用高可用性,对此问题的任何见解将不胜感激。

4

2 回答 2

4

高可用性是关于保护数据,而不是每秒都可用(因此会出现重试异常)。当缓存主机出现故障时,您会收到异常并且应该重试。在此期间,访问 HA 缓存可能会在它忙于四处移动和创建额外副本时向您抛出重试异常。区域使这更加复杂,因为它导致在再次成为 HA 之前必须复制更大的块。

此外,客户端保持与所有缓存主机的连接,因此当一个主机出现故障时,它会抛出异常发生的事情。

基本上,当一台主机出现故障时,Appfabric 会崩溃,直到 HA 缓存中再次存在所有数据的两个副本。我们在它前面创建了一个小层来处理这个逻辑,并一次删除一个服务器,以确保它处理所有场景,这样我们的应用程序就可以继续工作,但速度有点慢。

于 2012-09-13T01:12:17.493 回答
1

在与 Microsoft 开票后,我们将其范围缩小到拥有一个静态DataCacheFactory对象。

public class AppFabricCacheProvider : ICacheProvider
{
    private static readonly object Locker = new object();
    private static AppFabricCacheProvider _instance;
    private static DataCache _cache;

    private AppFabricCacheProvider()
    {
    }

    public static AppFabricCacheProvider GetInstance()
    {
        lock (Locker)
        {
            if (_instance == null)
            {
                _instance = new AppFabricCacheProvider();
                var factory = new DataCacheFactory();
                _cache = factory.GetCache("AdMatter");
            }
        }
        return _instance;
    }
    ...
}

查看tracelog来自 AppFabric 的 s,客户端仍在尝试连接到所有主机,而不处理主机宕机。在客户端上重置 IIS 会强制DataCacheFactory创建一个新的(在我们的App_Start)并停止异常。

MS 工程师一致认为这种方法是最佳实践方式(我们还发现了几篇关于此的文章:请参阅链接链接

他们正在继续为我们研究解决方案。同时,我们提出了以下临时解决方法,DataCacheFactory在遇到上述异常之一的情况下,我们强制创建一个新对象。

public class AppFabricCacheProvider : ICacheProvider
{
    private const int RefreshWindowMinutes = -5;

    private static readonly object Locker = new object();
    private static AppFabricCacheProvider _instance;
    private static DataCache _cache;
    private static DateTime _lastRefreshDate;

    private AppFabricCacheProvider()
    {
    }

    public static AppFabricCacheProvider GetInstance()
    {
        lock (Locker)
        {
            if (_instance == null)
            {
                _instance = new AppFabricCacheProvider();
                var factory = new DataCacheFactory();
                _cache = factory.GetCache("AdMatter");
                _lastRefreshDate = DateTime.UtcNow;
            }
        }
        return _instance;
    }

    private static void ForceRefresh()
    {
        lock (Locker)
        {
            if (_instance != null && DateTime.UtcNow.AddMinutes(RefreshWindowMinutes) > _lastRefreshDate)
            {
                var factory = new DataCacheFactory();
                _cache = factory.GetCache("AdMatter");
                _lastRefreshDate = DateTime.UtcNow;
            }
        }
    }

    ...

    public T Put<T>(string key, T value)
    {
        try
        {
            _cache.Put(key, value);
        }
        catch (SocketException)
        {
            ForceRefresh();
            _cache.Put(key, value);
        }
        return value;
    }

当我们了解更多信息时将更新此线程。

于 2012-09-20T17:06:10.480 回答