正文
图4
当团队比较大,或者服务很复杂的时候,应该尽可能的将服务拆分。我们团队拆分大概花了三个月的时间,大概拆分了 60 多个微服务,每一个服务是由唯一的一个工程师来负责开发和运维的。
大家可以想到这张图(图 4)一共有多少人,
60 多个微服务是多少人做的吗?实际上只有三个工程师
。平均每个工程师大概维护 20 到 30 个服务。
我们用的 KOS 整套体系,其中绿色的方块指的是一个部署,蓝色的方块指一个 SVN 的接入点,中间圆的部分用来做异步通讯。
这张图不是手画出来的,是通过脚本自动生成
,因为要求所有的代码和配置一定要版本化,所有的调用关系都可以在代码里面反映出来,所以我们用脚本自动的处理所有的配置文件,最终就可以生成这样的一张图。
如果你的团队号称是微服务,但你画不出来这样一张图,说明你的微服务自动化上可能存在一定的问题。
微服务三个特点
对于微服务我总结三个特点:
1)调用关系即架构
怎么去处理这种调用关系,意味着你的架构是什么样子的。在我们的架构里面,图里面一定是单向的,不允许出现循环的依赖的关系。因为如果那样的话,你的项目会出现一个很大的灾难,当其中一个点出了问题之后,你会回馈到达一个节点本身,整个服务就会出现这种情况。
2)工程师独立推动架构演化
因为我们微服务不仅按照项目来切分的,而且是按照人来切分的,所有每一位工程师独立负责不同的微服务,这样意味着
所有的架构是由我们的工程师——实际上只有三位工程师——独立推进的
。
3)开发即运维
我们没有运维只有开发的同学,但是我们给开发的同学提供了非常好的运维的工具。从代码开始,根据配置文件生成新的版本提交到KPS上去,部署上线之后,我们会有一些监控的脚本去核实这个 API 是不是可用,如果没有问题就可以直接部署上去。
中间也会出现问题,但是对于一个比较小的团队来说,快速出现问题永远比不出现问题要好。
微服务技术选型
团队的技术选型如图 5 所示。
图5
3. 机器学习系统框架演进
深度学习模型的存储量主要在 CPU,非常适合用微服务解决。
如果是用 CPU 来做 Kubernetes 的话,深度学习模型的存储量主要是在 CPU 上,所以使用带有弹性扩容的微服务架构是比较适合的。图 6 所示用的是 Concurrency,平均的的 Time per second 是将近 600 毫秒,基于 Kubernetes 实现了这样一套比较简单的框架。
图6
传统做法、改进做法和最优做法
图 7 所示是传统的做法,需要三个不同的部门,因为这个模型是一个 CNN 模型,而且不是一次得到的结果,要反复做多轮。就是平均来说,一个 VGG 模型在 CNN 上大概需要 40 毫秒左右,所以如果你要去 Serve 一个跟图象相关的模型,在 CPU 上超过 100 毫秒是非常正常的事情。
以上是常见团队的划分。比如需要一些月薪 50K 以上的算法工程师,他们做的事情就是要搜集清理他们的数据,要训练模型,要用 Python。然后牛逼的模型就出现了,交给牛逼的系统工程师。
系统工程师发现这个模型不能直接用,要写一些代码,就是要把脚本粘合在一起,而且有一些逻辑,比如用 Python 来实现 Bm Sersev 需要一秒的时间,才能生成一句话,这个在线上是无法忍受的。同时发现效率也很差,需要做调优,有一些调优可能涉及到模型的东西,所以要反复跟算法工程师沟通,所以用 Java 或者 C++ 把这个东西搞定之后再交给运维工程师。