5

Secondaries=1クラスター構成で HighAvailability を有効にするための設定以外に、特にキャッシュ クライアント構成で何かありますか?

私たちの構成:

about 構成では、3 つのホストに作成されたプライマリ リージョンとセカンダリ リージョンが表示されますが、ホストの 1 つが停止すると、次の例外が発生します。

  • 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

高可用性のポイントは、サービスを中断することなくホストのダウンを処理できることではありませんか? 名前付きリージョンを使用しています - これにより高可用性が損なわれますか? 名前付きリージョンは 1 つのホストにしか存在できないことをどこかで読みました (セカンダリが別のホストに存在することを確認しました)。キャッシュ クライアントの構成が高可用性を有効にするために何かが欠けているように感じます。この問題に関する洞察をいただければ幸いです。

4

2 に答える 2

4

高可用性とは、データを毎秒利用できるようにすることではなく、データを保護することです (したがって、再試行の例外が発生します)。キャッシュ ホストがダウンすると、例外が発生し、再試行する必要があります。その間、HA キャッシュにアクセスすると、シャッフルして余分なコピーを作成するのに忙しいため、再試行例外が返される場合があります。リージョンを使用すると、再び HA になる前に大きなチャンクをコピーする必要があるため、これはさらに複雑になります。

また、クライアントはすべてのキャッシュ ホストへの接続を維持するため、いずれかがダウンすると、何かが発生したという例外がスローされます。

基本的に、1 つのホストがダウンすると、Appfabric はすべてのデータの 2 つのコピーが HA キャッシュに再び存在するまでフリークアウトします。このロジックを処理するためにその前に小さなレイヤーを作成し、サーバーを一度に 1 つずつ削除して、すべてのシナリオを確実に処理できるようにしました。

于 2012-09-13T01:12:17.493 に答える
1

DataCacheFactoryMicrosoft でチケットを開いた後、静的オブジェクトを持つことに絞り込みました。

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;
    }
    ...
}

AppFabric からの s を見るとtracelog、クライアントはホストのダウンを処理せずにすべてのホストに接続しようとしています。クライアントで 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 に答える