[
https://issues.apache.org/jira/browse/PHOENIX-4010?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16099296#comment-16099296
]
ASF GitHub Bot commented on PHOENIX-4010:
-----------------------------------------
Github user JamesRTaylor commented on a diff in the pull request:
https://github.com/apache/phoenix/pull/268#discussion_r129185421
--- Diff:
phoenix-core/src/main/java/org/apache/phoenix/cache/ServerCacheClient.java ---
@@ -394,4 +420,82 @@ public static String idToString(byte[] uuid) {
}
return regionStartKey;
}
+
+ public boolean addServerCache(byte[] startkeyOfRegion, ServerCache
cache, HashCacheFactory cacheFactory,
+ byte[] txState, PTable pTable) throws Exception {
+ HTableInterface table = null;
+ byte[] cacheId = cache.getId();
+ try {
+ ConnectionQueryServices services =
connection.getQueryServices();
+ byte[] tableName = pTable.getPhysicalName().getBytes();
+ table = services.getTable(tableName);
+ boolean success = addServerCache(table, startkeyOfRegion,
pTable, cacheId, cache.getCachePtr(), cacheFactory, txState);
+ //track keys so that we can remove the hash table cache from
the new regionservers where the cache was re-sent
+ cache.addKey(startkeyOfRegion);
+ return success;
+ } finally {
+ Closeables.closeQuietly(table);
+ }
+ }
+
+ public boolean addServerCache(HTableInterface htable, byte[] key,
final PTable cacheUsingTable, final byte[] cacheId,
+ final ImmutableBytesWritable cachePtr, final
ServerCacheFactory cacheFactory, final byte[] txState)
+ throws Exception {
+ byte[] keyInRegion = getKeyInRegion(key);
+ final Map<byte[], AddServerCacheResponse> results;
+ try {
+ results =
htable.coprocessorService(ServerCachingService.class, keyInRegion, keyInRegion,
+ new Batch.Call<ServerCachingService,
AddServerCacheResponse>() {
+ @Override
+ public AddServerCacheResponse
call(ServerCachingService instance) throws IOException {
+ ServerRpcController controller = new
ServerRpcController();
+ BlockingRpcCallback<AddServerCacheResponse>
rpcCallback = new BlockingRpcCallback<AddServerCacheResponse>();
+ AddServerCacheRequest.Builder builder =
AddServerCacheRequest.newBuilder();
+ final byte[] tenantIdBytes;
+ if (cacheUsingTable.isMultiTenant()) {
+ try {
+ tenantIdBytes =
connection.getTenantId() == null ? null
+ :
ScanUtil.getTenantIdBytes(cacheUsingTable.getRowKeySchema(),
+
cacheUsingTable.getBucketNum() != null, connection.getTenantId(),
+
cacheUsingTable.getViewIndexId() != null);
+ } catch (SQLException e) {
+ throw new IOException(e);
+ }
+ } else {
+ tenantIdBytes = connection.getTenantId()
== null ? null
+ :
connection.getTenantId().getBytes();
+ }
+ if (tenantIdBytes != null) {
+
builder.setTenantId(ByteStringer.wrap(tenantIdBytes));
+ }
+ builder.setCacheId(ByteStringer.wrap(cacheId));
+
builder.setCachePtr(org.apache.phoenix.protobuf.ProtobufUtil.toProto(cachePtr));
+ builder.setHasProtoBufIndexMaintainer(true);
+
ServerCacheFactoryProtos.ServerCacheFactory.Builder svrCacheFactoryBuider =
ServerCacheFactoryProtos.ServerCacheFactory
+ .newBuilder();
+
svrCacheFactoryBuider.setClassName(cacheFactory.getClass().getName());
+
builder.setCacheFactory(svrCacheFactoryBuider.build());
+ builder.setTxState(ByteStringer.wrap(txState));
+ instance.addServerCache(controller,
builder.build(), rpcCallback);
+ if (controller.getFailedOn() != null) { throw
controller.getFailedOn(); }
+ return rpcCallback.get();
+ }
+ });
+ } catch (Throwable t) {
+ throw new Exception(t);
+ }
+ if (results != null && results.size() == 1) { return
results.values().iterator().next().getReturn(); }
+ return false;
+
+ }
+
+ public static ServerCache getCacheForId(List<ServerCache> caches, Long
cacheId) {
--- End diff --
How about using a Map<ImmutableBytesPtr,ServerCache> instead of a List and
switching id to ImmutableBytesPtr? Then you can get rid of this static method.
> Hash Join cache may not be send to all regionservers when we have stale HBase
> meta cache
> ----------------------------------------------------------------------------------------
>
> Key: PHOENIX-4010
> URL: https://issues.apache.org/jira/browse/PHOENIX-4010
> Project: Phoenix
> Issue Type: Bug
> Reporter: Ankit Singhal
> Assignee: Ankit Singhal
> Fix For: 4.12.0
>
> Attachments: PHOENIX-4010.patch, PHOENIX-4010_v1.patch,
> PHOENIX-4010_v2.patch, PHOENIX-4010_v2_rebased_1.patch,
> PHOENIX-4010_v2_rebased.patch
>
>
> If the region locations changed and our HBase meta cache is not updated then
> we might not be sending hash join cache to all region servers hosting the
> regions.
> ConnectionQueryServicesImpl#getAllTableRegions
> {code}
> boolean reload =false;
> while (true) {
> try {
> // We could surface the package projected
> HConnectionImplementation.getNumberOfCachedRegionLocations
> // to get the sizing info we need, but this would require a
> new class in the same package and a cast
> // to this implementation class, so it's probably not worth
> it.
> List<HRegionLocation> locations = Lists.newArrayList();
> byte[] currentKey = HConstants.EMPTY_START_ROW;
> do {
> HRegionLocation regionLocation =
> connection.getRegionLocation(
> TableName.valueOf(tableName), currentKey, reload);
> locations.add(regionLocation);
> currentKey = regionLocation.getRegionInfo().getEndKey();
> } while (!Bytes.equals(currentKey, HConstants.EMPTY_END_ROW));
> return locations;
> {code}
> Skipping duplicate servers in ServerCacheClient#addServerCache
> {code}
> List<HRegionLocation> locations =
> services.getAllTableRegions(cacheUsingTable.getPhysicalName().getBytes());
> int nRegions = locations.size();
>
> .....
> if ( ! servers.contains(entry) &&
> keyRanges.intersectRegion(regionStartKey,
> regionEndKey,
> cacheUsingTable.getIndexType() ==
> IndexType.LOCAL)) {
> // Call RPC once per server
> servers.add(entry);
> {code}
> For eg:- Table âTâ has two regions R1 and R2 originally hosted on
> regionserver RS1.
> while Phoenix/Hbase connection is still active, R2 is transitioned to RS2 ,
> but stale meta cache will still give old region locations i.e R1 and R2 on
> RS1 and when we start copying hash table, we copy for R1 and skip R2 as they
> are hosted on same regionserver. so, the query on a table will fail as it
> will unable to find hash table cache on RS2 for processing regions R2.
--
This message was sent by Atlassian JIRA
(v6.4.14#64029)