从19年10月起,加入新团队已经一年有零了,期间主要的工作是负责后台整体架构和项目交付落地。做出了一些成绩,也留有不足之处,在这个年末之际应该做一个总结了,作为20年的年终工作总结,也作为小团队AI领域微服务架构落地的经验总结。

一、当时的状况

19年8月,有几个同事包括我都先后离开腾讯,老领导进入一家AI公司出任CEO重新创业,当时我在家休息了1个月,在老领导的邀请下,加入了他们的团队,负责后台。

产品情况

产品主打形体识别(REID),主要的功能是分析离线视频、实时视频、以图搜图,重塑轨迹。主要客户是公安系统的刑侦、科信等部门。19年之前主要是windows单机版本, 偏工具类应用,主打离线视频分析。19年之后开始打造集群版本,目标是支撑千路摄像头的实时分析和检索。

人才情况

当时整个研发中心分成3个组:客户端、后台、算法,这个划分一直持续到今天。具体到后台组一共有4个人,2个2~3年工作经验,2个试用期的应届生,这就是当时的人力情况,算的上人力单薄了。

技术难点

  • 算法上,换装问题、夜间识别效果差
  • 算法性能优化,需要不断提高单GPU处理的路数,以降低硬件成本
  • 检索的耗时,1亿条特征可以在秒级返回
  • 稳定性,离线交付、受限网络下,系统要高可用、高自愈、减少运维成本。

团队目标

目标就是打造能支撑千路的AI处理&检索集群系统,稳定运行,高效准确的满足客户的刑侦办案需求。具体到后台组就是改造现有windows单机版本,确保功能正常稳定的落地交付。后台的计划大概有3个时间节点和目标:

  • 3个月内可以完成单机向集群的迁移,组成3台机器的集群(百路摄像头),使各项功能正常运行。
  • 接下来半年到一年的时间,优化各项性能指标,提高稳定性,集群规模10台(支撑数百路摄像头)。
  • 到20年上半年,可以支撑1千路,30亿条记录,并且各项性能指标达到业界先进水平,成本能达到业界较低水平。

二、架构的演进

windows单机版本的不足

  1. 单体架构,不易维护:很多模块的代码都写在一起、跑在一起,牵一发动全身,不利于灵活的维护和升级
  2. 代码重复,不易维护:有几个重要模块,80%以上的代码和流程是完全一致的,但因为某些参数和历程不同而人为的拷贝了2份,导致后续改动要去2个地方改,经常遗漏出错。
  3. 不支持多实例:程序中维护了很多状态,导致只能运行一个实例,无法同时运行多个实例,以提高系统的吞吐能力。
  4. 性能较差:存储的IO、服务的QPS无法满足较大规模数据量的并发量。
  5. 接口模糊:采用请求用http回包用websocks的方式,且没有良好的接口文档。

应对方案

针对以上问题,结合结合及团队人员情况和团队目标,制定了后台新的技术栈:

  • 整体架构:微服务架构,服务通过Docker打包
  • 语言: C++&Golang, 优先使用Golang, 性能要求高或者依赖显卡或其他特殊情况用C++
  • 接口:微服务内部接口走GRPC或者消息队列,对外暴露GRPC、GRPC-WEB、接口规范对齐AWS
  • 数据库:Mysql
  • 消息队列:Nsq
  • 宿主机系统:Centos7.6
  • 集群治理:K8S
  • k8部署方案:Helm&Helmfile
  • 监控报警:Prometheus
  • 日志管理:Loki

重构策略

首先,我们把windows单机版本,以能让其跑起来的目标,稍微改造的将他运行在了k8s中,然后制定了集群版本开发的几个原则:

  • 李代桃僵,采用温和的方式,将单体服务分模块的逐步改造成微服务,比如11月份的迭代,计划改造设备管理模块和检索模块,12月份改造预处理模块和地图模块,这样的好处是旧的版本还可以演示运行,这样经过几个迭代后,最后干净彻底的将单体服务替换掉。
  • 分而治之:将庞大的单体服务改造成按功能划分的多个微服务。
  • 分久必合:将功能雷同的一些代码或者服务进行合并,合并成一个服务,减少维护的成本。
  • 拥抱开源:引入seaweedfsminiofaisstidb等高星的github项目,解决系统的性能瓶颈。

经过大概2个月的努力,期间又入职了2个开发人员,在2019年12月中旬,终于初步完成了,设备管理、预处理器、分布式检索、国标28181对接等模块的微服务化工作,然后我们迎接了第一次实战演练的机会,在某公安局实战了100路摄像头的规模,然后在20年5月份和11月份进行了2次500路规模的实战演练,一路逢山开路、遇水搭桥,终于到年底算是输出了一个比较稳定的版本。

三、经验总结

  • 实践是检验真理的唯一标准,尤其是我们这种ToB项目,系统必须在用户的真实环境下运行才能发现问题,解决问题。
  • 拥抱标准,尽量采用主流的方案,比如对于小图存储我们采用了S3的接口,相关文档、工具健全,并且很容易对接和切换底层实现。
  • 建立内部文档库,凡是会发给第二个人的资料,务必形成共享文档,长期看会极大的提高沟通效率和新人的融入速度。
  • 建立内部的规范,接口规范、服务配置规范、Git注释规范等等,选择合适的定下来,减少沟通的成本。
  • 一切代码版本化,代码、接口、k8s配置、模型文件、镜像、安装包等等,都必须有唯一的版本,方便沉淀稳定的版本和回溯问题。
  • 勇于启用新人,合适的工作压力对新人是前进的动力、要对他们有足够的信任和关注,使其既可以实现自我价值也可以为团队奉献。

四、不足支持

  • 量化不足 没有对各种业务指标,制定合理的目标;亦未埋点形成合理的数据报表,严重制约系统整体的质量。
  • 成本劣势 没有关注成本,ToB成本是决定项目落地的一个重要指标,成本方面重视不足,导致产品性价比没有核心竞争力。