[
https://issues.apache.org/jira/browse/HBASE-8630?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13669142#comment-13669142
]
Anoop Sam John commented on HBASE-8630:
---------------------------------------
bq.Neither HadoopUser nor SecureHadoopUser override hashCode() method,
therefore, two tickets have the same hashCode only when they refer to the same
object.
in 94 code base I can see a hashcode() impl in abstract class User. HadoopUser
and SecureHadoopUser extends User
{code}
public int hashCode() {
return ugi.hashCode();
}
{code}
> 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, 8630-trunk-v2.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