设定有如下需求:
现要从hbase
中导出 2016 年整年的,大约10w
只股票行情数据,数据总量约100t
导出成如下格式:
2016-01-01/facebook.txt linkedin.txt amazon.txt google.txt...
...
2016-12-31/facebook.txt linkedin.txt amazon.txt google.txt...
汇总到hdfs
中供需求方使用
已知数据量规模大概是100t
,那么单台机器处理肯定不是不行的,先不说大多数磁盘都没这么大,即便磁盘有这么大,单台机器处理对于内存和 cpu 要求也很高,所以我们将问题一般化,使用数量有限的低配机器。
那么接下来要处理的就是如何对任务进行分割,最容易想到的有两种:
以上两种都可以,都涉及到最后汇总 hdfs 的情况,不过按照股票分割粒度更细,更便于控制,这里我们选用后者。
选定分割方式后又会遇到一个问题,如果将任务分割给多台机器,这里先说两种:
很明显方案二比方案一要好,这里我们选用方案二
现在机器已经分配好了,剩下的就只有单机处理了,剩下的就只有并发的知识了
应到每台机器上的逻辑就是:对于获取到的每只股票,扫描整年的数据,然后写本地,写好之后 copy 到 hdfs 即可,再细化下去后大概会遇到如下几个问题:
hbase
数据读取方,消费者便是数据处理方100g
的空间,那么必须考虑本次可存的文件最大上线,一旦告警必须等待磁盘数据拷贝完成再继续处理block
任务,但是不能reject
TSDB
的存储,当然最好只扫描一次,但是扫出来的数据都必须根据时间判断,会浪费性能,多线程写还需要考虑文件锁,进一步降低性能,另外如果程序判断按照天截止,又容易造成数据遗漏,不按照天截止缓存整年的数据之后再拷贝到hdfs
又会增加时间开销scan
,每个线程仅控制一天,避免多线程写,同时便于单文件写好之后立即通知上传线程将文件汇总过去如已经明确相关的hbase
,hdfs
,其他包含可能会用到的组件如:消息队列,缓存等
会涉及到BlockingQueue
,ThreadPool
,CountdownLatch
,Lock
等concurrent
知识运用,举个具体例子:
等待ThreadPool
的所有任务完成
ThreadPool
提交任务阻塞
BlockingQueue
Thread
同步控制
CountdownLatch
的使用控制生产者和消费者终止
PoisonPill
的使用异步任务处理
Lock
使用
这就是一种比较常见的,用到“大数据”处理和并发知识的场景,如果网友有更好的思路,欢迎留言讨论~
1
billlee 2017-03-19 21:19:43 +08:00
没太看懂,这个直接用 mapreduce 不可以吗?
|
3
log4geek 2017-03-22 14:31:12 +08:00
说到多线程,还要搞清楚 Java 中的 synchronized 、 Object.wait()、 Object.notify()/notifyAll()原理
传送门 http://log4geek.cc/2017/02/java%e4%b8%ad%e7%9a%84synchronized%e3%80%81object-wait%e3%80%81object-notifynotifyall%e5%8e%9f%e7%90%86/ |