Я пытаюсь получить более 1 миллиона сущностей в хранилище данных за один запрос, но с помощью пакетирования, чтобы избежать тайм-аута хранилища данных.
Вот мой код.
public List<T> listByLimitation(Query query, Integer limit)
throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, Exception {
Integer chunkSize = 100;
Integer prefetchedSize = 100;
if(limit >= 1000 && limit <= 5000)
{
chunkSize = 1000;
prefetchedSize = 1000;
}
else if(limit >= 5001 && limit <= 10000)
{
chunkSize = 3000;
prefetchedSize = 2000;
}
else if(limit >= 10001 && limit < 100000 )
{
chunkSize = 5000;
prefetchedSize = 3000;
}
else
{
chunkSize = 7000;
prefetchedSize = 5000;
}
List<T> models = Lists.newArrayListWithExpectedSize(200000);
QueryResultList<Entity> queryResultList = datastore.prepare(query).asQueryResultList(FetchOptions.Builder.withLimit(limit).chunkSize(chunkSize).prefetchSize(prefetchedSize));
Iterator<Entity> iterator = datastore.prepare(query).asIterator(FetchOptions.Builder.withLimit(limit).chunkSize(chunkSize).prefetchSize(prefetchedSize));
while(true)
{
while (iterator.hasNext())
{
Constructor<T> constructor = cls.getConstructor(Entity.class);
T model = constructor.newInstance(iterator.next());
models.add(model);
}
this.logger.log(Level.SEVERE,"EntityModelSize:" + models.size()); //just for checking
Cursor cursor = queryResultList.getCursor();
queryResultList = datastore.prepare(query).asQueryResultList(FetchOptions.Builder.withLimit(limit).startCursor(cursor).chunkSize(chunkSize).prefetchSize(prefetchedSize));
iterator = datastore.prepare(query).asIterator(FetchOptions.Builder.withLimit(limit).startCursor(cursor).chunkSize(chunkSize).prefetchSize(prefetchedSize));
if(queryResultList.isEmpty())
{
break;
}
}
return models;
}
и он возвращаетошибка.
java.lang.OutOfMemoryError: превышен лимит накладных расходов GC в свойстве com.google.storage.onestore.v3.OnestoreEntity $. (OnestoreEntity.java:4356) в com.google.storage.onestore.v3.OnestoreEntity $ EntityProto.addRawProperty (OnestoreEntity.java:9834) в com.google.storage.onestore.v3.OnestoreEntity $ EntityProto.merge (OnestoreEntity.java:10341) в com.google.apphosting.api.Datastore$ QueryResult.merge (DatastoreV3Pb.java:28421) на com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage.mergeFrom (ProtocolMessage.java:453) на com.google.appengine.repackaged.com.google..io.protocol.ProtocolMessage.mergeFrom (ProtocolMessage.java:470) на com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage.parseFrom (ProtocolMessage.java:579) на com.google.appengine.api.datastore.DatastoreApiHelper $ 1.wrap (DatastoreApiHelper.java:120) на com.google.appengine.api.datastore.DatastoreApiHelper $ 1.wrap (DatastoreApiHelper.java:113) на странице com.google.appengine.api.pper(FutureWrapper.java:60) на com.google.appengine.api.utils.FutureWrapper.get (FutureWrapper.java:101) на com.google.appengine.api.datastore.FutureHelper.getInternal (FutureHelper.java:69) наcom.google.appengine.api.datastore.FutureHelper.quietGet (FutureHelper.java:33) в com.google.appengine.api.datastore.BaseQueryResultsSource.loadMoreEntities (BaseQueryResultsSource.java:243) в com.googleiappengine.хранилище данныхjava: 99) в com.google.appengine.api.datastore.LazyList.getCursor (LazyList.java:325) в com.kustom360.lib.client.DatastoreController.listByLimitation (DatastoreController.java:132)
У меня есть задание потока данных для этого типа запроса, но я просто пытаюсь обработать получение больших данных, не используя какие-либо другие службы или API.
Я не думаю, что ошибка памяти не в моей стороне.Как указывает ошибка в методе getCursor их реализации LazyList.
Можно запросить миллионы объектов в пакетном режиме с помощью курсоров, но в одном запросе?
Спасибо!