写点什么

Evernote 从自有数据中心到 Google 云的迁移 - 第 1 篇

  • 2017-03-30
  • 本文字数:3379 字

    阅读完需:约 11 分钟

2016 年底,Evernote 对他们的服务进行了一次大规模的迁移。他们将 Evernote 服务从自有数据中心迁移到了 Google Cloud Platform 上。他们在短短的 70 天内完成了整个迁移过程,包括 Evernote 服务、存储数据和其他配套服务。参与这次迁移的工程师们在 Evernote 官方博客上分享了这次迁移的过程。文章包含了 5 个部分。以下译文已获得翻译授权。

第一部分:Evernote 服务和迁移到 Google 云平台的可选方案

Evernote 服务在 2008 年开始投入使用,我们一直维护着自己的服务器和网络。我们有很大的自由度来构建服务,但同时也面临着一些挑战:伸缩困难、升级缓慢、高昂的维护成本。虽然我们的基础设施在过去为 Evernote 提供了很好的支持,但在未来,我们需要更快的速度和更大的灵活性,而这些正是目前的基础设施所缺乏的。

迁移到公有云这一决定让 Evernote 的每一位员工都兴奋不已。在首次发布迁移声明之后,我们便在幕后启动了从物理数据中心到Google 云平台(GCP)的迁移工作。经过70 天日以继夜的奋战,我们完成了迁移。

可能有些人想了解我们的迁移过程,又或者想进行类似的迁移,所以我们决定把迁移过程分享出来。我们会告诉大家在迁移过程中我们都做了哪些事情,以及如何能够快速地完成迁移。这不是一个完整的迁移手册,不过它涵盖了我们做出的所有关键决策,以及我们是如何实现它们的。

先让我们来了解一下Evernote 服务的概况。

Evernote 服务

我们的服务由以下几个组件组成。

分片(NoteStore)

分片是 Evernote 服务的核心单元,用于存储用户的笔记。每个分片最多可以支撑 30 万个 Evernote 用户,并包含了如下几个组件。

  • 基于 Tomcat 的前端 Web 服务层:Evernote 客户端会连接到这个层。
  • 数据存储层:用于存储用户笔记的 MySQL 数据库。
  • 搜索索引:基于 Lucene 的服务端搜索索引,用于搜索用户的笔记内容。

我们总共有 762 个分片,存储着 2 亿个用户账号和大约 50 亿个用户笔记。

UserStore

UserStore 使用 MySQL 数据库来存储用户信息,包括他们的认证信息。因为数据库管理着所有用户的状态和认证信息,所以它是最为关键也是最为复杂的一个组件,在迁移过程中我们需要格外小心。

用户附件存储(资源)

我们有一个单独的文件存储层,用于存储 50 亿个用户附件(我们把这些附件称为资源)。这个层由 206 个自包含的 WebDav 服务器组成。每个用户附件有三个副本,其中两个分别被保存到本地的两个不同的 WebDev 服务器上,另外一个被发送到远程灾备数据中心的 WebDav 服务器上。

前端负载均衡

我们的高可用负载均衡器集群负责将用户请求路由到特定的分片上。

配套服务

我们还有 200 多台 Linux 服务器用于缓存和执行批处理任务,比如笔迹识别和文本识别。

我们的迁移可选方案

Evernote 服务规模庞大,向云端迁移是一项复杂的工程,我们需要作出很多与依赖项有关的决策。我们希望能够尽快完成迁移,所以我们为关键性决策制定了一个草案。

我们要先理清楚需要做出哪些变更。我们知道,有些组件无法直接被简单地迁移到云端,所以我们把组件分为两类。

  • 转移:有些组件在 CGP 上能够找到几乎一样的替代品,分片、UserStore 以及大部分配套服务都属于这一类。在我们的物理数据中心,这些组件都是基于 Linux 的,所以我们将会直接把它们迁移到云端的 Linux 虚拟机上。
  • 转换:在迁移过程中需要对用户附件存储、负载均衡层和识别服务(Reco)做一些重大的转换。对于这些组件来说,要么在云端找不到相应的替代方案,要么云端已经存在更好的替代方案。

迁移方法

接下来我们要开始计划如何进行迁移,我们有两种选择。

  • 一次性迁移:迁移项目里存在着一个分界点,跨过这个分界点就等于完成了 100% 的切换。对于自有数据中心和采用了单体架构的组织来说,这种方式会更适合(这或许也是唯一可行的方案)。
  • 阶段性迁移:这是一种分而治之的方法,根据类型或用户将服务分组,进行阶段性的迁移。采用这种方式可以在提交阶段性工作之前对其进行测试和验证。

从我们的情况来看,一次性迁移的方案并不适合我们。即使做了详尽的计划,一次性迁移完所有的组件仍然存在很大的风险。况且,我们的应用并非为多站点运行而设计的,尽管我们的环境在很早之前就已经支持多站点运行。

所以,我们需要在上述的两种极端之间找到一个折衷的方案,我们决定采取“增速阶段性切换”的方案。整个迁移过程要在短短的 20 天内完成,它包含了多个阶段,每个阶段的风险需要被降到最低。如果某些阶段的工作无法达到预期的效果,可以进行回滚。

第二部分:保护 GCP 上的用户数据

我们的安全团队负责保护用户数据的安全。在向云端迁移的过程中,我们要考虑如何保证用户数据的安全。我们面临两个主要的问题。

  1. 我们即将把数据交由 Google 来看管,他们是否拥有足够成熟的安控措施,能够避免给我们的服务带来新的风险?
  2. GCP 是否提供了等价的或者更好的安控措施来保证数据的安全?
厂商信任

我们内部有一个厂商审查流程,由我们的法律团队和安全团队共同执行这个流程。我们在与新的服务提供商展开合作之前,会对相关的隐私和安全问题进行审查。

在厂商审查过程中,我们会检查 60 多项与隐私和安全有关的问题。这些内容与我们内部程序的结构保持一致,通过这些审查,我们就可以知道厂商是否符合我们的预期。审查内容可以被分为几类。

  • 组织层面的控制措施
  • 基础设施的安全
  • 产品安全
  • 物理设施安全
  • 与隐私有关的数据使用

我们和 Google 一起对他们的审计报告进行了评审,发现他们在各个方面都能够满足我们的预期。

接下来,我们将注意力放在他们是否提供了用于保护用户数据安全的安控措施上。

云安全控制措施

首先,我们对现有的所有用于保护用户数据的安全措施进行了评审。这些安控措施包括使用了双因子认证的远程访问 VPN 和提供了流量过滤功能的防火墙。还有其他一些物理安控措施,比如物理外围、生物技术认证、探头,以及用于防止物理数据被盗的警报系统。我们在安全主页上有很多关于基础设施安全防护的讨论。

我们列出了一个表格,记录了迁移过程中需要注意的安全问题,下面是一些主要内容。

  • 外围网络安全(向内流量和向外流量过滤)
  • 内部隔离
  • 多因子认证
  • 传输加密
  • 缺陷管理
  • 身份信息和访问控制
  • 诊断日志
  • 入侵检测
  • 变更监控

我们还需要考虑多租户云环境可能会出现新的威胁模型。内存和存储的使用方式与过去也不一样。我们还要考虑来自其他用户的威胁,这些用户与我们处在同一虚拟层上。好在 Google 已经考虑到了这些问题,他们在博客上就如何解决这些问题进行过讨论。

我们在 GCP 上为我们的大部分安控措施找到了等价的替代方案。我们还为静态数据加密找到了一种更好的替代方案。而对于其他一些安控措施,比如 IP 白名单,我们只能通过改造我们的架构,让它不再依赖传统的网络安控。我们使用包含了 Google 托管密钥的 CGP 服务账号来实现这一改造。

如何安全地使用 GCP 服务账号

迁移到云平台之后,原先的静态 CIDR 块被静态公共 IP 和动态公共 IP 的混合体所替代。维护 IP 白名单的成本非常高,而且在 CGP 的其他服务里并不存在这样的功能。

在我们的安控架构里,网络和用户数据之间包含至少两个安全层。内部服务全部被部署在一个安全的网络外围里,服务之间通过 API 密钥进行交互。我们以一种安全的方式来存储和分发这些密钥,不过仍然存在泄露或被盗的风险。如果真的发生泄露或被盗,我们还有第二个安全层。在我们的生产环境之外,秘钥失去了它们的作用,而要想进入生产环境使用这些秘钥,必须先通过双因子认证。

每一个 GCP 服务都是互联网服务,它们并没有提供面向用户的白名单安控机制用于访问 Google 计算引擎(GCE)项目里的主机。我们需要在密钥和用户数据之间添加另一个安全层。

我们使用 GCP 服务账号解决了这个问题。每个 GCE 项目都有一个默认的服务账号,在 GCE 中启动的实例可以通过这个账号来访问其他服务。Google 提供了一组公钥 / 私钥对,密钥对每 24 小时自动翻转一次。对于自定义的服务账号,也会执行相同的操作。我们可以为每个主机角色创建一个自定义服务账号,并通过配置虚拟实例来使用这些账号。现在,那些运行在这些虚拟实例上的应用就可以使用内置的 Google 托管密钥。

我们的运维工程师没有必要访问这些密钥,因为 Google 每天都会自动翻转这些密钥。要想访问到这些密钥只能通过渗透我们的基础设施,不过我们目前已经具备了相应的防护能力。

总的来说,我们对云平台的安全充满了信心。我们还会继续加强平台的安全,把不断变化的安全威胁甩在身后。

2017-03-30 17:003457
用户头像

发布了 322 篇内容, 共 140.0 次阅读, 收获喜欢 145 次。

关注

评论

发布
暂无评论
发现更多内容

CAP 原理及Doris 临时失效的处理过程

Acker飏

极客大学架构师训练营 CAP

学习总结 - 第 6 周

饶军

NOSQL - 第六周总结

孙志平

架构师训练营第6周作业

饶军

MySQL 高可用和分布式数据库(训练营第六课)

看山是山

zookeeper CAP 主从复制 主主复制 MySQL 高可用

CAP原则

熊威

架构师训练营第六周作业

王铭铭

week6 学习总结 Nosql

Z冰红茶

NOSQL - 第六周作业

孙志平

程序员的眼界真的不要,也不能只局限于技术

非著名程序员

极客时间 程序员 提升认知

探秘 Spring 的 PropertyEditor

CoderLi

Java spring 后台

架构师训练营第六周作业

sunnywhy

一个成都程序猿写于离开北京一周年与26岁生日的这一天

why技术

生活 程序人生 北漂 成都

架构师训练营第六周总结

sunnywhy

天猫小店、京东小店的问题分析

石云升

价值网络 新零售 天猫小店

架构师训练营第六周

大丁💸💵💴💶🚀🐟

CAP

Kiroro

CAP 原理

Z冰红茶

static关键字真能提高Bean的优先级吗?答:真能

YourBatman

spring springboot SpringCloud 极客大学架构师训练营 Spring Bean

「1.4万字」玩转前端 Video 播放器 | 多图预警

阿宝哥

大前端 流媒体 Video播放器 HLS

学会使用Vue JSX,一车老干妈都是你的

前端有的玩

Java Vue 大前端 技巧 React

图解:有向环、拓扑排序与Kosaraju算法

淡蓝色

Java 数据结构 算法

我学会了用Python预测股票价格

博文视点Broadview

Python 读书笔记 算法 数据分析

蟒周刊-429-Python 3.8.4 可用ed

ZoomQuiet大妈

Python 大妈 蟒周刊

总结

Kiroro

架构师训练营」第 6 周作业

edd

极客大学架构师训练营

Apache Flink 是什么?

Apache Flink

flink

Doris 临时失效 UML 时序图(训练营第六周)

看山是山

Doris

猿灯塔:spring Boot Starter开发及源码刨析(六)

猿灯塔

最右JS2Flutter框架——渲染机制(二)

刘剑

flutter 大前端 跨平台 探索与实践

GaussDB for DWS:内存自适应控制技术总结

华为云开发者联盟

大数据 数据湖 内存管理 sql 华为云

Evernote从自有数据中心到Google云的迁移-第1篇_Google_薛命灯_InfoQ精选文章