복붙노트

[REDIS] 푸른 레디 스에 StackExchange.Redis는 unusably 느리거나 시간 초과 오류가 발생합니다

REDIS

푸른 레디 스에 StackExchange.Redis는 unusably 느리거나 시간 초과 오류가 발생합니다

나는 레디 스에 기존 하늘빛에서-역할 캐시 사용을 모두 이동 (https://github.com/StackExchange/StackExchange.Redis)을 StackExchange.Redis 라이브러리와 함께 푸른 레디 스 미리보기를 사용하기로 결정하고 있습니다. 나는 많은 문제없이 모든 코드를 작성하지만, 그것을 실행하는 것은 절대적으로 unusably 느린 지속적으로 오류 시간 초과가 발생하는 경우 (내 타임 아웃 시간을 15 초로 설정되어 있습니다).

여기에 내가 어떻게 레디 스 연결을 설정하고 간단한 작업을 위해 그것을 사용하고 있습니다에 대한 관련 코드는 다음과 같습니다

    private static ConnectionMultiplexer _cacheService;
    private static IDatabase _database;
    private static object _lock = new object();

    private void Initialize()
    {
        if (_cacheService == null)
        {
            lock (_lock)
            {
                if (_cacheService == null)
                {
                    var options = new ConfigurationOptions();
                    options.EndPoints.Add("{my url}", 6380);
                    options.Ssl = true;
                    options.Password = "my password";
                    // needed for FLUSHDB command
                    options.AllowAdmin = true;

                    // necessary?
                    options.KeepAlive = 30;
                    options.ConnectTimeout = 15000;
                    options.SyncTimeout = 15000;

                    int database = 0;

                    _cacheService = ConnectionMultiplexer.Connect(options);
                    _database = _cacheService.GetDatabase(database);
                }
            }
        }

    }

    public void Set(string key, object data, TimeSpan? expiry = null)
    {
        if (_database != null)
        {
            _database.Set(key, data, expiry: expiry);
        }
    }

    public object Get(string key)
    {
        if (_database != null)
        {
            return _database.Get(key);
        }
        return null;
    }

가져 오기 및 설정 같은 매우 간단한 명령 종종 시간 초과 또는 완료 5 ~ 10 초 정도 걸릴 수행. 을 Negate의 종류 그 같은 캐시로 사용의 전체 목적을 보인다면 그것의 WAY 느린 실제로 내 데이터베이스에서 실제 데이터를 가져 오는 것보다 :)

나는 분명히 잘못된 아무것도 건가요?

편집 : 여기 아무것도에 대한 몇 가지 실마리 경우 (레디 스 데스크톱 관리자를 사용하여) 서버에서 가져온 몇 가지 통계가 있습니다.

Server
redis_version:2.8.12
redis_mode:standalone
os:Windows  
arch_bits:64
multiplexing_api:winsock_IOCP
gcc_version:0.0.0
process_id:2876

tcp_port:6379
uptime_in_seconds:109909
uptime_in_days:1
hz:10
lru_clock:16072421
config_file:C:\Resources\directory\xxxx.Kernel.localStore\1\redis_2092_port6379.conf

Clients
connected_clients:5
client_longest_output_list:0
client_biggest_input_buf:0
client_total_writes_outstanding:0
client_total_sent_bytes_outstanding:0
blocked_clients:0

Memory
used_memory:4256488
used_memory_human:4.06M
used_memory_rss:67108864
used_memory_rss_human:64.00M
used_memory_peak:5469760
used_memory_peak_human:5.22M
used_memory_lua:33792
mem_fragmentation_ratio:15.77
mem_allocator:dlmalloc-2.8

Persistence
loading:0
rdb_changes_since_last_save:72465
rdb_bgsave_in_progress:0
rdb_last_save_time:1408471440
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:-1
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok

Stats
total_connections_received:25266
total_commands_processed:123389
instantaneous_ops_per_sec:10
bytes_received_per_sec:275
bytes_sent_per_sec:65
bytes_received_per_sec_human:

편집 2 : 여기 오기 위해 사용하고 확장 방법 / 설정 - 그들은 단지 JSON으로 객체를 돌려 StringSet를 호출 매우 간단한 방법이다가.

    public static object Get(this IDatabase cache, string key)
    {
        return DeserializeJson<object>(cache.StringGet(key));
    }

    public static void Set(this IDatabase cache, string key, object value, TimeSpan? expiry = null)
    {
        cache.StringSet(key, SerializeJson(value), expiry: expiry);
    }

3 편집 : 여기에 몇 가지 예제 오류 메시지는 다음과 같습니다

    A first chance exception of type 'System.TimeoutException' occurred in StackExchange.Redis.dll
    Timeout performing GET MyCachedList, inst: 11, queue: 1, qu=1, qs=0, qc=0, wr=0/1, in=0/0

    A first chance exception of type 'System.TimeoutException' occurred in StackExchange.Redis.dll
    Timeout performing GET MyCachedList, inst: 1, queue: 97, qu=0, qs=97, qc=0, wr=0/0, in=3568/0

해결법

  1. ==============================

    1.여기에 푸른 레디 스 캐시 문서에서 권장되는 패턴입니다 :

    여기에 푸른 레디 스 캐시 문서에서 권장되는 패턴입니다 :

    private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() => {
        return ConnectionMultiplexer.Connect("mycache.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
    });
    
    public static ConnectionMultiplexer Connection {
        get {
            return lazyConnection.Value;
        }
    }
    

    몇 가지 중요한 포인트 :

  2. ==============================

    2.나는 비슷한 문제가 있었다. 레디 스 캐시는 비정상적으로 느린했지만 확실히 캐싱했다. 경우에 따라서는 페이지를로드 20-40 초 걸렸습니다.

    나는 비슷한 문제가 있었다. 레디 스 캐시는 비정상적으로 느린했지만 확실히 캐싱했다. 경우에 따라서는 페이지를로드 20-40 초 걸렸습니다.

    나는 캐시 서버가 사이트가 아닌 다른 위치에있는 것을 깨달았다. 나는 웹 사이트와 같은 위치에 살 수있는 캐시 서버를 업데이트 이제 모든 것이 예상대로 작동합니다.

    4-6초에서 그 같은 페이지는 이제로드됩니다.

    이러한 문제를 보내고 다른 사람에게 행운을 빕니다.

  3. ==============================

    3.문제는 연결 개체를 만들고 사용하는 방법이다. 우리는 처음에 정확한 문제를 직면하고 단일 연결 개체가 모든 웹 요청을 통해 익숙해 고정. 그리고 우리는 확인이 null 또는 우아한 재 객체를 생성하기위한 세션 시작에 연결되어 있습니다. 즉, 문제를 해결.

    문제는 연결 개체를 만들고 사용하는 방법이다. 우리는 처음에 정확한 문제를 직면하고 단일 연결 개체가 모든 웹 요청을 통해 익숙해 고정. 그리고 우리는 확인이 null 또는 우아한 재 객체를 생성하기위한 세션 시작에 연결되어 있습니다. 즉, 문제를 해결.

    Global.asax.cs 파일에서

    public static ConnectionMultiplexer RedisConnection;
    public static IDatabase RedisCacheDb;
    
    protected void Session_Start(object sender, EventArgs e)
        {
            if (ConfigurationManager.ConnectionStrings["RedisCache"] != null)
            {
                if (RedisConnection == null || !RedisConnection.IsConnected)
                {
                    RedisConnection = ConnectionMultiplexer.Connect(ConfigurationManager.ConnectionStrings["RedisCache"].ConnectionString);
                }
                RedisCacheDb = RedisConnection.GetDatabase();
            }
        }
    
  4. ==============================

    4.SSL 연결을 사용하는 경우 우리의 경우 문제입니다. 당신은 당신의 바탕 화면 관리자가 비 SSL 포트에서 실행되고 있는지 보여주는하고 있지만 코드는 SSL을 사용하고 있습니다.

    SSL 연결을 사용하는 경우 우리의 경우 문제입니다. 당신은 당신의 바탕 화면 관리자가 비 SSL 포트에서 실행되고 있는지 보여주는하고 있지만 코드는 SSL을 사용하고 있습니다.

    우리의 푸른에 대한 빠른 벤치 마크는 기본적으로 instand입니다 (또한 .NET 및 StackExchange.Redis 포함) LRANGE 명령 주위 80K 값을 검색, SSL없이 레디 스. SSL을 사용하는 경우, 동일한 쿼리 27 초 정도 걸립니다.

    웹 애플리케이션 : 표준 S2

    레디 스 : 표준 1기가바이트

    편집 : SLOWLOG 확인은, 레디 스 자체는 실제로 걸리는 정도 행을 잡아 그것의 14ms의 시간 slowlog을 칠 것 같다, 그러나 이것은 지금까지 SSL로 실제 전송으로부터 사용 가능. 우리는 레디 스 및 웹 애플리케이션 사이의 보안의 일종을 가지고 프리미엄 레디 스 함께했다.

  5. ==============================

    5.그것은 내 경우했다. SyncTimeout을 증가하는 것을 잊지 마십시오. 기본값은 1 초입니다.

    그것은 내 경우했다. SyncTimeout을 증가하는 것을 잊지 마십시오. 기본값은 1 초입니다.

    private static Lazy<ConnectionMultiplexer> ConnectionMultiplexerItem = new Lazy<ConnectionMultiplexer>(() =>
    {
        var redisConfig = ConfigurationOptions.Parse("mycache.redis.cache.windows.net,abortConnect=false,ssl=true,password=...");
    
        redisConfig.SyncTimeout = 3000;
    
        return ConnectionMultiplexer.Connect(redisConfig);
    });
    

    확인 당신의 푸른 레디 스 캐시와 푸른에서 같은 지역에서 클라이언트 사용자의 경우. 캐시 이스트 미국에 있지만 클라이언트가 서 미국에 있고 요청이 synctimeout 시간에 완료되지 않거나 로컬 개발 machinex에서 디버깅 할 때 시간 제한을 받고 수 있습니다 예를 들어, 당신은 시간 제한을 받고있을 수 있습니다. 매우 같은 푸른 지역의 캐시와 클라이언트를하는 것이 좋습니다. 당신이 교차 지역 통화를 할 수있는 시나리오가 있다면, 당신은 더 높은 값으로 synctimeout을 설정할 것입니다.

    더 읽기 : https://azure.microsoft.com/en-us/blog/investigating-timeout-exceptions-in-stackexchange-redis-for-azure-redis-cache/

  6. from https://stackoverflow.com/questions/25416562/stackexchange-redis-with-azure-redis-is-unusably-slow-or-throws-timeout-errors by cc-by-sa and MIT license