第三届阿里中间件性能大赛冠军答辩

2020-02-27 140浏览

  • 1.
  • 2.团队介绍 “作死小分队” • 傅宇,Splunk研发中心,毕业于南京大学 • 吴迪,Splunk研发中心,毕业于北京大学 2
  • 3.议程 • 问题回顾 • 算法思路 • 架构设计 • 实现细节优化 • 总结 3
  • 4.问题回顾 4
  • 5.问题 • 输入一批单表的增量数据变更信息,进行重放计算 • 变更包含 Insert/Update/Delete 三种类型 • 主键可能发生变更(UpdatePK) • 输出指定范围的查询结果 5
  • 6.重要信息 • 16核CPU • 并行算法! • 必须顺序读文件 • One-Pass算法 • Server端输入,Client端输出 6
  • 7.算法思路 7
  • 8.如何并行? • 串行算法:单表、单线程 • 如何切分这个问题,且能并行计算? 8
  • 9.分桶 • 把数据表按 hash(PK) 切分成 N 个 Bucket 9
  • 10.分桶 • 把 Insert / Update / Delete 分发到相应 PK 所在的 桶即可 • 对同一条记录的修改,在队列中按顺序出现 10 INSERT id null 13 score null 90 UPDATE id 13 13 score 90 95 DELETE id 13 null score 95 null
  • 11.别忘了UpdatePK • 怎样处理UpdatePK? UPDATE id 11 13 14 score 90 95
  • 12.别忘了UpdatePK • 把更新后的 PK 转发到原来的桶 • 然而,Parser无法并行! UPDATE id 13 14 PK Bucket … … 14 3 … … 12 14 90 95 Bucket 3 relayMap DELETE id score ...
  • 13.别忘了UpdatePK • 先把数据“搬”到新的桶,再做其他的 Update UPDATE id 13 14 score 90 data Bucket 3 13 Bucket 4 95
  • 14.Milestone 1 Bucket 14
  • 15.等等……! 说的容易,你搬一个试试啊! 15
  • 16.Channel • 用一个 channel 连接 UpdatePKSrc 事件和 UpdatePKDst 事件 16
  • 17.Channel • 要搬运的记录 data 通过 channel 从发送方传递到 接收方 • buf_size = 0 双方都要等待 • buf_size = 1 接收方等待 • 可用 CountDownLatch 实现 17
  • 18.当前队列 UPDATE id 18 13 14 score 90 95
  • 19.如果 Bucket 3 的动作略快一些…… 19
  • 20.如果 Bucket 3 的动作略快一些…… 20
  • 21.如果 Bucket 4 的动作略快一些…… 21
  • 22.如果 Bucket 4 的动作略快一些…… 22
  • 23.阻塞 • 用 Channel 的思路没错,但是会阻塞 • 事实上,这比你想的还要糟糕 23
  • 24.循环阻塞!退化到协程 UPDATE id 0 100 UPDATE id 1 101 UPDATE id 2 102 UPDATE id 3 103 …… hash(x) = x mod 3 24
  • 25.解决阻塞 • 先回忆一下 Future/Promise 25
  • 26.Future/Promise in Clojure ;; an example to show a future that delivers promise user=> (def p (promise)) #'user/p ;; future that will deliver the promise from another thread after 10 sec delay user=> (future (Thread/sleep 10000) (deliver p 123)) #future[{:status :pending, :val nil} 0x9a51df1] ;; within 10 seconds dereference p, and wait for delivery of the value user=> @p 123 阻塞(等待)10s 26
  • 27.非阻塞方法 ;; Create a promise user=> (def p (promise)) #'user/p ; p is our promise ;; Check if was delivered/realized user=> (realized? p) false ; No yet ;; Delivering the promise user=> (deliver p 42) #d: