本方案试运行中,待观测其性能、稳定性及健壮性,请勿直接应用生产。
涉及的技术栈。
hadoop,版本2.6.0,主要用来存储数据及进行离线分析。
hive,版本1.2.1,主要用来管理数据(注意没有用到MR分析);
hbase,版本1.2.4,主要用来存储中间输出数据(可看作缓存);
flume,版本1.7.0,主要用来从业务系统收集数据以及从jms收集数据。
kafka,版本0.10.1.0,主要用来收集业务系统日志数据和汇总日志数据。
spark,版本2.0.1,主要用来取代hive的MR分析,并针对基础数据进行数据筛选分析等(可看作离线数据分析引擎)。
redis,版本3.0.6,主要用来缓存分析中的增量数据,设定当天数据时效为36小时,每天同步一次昨天的增量日志数据到全量数据库中。
storm,版本0.10.2,主要用来日志实时分析,如用户画像实时更新,PV统计等。
mongodb,版本3.2.10,主要用来存储终态数据,如用户画像、PV值等供业务系统使用。
ganglia,版本3.2.0,主要用来监控各节点状态。
其它如haproxy、nginx等辅助ha工具这里不再赘述。
首先看一张架构图。
根据架构图设计出网络拓扑图
最后是流程图
以下是数据流向说明:
1、业务系统收集日志数据
2、业务系统可发送日志数据到消息集群(kafka)
3、采集器(flume)主动收集日志数据,发送到消息集群(kafka)
4、所有日志数据,最终流向消息集群(kafka),然后分流到实时计算和离线计算两个方向(注意一份日志数据会被复制两份,一份供实时计算使用,一份供离线计算使用,且hadoop集群分为实时计算hadoop集群和离线分析hadoop集群,两者互不干扰)
4.1、实时计算
4.1.1、storm从消息集群(kafka)拉取数据,首先筛选出有用的数据(针对不同的topology),存储到hbase。
4.1.2、然后针对分析类型,预处理数据,预处理数据分两种存储,一种是增量,使用redis,一种是全量,使用hbase。当天数据全部存储到增量表中,并设置时效36小时,自动清除过期数据,每天将增量数据,同步到全量数据中。同时更新一个key,还要把key发送到更新key消息集群(kafka),供下一步分析使用。
4.1.3、最后从更新key消息集群(kafka)读取更新key,然后获取缓存数据,进行算法分析,分析结果更新到mongodb中。
4.2、离线计算
4.2.1、首先采集器(flume)从消息集群(kafka)中拉取数据,然后将数据存储到hive中
4.2.2、建立shell定时任务,使用spark针对基础数据,按天进行同实时计算同样的分析,存储到hbase中。并将最终结果存储到mongodb(存储时 注意不要和实时分析放在同一个document里)。
5、开放spark的thirfserver对外提供日志数据查询供运维定位问题。
6、分析数据流向mongodb,供业务使用,基础数据直接对外提供访问供运维定位问题。
解释一下为什么要离线和实时都进行一次同样的操作。
因为实时计算架构一旦中断,虽然历史数据不会丢失,但中断那一段时间的数据就需要重新进行分析和计算,如果数据量比较大,分析任务比较多,那将会造成一定的损失。而使用加上离线后,因为架构中区别离线hadoop和实时hadoop,所以数据相对隔离的,实时hadoop丢失数据可以从离线hadoop中同步过来,使用hbase的LoadIncrementalHFiles命令即可。
涉及到开发的部分:
1、flume的过滤器:除了jms方式能够统一格式,flume自采就会采集到各种各样格式的数据,这就需要一个转换,将数据转换成标准的格式。
2、redis缓存数据同步hbase:将增量数据同步到hbase的系统
3、topology:topology是storm的核心,需要用户编写spout、bolt、Topology来完成一些列分析处理操作
系统难点:
1、flume从kafka拉取数据后,存入hive中:想要做到数据实时插入,而不是定时load数据到hive。但目前还没一个完美的解决方案。一个变相的解决办法是限定hive表,然后根据规则将数据写入到hive表文件里。如:表user,按date天分区,每天一个文件,那flume在插入数据的时候不走hive,直接将数据按天分文件,写入到对应的hive表文件里,这样hive可以读取到新添进去的数据,变相实现实时插入。此种方法需要flume保证数据格式。
2、由于技术栈涉及较广,需要多部分配合,资源调配,并且会增加一定的人员学习成本和运营成本。
建议:
1、建议先实现一部分,比如先放弃实时计算,和离线计算,只运行基础数据存储,只供运维定位问题使用,总结经验,然后根据需求一点一点扩充。
2、根据不同技术特定,进行差异化的服务器硬件配置,比如spark需要高内存,低硬盘,那就可以把硬盘容量调小点;比如hadoop需要高性能的io,对内存要求不高,那就把硬盘配置好点。还可以二者结合,互相弥补,可能性能也会有所提升。