Hbase之happybase[TTransportException Broken pipe]分析二

前一篇介紹了使用happybase連接池未關(guān)閉連接引起B(yǎng)roken pipe異常

這篇繼續(xù)分析,當(dāng)每次我們使用完連接后手動close依然會存在一個問題。

通常我們使用連接池會在全局變量中實例話一個pool對象,后續(xù)再通過pool獲取連接進行后續(xù)操作。

當(dāng)我們創(chuàng)建連接池對象后,happybase會根據(jù)size創(chuàng)建多個connection實例到隊列中,同時會將第一個connection連接打開,注釋中提到之所以打開一個連接是為了確保如果出現(xiàn)一些找不到主機之類的錯誤能第一時間發(fā)現(xiàn)。

class ConnectionPool(object):
    def __init__(self, size, **kwargs):
        if not isinstance(size, int):
            raise TypeError("Pool 'size' arg must be an integer")

        if not size > 0:
            raise ValueError("Pool 'size' arg must be greater than zero")

        logger.debug(
            "Initializing connection pool with %d connections", size)

        self._lock = threading.Lock()
        self._queue = queue.LifoQueue(maxsize=size)
        self._thread_connections = threading.local()

        connection_kwargs = kwargs
        connection_kwargs['autoconnect'] = False

        for i in range(size):
            connection = Connection(**connection_kwargs)
            self._queue.put(connection)

        # The first connection is made immediately so that trivial
        # mistakes like unresolvable host names are raised immediately.
        # Subsequent connections are connected lazily.
        with self.connection():
            pass

但是問題就出現(xiàn)在這里,當(dāng)我們初始化一個連接池后如果沒有立即使用,那么第一個連接池中的連接會出現(xiàn)被斷開的情況,那么接下來拿到這個連接去操作都會出現(xiàn)broken pipe異常。

這里只探討對于這個問題可能的解決方法

  1. 外部使用的時候為方法增加異常重試,連接池中出現(xiàn)異常本身會重置連接

2.第一次不打開連接,如#147處理方案
這個解決新家了一個autoconnect的參數(shù),當(dāng)autoconnect為False就不執(zhí)行第一個連接。但是在connection的異常處理中還是會打開一個連接,這樣也會出現(xiàn)同樣的問題,所以這里也應(yīng)該加上。

        try:
            # Open connection, because connections are opened lazily.
            # This is a no-op for connections that are already open.
            connection.open()

            # Return value from the context manager's __enter__()
            yield connection

            connection.close()

        except (TException, socket.error):
            # Refresh the underlying Thrift client if an exception
            # occurred in the Thrift layer, since we don't know whether
            # the connection is still usable.
            logger.info("Replacing tainted pool connection")
            connection._refresh_thrift_client()
            if autoconnect:
                connection.open()

3.和1類似,只是在 happybase中處理網(wǎng)絡(luò)異常重置連接后重試#184

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容