微批次

把你未使用的CPU和内存更好的用来交换滥用导致的延时。

— 克林贡谚语

翻阅过一两次101Stream的崩溃说明,勇敢的黑客们准备好一些快速的ROI(投资回报率)。实际上有效的调度与用于检测在每秒处理百万级消息待办事项的唯一标准相距甚远。

分布式系统的一个常见问题是由独立或有缓冲的IO写操作导致的延迟。当这种情况发生时,微批次或小块处理是将独立数据操作归类的方式。术语Micro(微量)的背后隐藏着一个更为具象化的名词:In Memory(内存中)。由于当前系统的速度仍然受限在光速内,主内存的读取依然比磁盘耗费时间更少。

  1. 延迟消耗比较数据
  2. L1 cache reference 0.5 ns
  3. Branch mispredict 5 ns
  4. L2 cache reference 7 ns 14x L1 cache
  5. Mutex lock/unlock 25 ns
  6. Main memory reference 100 ns 20x L2 cache, 200x L1 cache
  7. Compress 1K bytes with Zippy 3,000 ns
  8. Send 1K bytes over 1 Gbps network 10,000 ns 0.01 ms
  9. Read 4K randomly from SSD* 150,000 ns 0.15 ms
  10. Read 1 MB sequentially from memory 250,000 ns 0.25 ms
  11. Round trip within same datacenter 500,000 ns 0.5 ms
  12. Read 1 MB sequentially from SSD* 1,000,000 ns 1 ms 4X memory
  13. Disk seek 10,000,000 ns 10 ms 20x datacenter roundtrip
  14. Read 1 MB sequentially from disk 20,000,000 ns 20 ms 80x memory, 20X SSD
  15. Send packet CA->Netherlands->CA 150,000,000 ns 150 ms
  16. Notes
  17. -----
  18. 1 ns = 10-9 seconds
  19. 1 ms = 10-3 seconds
  20. * Assuming ~1GB/sec SSD
  21. Credit
  22. ------
  23. By Jeff Dean: http://research.google.com/people/jeff/
  24. Originally by Peter Norvig: http://norvig.com/21-days.html#answers

Streams是数据序列,因此找到可以切分缓冲区总量的范围是一个非常好的API。

主要有两类定界:

  • Buffer(缓冲区):依据范围将onNext(T)累加为一组List传入子订阅者。
    • 最好使用需要把Iterable作为入参的外部API。
  • Window(窗口):分离边界转发onNext(T)为不同Stream<T>并传递给子订阅者。
    • 最好使用如Reduce或任何订阅者/行为的积聚者反应到onComlete()
    • 可以结合flatMapconcatMap在常规Stream<T>的独立窗口中做合并。