收集批量更新数据并在通过阈值限制或超时后发送数据?

问题描述:

在网络服务器内存中积累数据达到数据库写入数据库的特定时间限制是否是一种很好的策略&在每个指定时间间隔后或在数据增长到大于阈值大小后,将其作为批量更新发送。收集批量更新数据并在通过阈值限制或超时后发送数据?

这种类型的数据非常小,就像在两个实体之间添加关系一样,这意味着只需在行中添加一组ID。

(当然,延迟的数据应该是预期不会立即可见的)。

这种方法有什么缺点吗?


使用方法:卡桑德拉DB,与Java & JSF构建Web应用程序。

+0

延迟可能足够小,以至于显示为“立即”,因为不会添加延迟。即它不可能具有零延迟,但也不可能让人看到小的延迟。 –

简答:这是一个坏主意。

卡桑德拉的批处理操作(例如http://pycassa.github.com/pycassa/api/pycassa/batch.html)可让您在幂等单位中对更新进行分组。这允许您将批处理作为一个单元重试,因此其目的与关系数据库中的事务大致相似。

然而,与交易类比不同的是,对绩效的影响可以忽略不计,事实上人为地将负荷“突发”通常会适得其反。

+0

谢谢乔纳森!对于Hector提供的批处理操作,有没有类似于'queue_size'的方法(在阈值大小后自动发送批处理) –

+0

你的意思是这是一个糟糕的主意,因为客户端库已经通过批处理突变提供了这个选项,对! –

+0

不,我的意思是,如果你想批量作为优化,而不是因为一组操作在逻辑上属于一起,那么你做错了。 (如果他们在逻辑上属于你在一起,你不需要担心队列大小等......) – jbellis

主要缺点是它需要另一个线程来实现超时(少量的复杂度),但好处可能会更大。

实现一个简单的方法是使用等待/通知(似乎没有被使用并发库一个很好的解决方案)

private final List<T> buffered = new ArrayList<T>(); 
private final int notifySize = ... 
private final int timeoutMS = ... 

public synchronized void add(T t) { 
    buffered.add(t); 
    if (buffered.size() >= notifySize) 
     notifyAll(); 
} 

public synchronized void drain(List<T> drained) throws InterruptedException { 
    while(buffered.isEmpty()) 
     wait(timeoutMS); 
    drained.addAll(buffered); 
    buffered.clear(); 
} 

add和排水可由任意数量的被称为的线程,但我想你只会有一个线程耗尽,直到它被中断。

+0

因此,因为我使用的是JSF,那么在Web服务器上的应用程序作用域托管bean中累积数据是否好,然后在跨越阈值后传递该数据?你能否澄清你认为可以接受多少时间? (假设最终用户对该数据没有任何紧迫性) –

+1

这真的取决于你。然而,典型的延迟可能是0.5到5秒。它可能短至0.05秒,甚至长于30秒。无论您是否使用JSF,此方法都可以工作。 –