Will Berkeley created KUDU-2710: ----------------------------------- Summary: Retries of scanner keep alive requests are broken in the Java client Key: KUDU-2710 URL: https://issues.apache.org/jira/browse/KUDU-2710 Project: Kudu Issue Type: Bug Affects Versions: 1.9.0 Reporter: Will Berkeley Assignee: Will Berkeley
KuduRpc implements a default `partitionKey` method: {noformat} /** * Returns the partition key this RPC is for, or {@code null} if the RPC is * not tablet specific. * <p> * <strong>DO NOT MODIFY THE CONTENTS OF THE RETURNED ARRAY.</strong> */ byte[] partitionKey() { return null; } {noformat} Subclasses override this method to indicate the start key of the tablet they should be sent to, and the Java client uses this, in part, to select which tserver to send retries to. The default implementation returns {{null}}, which is a special value that is only valid as a partition key for the master table. The keep alive RPC does not override this method, so it uses the default implementation. When {{KuduScanner#keepAlive}} is called, the initial keep alive RPC does not use {{partitionKey}}, so it works OK. However, retries go through standard retry logic, which calls {{delayedSendRpcToTablet}}, which calls {{sendRpcToTablet}} after a delay and on a timer thread. In {{sendRpcToTablet}} we call {{getTableLocationEntry}} with a null {{partitionkey}}, because the RPC never set one. That results in {{cache.get(partitionKey)}} throwing an exception (usually) because there are multiple entries in the cache for the table, but the {{null}} partition key makes the lookup act like it is looking up the master table, so the invariant check for the master table {{Preconditions.checkState(entries.size() <= 1)}} fails. As a workaround, users can set {{keepAlivePeriodMs}} on {{KuduReadOptions}} to something very large like {{Long.MAX_VALUE}}; or, if using the default source, pass the {{kudu.keepAlivePeriodMs}} spark config with a very large value. Note that there also has to be something causing keep alive requests to fail and retry, and this is relatively rare (in my experience). To fix, we'll need to make sure that keep alive RPCs act like scan RPCs, and are always retried on the same server as the one currently open for scanning (or no op if there is no such server). Also, it's not wise to keep the default implementation in KuduRpc-- subclasses ought to have to make an explicit choice about the default partition key, which is a proxy for which tablet they will go to. -- This message was sent by Atlassian JIRA (v7.6.3#76005)