很早之前就看过《三傻大闹宝莱坞》很是崇拜里面的主角兰彻,除了他的聪明以外,更重要的是他的学习方法,以及事事都能看清本质的能力。都说学会学习比学习更重要,虽然自己也在保持学习,但好像没有什么明显进步,学的多忘记的也多,一直在寻找合适的学习方法。所以开始以一种从需求和已有知识出发去理解和学习新知识的方法来学习,而不是一上来就学习某个框架怎么做的,有哪些组件,干什么的。
好,回归主题,这篇聊聊实时计算。
实时计算?不就是把数据从数据流拿进来按需求算一下,例如什么最大最小值、平均值之类的,抑或是统计一下流进来的数据有符合业务需求的数据有哪些就好了嘛,so easy,分分钟撸一个
void counter(String key, int period){
startTime = now()
while (true){
// 1 读数据
data = readkafka()
// 2 处理,以统计某个key的次数为例
int count = 0
for (d in data){
if (d == key){
count++
}
}
if (now() - startTime == period){
println(count)
startTime = now()
}
}
}
乍一看好像和后端开发没啥区别,不就是从kafka取数据,然后计算一下,数据结果嘛,不同的就是后端开发将状态(比如用户信息)放在了db/nodb自己不存状态,请求来了去db查一下,再更新一下,最后 返回结果。
先不说针对每个实时计算业务都从头开发的冗余工作之多,连基础的代码没bug都很难保证,就更不用说能否抗住大流量了。
所以这时候框架的作用就体现出来了,flink 基于kappa架构(后面再分析lambda/kappa架构),提供了很多功能,先不说那么多功能,我们先来看看他的实现思路,既然是要计算的,肯定就有状态了,只不过后端开发是将状态保存在db中自己不保存状态,通过事务来保证数据一致性,写后端代码会非常注重请求幂等,万一服务挂了怎么保证数据一致性,那flink 是怎么实现的呢,flink 就基于状态计算,将状态保存在内存中,如下图所示
如果只是将状态放在内存的话,某时刻宕机了岂不是状态又没有了,flink 通过checkpoint 机制将状态放到外部存储,宕机回复也能从checkpoint开始计算,后面会详述checkpoint。
既然是大流量的数据,单机肯定是扛不住了,针对高并发,后端服务无非就是负载均衡、加机器,当然flink也是用集群解决数据量大的问题,但是人家既然时框架了,肯定就有一套完成的开发和提交任务流程了,不像最初的后端开发一样,现在nginx上配置转发到哪些节点,再将每个节点上的服务更新。
如果是自己开发针对不一样的业务需求可能需要起不同的服务,这个过程非常繁琐,flink 既然时框架就提供了方便的并行度设置方法,只需要设置好需要的并行度就可以了,同时除了自带的集群启动和任务提交模式也支持yarn等资源管理调度框架,这个后续再聊。
知道为什么比知道是什么更重要。记录自己的思考和学习过程。如有谬误还请网友指出。