복붙노트

[REDIS] BookSleeve를 사용하여 오픈 레디 스 연결을 유지

REDIS

BookSleeve를 사용하여 오픈 레디 스 연결을 유지

사람이 BookSleeve 라이브러리를 통해 레디 스를 가져 오는 솔리드 패턴이 있습니까?

내말은:

BookSleeve의 저자 @MarcGravell는 열 및 연결마다 시간을 닫습니다 아니라 응용 프로그램 전반에 걸쳐 하나의 연결을 유지하지 않는 것이 좋습니다. 그러나 당신은 어떻게 네트워크 중단을 처리 할 수 ​​있습니까? 즉, 연결이 처음에 성공적으로 오픈 될 수 있지만, 일부 코드 / 레디 스에 쓰기 읽기를 시도 할 때, 연결이 떨어졌다 가능성이있다 당신은 그것을 다시 (그리고 만약이 열리지 않습니다 우아하게 실패한다 -하지만 즉, 귀하의 설계 요구에 달려있다.)

나는 일반 레디 스 연결 개방을 커버 코드 (들)을 추구하고, 각 읽기 / 쓰기 전에 사용되는 일반적인 '살아있는'체크 (+ 옵션 깨어 살아 있지 않은 경우).

이 질문은 문제에 대한 좋은 태도를 제안하지만 (이것은 예를 들어, 잃어버린 연결을 복구하지 않습니다) 부분적으로 만, 그리고 그 질문에 대한 허용 대답은 올바른 방법을 그립니다하지만 구체적인 코드를 보여주지 않습니다.

나는이 스레드가 고체 답변을 얻을 결국 .NET 응용 프로그램에서 BookSleeve 사용에 관해서 위키의 일종 될 것입니다 바랍니다.

-----------------------------

중요 업데이트 (21/3/2014) :

-----------------------------

마크 Gravell (@MarcGravell) / 스택 Exchange는 최근 궁극적으로 Booksleeve를 대체 StackExchange.Redis 라이브러리를 발표했다. 이 새로운 라이브러리는 특히, 내부적으로 재 연결을 처리하고 내 질문의 중복을 렌더링 (즉,이 Booksleeve도 아래에있는 내 대답을 중복 아니에요,하지만 가장 좋은 방법은 앞으로 새로운 StackExchange.Redis 라이브러리를 사용하기 시작하는 것 같다).

해결법

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

    1.내가 어떤 좋은 답변을 가지고하지 않았으므로,이 솔루션을 함께했다 (귀하의 답변 BTW 덕분에 @ 사이먼과 @ 알렉스!).

    내가 어떤 좋은 답변을 가지고하지 않았으므로,이 솔루션을 함께했다 (귀하의 답변 BTW 덕분에 @ 사이먼과 @ 알렉스!).

    나는 참고로 지역 사회 모두와 함께 공유하고자합니다. 물론, 어떤 수정은 높게 평가 될 것입니다.

    using System;
    using System.Net.Sockets;
    using BookSleeve;
    
    namespace Redis
    {
        public sealed class RedisConnectionGateway
        {
            private const string RedisConnectionFailed = "Redis connection failed.";
            private RedisConnection _connection;
            private static volatile RedisConnectionGateway _instance;
    
            private static object syncLock = new object();
            private static object syncConnectionLock = new object();
    
            public static RedisConnectionGateway Current
            {
                get
                {
                    if (_instance == null)
                    {
                        lock (syncLock)
                        {
                            if (_instance == null)
                            {
                                _instance = new RedisConnectionGateway();
                            }
                        }
                    }
    
                    return _instance;
                }
            }
    
            private RedisConnectionGateway()
            {
                _connection = getNewConnection();
            }
    
            private static RedisConnection getNewConnection()
            {
                return new RedisConnection("127.0.0.1" /* change with config value of course */, syncTimeout: 5000, ioTimeout: 5000);
            }
    
            public RedisConnection GetConnection()
            {
                lock (syncConnectionLock)
                {
                    if (_connection == null)
                        _connection = getNewConnection();
    
                    if (_connection.State == RedisConnectionBase.ConnectionState.Opening)
                        return _connection;
    
                    if (_connection.State == RedisConnectionBase.ConnectionState.Closing || _connection.State == RedisConnectionBase.ConnectionState.Closed)
                    {
                        try
                        {
                            _connection = getNewConnection();
                        }
                        catch (Exception ex)
                        {
                            throw new Exception(RedisConnectionFailed, ex);
                        }
                    }
    
                    if (_connection.State == RedisConnectionBase.ConnectionState.Shiny)
                    {
                        try
                        {
                            var openAsync = _connection.Open();
                            _connection.Wait(openAsync);
                        }
                        catch (SocketException ex)
                        {
                            throw new Exception(RedisConnectionFailed, ex);
                        }
                    }
    
                    return _connection;
                }
            }
        }
    }
    
  2. ==============================

    2.다른 시스템 (예 ADO.NET 등), 이것은 연결 풀을 사용하여 달성된다. 당신은 정말 새로운 연결 개체를 얻을 있지만, 사실 풀에서 하나를 얻을 않았다.

    다른 시스템 (예 ADO.NET 등), 이것은 연결 풀을 사용하여 달성된다. 당신은 정말 새로운 연결 개체를 얻을 있지만, 사실 풀에서 하나를 얻을 않았다.

    풀 자체는 발신자의 코드에서 독립적으로, 새로운 연결, 죽은 연결을 관리합니다. 여기에 아이디어는 네트워크 문제를 (발신자 코드는 서버가 다운되는 동안 실패하지만, 온라인으로 돌아 오면 다시 시작됩니다) 더 나은 성능 (새 연결이 costy입니다 설립)가, 생존하는 것입니다. 연결의 "유형"당 응용 프로그램 도메인 당 사실 하나의 풀에 있습니다.

    이 동작 증발하는 당신은 ADO.NET 연결 문자열을 볼 때. 예를 들어 SQL Server 연결 문자열 (ConnectionString을 속성)이 또한 필요한 경우 현재 응용 프로그램 도메인 풀을 다시 programmaticaly에 사용되는 ClearAllPools 방법이다 등, '최대 풀 크기', '최소 풀 크기', '풀링'의 개념을 가지고 예를 들어.

    나는 BookSleeve 코드로보고 기능의이 종류에 아무것도 가까이 표시되지 않습니다,하지만 다음 릴리스 계획 것으로 보인다 : BookSleeve 있도록 로드맵을 제공하여드립니다.

    그 동안, 나는 RedisConnection는 당신이 죽은 때를 감지하기 위해,이 사용할 수있는 오류 이벤트를 가지고 당신이 당신의 자신의 연결 풀을 작성할 수 있습니다 가정합니다.

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

    3.나는 C #을 프로그래머가 아니지만, 내가 문제를보고 싶은데 방법은 다음과 같다 :

    나는 C #을 프로그래머가 아니지만, 내가 문제를보고 싶은데 방법은 다음과 같다 :

    여기에 의사 코드의 일종이다 :

    function execute(redis_con, lambda_func) {
        try {
            return lambda_func(redis_con)
        }
        catch(connection_exception) {
            redis_con = reconnect()
            return  lambda_func(redis_con)
        }
    }
    
  4. from https://stackoverflow.com/questions/8645953/maintaining-an-open-redis-connection-using-booksleeve by cc-by-sa and MIT license