场景:杭州 阿里云的 mysql数据,秒级同步到 深圳 腾讯云 的hadoop,出报表
常规的思路是这样的:
杭州:
(1)mysql =》 (2)maxwell / canal 获取 binlog =》 (3)数据打到kafka =》
深圳:
=》(4)sparkstreaming / flink / kafka =》 (5)hive / kudu + impala jdbc 或者 hbase + phoenix / es 二级索引 =》report
但是存在一些需要注意的细节:
(1) mysql 数据源取从库,不能影响主库写数据的性能
(3) kafka:
kafka 数据不能保证全局有序,但可以保证单个分区(partition)有序,因此为了保证同一个业务的增删改在同一个 partition, 必须用 业务id 的 hash 作为分区字段
(3)-(4) 的跨地域对接问题:
-
参考方案:kafka <=>sparkstreaming, kafka <=> flink, kafka <=> kafka
-
介于 flink,sparkstreaming 的同步机制,断网机制 以及 网络抖动机制的处理不一定非常好,实际网络并非专线,而是跨省互联网,只考虑 kafka <=> kafka.所以杭州和深圳都要搭 kafka
-
kafka 之间的同步问题:
-
参考方案:常见的流同步组件如 kafka 自带的 mirrormaker,cdh 的 streamset,apache 的nifi,uber 开源的 ureplicator, Linkedin 的 linkred.
-
上诉第三方组件,只能实现 topic <=> topic 之间的同步,如需要实现 partition <=> partition(同一个业务的增删改要在一个 partition 下) 之间的同步需要自己该源码。实际方案选的是修改 nifi 源码(nifi 支持 监控,图形化界面,以及动态分区扩展)。
-
(5)kafka 数据落地问题:
-
hive 不考虑,mysql 里有很多 upset 操作。
-
hbase + phoenix 查询慢不考虑。
-
hbase + es:es 的单表性能非常好,可以提供毫秒级的体验,但每次只能查询单表数据,多条数据需要用多个线程同时去处理, 太麻烦,也不考虑。
-
kudu:
-
支持 upset,kudu + impala 读取速度方面还能接受,sparkstreaming 提供了 kudu 的支持(kuducontext), 一行代码就可以更新数据,可以直接使用 sparkstreaming 对接 kafka 再完成数据落地到 kudu,此方案需要 report 端定时刷新 kudu 数据,如果接受小几秒的延迟,可以考虑。
-
报表的实时渲染,使用 impala jdbc 存在延迟,可考虑将 kafka 数据直接打到 sparkstreaming / flink,后者在将数据打到 redis,report 通过 websocket 长连接到一个 nodejs 的进程,这个 nodejs 进程再注册 redis 的 pub_sub 消息队列,对 redis 的数据做一个转发,从而实现 redis 将消息实时推送到 report 端实时渲染。
-