Skip to content

技术研发的注意事项

选择合适的编程语言

例如开发一个搜索引擎系统,首先需要根据具体的需求,对系统的各个部分选择合适的编程语言。

Infra 层:

  • 对延迟(latency)的要求极高,偏向于使用 C++;

中间层(middle tier or 服务器端):

  • 并没有特别复杂的处理和对延迟的高需求,主要是以一些业务逻辑为主;
  • 以 Java、Python、PHP 等为主,对程序员来说,使用这种高级语言也更容易上手和调试。

合理使用缓存

缓存为我们节约了大量的 CPU 容量(capacity)和延迟。缓存(cache)在实际工程中十分重要。

如果没了缓存,容易造成很多问题。

  • 服务器负荷迅速飙升,崩溃的几率大大增加。
  • 端对端的延迟迅速飙升,请求超时的概率大大增加。

是不是缓存越多就越好呢?——显然不是

第一,通常来说,缓存比较昂贵,所以在使用上,我们都会有一个限度,不能无限制索取

第二,缓存不是万能的,过度增加缓存,也会损害用户的产品体验。比如搜索结果的 retrieval 和排序这两块,理想状况下,肯定是做实时的 model serving 最好,因为这样对用户的个性化推荐更准确和实时。之所以会对 model 有几个小时的缓存,更多的是出于性能的考虑,但如果把缓存从几小时改为几天,显然不合适,无疑会对用户的产品体验造成极大的负面影响。

说明

缓存到底取多久、取多少,往往是用户对产品参与度和性能的一个权衡,需要根据一些具体的分析以及 A/B 测试做出决定。

健全的日志记录系统

大型公司的系统,往往由成千上万个小系统组合而来,如果发生故障,比如 Google、Facebook 的某项服务突然宕机了,就需要以最快的速度找出原因并做出修复。这靠的正是健全的日志记录系统,使得我们能够方便地分解错误原因,一层一层追溯,直到找到根源。

一般来说,在线上环境中,我们需要两种类型的日志记录模式。

实时 logging

考虑到服务器的压力,通常会做降采样(downsampling),比如 log 实际流量的 1%。这样的好处是,可以及时跟踪各项指标,如果有情况,立即触发警报(alert)。

实时 logging 也有利于我们进行各种线上实验。

日常 full logging

每天更新一次也就是 daily 的 full logging,有助于我们统计一些信息,进行分析,比如做成仪表板(dashboard),方便查看每天的各项指标,来跟踪进度。此外,full logging 的 table,也常常用于 ML 组的训练数据(training data)。

Profiling

profile,在实际开发中是非常重要的一项功能,能够帮助开发人员详细了解系统每个部分的效率,并加以提高。

提示

在线上环境中,通常会在许多必要的地方加上 profile 的代码,这样就能够知道这段代码的延迟是多少,哪个部分的延迟特别严重等等,然后对症下药。

如果没有 profile,很容易导致开发人员随意增加功能而不进行优化,这样以来,随着时间的推移,系统越来越冗余,延迟也会越来越高。

测试

无论是单元测试(unit test)、集成测试(integration test)还是其他,都是保证代码质量、减小 bug 发生概率的一个有效手段。

在真正规范的公司或是小组里,开发人员如果新增或改变了一个功能而不写测试,是过不了代码评审的。

除了日常开发中所写的测试外,在代码 push 到线上之前,最好还要加一层测试。

说明

Google 或者 Facebook 的代码在 push 的过程中,都会有专门的 service,去模拟不同的用户发送请求,然后看返回的响应是不是符合要求。如果出错,就会阻止代码的 push,这也就告诉了开发人员,他们所写的代码可能存在问题,需要再次检查。