我有一个队列,其中包含根据作业类型而不同的执行程序池的作业。队列在数据库表中,包含来自具有优先级等的不同客户端的作业。我省略了一些与问题无关的细节。 有时,不同的客户会以相同的优先级同时将许多作业放入队列中,例如约15-20'000个作业。
在当前的实现中,使用符合此条件的休眠模式来获取作业,再次,为了简化起见,我省略了一些限制。
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, -minutes);
Criteria c = getSession().createCriteria(QueueEntry.class)
.add(Restrictions.eq("processing", false))
.add(Restrictions.or(Restrictions.ge("serverTimestamp", cal.getTime()), Restrictions.ge("sentTimestamp", cal.getTime())))
.add(Restrictions.lt("attemps", attemps))
.addOrder(Order.asc("priority"))
.addOrder(Order.asc("serverTimestamp"))
.setMaxResults(limit);
在当前情况下,如果客户端A在相同的优先级下在10:00:00中插入15k个任务,而客户端B在10:00:05(5秒后)中在30:00中插入了3k个任务,则B的任务将在这些任务之后被提取并执行的。
我需要在客户端之间平衡提取的作业(队列表中有一个“客户端”列)-例如,如果吞吐量为10个任务/秒,则要获得A的5个任务和B的5个任务。如果客户端B没有更多任务,则获得A的10个任务。
是否有一些简单的方法或技巧可以对查询执行此操作?数据库是Postgres。
答案 0 :(得分:0)
我认为您无法通过修改现有的Criteria
或仅使用一个查询来完成此操作。为了防止客户端饥饿,您必须为每个客户端创建单独的资源池,这是Fair Scheduler for Hadoop采取的方法:
公平调度程序将作业组织到多个池中,并在这些池之间公平地分配资源。默认情况下,每个用户都有一个单独的池,以便每个用户都可以平等地共享群集。也可以根据用户的Unix组或任何jobconf属性来设置作业池。在每个池中,可以使用公平共享或先进先出(FIFO)调度来调度作业。
您可以运行查询以获取具有正在等待的作业总数的不同客户端的列表。根据不同的客户数,划分全局作业限制,并在单独的查询中为每个给定的客户获取等待的作业。