繁体   English   中英

如何使用Google App Engine(Java)任务队列在一个实体中保留大量数据/行

[英]How to use Google App Engine's (Java) Task Queues to Persist a lot of data / rows in one Entity

我试图在一个实体中坚持大约28,000“行”,例如EMPLOYEE

基本上,我的目标是避免使用超过30秒的PUT终止/超时 - 如果我通过调用发送到servlet的doPost()请求来执行28,000个PUT,则可能会发生这种情况。

所以我正在考虑使用Google App Engine文档中描述的任务。

基本上,我想在war目录中上传一个拥有28,000名“员工”的csv文件。 然后创建一个任务,将这28,000个员工行异步PUT到EMPLOYEE实体。

  • Q1:这是一个可行的解决方案还是有更好的方法? 同样,目标是执行PUT以避免由于30秒限制而终止。

  • Q2:我还应该使用什么queue.xml配置来确保我能够尽快执行这些PUT?

  • Q3:现在,我已经尝试过,类似于博客文章: http//gaejexperiments.wordpress.com/2009/11/24/episode-10-using-the-task-queue-service/但我得到了23秒左右后出现以下错误:

     SEVERE: Job default.task1 threw an unhandled Exception: com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 5: http method POST against URL http://127.0.0.1:8888/dotaskservlet timed out. at com.google.appengine.api.urlfetch.dev.LocalURLFetchService.fetch(LocalURLFetchService.java:236) at com.google.appengine.api.taskqueue.dev.LocalTaskQueue$UrlFetchServiceLocalTaskQueueCallback.execute(LocalTaskQueue.java:471) at com.google.appengine.api.taskqueue.dev.UrlFetchJob.execute(UrlFetchJob.java:77) at org.quartz.core.JobRunShell.run(JobRunShell.java:203) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) 16/02/2011 12:12:55 PM org.quartz.core.ErrorLogger schedulerError SEVERE: Job (default.task1 threw an exception. org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 5: http method POST against URL http://127.0.0.1:8888/dotaskservlet timed out.] at org.quartz.core.JobRunShell.run(JobRunShell.java:214) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) * Nested Exception (Underlying Cause) --------------- com.google.apphosting.api.ApiProxy$ApplicationException: ApplicationError: 5: http method POST against URL http://127.0.0.1:8888/dotaskservlet timed out. at com.google.appengine.api.urlfetch.dev.LocalURLFetchService.fetch(LocalURLFetchService.java:236) at com.google.appengine.api.taskqueue.dev.LocalTaskQueue$UrlFetchServiceLocalTaskQueueCallback.execute(LocalTaskQueue.java:471) at com.google.appengine.api.taskqueue.dev.UrlFetchJob.execute(UrlFetchJob.java:77) at org.quartz.core.JobRunShell.run(JobRunShell.java:203) at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520) 
  • 问题4:我还在http:// localhost:8888 / _ah / admin检查了数据存储区查看器,它似乎只在该实体中创建了1000个结果。 是1000的限制?

  • Q5:如何摆脱上述错误?

  • 问题6:可以确认任务的最长允许时间是10分钟吗? 还是30秒呢? 我确实来过这个: http//code.google.com/appengine/docs/java/taskqueue/overview.html#Task_Execution

以下是使用mapreduce解析CSV文件的示例/教程,似乎与您的需求类似:

http://ikaisays.com/2010/08/11/using-the-app-engine-mapper-for-bulk-data-import/

我会通过DeferredTask进行批量保存,大致类似这样:

List<Employee> employees=...
EmployeeWriter qr = new EmployeeWriter (employees);
TaskHandle task = QueueFactory.getDefaultQueue().add(withPayload(qr));

哪里

public class EmployeeWriter implements DeferredTask {
   public EmployeeWriter () {    }
   public EmployeeWriter (List<Employee> employees) { 
          this.employees=new LinkedList(employees);  
   }

    private LinkedList<Employee> employees;

    @Override
    public void run() {
      Stopwatch sw = Stopwatch.createStarted();
      try {
        do {
           List employeesTosave=Pull100EmployeesFromLinkedList(employees)
           ofy().save(employeesTosave).now();

        } while (sw.elapsed(TimeUnit.MINUTES) < 9);
     finally {
        sw.stop();
        if (!employees.isEmpty()) {
            QueueFactory.getDefaultQueue().add(withPayload(this));
        }
    }

}

如果您的目标只是自己上传大量数据,而不是让用户这样做,我认为更容易的工具就是批量上传。 您可以从本地计算机运行python程序,为您处理请求限制和故障恢复。

http://ikaisays.com/2010/06/10/using-the-bulkloader-with-java-app-engine/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM