hbase-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Ted Yu (JIRA)" <j...@apache.org>
Subject [jira] [Updated] (HBASE-8630) Share Socket Connections for different HConnectionImplementations
Date Wed, 29 May 2013 03:54:20 GMT

     [ https://issues.apache.org/jira/browse/HBASE-8630?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Ted Yu updated HBASE-8630:
--------------------------

    Status: Patch Available  (was: Open)
    
> Share Socket Connections for different HConnectionImplementations
> -----------------------------------------------------------------
>
>                 Key: HBASE-8630
>                 URL: https://issues.apache.org/jira/browse/HBASE-8630
>             Project: HBase
>          Issue Type: Improvement
>          Components: Client
>    Affects Versions: 0.94.3
>            Reporter: cuijianwei
>         Attachments: 8630-trunk-v1.txt
>
>
> In org.apache.hadoop.hbase.ipc.HBaseClient.java, socket connections are pooled by map
as:
> {code} protected final PoolMap<ConnectionId, Connection> connections; {code}
> The hashCode of ConnectionId is defined as:
> {code}     public int hashCode() {
>       return (address.hashCode() + PRIME * (
>                   PRIME * System.identityHashCode(protocol) ^
>              (ticket == null ? 0 : ticket.hashCode()) )) ^ rpcTimeout;
>     } {code}
> As we can see, ticket.hashCode() will contribute to hashCode of ConnectionId. For hbase
without authentication, the ticket should be a HadoopUser; while for hbase with authentication,
the ticket should be a SecureHadoopUser. Neither HadoopUser nor SecureHadoopUser override
hashCode() method, therefore, two tickets have the same hashCode only when they refer to the
same object.
>   On the other hand, when we use HTable to access hbase, firstly, we will invoke HBaseRPC.waitForProxy(...)
to create a proxy for region server as follows:
> {code}              server = (HRegionInterface) HBaseRPC.waitForProxy(
>                   serverInterfaceClass, HRegionInterface.VERSION,
>                   address, this.conf,
>                   this.maxRPCAttempts, this.rpcTimeout, this.rpcTimeout); {code}
> Then HBaseRpc.getProxy(...) will be called as follows:
> {code}public static VersionedProtocol getProxy(Class<? extends VersionedProtocol>
protocol,
>       long clientVersion, InetSocketAddress addr, Configuration conf,
>       SocketFactory factory, int rpcTimeout) throws IOException {
>     return getProxy(protocol, clientVersion, addr,
>         User.getCurrent(), conf, factory, rpcTimeout);
>   } {code}
> We can see, User.getCurrent() will be invoked to generate the ticket to build socket
connection. User.getCurrent() is defined as:
> {code}
> public static User getCurrent() throws IOException {
>     User user;
>     if (IS_SECURE_HADOOP) {
>       user = new SecureHadoopUser();
>     } else {
>       user = new HadoopUser();
>     }
>     if (user.getUGI() == null) {
>       return null;
>     }
>     return user;
>   }
> {code}
> Therefore, we will get different tickets when we create different proxies for the same
region server, so that these proxies can't share the created socket connections and will create
new socket connections even if they have the same HBaseConfiguration.
> We can use the following case to validate the description above:
> {code}
> public static void main(String args[]) throws Exception {
>     Configuration conf = HBaseConfiguration.create();
>     for (int i = 0;; ++i) {
>       HTable table = new HTable(conf, TestTable.testTableName);
>       table.close();
>     }
> }
> {code}
> Each time we close the HTable, the created region server proxies will be closed as the
underlying HConnectionImplementation will be closed. However, the created socket connections
won't be closed and wait to be shared in future. Then, when we create HTable in the next turn,
we will create server proxy again, get a new ticket and consequently create new socket connections.
The created socket connections last turn can not be used any more. As the loop goes on, thousands
of socket will be created to connect region servers until we get an exception to show no more
sockets could be created.
> To fix the problem, maybe, we can use ticket.getName().hashCode() instead of ticket.hashCode()?

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Mime
View raw message