大型系统应用架构实践 - 路由服务

886 阅读3分钟

希望分布在全球的用户能访问延迟最小的机房,性能优先,同时兼顾容灾

路由表

告知调用方,用户应该归属于那个机房。书中的返回结果是:归属机房和用户状态

  • 用户状态:记录用户迁移或者容灾中,当前用户处于那个阶段,确保数据一致性

路由表原理

约束

  1. 必须保存在内存中,且尽量少的占用内存
  2. 查询快
  3. 不能依赖第三方系统
  4. 路由表设计应支持自由升级

方案比较

image.png

书中的方案

使用比特数组,考虑到要知道机房,假设共有8个机房,那么将3位作为机房标识,1位做用户状态标识,即可将(0,3)内的下标表示一个用户

  • 一个用户占据4bit,1亿只需要47MB

方案的问题:用户ID分布不均匀

  • 尽管实际上只有1亿左右用户,但是占据了20亿的数据区域范围

解决方案:分段

  • 假设以100万为分段,如果这段内没有数据,也就指向null,节省空间

机房容灾和扩容

  • 问题:比如双十一临时某个机房流量比较大,需要分流到另一个机房
  • 方案:引入逻辑机房,逻辑机房在需要的时候可以映射到物理机房、灾备机房或者分流机房

路由表更新

约束

  1. 数据一致性:变更过程中,会出现一个用户归属信息在不同机房或机器节点不一致的可能性,出现后会导致多地写数据,从而失去一致性
  2. 可恢复、可回滚:系统本身应该能确定恢复到某一个期望状态,比如 变更过程中的失败,需要恢复到上一个正常状态
  3. 快速变更:不希望影响用户体验

方案

加入中间状态。系统原来就只有状态A、状态C,二者是不能共存的,加入中间状态B,AB或者BC都能共存

路由表变更则是加入了一个禁写的状态,通过禁写状态将新旧路由的生效时间严格的隔离开来

  • 禁写会影响用户体验,需要在用户不活跃的阶段进行变更
  • 用户状态这里就是指,用户是否可以写入

技术方案执行

  • 引入zk和tair,将要变更的数据版本写入tair,准备好后,将版本推入zk,所有的watcher(需要加载路由的机器)都收到推送,执行变更
  • 针对zk本身的一些异常、特性做一致性的处理

逻辑执行

  • 变更的时候找用户最空闲的时间,对同一个时间段内对用户进行批量的变更
  • 对需要进行变更的用户进行同slot、同源、同目标分组,批量变更

如何确定用户的归属机房?

以区域(国家或大洲)为单位,将用户多端DNS解析以及路由表映射到性能最好的机房

  • 每个用户对机房进行探测,按照区域统计,再把区域中的所有用户跟性能最好的进行连接

如何将存量用户加入路由表?

主要场景是:方案刚上线和新机房启用。主要做的事情是,重新计算目前系统中的用户归属,按照逻辑执行中的方式进行渐进式的变更即可

新用户加入后如何进行增量的路由更新?

主要场景是:新用户注册和用户迁移。新注册用户首先归属默认机房,然后进行多机房探测,必要时进行增量更新,方案与存量更新一致

参考

《大型系统应用架构实践》