数据流基础——块的节流
问题
假设在数据流网格中存在分叉场景,而数据需要以负载均衡的方式流动。
解决方案
在默认情况下,当块生成输出数据时,它会按链接生成的顺序检查所有的链接,试图让数据顺着每个链接、一次一个地向下流动。另外,没个数据流块都会保持输入缓冲,并在做好处理数据的准备钱,接收任意量的数据。
在分叉场景中会导致一个问题,即一个源关联了两个目标块,这时第二个目标块便会“饥荒”。当源块生成数据时,它会视图让数据顺着没个连接向下流动。第一个目标块总会接收数据并将其缓冲。因此,源块永远不会尝试让数据留到第二个目标块。这时可以使用BoundedCapacity块选项,通过节流目标块来解决这个问题。BoundedCapacity被默认设置为DataflowBlockOptions.Unbounded,这就会造成第一个目标块缓冲所有数据,即便目标块尚未做好处理这些数据的准备,也会如此。
可以将BoundedCapacity设置为任意大于零的值,当然,设置为DataflowBlockOptions.Unbounded也是可以的。只要目标块能跟上从源块传来的数据,即使设置为1也是完全可以。
var sourceBlock=new BufferBlock<int>();
var options=new DataflowBlockOptions{BoundedCapacity=1};
var targetBlockA=new BufferBlock<int>(options);
var targetBlockB=new BufferBlock<int>(options);
sourceBlock.LinkTo(targetBlockA);
sourceBlock.LinkTo(targetBlockB);
讨论
节流对于实现分叉场景中的复杂均衡很有用,但它也可以用于任何需要实现节流的场景。比如,在用来自I/O操作的数据填充数据流网格时,就可以对网格中的块使用BoundedCapacity。这样一来,在网格尚未准备好之前,就不会读取过多的I/O数据,而且在能够处理数据之前,网格也不会缓冲所有输入数据。