7.1 MapReduce Offline... 33 7.2 Online 计 算... 34 7.2.1 流 式 计 算... 34 7.2.2 并 行 数 据 库 的 SQL 查 询... 35 7.2.3 数 据 仓 库 复 杂 查 询... 36 8 应 用... 38 8.1 电 子 商

Similar documents
支付宝2011年 IT资产与费用预算

PowerPoint 演示文稿

Oracle 4

温州市政府分散采购

深入理解otter

从上面这个表格中我们可以很明显看到巨大的差异当数据全部缓存到内存中 内存大小会影响所有操作 不管是 SELECT 还是 INSERT/UPDATE/DELETE 操作 INSERT 当往一个随机排序的索引中插入数据的时候会造成随机的读/写 UPDATE/DELETE 当更改数据的时候会导致磁盘的读/

2005 3

ebook 132-2

A API Application Programming Interface 见 应 用 程 序 编 程 接 口 ARP Address Resolution Protocol 地 址 解 析 协 议 为 IP 地 址 到 对 应 的 硬 件 地 址 之 间 提 供 动 态 映 射 阿 里 云 内

Simulator By SunLingxi 2003

ebook 132-6

穨control.PDF

SiteView技术白皮书

Azure_s

untitled

项目采购需求编写模板

1 o o o CPU o o o o o SQL Server 2005 o CPU o o o o o SQL Server o Microsoft SQL Server 2005

季刊9web.indd

摘 要 1. GSLB: 全 局 负 载 均 衡 2. SLB: 服 务 器 负 载 均 衡 四 层 交 换 LVS 七 层 交 换 Nginx 3. Heartbeat 实 现 HA 4. MySQL 数 据 库 集 群 5. 集 群 环 境 下 的 存 储 备 份 6. 集 群 的 监 控 及

Microsoft Word htm

Microsoft Word - 134招标文件.doc

Partition Key: 字 符 串 类 型, 表 示 当 前 Entity 的 分 区 信 息 这 个 Property 对 于 Table Service 自 动 纵 向 和 横 向 扩 展 至 关 重 要 Row Key: 字 符 串 类 型, 在 给 定 Partition Key 的

案例分享产品文档

untitled

學 科 100% ( 為 單 複 選 題, 每 題 2.5 分, 共 100 分 ) 1. 請 參 閱 附 圖 作 答 : (A) 選 項 A (B) 選 項 B (C) 選 項 C (D) 選 項 D Ans:D 2. 下 列 對 於 資 料 庫 正 規 化 (Normalization) 的 敘

Chap6.ppt

SAP HANA 最 简 单 的 理 解 ERP CRM SRM BI 列 存 储 2

IT Data-intensive application,iscsi Middl

Dell EMC Data Domain DDOS 5.5 Data Domain Data Domain Data Domain : Data Domain Boost (DDBoost) Dell EMC DDBoost Data Domain DDBoost Source De-Dup Bac

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

Go构建日请求千亿微服务最佳实践的副本

第一章 Linux與網路資源

ebook 96-16

自由軟體教學平台

经华名家讲堂

PIC_SERVER (11) SMTP ( ) ( ) PIC_SERVER (10) SMTP PIC_SERVER (event driven) PIC_SERVER SMTP 1. E-

BYOD Http Redirect convergence Client (1) 2008R2 NLB( ) (2) NLB Unicast mode switch flooding (arp ) NLB DNS Redirect 1. Round-Robin DNS DNS IP/DNS Cli

第 1 章 概 述 1.1 计 算 机 网 络 在 信 息 时 代 中 的 作 用 1.2 计 算 机 网 络 的 发 展 过 程 *1.2.1 分 组 交 换 的 产 生 *1.2.2 因 特 网 时 代 *1.2.3 关 于 因 特 网 的 标 准 化 工 作 计 算 机 网 络 在

Socket Socket TcpClient Socket.Connect TcpClient.Connect Socket.Send / Receive NetworkStream 6-5

业 务 与 运 营 Business & Operation (Transform) 加 载 (Load) 至 目 的 端 的 过 程, 该 部 分 在 数 据 挖 掘 和 分 析 过 程 中 为 最 基 础 的 一 部 分 一 个 良 好 的 ETL 系 统 应 该 有 以 下 几 个 功 能 1

C10_ppt.PDF

一 套 真 正 只 用 Server Cluster 集 群 结 构 的 模 式 覆 盖 多 种 硬 件 平 台 操 作 系 统 和 数 据 库 的 数 据 传 输 平 台 和 联 机 事 务 处 理 软 件, 并 且 能 够 自 由 组 合 这 些 平 台 形 成 最 佳 应 用 环 境 具 有

目錄... ivv...vii Chapter DETECT

Microsoft Word - Web Dynpro For ABAP跟踪测试工具简介 _2_.doc

Cloudy computing forEducation

Bus Hound 5

(Methods) Client Server Microsoft Winsock Control VB 1 VB Microsoft Winsock Control 6.0 Microsoft Winsock Control 6.0 1(a). 2

untitled

目 录 简 介... 3 MYSQL 企 业 版... 3 MYSQL 数 据 库... 3 MYSQL 企 业 备 份 工 具... 4 MYSQL 企 业 版 监 控 器 和 顾 问 工 具... 4 MYSQL 查 询 分 析 器... 7 MYSQL WORKBENCH... 8 MYSQL

untitled

PowerPoint 演示文稿

目錄

經濟統計資料庫管理資訊系統


Hitachi Vantara Hitachi Vantara Hitachi, Ltd. Hitachi Vantara IT OT Go Go

第一章标准答案.doc

Microsoft Word - 選擇_無解答2_.doc

W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO

VASP应用运行优化

<4D F736F F D CAD3C6B5BCE0BFD8BDE2BEF6B7BDB0B8A3A8B4E6B4A2B2BFCAF0A3A9BCBCCAF5B0D7C6A4CAE92E646F63>

合集

2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM

合, 采 取 有 效 的 跟 进 和 配 套 措 施, 加 强 事 中 事 后 监 管, 防 止 出 现 管 理 脱 节, 不 断 提 高 政 府 管 理 科 学 化 规 范 化 法 治 化 水 平 附 件 :1. 省 政 府 决 定 取 消 的 行 政 审 批 事 项 目 录 2. 省 政 府 决

QVM330 多阜寬頻路由器

热设计网

1. 二 進 制 數 值 ( ) 2 轉 換 為 十 六 進 制 時, 其 值 為 何? (A) ( 69 ) 16 (B) ( 39 ) 16 (C) ( 7 A ) 16 (D) ( 8 A ) 在 電 腦 術 語 中 常 用 的 UPS, 其 主 要 功 能

电力信息化2013年第1期.indb

(UTM???U_935_938_955_958_959 V )

% ~ AAA

Xilinx Alliance Program Certified GJVZsIPb3 IPb3pg(lwE & by2eh;[d)y IP ROM

例 如, 一 个 含 有 2000 个 记 录 的 文 件, 每 个 磁 盘 块 可 容 纳 250 个 记 录, 则 该 文 件 包 含 8 个 磁 盘 块 然 后 对 该 文 件 作 二 路 归 并 的 外 排 序, 每 次 往 内 存 读 入 两 个 磁 盘 块, 排 序 后 再 写 回 磁

/ / (FC 3)...

目 录 1. 业 务 流 程 系 统 开 发 面 临 的 挑 战 与 机 遇 业 务 流 程 管 理 新 一 代 开 源 业 务 流 程 开 发 平 台 BPMX BPMX3 是 什 么 为 什 么 要 优 先 采 用 BPMX

2013_6_3.indd

声 明 本 公 司 及 全 体 董 事 监 事 高 级 管 理 人 员 承 诺 不 存 在 任 何 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏, 并 对 其 真 实 性 准 确 性 完 整 性 承 担 个 别 和 连 带 的 法 律 责 任 本 公 司 负 责 人 和 主 管 会 计 工

<4D F736F F D20C9CFBAA3CAD0BCC6CBE3BBFAB5C8BCB6BFBCCAD4C8FDBCB6BFBCCAD4B4F3B8D95FBDA8D2E9B8E55F5F E646F63>

6-1 Table Column Data Type Row Record 1. DBMS 2. DBMS MySQL Microsoft Access SQL Server Oracle 3. ODBC SQL 1. Structured Query Language 2. IBM

IBM System x 系列手册

ebook10-5

<4D F736F F D20312D3120B9ABBFAAD7AAC8C3CBB5C3F7CAE9A3A8C9EAB1A8B8E5A3A92E646F63>

2 : ; :

网宿科技股份有限公司2016年半年度报告全文

十萬元以上採購、修繕

QVM330 多阜寬頻路由器

EMC® VNX® Series VNX8000™ Block 安装指南

叮当旺业通

C6_ppt.PDF

SL2511 SR Plus 操作手冊_單面.doc

hks298cover&back

校友会系统白皮书feb_08

Symantec™ Sygate Enterprise Protection 防护代理安装使用指南

Microsoft Word - 13院21号.doc

ebook 145-6



untitled

目 录 目 录 平 台 概 述 技 术 架 构 技 术 特 点 基 于 统 一 平 台 的 多 产 品 线 支 撑 先 进 性 安 全 性 开 放 性 高 性 能 和

jdbc:hsqldb:hsql: jdbc:hsqldb:hsqls: jdbc:hsqldb:http: jdbc:hsqldb:https: //localhost // :9500 / /dbserver.somedomain.com /an_alias /enrollme

IP TCP/IP PC OS µclinux MPEG4 Blackfin DSP MPEG4 IP UDP Winsock I/O DirectShow Filter DirectShow MPEG4 µclinux TCP/IP IP COM, DirectShow I

<4D F736F F D20CFB5B7D62DCFC2CEE749CAD4CCE22D3037C9CF>

Transcription:

分 布 式 系 统 工 程 实 践 杨 传 辉 日 照 @ 淘 宝 V 0.1 2010-10 分 布 式 系 统 工 程 实 践... 1 1 引 言... 3 2 基 础 知 识... 3 2.1 硬 件 基 础... 4 2.2 性 能 估 算... 4 2.3 CAP... 6 2.4 一 致 性 模 型... 7 2.5 NOSQL 与 SQL... 9 2.6 Two-Phase commit... 10 2.7 Paxos... 11 3 关 键 技 术 实 现... 12 3.1 网 络 编 程 框 架... 12 3.2 HA 与 Replication... 13 3.3 分 裂... 14 3.4 迁 移... 15 3.5 负 载 均 衡... 16 3.6 Chubby... 16 3.7 分 布 式 事 务... 17 3.8 Copy-on-write 与 Snapshot... 17 3.9 操 作 日 志 与 checkpoint... 19 3.10 列 式 存 储 与 压 缩... 19 4 通 用 存 储 系 统 分 类... 20 5 典 型 存 储 系 统 工 程 实 现... 21 5.1 单 机 存 储 引 擎... 21 5.1.1 随 机 访 问 存 储 引 擎... 21 5.1.2 通 用 存 储 引 擎... 22 5.1.3 单 机 存 储 优 化... 23 5.2 SQL 数 据 库... 23 5.3 线 上 最 终 一 致 性 系 统... 24 5.4 线 上 弱 一 致 性 系 统... 26 5.5 半 线 上 及 线 下 系 统... 29 5.5.1 两 层 结 构... 29 5.5.2 GFS... 30 5.5.3 Bigtable... 31 6 通 用 计 算 系 统 分 类... 32 7 典 型 计 算 系 统 工 程 实 现... 33

7.1 MapReduce Offline... 33 7.2 Online 计 算... 34 7.2.1 流 式 计 算... 34 7.2.2 并 行 数 据 库 的 SQL 查 询... 35 7.2.3 数 据 仓 库 复 杂 查 询... 36 8 应 用... 38 8.1 电 子 商 务 类... 38 8.2 搜 索 类... 38 8.3 社 交 类... 39 8.4 邮 箱 类... 40 8.5 图 片 及 视 频 类... 40 8.6 数 据 仓 库 类... 40 8.7 云 服 务 类... 41 9 工 程 实 现 注 意 事 项... 41 9.1 工 程 现 象... 41 9.2 规 范 制 订... 42 9.3 经 验 法 则... 42 9.4 质 量 控 制... 42 9.4.1 测 试 第 一... 42 9.4.2 代 码 Review... 42 9.4.3 服 务 器 程 序 的 资 源 管 理... 43 10 致 谢... 43 11 参 考 文 献... 43 11.1 书 籍 类... 43 11.2 论 文 类... 43 11.2.1 分 布 式 理 论... 43 11.2.2 Google 系 列... 44 11.2.3 Dynamo 及 P2P 系 列... 44 11.2.4 存 储 系 统... 44 11.2.5 计 算 系 统... 44 11.2.6 其 它... 44 11.3 网 页 类... 45 11.3.1 个 人 博 客 类... 45 11.3.2 专 题 类... 45 11.3.3 其 它... 45

1 引 言 NOSQL 的 资 料 很 多, 不 过 不 成 体 系, 让 分 布 式 系 统 开 发 工 程 师 无 所 适 从 笔 者 根 据 过 去 跟 着 阳 老 师 开 发 类 似 Google GFS/MapReduce/Bigtable 的 系 统 以 及 对 Dynamo, PNUTS 等 典 型 系 统 的 理 解 尝 试 梳 理 流 行 的 分 布 式 存 储 和 计 算 系 统 的 分 类, 设 计 及 实 现 本 文 结 构 安 排 如 下 : 基 础 知 识 : 一 个 大 规 模 数 据 处 理 系 统 工 程 师 必 备 的 基 础 知 识 ; 关 键 技 术 实 现 : 工 程 实 践 中 遇 到 的 典 型 问 题 的 解 决 思 路 ; 通 用 存 储 系 统 分 类 : 讲 述 笔 者 关 于 存 储 系 统 如 何 划 分 的 个 人 观 点 ; 典 型 存 储 系 统 工 程 实 现 : 选 取 典 型 的 存 储 系 统 讲 述 大 致 实 现 ; 通 用 计 算 系 统 分 类 : 讲 述 笔 者 对 于 计 算 系 统 如 何 划 分 的 个 人 观 点 ; 典 型 计 算 系 统 工 程 实 现 : 讲 述 典 型 计 算 系 统 的 大 致 实 现 ; 应 用 : 存 储 & 计 算 系 统 应 用 的 一 些 实 例 ; 工 程 实 现 注 意 事 项 : 总 结 设 计 和 开 发 过 程 中 可 能 犯 的 一 些 错 误 ; 致 谢 及 参 考 资 料 : 列 出 一 些 值 得 看 的 论 文 和 网 页 资 料 ; 每 个 章 节 涉 及 的 话 题 都 很 大, 由 于 笔 者 的 水 平 实 在 是 非 常 非 常 有 限, 只 能 说 是 尽 力 把 自 己 知 道 并 能 够 说 明 白 的 写 下 来, 作 为 自 己 对 过 去 工 作 的 回 忆 把 其 中 任 何 一 个 话 题 讲 明 白 都 远 远 超 出 了 我 的 能 力 范 畴, 写 错 的 地 方 在 所 难 免, 各 位 同 学 发 现 问 题 尽 管 笑 一 笑, 当 然, 欢 迎 任 何 形 式 的 讨 论, 我 会 尽 量 和 更 多 的 同 学 讨 论 来 不 断 完 善 这 个 文 档 本 文 只 是 一 个 初 始 综 述, 后 续 将 细 化 每 一 个 问 题 并 发 表 到 博 客 中 2 基 础 知 识 本 章 描 述 工 程 实 现 需 要 的 一 些 基 础 知 识, 由 于 篇 幅 的 关 系, 只 抽 取 一 些 认 为 对 理 解 和 设 计 大 规 模 系 统 必 要 的 基 础 知 识 进 行 描 述 另 外, 假 设 读 者 了 解 NOSQL 基 本 概 念, 做 过 或 者 看 过 一 两 个 类 似 的 系 统, 阅 读 过 GFS/Bigtable/Paxos 相 关 的 论 文 分 布 式 理 论 有 一 个 特 点 是 : 大 致 的 做 法 是 很 容 易 想 到 的, 但 是 完 全 没 有 问 题 的 做 法 非 常 难 想, 理 解 理 论 的 用 处 就 在 于 区 分 出 想 法 的 问 题 在 哪 儿 以 及 实 现 的 难 度

2.1 硬 件 基 础 分 布 式 系 统 开 发 工 程 师 需 要 了 解 硬 件 的 大 致 价 格, 熟 记 硬 件 的 性 能 硬 件 大 致 性 能 如 下 : L1 cache reference Branch mispredict L2 cache reference Mutex lock/unlock Main memory reference Send 1M bytes over 1Gbps network Read 1M sequentially from memory Round trip within data center Disk seek Read 1MB sequentially from disk 0.5ns 5ns 7ns 100ns 100ns 10ms 0.25ms 0.5ms 8~10ms 20~25ms 标 记 为 红 色 性 能 参 数 比 较 常 用, 其 中, 磁 盘 的 性 能 指 标 专 指 分 布 式 平 台 专 用 的 大 容 量 SATA 磁 盘, 寻 道 时 间 为 8~10ms, 顺 序 读 取 速 率 为 40~50MB 某 些 应 用 使 用 SAS 磁 盘 或 者 Flash 盘, 性 能 较 好, 评 估 时 需 查 看 硬 件 的 性 能 参 数 磁 盘 和 网 络 都 有 一 个 特 征, 一 次 读 写 的 数 据 量 越 大 性 能 越 好, 这 是 由 硬 件 特 征 及 底 层 软 件 算 法 决 定 的, 如 tcp 慢 连 接 和 磁 盘 寻 道 时 间 长 2.2 性 能 估 算 给 定 一 个 问 题, 往 往 会 有 多 种 设 计 方 案, 而 方 案 评 估 的 一 个 重 要 指 标 就 是 性 能, 如 何 在 系 统 设 计 时 估 算 而 不 是 程 序 执 行 时 测 试 得 到 性 能 数 据 是 系 统 架 构 设 计 的 重 要 技 能 性 能 估 算 有 如 下 用 途 : 1) 多 种 设 计 方 案 选 择 ; 2) 评 价 程 序 实 现 是 否 足 够 优 化 ; 3) 向 框 架 / 服 务 提 供 方 提 出 性 能 要 求 的 依 据 ;

很 多 同 学 喜 欢 通 过 查 看 程 序 运 行 时 CPU 及 网 络 的 使 用 情 况 来 评 价 程 序 是 否 足 够 优 化, 这 也 是 一 种 很 重 要 的 方 法 然 而, 这 种 方 法 掩 盖 了 不 优 化 的 实 现, 如 O(N) 的 算 法 被 错 误 实 现 成 O(N^2), 网 络 收 发 冗 余 数 据 等 性 能 评 估 需 要 假 设 程 序 的 执 行 环 境, 如 集 群 规 模 及 机 器 配 置, 集 群 上 其 它 服 务 占 用 资 源 的 比 例 对 硬 件 性 能 指 标 有 了 初 步 认 识 以 后, 我 们 可 以 做 出 一 些 简 单 的 判 断, 如 : 某 K-V 引 擎 RD: 我 们 的 K-V 引 擎 单 客 户 端 同 步 读 取 每 秒 可 以 达 到 18000/s 问 : 是 否 批 量 读 取? 答 : 是, 每 批 读 取 10 个 记 录 由 于 tcp Round trip 时 间 为 0.5ms, 读 取 请 求 个 数 的 理 论 极 限 为 2000/s, 而 上 例 中 K-V 引 擎 的 RD 却 说 单 客 户 同 步 读 取 可 以 达 到 18000/s, 可 以 断 定 该 RD 指 的 是 批 量 读 取 方 式 且 这 已 经 是 单 机 能 够 做 到 的 极 限 值 了 下 面 我 们 通 过 几 个 实 例 说 明 如 何 进 行 性 能 评 估 1. 1GB 的 4 字 节 整 数, 内 存 排 序 时 间 为 多 少? 拿 到 这 个 问 题, 我 们 往 往 会 计 算 CPU 运 算 次 数, 如 快 排 的 运 算 次 数 为 1.4 * N * log(n), 其 中 1.4 为 快 排 的 系 数, 再 根 据 CPU 的 运 算 频 率 计 算 出 排 序 耗 时 不 过 这 种 方 法 很 土 也 不 是 很 准,Jeff Dean 告 诉 我 们 可 以 这 样 估 算 : 排 序 时 间 = 比 较 时 间 ( 分 支 预 测 错 误 ) + 内 存 访 问 时 间 快 排 过 程 中 会 发 生 大 量 的 分 支 预 测 错 误, 所 以 比 较 次 数 为 2^28 * log (2^28) 2^33, 其 中 约 1/2 的 比 较 会 发 生 分 支 预 测 错 误, 所 以 比 较 时 间 为 1/2 * 2 ^ 32 * 5ns = 21s, 另 外, 快 排 每 次 找 到 分 割 点 都 需 要 一 遍 内 存 移 动 操 作, 而 内 存 顺 序 访 问 性 能 为 4GB/s, 所 以 内 存 访 问 时 间 为 28 * 1GB / 4GB = 7s 因 此, 单 线 程 排 序 1GB 4 字 节 整 数 总 时 间 约 为 28s 2. Bigtable 设 计 的 性 能 指 标 分 析 假 设 Bigtable 总 体 设 计 中 给 出 的 性 能 指 标 为 : 系 统 配 置 :50 台 4 核 8GB 内 存 12 路 SATA 硬 盘, 同 样 数 量 的 客 户 端 ; Table:row name:16-byte,column:16-byte,value:1kb;64kb data block;no compression; Random reads (in disk): 1KB/item*300item/s*50=15MB/s Random reads (in memory):1kb/item*4000item/s*50=200mb/s Random writes:1kb/item*2000item/s*50=100mb/s Sequential reads(in disk):1kb/item*1000item/s*50=50mb/s Sequential writes:1kb/item*2000item/s*50=100mb/s 先 看 磁 盘 中 的 随 机 读 取 性 能, 由 于 在 Bigtable 的 设 计 中 每 个 随 机 读 取 都 要 读 取 一 个 64KB 的 大 块, 而 磁 盘 中 读 取 64KB 数 据 时 间 为 : 磁 盘 寻 道 时 间 + 读 取 时 间 = 10ms + 64KB / 50MB/s = 12ms 所 以 每 秒 读 取 300 个 记 录 指 多 客 户 端 读 取 或 者 单 客 户 端 异 步 / 批 量 读 取 由 于 每 台 机 器 有 12 个 SATA 大 容 量 磁 盘, 随 机 读 的 理 论 值 为 12 * 1s / 12ms = 1000 个 /s 设 计 为 每 秒 读 取 300 个 是 考 虑 到 有 负 载 平 衡 等 因 素 简 单 地 打 了 一 个 折 扣 再 看 内 存 中 的 随 机 读 取 一 般 来 说, 内 存 操 作 都 是 每 秒 1W~10W 由 于 网 络 发 送 小 数 据 有 较 多 overhead 且 Bigtable 内 存 操 作 有 较 多 的 内 存 开 销, 所 以 保 守 设 计 为 单 机 每 秒 读 取 4000 个 记 录 其 它 的 可 类 似 分 析 性 能 分 析 可 能 会 很 复 杂, 因 为 不 同 的 情 况 下 决 定 性 能 的 瓶 颈 不 一 样,

有 的 时 候 是 网 络, 有 的 时 候 是 磁 盘, 有 的 时 候 甚 至 是 机 房 的 交 换 机 这 种 性 能 分 析 的 经 验 是 需 要 慢 慢 积 累 的 最 后, 我 们 再 看 看 某 一 个 MapReduce 应 用 的 例 子 MapReduce 可 以 简 单 地 分 为 几 个 过 程 :Map 处 理 时 间 + shuffle 和 排 序 时 间 + reduce 处 理 时 间, 虽 然 shuffle map 处 理 和 排 序 可 以 部 分 并 行, 但 性 能 估 算 的 时 候 不 必 考 虑 假 设 50 台 机 器, 原 始 输 入 为 50G, 例 中 MapReduce 应 用 的 map 函 数 处 理 时 间 为 100s,reduce 函 数 处 理 时 间 为 60s,shuffle 的 中 间 结 果 数 据 量 为 300G,reduce 输 出 的 最 终 结 果 大 小 为 600M Map 处 理 时 间 = 输 入 读 取 时 间 + Map 函 数 处 理 时 间 + 输 出 中 间 结 果 时 间 其 中, 输 入 读 取 时 间 = 50G / 2.5G = 25s (50 台 机 器, 假 设 每 台 机 器 读 取 带 宽 为 50M/s), Map 函 数 处 理 时 间 = 60s, 输 出 中 间 结 果 时 间 = 300G / 15G = 20s (50 台 机 器, 每 台 机 器 12 个 磁 盘, 假 设 用 满 6 个 磁 盘, 带 宽 为 6 * 50M = 300M) 所 以,Map 处 理 时 间 = 25s + 60s + 20s = 105s Shuffle 和 排 序 时 间 = shuffle 时 间 + 排 序 时 间 其 中,shuffle 时 间 = 300G / 2G = 150s (50 台 机 器, 假 设 每 台 机 器 的 读 取 和 写 入 带 宽 均 为 40M, 单 机 总 带 宽 为 80M) 排 序 时 间 = 单 机 排 序 6G 的 时 间, 假 设 每 条 记 录 为 1KB = 排 序 比 较 时 间 + 访 问 时 间, 约 为 25s 所 以,shuffle 和 排 序 的 时 间 = 150s + 25s = 175s Reduce 处 理 时 间 = reduce 函 数 处 理 时 间 + 最 终 结 果 输 出 时 间 其 中,reduce 函 数 处 理 时 间 = 100s, 最 终 结 果 输 出 时 间 = 600M / 500M (50 台 机 器, 单 机 写 DFS 假 设 时 间 为 10M/s) = 1s ( 忽 略 ) 所 以, 例 中 的 MapReduce 应 用 运 行 一 遍 大 致 需 要 的 时 间 = Map 处 理 时 间 + shuffle 和 排 序 时 间 + Reduce 处 理 时 间 = 105s + 175s + 100s = 380s, 当 然,MapReduce 过 程 中 还 有 框 架 的 开 销 和 其 它 应 用 的 影 响, 我 们 可 以 简 单 地 认 为 影 响 为 20%, 所 以 总 时 间 = 380s + 380s * 20% = 456s, 约 为 7~8 min 当 然,MapReduce 应 用 实 际 的 性 能 估 算 不 会 如 此 简 单, 实 际 估 算 时 需 要 考 虑 每 台 机 器 上 启 动 的 Map 和 Reduce 个 数 等 因 素, 且 需 要 根 据 实 验 的 结 果 不 断 地 验 证 和 重 新 调 整 估 算 但 是, 我 们 至 少 可 以 保 证, 估 算 的 结 果 和 实 际 不 会 相 差 一 个 数 量 级, 估 算 结 果 可 以 用 来 指 导 初 期 的 设 计 和 Map/Reduce Worker 的 个 数 Map/Reduce 任 务 数 选 择, 评 估 应 用 的 可 优 化 空 间 并 作 为 向 MapReduce 框 架 提 供 小 组 提 出 需 求 的 依 据 性 能 估 算 是 大 规 模 系 统 设 计 中 较 难 掌 握 的 技 能, 开 始 性 能 估 算 时 可 能 估 计 得 很 不 准, 不 过 不 要 气 馁, 通 过 在 项 目 中 不 断 练 习, 大 规 模 系 统 的 分 析 和 设 计 能 力 才 能 做 到 有 理 可 依 2.3 CAP CAP 是 一 个 很 时 髦 的 概 念, 然 而, 对 于 设 计 和 实 现 大 规 模 分 布 式 系 统 而 言, 只 需 要 在 脑 海 里 面 有 一 个 粗 略 的 概 念 即 可 我 们 先 看 看 CAP 是 怎 么 回 事 CAP 理 论 由 Berkerly 的 Brewer 教 授 提 出, 在 最 初 的 论 文 中, 三 者 含 义 如 下 : 一 致 性 (Consistency): 任 何 一 个 读 操 作 总 是 能 读 取 到 之 前 完 成 的 写 操 作 结 果 ;

可 用 性 (Availability): 每 一 个 操 作 总 是 能 够 在 确 定 的 时 间 内 返 回 ; 分 区 可 容 忍 性 (Tolerance of network Partition): 在 出 现 网 络 分 区 的 情 况 下, 仍 然 能 够 满 足 一 致 性 和 可 用 性 ; CAP 理 论 认 为, 三 者 不 能 同 时 满 足, 并 给 出 了 证 明, 简 单 阐 述 如 下 : 假 设 系 统 出 现 网 络 分 区 为 G1 和 G2 两 个 部 分, 在 一 个 写 操 作 W1 后 面 有 一 个 读 操 作 R2,W1 写 G1,R2 读 取 G2, 由 于 G1 和 G2 不 能 通 信, 如 果 读 操 作 R2 可 以 终 结 的 话, 必 定 不 能 读 取 写 操 作 W1 的 操 作 结 果 然 而, 这 种 对 一 致 性 及 可 用 性 的 定 义 方 法 在 工 程 实 践 上 意 义 不 大,CAP 理 论 只 是 粗 略 地 告 诉 我 们 天 下 没 有 免 费 的 午 餐 比 如 Availability 的 定 义,10 秒 钟 停 服 务 和 1 个 小 时 停 服 务 在 工 程 实 践 中 完 全 是 两 个 概 念 因 此, 我 们 往 往 会 修 改 CAP 的 定 义 如 下 : 一 致 性 (Consistency): 读 操 作 总 是 能 读 取 到 之 前 完 成 的 写 操 作 结 果, 满 足 这 个 条 件 的 系 统 称 为 强 一 致 系 统, 这 里 的 之 前 一 般 对 同 一 个 客 户 端 而 言, 但 可 能 是 一 个 客 户 端 的 多 个 Session; 可 用 性 (Availability): 读 写 操 作 在 单 台 机 器 发 生 故 障 的 情 况 下 仍 然 能 够 正 常 执 行, 而 不 需 要 等 到 机 器 重 启 或 者 机 器 上 的 服 务 分 配 给 其 它 机 器 才 能 执 行 ; 分 区 可 容 忍 性 (Tolerance of network Partition): 机 房 停 电 或 者 机 房 间 网 络 故 障 的 时 候 仍 然 能 够 满 足 一 致 性 和 可 用 性 ; 工 程 实 践 对 网 络 分 区 考 虑 较 少, 一 般 可 以 认 为 : 一 致 性 和 写 操 作 的 可 用 性 不 能 同 时 满 足, 即 如 果 要 保 证 强 一 致 性, 那 么 出 现 机 器 故 障 的 时 候, 写 操 作 需 要 等 机 器 重 启 或 者 机 器 上 的 服 务 迁 移 到 别 的 机 器 才 可 以 继 续 2.4 一 致 性 模 型 Amazon 的 CTO 专 门 在 官 网 中 阐 述 了 一 致 性 模 型, 足 见 其 重 要 性, 可 以 认 为, 一 致 性 要 求 直 接 决 定 了 存 储 系 统 设 计 和 实 现 的 复 杂 度 为 了 更 好 的 描 述 客 户 端 一 致 性, 我 们 通 过 以 下 的 场 景 来 进 行, 这 个 场 景 中 包 括 三 个 组 成 部 分 : 存 储 系 统 存 储 系 统 可 以 理 解 为 一 个 黑 盒 子, 它 为 我 们 提 供 了 可 用 性 和 持 久 性 的 保 证 Process A Process A 主 要 实 现 从 存 储 系 统 write 和 read 操 作 Process B 和 Process C Process B 和 C 是 独 立 于 A, 并 且 B 和 C 也 相 互 独 立 的, 它 们 同 时 也 实 现 对 存 储 系 统 的 write 和 read 操 作 下 面 以 上 面 的 场 景 来 描 述 下 不 同 程 度 的 一 致 性 : 强 一 致 性 强 一 致 性 ( 即 时 一 致 性 ) 假 如 A 先 写 入 了 一 个 值 到 存 储 系 统, 存 储 系 统 保 证 后 续 A,B,C 的 读 取 操 作 都 将 返 回 最 新 值 弱 一 致 性

假 如 A 先 写 入 了 一 个 值 到 存 储 系 统, 存 储 系 统 不 能 保 证 后 续 A,B,C 的 读 取 操 作 能 读 取 到 最 新 值 此 种 情 况 下 有 一 个 不 一 致 性 窗 口 的 概 念, 它 特 指 从 A 写 入 值, 到 后 续 操 作 A,B,C 读 取 到 最 新 值 这 一 段 时 间 最 终 一 致 性 最 终 一 致 性 是 弱 一 致 性 的 一 种 特 例 假 如 A 首 先 write 了 一 个 值 到 存 储 系 统, 存 储 系 统 保 证 如 果 在 A,B,C 后 续 读 取 之 前 没 有 其 它 写 操 作 更 新 同 样 的 值 的 话, 最 终 所 有 的 读 取 操 作 都 会 读 取 到 最 A 写 入 的 最 新 值 此 种 情 况 下, 如 果 没 有 失 败 发 生 的 话, 不 一 致 性 窗 口 的 大 小 依 赖 于 以 下 的 几 个 因 素 : 交 互 延 迟, 系 统 的 负 载, 以 及 复 制 技 术 中 replica 的 个 数 ( 这 个 可 以 理 解 为 master/salve 模 式 中,salve 的 个 数 ) 一 致 性 模 型 的 变 体 如 下 : Causal consistency( 因 果 一 致 性 ) 如 果 Process A 通 知 Process B 它 已 经 更 新 了 数 据, 那 么 Process B 的 后 续 读 取 操 作 则 读 取 A 写 入 的 最 新 值, 而 与 A 没 有 因 果 关 系 的 C 则 可 以 最 终 一 致 性 Read-your-writes consistency 如 果 Process A 写 入 了 最 新 的 值, 那 么 Process A 的 后 续 操 作 都 会 读 取 到 最 新 值 但 是 其 它 用 户 可 能 要 过 一 会 才 可 以 看 到 Session consistency 此 种 一 致 性 要 求 客 户 端 和 存 储 系 统 交 互 的 整 个 会 话 阶 段 保 证 Read-your-writes, 数 据 库 分 库 以 后 一 般 会 提 供 这 种 一 致 性 保 证, 使 得 同 一 个 Session 的 读 写 操 作 发 送 到 同 一 台 数 据 库 节 点 Monotonic read consistency 此 种 一 致 性 要 求 如 果 Process A 已 经 读 取 了 对 象 的 某 个 值, 那 么 后 续 操 作 将 不 会 读 取 到 更 早 的 值 Monotonic write consistency 此 种 一 致 性 保 证 系 统 会 序 列 化 执 行 一 个 Process 中 的 所 有 写 操 作 为 了 便 于 后 续 的 说 明, 我 们 修 改 Amazon CTO 关 于 最 终 一 致 性 的 定 义 Dynamo 通 过 NWR 策 略 提 供 的 最 终 一 致 性 主 要 是 针 对 Dynamo 的 多 个 副 本 而 言 的, 它 们 之 间 保 持 最 终 一 致 不 过 对 于 用 户, 我 们 假 设 N=3, W=2, R=2 的 一 种 情 况, 用 户 先 调 用 W1 写 A 和 B 两 个 副 本 后 成 功 返 回, 接 着 调 用 W2 写 B 和 A 两 个 副 本 后 成 功 返 回, 可 能 出 现 在 副 本 A 上 W1 先 于 W2 执 行, 而 在 副 本 B 上 W2 先 于 W1 执 行, 虽 然 副 本 A 和 B 都 能 够 通 过 执 行 满 足 交 换 律 的 合 并 操 作, 比 如 基 于 last write wins 的 策 略 进 行 合 并 使 得 最 终 副 本 A 和 B 上 的 数 据 完 全 一 致, 但 是 可 能 出 现 一 些 异 常 情 况, 比 如 副 本 A 和 B 所 在 的 机 器 时 钟 不 一 致, 合 并 的 结 果 是 W1 把 W2 给 覆 盖 了,W2 的 操 作 结 果 消 失 了 这 显 然 与 用 户 的 期 望 是 不 一 致 的 为 了 方 便 后 续 对 系 统 进 行 划 分, 我 们 把 Amazon Dynamo 这 种 需 要 依 赖 操 作 合 并, 可 能 会 丢 失 数 据 的 模 型 从 最 终 一 致 性 模 型 中 排 除 出 去 最 终 一 致 性 模 型 要 求 同 一 份 数 据 同 一 时 刻 只 能 被 一 台 机 器 修 改, 也 就 是 说 机 器 宕 机 时 需 要 停 很 短 时 间 写 服 务 Amazon Dynamo 提 供 的 一 致 性 模 型 我 们 归 类 到 一 般 的 弱 一 致 性 模 型 中

2.5 NOSQL 与 SQL NOSQL 可 以 认 为 是 选 取 了 SQL 特 性 的 子 集, 在 扩 展 性 和 用 户 接 口 友 好 两 个 方 面 做 了 一 个 权 衡 越 多 选 择, 越 多 迷 茫, 实 践 经 验 告 诉 我 们, 如 果 将 SQL 的 功 能 完 全 暴 露 给 用 户, 用 户 一 定 会 使 用 一 些 我 们 不 希 望 的 功 能, 比 如 多 表 join, 外 键, 等 等 NOSQL 的 意 义 在 于, 我 们 预 先 定 义 一 些 特 性, 这 些 特 性 满 足 某 一 个 应 用 的 需 求, 并 且 只 满 足 这 些 特 性 使 得 我 们 的 系 统 很 容 易 扩 展 SQL 定 义 了 一 个 功 能 全 集,NOSQL 根 据 应 用 特 点 选 取 几 种 特 定 的 应 用 定 义 不 同 的 特 性 集 合, 以 适 应 互 联 网 数 据 量 高 速 膨 胀 的 需 求 一 般 来 说,NOSQL 的 应 用 会 比 SQL 的 应 用 更 加 注 意 可 用 性, 所 以 NOSQL 应 用 对 外 表 现 为 经 常 可 以 选 择 最 终 一 致 性 模 型 不 过, 从 通 用 系 统 的 角 度 看, 这 里 的 最 终 一 致 性 指 : 大 多 数 操 作 允 许 读 取 老 的 数 据, 少 数 操 作 仍 然 希 望 读 取 最 新 的 数 据, 并 且 应 用 不 希 望 出 现 数 据 丢 失 的 情 况 所 以, 不 能 因 为 NOSQL 就 容 忍 数 据 丢 失 的 情 况, 虽 然 这 会 极 大 地 加 大 系 统 设 计 和 实 现 的 难 度 另 外,NOSQL 不 等 于 必 须 用 MapReduce 做 计 算 模 型, 虽 然 二 者 经 常 结 对 出 现, 不 过 本 质 上 是 不 相 关 的 NOSQL 比 较 常 见 的 模 型 包 括 : KV 模 型 : 只 支 持 最 简 单 的 针 对 <key, value> 对 的 操 作 支 持 简 单 table schema 的 模 型, 如 Bigtable 模 型 由 于 NOSQL 相 对 SQL 而 言 更 加 注 重 扩 展 性 成 本 等,NOSQL 有 一 些 共 同 的 设 计 原 则 : 假 设 失 效 是 必 然 发 生 的 :NOSQL 注 意 扩 展 性 和 成 本, 机 器 数 变 多 时, 原 本 属 于 异 常 现 象 的 机 器 故 障 变 成 一 种 正 常 现 象,NOSQL 也 采 用 一 些 比 较 便 宜 的 普 通 PC 机, 要 求 通 过 软 件 的 方 法 处 理 错 误 限 定 应 用 模 式 从 最 为 简 单 的 KV 应 用 模 型, 到 复 杂 的 支 持 用 户 自 定 义 schema 的 Bigtable 模 型,NOSQL 支 持 的 接 口 永 远 不 可 能 和 SQL 相 比 一 般 来 说,NOSQL 系 统 都 只 支 持 随 机 读 和 顺 序 读, 少 量 系 统 支 持 表 索 引, 类 似 外 键 这 种 影 响 扩 展 性 且 不 实 用 的 功 能 基 本 是 不 需 要 支 持 的 扩 容 : 数 据 库 扩 容 一 般 是 成 倍 增 加 机 器 的, 而 NOSQL 系 统 一 般 是 一 台 或 者 少 量 几 台 构 成 一 个 机 器 组 加 入 系 统 一 般 有 两 种 数 据 分 布 方 法, 一 种 是 一 致 性 Hash, 这 个 算 法 在 Dynamo 论 文 中 有 详 细 的 介 绍, 另 外 一 种 方 法 是 将 整 个 表 格 分 成 连 续 的 小 段, 每 个 小 段 是 一 个 子 表, 由 全 局 管 理 机 器 负 责 将 每 个 小 段 分 配 到 新 加 入 的 数 据 读 写 服 务 机 器 用 一 个 例 子 说 明 取 舍 SQL 的 部 分 特 性 带 来 的 好 处 比 如 单 机 SQL 的 add 操 作, 这 是 非 常 容 易 的, 然 而, 在 多 机 上 的 实 现 变 得 非 常 困 难 因 为 我 们 需 要 操 作 多 个 副 本, 可 能 出 现 某 些 操 作 成 功, 某 些 永 远 不 成 功 的 情 况, 我 们 只 能 通 过 一 些 锁 的 方 法 来 解 决, 比 如 分 布 式 事 务 的 两 阶 段 悲 观 锁 或 者 另 外 一 种 乐 观 锁 Mysql 团 队 也 有 部 分 同 学 开 始 通 过 削 减 SQL 模 型 不 必 要 的 特 性 来 满 足 互 联 网 数 据 高 速 增 长 的 需 求, 它 们 发 起 了 一 个 叫 做 Drizzle 的 项 目 Drizzle 诞 生 于 MySQL(6.0) 关 系 数 据 库 的 拆 分 在 过 去 几 个 月 里, 它 的 开 发 者 已 经 移 走 了 大 量 非 核 心 的 功 能 ( 包 括 视 图 触 发 器 已 编 译 语 句 存 储 过 程 查 询 缓 冲 ACL 以 及 一 些 数 据 类 型 ), 其 目 标 是 要 建 立 一 个 更 精 简 更 快 的 数 据 库 系 统

2.6 Two-Phase commit 两 阶 段 提 交 用 于 解 决 分 布 式 事 务, 虽 然 分 布 式 事 务 解 决 的 代 价 比 较 大, 不 过 理 解 两 阶 段 锁 协 议 能 加 深 我 们 对 分 布 式 系 统 哪 些 问 题 是 困 难 的? 的 理 解 Two-phase commit 的 算 法 实 现 (from <<Distributed System: Principles and Paradigms>>): 协 调 者 (Coordinator): write START_2PC to local log; multicast VOTE_REQUEST to all participants; while not all votes have been collected { wait for any incoming vote; if timeout { write GLOBAL_ABORT to local log; multicast GLOBAL_ABORT to all participants; exit; } record vote; } if all participants sent VOTE_COMMIT and coordinator votes COMMIT { write GLOBAL_COMMIT to local log; multicast GLOBAL_COMMIT to all participants; } else { write GLOBAL_ABORT to local log; multicast GLOBAL_ABORT to all participants; } 参 与 者 (Participants) write INIT to local log; wait for VOTE_REQUEST from coordinator; if timeout { write VOTE_ABORT to local log; exit; } if participant votes COMMIT { write VOTE_COMMIT to local log; send VOTE_COMMIT to coordinator; wait for DECISION from coordinator; if timeout { multicast DECISION_REQUEST to other participants; wait until DECISION is received; /* remain blocked*/ write DECISION to local log; } if DECISION == GLOBAL_COMMIT write GLOBAL_COMMIT to local log;

else if DECISION == GLOBAL_ABORT write GLOBAL_ABORT to local log; } else { write VOTE_ABORT to local log; send VOTE_ABORT to coordinator; } 另 外, 每 个 参 与 者 维 护 一 个 线 程 专 门 处 理 其 它 参 与 者 的 DECISION_REQUEST 请 求, 处 理 线 程 流 程 如 下 : while true { wait until any incoming DECISION_REQUEST is received; read most recently recorded STATE from the local log; if STATE == GLOBAL_COMMIT send GLOBAL_COMMIT to requesting participant; else if STATE == INIT or STATE == GLOBAL_ABORT; send GLOBAL_ABORT to requesting participant; else skip; /* participant remains blocked */ } 从 上 述 的 协 调 者 与 参 与 者 的 流 程 可 以 看 出, 如 果 所 有 参 与 者 VOTE_COMMIT 后 协 调 者 宕 机, 这 个 时 候 每 个 参 与 者 都 无 法 单 独 决 定 全 局 事 务 的 最 终 结 果 (GLOBAL_COMMIT 还 是 GLOBAL_ABORT), 也 无 法 从 其 它 参 与 者 获 取, 整 个 事 务 一 直 阻 塞 到 协 调 者 恢 复 ; 如 果 协 调 者 出 现 类 似 磁 盘 坏 这 种 永 久 性 错 误, 该 事 务 将 成 为 被 永 久 遗 弃 的 孤 儿 一 种 可 行 的 解 决 方 法 是 当 前 的 协 调 者 宕 机 的 时 候 有 其 它 的 备 用 协 调 者 接 替, 用 于 同 一 时 刻 只 能 允 许 一 个 协 调 者 存 在, 二 者 之 间 有 一 个 选 举 的 过 程, 这 里 需 要 用 到 Paxos 协 议 Jim Gray 和 Lamport 有 一 篇 论 文 专 门 论 述 协 调 者 单 点 的 解 决 方 法 分 布 式 事 务 执 行 过 程 中 是 需 要 锁 住 其 它 更 新 的, 因 此 工 程 实 践 中 需 要 降 低 锁 的 粒 度, 实 现 起 来 极 其 复 杂, 也 影 响 效 率, 所 以 几 乎 所 有 的 NOSQL 系 统 都 回 避 这 个 问 题 2.7 Paxos Paxos 基 本 可 以 认 为 是 实 现 分 布 式 选 举 的 唯 一 方 法, 其 它 的 正 确 协 议 都 是 Paxos 变 种 Paxos 最 为 常 见 的 用 途 就 是 单 点 切 换, 比 如 Master 选 举 Paxos 协 议 的 特 点 就 是 难, 理 解 Paxos 可 以 提 高 学 习 分 布 式 系 统 的 信 心 Paxos 选 举 过 程 如 下 : Phase 1 (a) A proposer selects a proposal number n and sends a prepare request with number n to a majority of acceptors. (b) If an acceptor receives a prepare request with number n greater than that of any prepare request to which it has already responded, then it responds to the request with a promise not to accept any more proposals numbered less than n and with the highest-numbered proposal (if any) that it has accepted. Phase 2 (a) If the proposer receives a response to its prepare requests (numbered n) from a majority of acceptors, then it sends an accept request to each of those acceptors for a proposal numbered n

with a value v, where v is the value of the highest-numbered proposal among the responses, or is any value if the responses reported no proposals. (b) If an acceptor receives an accept request for a proposal numbered n, it accepts the proposal unless it has already responded to a prepare request having a number greater than n. Paxos 算 法 的 证 明 有 两 个 方 面 : 一 个 是 正 确 性, 一 个 是 可 终 止 性 正 确 性 很 容 易 理 解, 只 要 Proposer 的 提 议 被 接 受, 至 少 保 证 超 过 一 半 的 Acceptor 接 受 提 议 另 外 一 个 方 面 是 可 终 止 性, 我 们 可 以 想 象 一 下,Paxos 算 法 总 是 往 前 走 的, 在 Phase 1,Proposer 至 少 收 集 超 过 半 数 Acceptor 希 望 接 受 的 提 议 信 息 ; 在 Phase2,Proposer 将 收 集 到 的 编 号 最 大 的 提 议 发 送 给 这 些 Acceptor 如 果 中 间 其 它 的 Proposer 提 出 编 号 更 大 的 建 议, 提 议 被 接 受 不 断 重 试, 总 会 碰 到 一 次 提 议 成 功 的 情 况 不 过 理 论 上 也 可 能 出 现 特 别 差 的 情 况, 例 如 : 1, Proposer A 提 议 编 号 为 N 的 建 议, 进 入 Phase 1; 2, Proposer B 提 议 编 号 为 N+1 的 建 议, 进 入 Phase 1; 3, Proposer A 提 议 编 号 为 N 的 建 议, 进 入 Phase 2; 4, Proposer A 提 议 编 号 为 N+2 的 建 议, 进 入 Phase 1; 5, Proposer B 提 议 编 号 为 N+1 的 建 议, 进 入 Phase 2; 如 此 循 环, 最 后 的 结 果 是 永 远 不 可 能 有 提 议 被 接 受, 算 法 不 终 止 这 个 问 题 在 理 论 上 确 实 是 没 法 解 决 的, 需 要 选 择 一 个 distinguished proposer, 工 程 实 践 时 可 以 通 过 一 些 超 时 机 制 来 实 现, 比 如 Proposer A 在 第 5 到 10s 提 建 议,Proposer B 在 第 10 到 15s 提 建 议 3 关 键 技 术 实 现 大 规 模 分 布 式 系 统 工 程 实 现 时 一 般 会 采 用 朴 实 的 技 术, 每 个 技 术 点 看 起 来 都 非 常 简 单, 但 是 组 合 起 来 威 力 很 大, 引 入 复 杂 的 技 术 之 前 我 们 应 该 先 想 想 工 程 上 的 实 现, 因 为 分 布 式 系 统 本 来 就 不 是 研 究 问 题, 而 是 一 个 系 统 工 程 本 章 我 们 看 一 下 常 用 的 一 些 技 术 是 如 何 实 现 的 3.1 网 络 编 程 框 架 服 务 器 编 程 都 需 要 有 一 个 可 控 的 网 络 编 程 框 架 Taobao 公 司 开 源 了 一 个 tbnet 框 架, 这 个 框 架 设 计 非 常 优 雅, 我 们 结 合 tbnet 说 明 网 络 编 程 框 架 的 设 计 网 络 编 程 包 括 客 户 端 编 程 和 服 务 器 端 编 程 客 户 端 有 同 步 和 异 步 两 种 模 式 : 同 步 模 式 下, 客 户 端 往 socket 连 接 中 发 送 请 求 后 等 待 服 务 器 端 应 答 ; 异 步 模 式 下, 客 户 端 往 socket 连 接 附 带 的 队 列 中 拷 贝 请 求 内 容 ( 给 每 个 请 求 分 配 唯 一 的 请 求 号 ) 后 立 即 返 回, 等 到 服 务 器 端 应 答 时, 客 户 端 的 接 收 线 程 会 调 用 相 应 的 回 调 函 数 Tbnet 客 户 端 实 现 的 是 异 步 模 型, 因 为 同 步 模 型 可 以 通 过 异 步 模 型 来 封 装 服 务 器 端 监 听 客 户 端 的 连 接, 接 收 到 客 户 端 的 请 求 后 放 到 socket 连 接 附 带 的 任 务 队 列 中, 该 任 务 队 列 所 在 的 线 程 会 不 断 地 从 任 务 队 列 取 任 务 并 调 用 用 户 定 义 的 任 务 处 理 函 数 一 个 网 络 编 程 框 架 至 少 包 含 三 个 组 件 : 连 接 管 理, 任 务 队 列, 线 程 池 具 体 实 现 时, 客 户 端 和 服 务 器 端 都 有 网 络 线 程 负 责 发 送 和 接 收 网 络 包, 并 有 超 时 检 查 线 程 负 责 连 接 超 时 管 理 Tbnet 的 Transport 就 是 负 责 网 络 传 输 层 的 一 个 类, 它 负 责 开 两 个 线 程, 一 个 用 来 传 输, 一 个

检 查 超 时, 另 外, 它 提 供 两 个 方 法 listen 和 connect, 用 于 服 务 器 端 的 监 听 和 客 户 端 的 连 接 Transport 传 输 数 据 的 线 程 就 是 事 件 循 环, 不 断 监 听 发 生 的 事 件, 并 调 用 事 件 处 理 函 数 事 件 处 理 函 数 一 般 是 将 接 收 到 的 任 务 放 入 到 服 务 器 端 的 任 务 队 列 中 Tbnet 中 还 有 一 个 channel 的 概 念, 这 里 面 封 装 了 异 步 模 型 需 要 的 请 求 号, 回 调 函 数 及 相 应 的 参 数, 网 络 传 输 线 程 收 到 服 务 器 端 的 回 复 包 时 调 用 channel 上 的 处 理 函 数 Tbnet 的 ConnectionManager 用 于 底 层 的 连 接 池 管 理 网 络 编 程 框 架 需 要 将 某 些 逻 辑 暴 露 给 用 户 重 载 Tbnet 暴 露 了 如 下 的 逻 辑 : 1, 服 务 器 端 接 收 到 网 络 包 时 需 要 根 据 网 络 包 编 号 创 建 相 应 的 Packet 对 象, 创 建 Packet 的 操 作 用 户 可 重 载 ; 2, 服 务 器 端 创 建 Packet 后 默 认 的 处 理 方 法 是 加 入 任 务 队 列, 用 户 可 重 载, 比 如 用 户 可 能 需 要 将 读 请 求 和 写 请 求 加 入 不 同 的 任 务 队 列 ; 3, 任 务 队 列 所 在 的 线 程 不 断 取 队 列 中 的 任 务 并 调 用 任 务 处 理 函 数, 用 户 可 重 载 任 务 处 理 函 数 ; 4, 客 户 端 可 以 异 步 发 送 请 求 时 自 定 义 回 调 函 数 ; 一 般 来 说, 服 务 器 处 理 逻 辑 是 类 似 的, 可 以 封 装 一 个 通 用 的 服 务 器 编 程 框 架, 用 户 只 需 定 义 一 些 必 要 的 处 理 函 数 就 可 以 写 出 一 个 服 务 器 程 序 3.2 HA 与 Replication 为 了 保 证 可 靠 性, 需 要 实 现 复 制, 一 般 有 三 种 复 制 模 式 : 异 步, 强 同 步, 半 同 步 异 步 复 制 是 Mysql 的 Replication 采 用 的 模 式, 实 现 最 为 简 单, 不 过 如 果 Master 宕 机 立 即 切 换 到 Slave 或 者 Master 机 器 出 现 磁 盘 故 障 会 丢 失 最 后 的 更 新, 异 步 模 式 如 果 要 保 证 完 全 不 丢 数 据 一 般 采 用 可 靠 的 共 享 存 储 实 现 异 步 模 式 实 现 简 单,Master 有 一 个 线 程 不 断 扫 描 操 作 日 志 文 件, 将 最 新 的 修 改 发 送 给 Slave,Slave 有 线 程 接 受 Master 发 送 的 更 新 操 作 并 回 放, 接 受 日 志 和 回 放 一 般 采 用 两 个 线 程 如 果 Slave 宕 机, 以 后 重 启 时 向 Master 注 册, 将 Slave 最 新 的 日 志 点 告 知 Master,Master 为 这 个 Slave 启 动 一 个 同 步 线 程 从 最 新 的 日 志 点 开 始 不 断 地 传 输 更 新 操 作 强 同 步 模 式 下, 每 一 个 修 改 操 作 需 要 先 写 入 Slave, 然 后 写 入 Master 的 磁 盘 中 才 能 成 功 返 回 客 户 端 普 通 的 强 同 步 模 式 有 一 个 问 题, 那 就 是 Slave 宕 机 也 必 须 停 止 写 服 务, 只 能 保 证 可 靠 性 而 不 能 保 证 可 用 性 有 一 种 比 较 合 适 的 折 衷,Master 保 存 一 个 Slave 机 器 列 表, 每 个 写 操 作 都 需 要 同 步 到 Slave 列 表 的 所 有 的 机 器, 如 果 发 现 某 个 Slave 连 接 不 上, 将 它 从 Slave 列 表 中 删 除 工 程 实 现 时,Master 有 一 个 线 程 负 责 先 将 数 据 都 同 步 到 Slave, 然 后 写 入 本 地 磁 盘 和 内 存, 为 了 提 高 性 能, 需 要 将 操 作 日 志 批 量 发 送 给 Slave, 如 果 Slave 宕 机, 将 它 提 出 Slave 列 表 比 较 麻 烦 的 是 Slave 宕 机 重 启 后 向 Master 注 册,Master 可 以 选 择 立 刻 将 Slave 加 入 Slave 列 表 并 往 新 加 入 的 Slave 同 步 数 据, 与 此 同 时,Slave 从 Master 获 取 落 后 的 日 志, 当 落 后 的 日 志 全 部 获 取 完 成 时,Slave 和 Master 保 持 同 步, 如 果 这 时 Master 宕 机,Slave 是 可 以 切 换 为 Master 继 续 提 供 服 务 的 半 同 步 模 式 指 的 是 有 N 个 Slave, 数 据 写 入 到 其 中 的 K 个 Slave 并 写 入 Master 本 地 就 可 以 成 功 返 回 客 户 端, 只 要 K >= 1, 就 可 以 保 证 当 Master 宕 机 时, 可 以 通 过 分 布 式 选 举, 比 如 Paxos 选 举 算 法 选 取 数 据 最 新 的 Slave 继 续 提 供 服 务 Berkerly DB 实 现 了 这 种 半 同 步 模 式, 有 兴 趣 的 同 学 可 以 参 考 下 一 种 可 能 的 做 法 是 :Master 对 每 个 Slave 创 建 一 个 同 步 线 程 用 于 数 据 同 步, 并 维 护 一 个 协 调 者 线 程, 每 个 Slave 线 程 将 数 据 同 步 完 成 后 通 过 信 号 量 通 知 协 调 者 线 程, 协 调 者 线 程 发 现 K 个 Slave 已 经 同 步 完 毕 时 可 以 返 回 客 户 端 工 程 实 现 是 需 要 考 虑

对 多 个 Slave 同 时 上 下 线,Slave 瞬 断 等 各 种 异 常 情 况 模 拟 测 试, 这 是 非 常 复 杂 的 HA 还 有 一 个 Master 宕 机 后 的 切 换 问 题 如 果 是 数 据 库 应 用, 我 们 一 般 会 把 数 据 库 的 数 据 写 入 到 共 享 存 储 中 使 得 数 据 库 本 身 没 有 状 态, 这 时, 可 以 从 机 器 池 中 任 意 选 择 一 台 机 器 作 为 Slave 加 载 数 据 而 考 虑 到 成 本 问 题, 在 NOSQL 系 统 中,Master 和 Slave 是 share-nothing 的 在 强 同 步 模 式 下, 我 们 需 要 让 Slave 有 识 别 自 己 是 否 和 Master 状 态 一 致 的 能 力, 从 而 Master 宕 机 时 可 以 通 过 DNS 或 者 VIP 等 手 段 迁 移 到 Slave, 这 里 可 以 引 入 Lease 机 制 ; 在 半 同 步 模 式 下, 我 们 需 要 保 证 有 Slave 和 Master 状 态 一 致, 从 而 Master 宕 机 时 出 发 一 次 选 举 过 程, 通 过 Paxos 协 议 产 生 新 的 Master 3.3 分 裂 分 裂 一 般 对 提 供 强 一 致 性 和 最 终 一 致 性 的 系 统 而 言 我 们 假 设 按 照 类 似 Bigtable 中 的 数 据 划 分 方 法 对 表 格 进 行 拆 分, 一 个 大 表 被 拆 分 成 大 小 接 近 100MB ~ 200MB 的 子 表 tablet, 每 个 子 表 服 务 一 段 连 续 的 数 据 范 围 但 某 个 子 表 访 问 过 于 频 繁 时, 需 要 分 裂 为 两 个 子 表, 从 而 将 服 务 迁 移 到 其 它 机 器 一 个 子 表 变 成 两 个 大 小 相 近 的 子 表 的 过 程, 就 叫 分 裂 子 表 分 裂 单 机 上 的 做 法 是 不 难 的 通 用 的 做 法 可 以 将 需 要 分 裂 的 子 表 拷 贝 出 来, 按 照 确 定 的 分 裂 点 写 成 两 份, 拷 贝 过 程 中 新 来 的 写 操 作 记 录 操 作 日 志, 等 到 拷 贝 完 成 时 锁 住 写 操 作, 将 记 录 到 操 作 日 志 的 写 操 作 应 用 到 新 生 成 的 两 个 子 表 中, 释 放 写 锁, 分 裂 成 功 如 果 单 机 存 储 引 擎 支 持 快 照 功 能, 做 法 会 更 加 简 单 高 效 分 裂 时 只 需 要 生 成 一 个 快 照 并 将 快 照 中 的 数 据 按 照 确 定 的 分 裂 点 写 成 两 份, 接 着 锁 住 写 操 作 并 将 拷 贝 过 程 中 新 来 的 写 操 作 应 用 到 新 生 成 的 两 个 子 表 中 Merge-dump 存 储 引 擎 分 裂 时 还 有 更 加 简 单 的 做 法 我 们 以 Bigtable 的 Merge-dump 存 储 引 擎 为 例, 写 操 作 以 操 作 日 志 的 形 式 写 入 到 SSTable 中,compaction 合 并 过 程 将 多 个 SSTable 合 并 为 一 个 SSTable, 原 来 的 SSTable 通 过 定 期 的 垃 圾 回 收 过 程 删 除 Merge-dump 存 储 引 擎 上 执 行 分 裂 操 作 不 需 要 进 行 实 际 的 数 据 拷 贝 工 作, 只 需 要 将 内 存 中 的 索 引 信 息 分 成 两 份, 比 如 分 裂 前 子 表 的 范 围 为 (start_key, end_key], 内 存 中 的 索 引 分 成 两 个 范 围 (start_key, split_key] 和 (split_key, end_key],compaction 合 并 的 过 程 中 为 两 个 分 裂 后 的 子 表 生 成 不 同 的 SSTable 文 件 分 裂 的 难 点 在 于 如 何 使 得 多 机 在 同 一 个 分 裂 点 原 子 地 分 裂 这 个 问 题 涉 及 到 多 机 之 间 协 调, 所 以 我 们 一 般 可 以 采 用 两 阶 段 锁 来 解 决,Yahoo 的 PNUTS 系 统 正 是 采 用 了 这 种 做 法 两 阶 段 锁 的 性 能 问 题 倒 是 其 次, 工 程 实 现 中 更 为 重 要 的 是 这 个 协 议 实 现 很 复 杂, 非 常 难 以 构 造 各 种 异 常 case 进 行 测 试, 很 容 易 出 现 代 码 错 误 导 致 死 锁 的 问 题 Bigtable 采 用 了 另 外 一 种 思 路 既 然 多 机 原 子 地 执 行 分 裂 很 难 做, 我 们 就 做 单 机 分 裂 好 了 Bigtable 设 计 中, 同 一 个 子 表 tablet 同 一 个 时 刻 只 能 被 一 台 工 作 机 Tablet Server 服 务 由 于 只 在 一 个 服 务 节 点 进 行 分 裂, 问 题 得 到 了 解 决, 底 层 的 GFS 系 统 会 负 责 文 件 系 统 的 可 靠 性 和 可 用 性 保 证 当 然, 我 们 也 可 以 将 机 器 分 成 一 个 一 个 的 group, 每 一 个 子 表 都 在 某 个 group 的 每 台 机 器 存 放 一 个 备 份, 也 就 是 说, 如 果 数 据 复 制 N 份, 一 个 group 就 有 N 台 机 器 同 一 个 group 同 一 时 刻 只 有 一 台 机 器 提 供 写 服 务, 其 它 机 器 提 供 读 服 务, 当 group 中 提 供 写 服 务 的 机 器 宕 机 时, 由 group 中 的 其 它 机 器 顶 替 加 入 新 机 器 以 group 为 单 位, 每 次 新 增 N 台 分 裂 操 作 由 group 中 提 供 写 服 务 的 Master 节 点 执 行, 分 裂 操 作 写 日 志 并 同 步 到 Slave 节 点,Slave 节 点 接 收 到 分 裂 日 志 也 执 行 分 裂 如 果 Master 分 裂 成 功 但 是 Slave 分 裂 失 败, 也 不 会 出 现 问 题 因 为 只 要 不 出 现 子 表 的 迁 移, 在 单 机 上 分 裂 成 功 与 否 是 不 会 影 响 正 确 性 的 简 单 来 说, 同 一

个 group 同 一 时 刻 总 是 有 一 个 Master 节 点 作 为 代 表,Slave 节 点 上 的 状 态 与 Master 不 一 致 时 以 Master 为 准 工 程 实 践 中, 分 裂 仍 然 是 很 复 杂 的, 因 此 国 内 几 乎 所 有 的 分 布 式 存 储 系 统 都 采 用 预 先 切 分 好 tablet 的 方 法 只 要 切 分 得 比 较 细, 系 统 支 撑 一 两 年 是 没 有 问 题 的, 等 到 出 现 问 题 时 可 以 整 个 系 统 停 服 务 对 数 据 重 新 划 分 3.4 迁 移 我 们 仍 然 假 设 整 个 大 表 按 照 类 似 Bigtable 中 的 方 法 被 划 分 为 很 多 的 子 表 tablet 子 表 迁 移 在 集 群 主 控 机 的 指 导 下 进 行, 迁 移 的 做 法 和 分 裂 有 很 多 共 通 之 处 假 设 机 器 A 需 要 将 子 表 迁 移 到 机 器 B, 迁 移 的 做 法 与 单 机 子 表 分 裂 时 拷 贝 数 据 的 方 法 类 似 分 为 两 个 阶 段, 第 一 个 阶 段 将 机 器 A 的 待 迁 移 子 表 的 数 据 拷 贝 到 机 器 B, 这 个 阶 段 新 来 的 修 改 操 作 只 记 录 操 作 日 志 ; 第 二 个 阶 段 停 止 写 服 务, 将 第 一 个 阶 段 拷 贝 数 据 过 程 中 接 收 到 的 修 改 操 作 拷 贝 到 机 器 B; 数 据 迁 移 完 成 时 主 控 机 修 改 被 迁 移 子 表 的 位 置 信 息, 整 个 迁 移 过 程 结 束 同 样, 如 果 单 机 存 储 引 擎 支 持 快 照 功 能, 整 个 流 程 会 更 加 容 易 和 高 效 Bigtable 的 迁 移 依 赖 于 底 层 GFS 提 供 可 靠 的 文 件 存 储,Bigtable 写 操 作 的 操 作 日 志 持 久 化 到 GFS 中, 且 每 个 tablet 由 一 台 Tablet Server 提 供 服 务 当 Tablet Server 出 现 宕 机 或 者 负 载 平 衡 需 要 执 行 子 表 迁 移 操 作 时, 只 需 要 停 止 源 Tablet Server 对 待 迁 移 tablet 的 服 务 并 在 目 的 Tablet Server 上 重 新 加 载 tablet 即 可 由 于 Bigtable 有 GFS 提 供 可 靠 存 储, 我 们 可 以 认 为 Tablet Server 服 务 节 点 是 无 状 态 的 我 们 在 这 里 提 出 一 种 设 计 方 案 : 将 机 器 分 成 一 个 一 个 的 group, 每 一 个 子 表 都 在 某 个 group 的 每 台 机 器 存 放 一 个 备 份, 同 一 个 时 刻 一 个 group 中 只 有 一 台 机 器 提 供 写 服 务, 其 它 机 器 都 提 供 读 服 务 将 子 表 从 group A 迁 移 到 group B 其 实 就 是 将 子 表 从 group A 中 的 Master 机 器 迁 移 到 group B 中 的 Master 机 器, 整 个 过 程 由 集 群 的 主 控 机 来 协 调 下 面 我 们 考 虑 一 下 迁 移 过 程 中 发 生 的 各 种 异 常 情 况 : 1, 迁 移 的 第 一 个 阶 段 group A 中 Master 宕 机 :group A 中 某 台 与 Master 保 持 强 同 步 的 Slave 接 替 Master 对 外 服 务, 整 个 迁 移 过 程 失 败 结 束 ; 2, 迁 移 的 第 二 个 阶 段 group A 中 Master 宕 机 :group A 中 某 台 与 Master 保 持 强 同 步 的 Slave 接 替 Master 对 外 服 务, 整 个 迁 移 过 程 失 败 结 束 ; 3, 迁 移 过 程 中 group B 中 Master 宕 机 : 整 个 迁 移 过 程 失 败 结 束 ; 4, 拷 贝 数 据 完 成 后 集 群 主 控 机 修 改 子 表 位 置 信 息 失 败 : 此 时 被 迁 移 tablet 在 group A 和 group B 中 的 数 据 完 全 一 样, 任 意 一 个 group 提 供 服 务 均 可 ; 5, 迁 移 完 成 后 group A 中 Master 宕 机 :group A 中 某 台 与 Master 保 持 强 同 步 的 Slave 接 替 Master 对 外 服 务, 这 个 Slave 可 能 不 知 道 子 表 已 经 迁 移 的 信 息 子 表 迁 移 后 客 户 端 写 操 作 需 要 重 新 建 立 连 接, 这 个 过 程 会 请 求 集 群 的 主 控 机, 但 是 group A 的 机 器 可 能 使 用 老 数 据 继 续 提 供 读 服 务, 这 就 需 要 Master 将 子 表 迁 移 信 息 告 知 group A 中 的 其 它 机 器 上 述 的 机 器 同 构 的 做 法 有 一 个 问 题 : 增 加 副 本 需 要 全 部 拷 贝 一 台 机 器 存 储 的 数 据, 如 果 数 据 总 量 为 1TB, 拷 贝 限 速 20MB/s, 拷 贝 时 间 为 十 几 个 小 时, 另 外, 子 表 迁 移 的 工 程 实 现 也 比 较 麻 烦 因 此, 工 程 上 多 数 系 统 静 态 分 配 好 每 个 子 表 所 在 的 机 器 并 且 不 迁 移, 如 数 据 库 sharding 预 先 分 配 好 每 一 份 数 据 所 在 的 机 器 另 外 一 种 做 法 是 设 计 的 时 候 分 离 静 态 数 据 和 修 改 数 据, 定 期 合 并, 迁 移 的 时 候 只 迁 移 静 态 数 据, 这 个 思 想 在 淘 宝 最 近 研 发 的 Oceanbase 系 统 里 面 有 所 体 现

3.5 负 载 均 衡 负 载 平 衡 是 一 个 研 究 课 题, 难 点 在 于 负 载 平 衡 的 策 略 和 参 数 调 整, 工 程 化 的 难 度 不 大, 和 数 据 挖 掘 相 关 的 项 目 有 些 类 似, 需 要 不 断 地 做 假 设 并 做 实 验 验 证 负 载 平 衡 有 两 种 思 路, 一 种 是 集 群 总 控 机 根 据 负 载 情 况 全 局 调 度, 另 一 种 思 路 是 采 用 DHT 方 法 第 二 种 思 路 可 以 参 考 Amazon Dynamo 的 论 文,DHT 算 法 中 每 个 节 点 分 配 的 token 决 定 了 数 据 及 负 载 的 分 布 假 设 DHT 环 中 有 S 个 节 点, 一 种 比 较 好 的 token 分 配 方 法 是 将 整 个 Hash 空 间 分 成 Q 等 份,Q >> S,token 分 配 维 持 每 个 节 点 分 配 Q/S 个 token 的 特 性 当 节 点 下 线 时, 需 要 将 它 所 服 务 的 token 分 配 给 其 它 节 点, 从 而 保 持 每 个 节 点 包 含 Q/S 个 token 的 特 性 ; 同 样, 当 新 节 点 上 线 时, 也 需 要 从 集 群 中 已 有 的 节 点 获 取 token 使 得 最 终 维 持 每 个 节 点 Q/S 个 token 的 特 性 第 一 种 思 路 需 要 工 作 机 通 过 heartbeat 定 时 将 读 写 个 数, 磁 盘, 内 存 负 载 等 信 息 发 送 给 主 控 机, 主 控 机 根 据 负 载 计 算 公 式 计 算 出 需 要 迁 移 的 数 据 放 入 到 迁 移 队 列 中 等 待 执 行 负 载 平 衡 的 时 候 需 要 注 意 控 制 节 奏, 比 如 一 台 工 作 机 刚 上 线 的 时 候, 由 于 负 载 最 轻, 如 果 主 控 机 将 大 量 的 数 据 迁 移 到 新 上 线 的 机 器, 由 于 迁 移 过 程 不 能 提 供 写 服 务, 整 个 系 统 的 对 外 表 现 性 能 会 因 为 新 增 机 器 而 变 差 一 般 来 说, 从 新 机 器 加 入 到 集 群 负 载 达 到 比 较 均 衡 的 状 态 需 要 较 长 一 段 时 间, 比 如 30 分 钟 到 一 个 小 时 3.6 Chubby Chubby 是 Google 的 Paxos 实 现,Paxos 靠 谱 的 实 现 不 多,Chubby 毫 无 疑 问 是 做 的 最 优 秀 的 Chubby 通 过 类 似 文 件 系 统 接 口 的 方 式 给 用 户 暴 露 分 布 式 锁 服 务 我 们 先 看 看 应 用 是 如 何 使 用 Chubby 服 务 的 在 GFS/Bigtable 论 文 中, 我 们 至 少 能 够 看 到 有 如 下 几 处 使 用 了 Chubby 1, Master 选 举 Master 宕 机 时, 与 Master 保 持 强 同 步 的 Slave 切 换 为 Master 继 续 提 供 服 务 在 这 个 过 程 中,Master 和 Slave 都 定 时 向 Chubby 请 求 成 为 Master 的 锁,Master 锁 有 一 个 Lease 的 期 限, 如 果 Master 正 常, 一 定 会 在 Master 锁 没 有 过 期 的 时 候 申 请 延 长 锁 的 时 间, 继 续 提 供 服 务 当 Master 宕 机 且 锁 的 Lease 过 期 时,Slave 将 抢 到 Master 锁 切 换 为 Master 2, tablet 服 务 为 了 保 证 强 一 致 性, 一 个 tablet 同 一 时 刻 只 允 许 被 一 个 Tablet Server 加 载 提 供 服 务 每 个 tablet server 启 动 时 都 向 Chubby 服 务 获 取 一 个 锁, 每 当 Master 发 现 tablet server 出 现 异 常 时, 它 也 尝 试 获 取 该 Tablet server 的 锁 Master 和 Tablet Server 二 者 只 有 一 个 节 点 能 够 获 取 到 锁, 如 果 锁 被 Master 获 取, 可 以 确 定 Tablet Server 已 经 宕 机, 此 时 可 以 将 它 服 务 的 tablet 分 配 给 其 它 机 器 3, 存 储 Bigtable 表 格 的 schema 信 息 由 于 Chubby 可 以 认 为 是 一 个 一 致 的 共 享 存 储, 并 且 schema 的 访 问 压 力 不 大,Chubby 可 以 存 储 schema 信 息 我 们 再 来 看 看 Chubby 内 部 大 致 是 如 何 实 现 的 Chubby 一 般 有 五 台 机 器 组 成 一 个 集 群, 可 以 部 署 成 两 地 三 机 房, 这 样 任 何 一 个 机 房 停 电 都 不 影 响 Chubby 服 务 Chubby 内 部 的 五 台 机 器 需 要 通 过 实 现 Paxos 协 议 选 取 一 个 Chubby Master 机 器, 其 它 机 器 是 Chubby Slave, 同 一 时 刻 只 有 一 个 Chubby Master Chubby 相 关 的 数 据, 比 如 锁 信 息, 客 户 端 的 Session 信 息 都 需 要 同 步 到 整 个 集 群, 采 用 半 同 步 的 做 法, 超 过 一 半 的 机 器 成 功 就 可 以 回 复 客 户 端 每 个

Chubby Master 和 Chubby Slave 都 希 望 成 为 Chubby Master,Chubby Master 有 一 个 Lease 期 限, 如 果 Chubby Master 正 常, 它 将 在 Lease 快 到 期 的 时 候 延 长 Lease 期 限, 如 果 Chubby Master 宕 机,Chubby 集 群 内 部 将 触 发 一 次 Paxos 选 举 过 程 每 个 Chubby Slave 都 希 望 自 己 成 为 Chubby Master, 它 们 类 似 于 Paxos 协 议 中 的 Proposer, 每 个 Chubby 集 群 中 的 节 点 都 是 Acceptor, 最 后 可 以 确 保 只 有 一 个 和 原 有 的 Chubby Master 保 持 完 全 同 步 的 Chubby Slave 被 选 取 为 新 的 Chubby Master 当 然, 无 论 是 Paxos 选 举 还 是 Session, 锁 信 息 同 步,Chubby 集 群 内 部 机 器 故 障 检 测 都 远 没 有 这 么 简 单, 这 里 的 实 现 也 是 笔 者 的 揣 测, 如 果 有 同 学 感 兴 趣, 可 以 参 考 Berkerly DB 中 半 同 步 ( 包 括 选 举 过 程 ) 的 实 现, 这 部 分 代 码 是 由 Google 内 部 开 源 出 来 的 3.7 分 布 式 事 务 对 于 分 布 式 事 务, 大 多 数 情 况 下 我 们 应 该 想 的 是 如 何 回 避 它, 两 阶 段 锁 的 方 法 不 仅 效 率 低, 而 且 实 现 特 别 复 杂 有 的 时 候, 我 们 需 要 和 业 务 方 一 起 探 讨 如 何 规 避 分 布 式 事 务 这 里 我 们 会 用 到 流 行 的 概 念 BASE, 即 基 本 可 用, 柔 性 状 态, 柔 性 一 致 和 最 终 一 致 等 对 一 个 基 本 可 用 系 统 来 说, 我 们 需 要 把 系 统 中 的 所 有 功 能 点 进 行 优 先 级 的 划 分, 比 如 转 账 业 务 和 淘 宝 的 收 藏 夹 业 务 两 者 对 一 致 性 的 要 求 肯 定 是 不 同 的 柔 性 状 态 对 用 户 来 说 是 一 个 完 整 的 系 统, 它 的 一 致 性 是 不 允 许 有 任 何 损 失 的, 就 是 说 用 户 支 付 了 10 块 钱, 那 么 他 的 帐 户 上 必 然 是 只 扣 掉 了 10 块 钱 ; 但 是 对 于 系 统 内 部 的 状 态, 我 们 可 以 采 用 一 种 柔 性 的 策 略, 比 如 说 系 统 内 分 布 了 ABC 三 个 功 能 模 块, 我 们 允 许 它 们 在 某 一 时 刻 三 个 模 块 的 状 态 可 以 不 一 致 我 们 会 通 过 业 务 和 技 术 的 手 段, 比 如 说 异 步 机 制 或 者 批 处 理 方 式 来 保 证 系 统 通 过 柔 性 状 态 一 致 来 获 得 可 用 性 目 前 底 层 NOSQL 存 储 系 统 实 现 分 布 式 事 务 的 只 有 Google 的 系 统, 它 在 Bigtable 之 上 用 Java 语 言 开 发 了 一 个 系 统 Megastore, 实 现 了 两 阶 段 锁, 并 通 过 Chubby 来 避 免 两 阶 段 锁 协 调 者 宕 机 带 来 的 问 题 Megastore 实 现 目 前 只 有 简 单 介 绍, 还 没 有 相 关 论 文 在 这 个 问 题 上, 我 们 只 能 说 是 Google 的 同 学 工 程 能 力 太 强 了, 我 们 开 发 NOSQL 系 统 的 时 候 还 是 走 为 上 策 3.8 Copy-on-write 与 Snapshot Copy-on-write 技 术 在 互 联 网 公 司 使 用 比 较 多, 这 时 因 为 大 多 数 应 用 的 读 写 比 例 接 近 10 : 1,Copy-on-write 读 操 作 不 用 加 锁, 极 大 地 提 高 了 读 的 效 率, 特 别 是 现 在 服 务 器 一 般 都 有 8 个 或 者 16 个 核 Copy-on-write 技 术 还 带 来 了 一 个 好 处, 那 就 是 Snapshot 的 时 候 不 需 要 停 服 务, 而 Snapshot 功 能 对 于 分 布 式 文 件 系 统 非 常 重 要 Copy-on-write 技 术 在 树 形 结 构 中 比 较 容 易 实 现, 假 如 我 们 实 现 一 个 支 持 Copy-on-write 的 B 树, 基 本 可 以 用 来 作 为 大 多 数 管 理 结 构 的 内 部 数 据 结 构, 比 如 GFS 的 chunk 管 理, 文 件 名 管 理,Bigtable 中 的 子 表 管 理 Copy-on-write 的 示 意 图 如 下 :

如 上 图,B+ 树 每 次 执 行 更 新 操 作 时, 将 从 叶 子 到 根 节 点 路 径 上 的 所 有 节 点 先 拷 贝 出 来, 并 在 拷 贝 的 节 点 上 执 行 修 改, 更 新 操 作 通 过 原 子 地 切 换 根 节 点 的 指 针 来 提 交 由 于 使 用 了 Copy-on-write 技 术, 如 果 读 取 操 作 发 生 在 写 操 作 生 效 前 将 读 取 老 的 数 据, 否 则 读 取 新 的 数 据, 不 需 要 加 锁 Copy-on-write 技 术 需 要 利 用 到 引 用 计 数, 当 节 点 没 有 被 引 用, 也 就 是 引 用 计 数 减 为 0 时 被 释 放, 引 用 计 数 极 大 地 增 加 了 数 据 结 构 的 复 杂 度 如 果 需 要 对 B+ 树 的 某 一 个 子 树 进 行 Snapshot 操 作, 只 需 要 增 加 这 个 子 树 的 根 节 点 的 引 用 计 数 就 可 以 了, 后 续 的 读 取 操 作 都 将 读 取 执 行 Snapshot 操 作 时 的 数 据 对 于 Hash 这 样 的 常 用 数 据 结 构, 由 于 不 支 持 Copy-on-write, 如 果 需 要 支 持 Snapshot 操 作, 需 要 进 行 一 定 的 处 理 常 用 的 做 法 是 封 装 一 个 临 时 的 缓 冲 区, 执 行 Snapshot 到 删 除 Snapshot 的 过 程 中, 写 操 作 写 入 到 临 时 缓 冲 区, 读 操 作 需 要 合 并 静 态 数 据 和 临 时 缓 冲 区 中 的 动 态 数 据 分 布 式 系 统 中 的 Snapshot 操 作 比 单 机 操 作 要 复 杂 很 多, 我 们 以 GFS 文 件 系 统 的 Snapshot 为 例 进 行 说 明 为 了 对 某 个 文 件 做 Snapshot, 我 们 首 先 需 要 停 止 这 个 文 件 的 写 服 务, 接 着 增 加 这 个 文 件 的 所 有 chunk 的 引 用 计 数, 从 而 以 后 相 应 的 chunk 被 修 改 时 会 先 对 chunk 执 行 一 次 拷 贝 对 某 个 文 件 执 行 Snapshot 的 大 致 步 骤 如 下 : 1, 通 过 Lease 机 制 收 回 对 文 件 每 一 个 chunk 写 权 限, 停 止 对 文 件 的 写 服 务 ; 2, Master 拷 贝 文 件 名 等 元 数 据 生 成 一 个 新 的 Snapshot 文 件 ; 3, 对 执 行 Snapshot 的 文 件 的 所 有 chunk 增 加 引 用 计 数 ; 当 然, 工 程 实 现 时 远 不 止 这 么 简 洁, 请 设 计 时 务 必 考 虑 清 楚 各 种 异 常 和 细 节

3.9 操 作 日 志 与 checkpoint 无 论 是 数 据 库 还 是 NOSQL 系 统, 都 会 涉 及 到 操 作 日 志 这 是 因 为 磁 盘 和 内 存 不 一 样, 它 是 一 个 顺 序 访 问 设 备, 每 一 个 磁 盘 读 写 操 作 都 需 要 寻 道, 而 这 个 寻 道 时 间 占 整 个 读 写 操 作 的 百 分 比 很 大 操 作 日 志 的 原 理 很 简 单 : 为 了 利 用 好 磁 盘 的 顺 序 读 写 特 性, 将 客 户 端 的 写 操 作 先 顺 序 写 入 到 磁 盘 中, 然 后 应 用 到 内 存 中, 由 于 内 存 是 随 机 读 写 设 备, 可 以 很 容 易 通 过 各 种 数 据 结 构, 比 如 B+ 树 将 数 据 有 效 地 组 织 起 来 当 机 器 宕 机 重 启 时, 只 需 要 回 放 操 作 日 志 就 可 以 恢 复 内 存 状 态 为 了 提 高 系 统 的 并 发 能 力, 系 统 会 积 攒 一 定 的 操 作 日 志 再 批 量 写 入 到 磁 盘 中 如 果 每 次 宕 机 恢 复 都 需 要 回 放 所 有 的 操 作 日 志, 效 率 是 无 法 忍 受 的,Checkpoint 正 是 为 了 解 决 这 个 问 题 系 统 定 期 将 内 存 状 态 以 checkpoint 文 件 的 形 式 dump 到 磁 盘 中, 并 记 录 checkpoint 时 刻 对 应 的 操 作 日 志 回 放 点, 以 后 宕 机 恢 复 只 需 要 先 加 载 checkpoint 后 回 放 checkpoint 对 应 的 日 志 回 放 点 以 后 的 操 作 日 志 由 于 将 内 存 状 态 dump 到 磁 盘 需 要 很 长 的 时 间, 而 这 段 时 间 还 可 能 有 新 的 写 操 作,checkpoint 必 须 找 一 个 一 致 的 状 态 如 果 系 统 的 数 据 结 构 支 持 Copy-on-write, 事 情 变 得 相 当 简 单 : 只 需 要 增 加 B+ 树 的 根 节 点 的 引 用 计 数 对 整 棵 树 做 一 个 快 照, 记 录 此 时 对 应 的 操 作 日 志 回 放 点 即 可, 然 后 将 这 个 快 照 dump 到 磁 盘 中 由 于 执 行 checkpoint 的 时 候 需 要 记 录 此 时 对 应 的 日 志 回 放 点, 一 个 小 小 的 技 巧 就 是 生 成 checkpoint 的 时 候 切 一 下 操 作 日 志 的 文 件, 使 得 编 号 为 i 的 checkpoint 文 件 对 应 编 号 为 i+1 的 操 作 日 志 文 件 3.10 列 式 存 储 与 压 缩 列 式 存 储 主 要 应 用 在 数 据 仓 库 类 的 应 用, 列 式 存 储 将 同 一 个 列 的 数 据 存 放 在 一 起, 同 一 个 列 里 面 按 照 行 有 序 由 于 同 一 个 列 的 数 据 重 复 读 很 高, 列 式 存 储 压 缩 时 有 很 大 的 优 势, 比 如 Google Bigtable 列 式 存 储 对 网 页 库 压 缩 可 以 达 到 10~15 倍 的 压 缩 率 而 且, 数 据 仓 库 类 应 用 本 身 就 是 按 照 列 来 访 问 的, 比 如 查 询 来 自 湖 南 的 用 户 请 求 个 数 由 于 用 户 的 读 写 操 作 使 用 的 SQL 语 句 是 按 照 行 的 顺 序, 列 式 存 储 在 实 现 更 新 操 作 事 务 性, 读 取 某 一 行 等 普 通 的 数 据 库 操 作 相 对 比 较 麻 烦 压 缩 是 一 个 专 门 的 研 究 课 题, 没 有 通 用 的 做 法, 需 要 根 据 数 据 的 特 点 选 择 或 者 自 己 开 发 新 的 算 法 压 缩 的 本 质 就 是 找 数 据 的 重 复 或 者 规 律, 用 尽 量 少 的 字 节 表 示 压 缩 算 法 一 般 有 一 个 窗 口 的 概 念, 在 窗 口 的 内 部 找 重 复 或 者 规 律 存 储 系 统 在 选 择 压 缩 算 法 的 时 候 有 两 个 考 虑 点 : 压 缩 比 和 效 率 读 操 作 需 要 先 读 取 磁 盘 中 的 内 容 再 解 压 缩, 写 操 作 需 要 先 压 缩 再 将 压 缩 结 果 写 入 到 磁 盘, 整 个 操 作 的 延 时 包 括 压 缩 / 解 压 缩 和 磁 盘 读 写 的 延 迟, 压 缩 比 也 大, 磁 盘 读 写 的 数 据 量 越 大, 相 应 地 压 缩 / 解 压 缩 的 时 间 也 长, 所 以 这 里 需 要 一 个 很 好 的 权 衡 点 压 缩 算 法 的 设 计 和 选 择 远 超 出 我 的 能 力 范 围, 常 用 的 压 缩 算 法 有 gzip,lzo,lzw 在 Google 的 Bigtable 系 统 中, 设 计 了 Zippy 和 BMDiff 两 种 压 缩 算 法 Zippy 是 和 LZW 类 似 的 Zippy 并 不 像 LZW 或 者 gzip 那 样 压 缩 比 高, 但 是 他 处 理 速 度 非 常 快 BMDiff 压 缩 速 率 可 达 到 100MB ~ 200MB, 解 压 缩 速 率 达 到 400MB ~ 1000MB, 压 缩 近 似 度 高 的 数 据 压 缩 比 也 很 不 错 可 见 压 缩 算 法 的 选 择 不 能 仅 仅 看 压 缩 比, 还 要 看 算 法 执 行 效 率

4 通 用 存 储 系 统 分 类 从 本 质 上 将, 通 用 存 储 系 统 只 需 要 一 套 就 可 以 满 足 互 联 网 公 司 95% 以 上 的 需 求, 因 为 从 语 义 上 讲, 一 套 系 统 能 够 表 达 的 语 义 和 多 套 系 统 没 有 区 别, 二 者 都 是 完 备 的 根 据 公 开 的 资 料,google 也 正 是 朝 着 这 个 方 向 努 力 的, 不 过 这 不 仅 要 求 工 程 师 有 超 强 的 能 力, 还 要 求 公 司 有 一 个 很 好 的 制 度 保 证 工 程 师 之 间 不 要 为 了 因 为 贪 功 而 竞 争, 比 如 发 现 通 用 系 统 有 某 处 不 符 合 需 求 就 另 起 炉 灶 开 发 一 个 专 用 系 统 从 工 程 的 角 度 上 看, 一 个 工 程 代 码 量 翻 番, 工 程 的 复 杂 度 至 少 是 原 来 的 四 倍 权 衡 互 联 网 公 司 业 务 的 需 求 及 通 用 系 统 的 工 程 复 杂 度, 笔 者 认 为 互 联 网 公 司 大 致 需 要 如 下 几 类 存 储 系 统 : 1, 数 据 库 及 类 数 据 库 2, 线 上 最 终 一 致 性 系 统 3, 线 上 弱 一 致 性 系 统 4, 半 线 上 及 线 下 系 统 数 据 库 及 类 数 据 库 系 统 的 存 在 毋 庸 置 疑,NOSQL 不 可 能 完 全 替 换 数 据 库 系 统 关 系 型 数 据 库 支 持 的 操 作 丰 富 多 样, 厂 商, 工 具 支 持 也 已 经 规 模 化, 开 发 人 员 也 认 可 了 SQL 模 型 这 种 类 型 的 存 储 系 统 提 供 复 杂 的 语 义, 但 是 扩 展 性 稍 差 类 数 据 库 系 统 是 数 据 库 与 NOSQL 之 间 的 一 个 折 衷, 比 如 Drizzle 通 过 减 少 一 些 不 必 要 的 Mysql 通 过 增 强 扩 展 性 类 数 据 库 系 统 是 根 据 互 联 网 应 用 的 特 点 选 择 数 据 库 的 特 性 子 集 加 以 支 持, 如 果 说 数 据 库 的 出 发 点 是 尽 可 能 支 持 所 有 SQL 特 性, 那 么, 类 数 据 库 系 统 的 出 发 点 是 在 满 足 应 用 的 前 提 下 尽 量 不 支 持 不 必 要 的 SQL 特 性 与 普 通 NOSQL 系 统 不 同 的 是, 类 数 据 库 系 统 一 般 不 会 有 过 多 的 动 态 分 裂 和 迁 移, 并 且 支 持 事 务 线 上 最 终 一 致 性 系 统 指 提 供 线 上 服 务 且 保 证 最 终 一 致 性 线 上 系 统 对 用 户 操 作 的 延 时 一 般 在 ms 级 别, 比 如 1 ~ 30ms, 但 是 对 于 写 操 作, 机 器 宕 机 的 时 候 停 止 10~20s 的 写 服 务 很 多 时 候 是 可 以 接 受 的 线 上 最 终 一 致 性 系 统 的 读 操 作 保 证 1~30ms 的 延 迟, 且 读 操 作 只 允 许 有 秒 级 别 的 延 时, 对 同 一 份 数 据 同 一 时 刻 永 远 只 有 一 个 节 点 提 供 写 服 务, 因 此, 写 节 点 宕 机 时, 可 能 需 要 停 止 如 10~20s 的 写 服 务 这 种 类 型 的 系 统, 内 部 实 现 时 需 要 动 态 分 裂 和 迁 移 以 进 行 负 载 均 衡 线 上 弱 一 致 性 系 统 指 的 是 Dynamo 及 其 变 种 Cassandra 这 样 的 系 统 我 们 在 2.4 节 一 致 性 模 型 的 定 义 中 已 经 将 Dynamo 这 种 需 要 解 决 冲 突 的 系 统 归 类 为 弱 一 致 性 系 统 线 上 弱 一 致 性 KV 系 统 对 读 和 写 操 作 都 需 要 保 证 1 ~ 30ms 的 延 迟 线 上 弱 一 致 性 系 统 对 于 能 够 解 决 冲 突 的 应 用 非 常 有 效, 比 如 能 够 容 忍 时 钟 不 一 致 带 来 的 问 题 而 采 用 last write wins 的 策 略, 或 者 淘 宝 购 物 车 这 种 可 以 直 接 合 并 购 物 车 中 的 宝 贝 的 应 用 线 上 弱 一 致 性 的 一 个 特 别 大 的 好 处 是 可 以 采 用 P2P 的 方 法 实 现, 由 于 消 除 了 单 点, 任 何 一 个 节 点 出 点 小 问 题, 比 如 代 码 出 现 bug 都 不 会 给 整 个 系 统 带 来 太 大 的 影 响 对 于 互 联 网 公 司, 线 上 最 终 一 致 性 系 统 和 弱 一 致 性 系 统 二 者 实 现 一 个 就 可 以 了, 这 主 要 取 决 于 不 同 公 司 业 务 的 一 致 性 要 求 Dynamo 这 样 的 系 统 还 有 一 个 优 势 是 提 供 云 服 务, 因 为 消 除 了 单 点, 个 别 代 码 错 误 或 者 机 房 故 障 不 至 于 影 响 很 大, 而 基 于 类 似 last write wins 这 样 的 冲 突 解 决 策 略 很 少 会 出 现 问 题 而 强 一 致 性 系 统 一 般 需 要 有 Master 主 控 机, 这 是 一 个 单 点, 代 码 出 现 bug 影 响 很 大, 整 个 机 房 故 障 这 种 问 题 解 决 起 来 也 相 对 要 复 杂 很 多 半 线 上 及 线 下 系 统 指 的 就 是 以 GFS + Bigtable 为 代 表 的 存 储 系 统, 适 合 数 据 挖 掘, 搜 索 等 各 种 类 型 的 应 用 如 果 Bigtable 做 的 足 够 好, 是 可 以 解 决 线 上 最 终 一 致 性 KV 系 统 的 问 题 的, 也 就 是 说, 一 般 的 互 联 网 公 司 只 需 要 这 一 套 系 统 就 可 以 解 决 95% 的 需 求 假 设 没 有 Google

那 么 好 的 工 程 师 和 适 合 平 台 化 的 制 度, 可 以 将 GFS + Bigtable 定 位 为 解 决 半 线 上 及 线 下 问 题, 这 将 使 得 问 题 简 化 很 多 这 套 系 统 的 特 点 就 是 通 用, 不 过 整 体 工 程 量 过 于 复 杂 这 套 方 案 是 贵 族 化 解 决 方 案, 需 要 分 别 开 发 文 件 系 统 和 表 格 系 统, 且 为 了 解 决 单 点 问 题, 需 要 开 发 Chubby 锁 服 务, 且 设 计 时 总 是 追 求 通 用 性 和 性 能 极 限 Chubby 锁 服 务 代 码 非 常 复 杂, 但 是 出 了 一 点 小 问 题 会 使 得 整 个 集 群 没 法 服 务 5 典 型 存 储 系 统 工 程 实 现 本 章 首 先 大 致 描 述 单 机 上 存 储 引 擎 的 实 现, 接 着 根 据 通 用 存 储 系 统 的 分 类 选 取 一 些 典 型 系 统 加 以 介 绍 5.1 单 机 存 储 引 擎 简 单 来 说, 单 机 存 储 引 擎 解 决 如 下 几 个 问 题 : 1, 插 入 一 条 数 据 ; 2, 删 除 一 条 数 据 ; 3, 更 新 一 条 已 有 的 数 据 ; 4, 随 机 读 取 一 条 数 据 ;(Read) 5, 顺 序 扫 描 一 段 范 围 的 数 据 ;(Scan) 磁 盘 时 顺 序 性 设 备, 适 合 批 量 顺 序 写 入, 而 内 存 是 随 机 访 问 设 备, 适 合 通 过 各 种 数 据 结 构 组 织 起 来 从 而 提 供 快 速 的 插 入 删 除 查 找 性 能 单 机 存 储 引 擎 需 要 解 决 的 问 题 就 是 利 用 好 磁 盘 和 内 存 的 特 性 一 般 来 说, 互 联 网 对 单 机 存 储 引 擎 的 需 求 有 两 种 : 一 种 应 用 只 需 要 随 机 读 取 功 能, 没 有 顺 序 读 取 需 求, 另 一 种 应 用 需 要 兼 顾 随 机 读 取 和 顺 序 扫 描 需 求 另 外, 单 机 层 面 经 常 需 要 设 计 通 用 的 缓 存 子 系 统 5.1.1 随 机 访 问 存 储 引 擎 随 机 访 问 存 储 引 擎 不 支 持 顺 序 扫 描, 因 此, 这 种 类 型 的 存 储 引 擎 不 需 要 将 数 据 在 存 储 引 擎 中 连 续 存 放 由 于 磁 盘 是 顺 序 读 取 设 备, 可 以 采 用 Append-only 的 方 式 : 添 加 一 条 数 据 的 时 候 追 加 到 文 件 的 末 尾, 删 除 时 索 引 做 标 记, 修 改 数 据 时 追 加 新 数 据 到 数 据 文 件 末 尾 并 修 改 索 引 指 向 新 位 置 修 改 或 者 删 除 的 data 的 空 间 不 实 时 回 收, 而 是 通 过 在 系 统 比 较 空 闲 的 时 候 执 行 数 据 重 写 合 并 操 作 索 引 存 放 在 内 存, 可 以 通 过 B+ 树 或 者 Hash 的 方 式 组 织 这 里 有 一 个 问 题, 如 果 机 器 宕 机, 需 要 将 所 有 的 数 据 都 读 取 出 来 才 能 恢 复 内 存 中 的 全 部 索 引, 这 个 数 据 量 是 很 大 的 索 引 数 据 也 可 以 先 写 磁 盘 在 修 改 内 存 索 引 数 据 结 构, 由 于 索 引 文 件 远 小 于 数 据 文 件, 当 机 器 出 现 故 障 时, 只 需 要 将 全 部 的 索 引 数 据 读 取 出 来 构 造 内 存 数 据 结 构 就 可 以 了 稍 微 麻 烦 点 的 是 数 据 重 写 过 程, 数 据 重 写 过 程 相 当 于 先 对 数 据 做 一 个 Snapshot, 然 后 重 写 这 份 Snapshot, 回 收 删 除 和 修 改 操 作 造 成 的 文 件 空 洞, 而 且, 重 写 过 程 中 还 需 要 能 够 接 受 新 的 更 新 当 需 要 启 动 重 写 过 程 时, 先 等 待 以 前 的 写 操 作 结 束, 以 后 的 写 操 作 都 写 新 文 件 ( 相

当 于 执 行 一 次 Snapshot 操 作 ), 重 写 的 数 据 直 接 append 到 新 文 件 尾 部, 更 新 索 引 时 如 果 发 现 索 引 最 后 更 新 时 间 在 执 行 Snapshot 之 后, 说 明 是 重 写 过 程 中 有 新 的 更 新, 什 么 也 不 做 ; 否 则, 更 新 索 引 由 于 索 引 全 部 装 载 在 内 存 中, 每 次 随 机 读 取 操 作 最 多 访 问 一 次 磁 盘, 而 且, 写 操 作 也 没 有 太 多 的 冗 余 数 据, 因 此, 从 理 论 上 讲, 这 种 做 法 对 于 随 机 访 问 已 经 最 优 了 5.1.2 通 用 存 储 引 擎 通 用 存 储 引 擎 既 支 持 随 机 读 取, 又 能 很 好 地 支 持 顺 序 扫 描, 这 就 要 求 数 据 在 磁 盘 中 连 续 存 放, 一 个 比 较 常 见 的 做 法 就 是 Merge-dump 存 储 引 擎, 下 面 以 Bigtable 为 例 进 行 说 明 数 据 写 入 时 需 要 先 写 操 作 日 志, 成 功 后 应 用 到 内 存 中 的 MemTable 中, 写 操 作 日 志 是 往 磁 盘 中 的 日 志 文 件 追 加 数 据, 很 好 地 利 用 了 磁 盘 设 备 的 特 性 当 内 存 中 的 MemTable 达 到 一 定 的 大 小, 需 要 将 MemTable dump 到 磁 盘 中 生 成 SSTable 文 件 由 于 数 据 同 时 存 在 MemTable 和 可 能 多 个 SSTable 中, 读 取 操 作 需 要 按 老 到 新 合 并 SSTable 和 内 存 中 的 MemTable 数 据 数 据 在 SSTable 中 连 续 存 放, 因 此 可 以 同 时 满 足 随 机 读 取 和 顺 序 读 取 两 种 需 求 为 了 防 止 磁 盘 中 的 SSTable 文 件 过 多, 需 要 定 时 将 多 个 SSTable 通 过 compaction 过 程 合 并 为 一 个 SSTable, 从 而 减 少 后 续 读 操 作 需 要 读 取 的 文 件 个 数 一 般 地, 如 果 写 操 作 比 较 少, 我 们 总 是 能 够 使 得 对 每 一 份 数 据 同 时 只 存 在 一 个 SSTable 和 一 个 MemTable, 也 就 是 说, 随 机 读 取 和 顺 序 读 取 都 只 需 要 访 问 一 次 磁 盘, 这 对 于 线 上 服 务 基 本 上 都 是 成 立 的 插 入 删 除 更 新,Add 等 操 作 在 Merge-dump 引 擎 中 都 看 成 一 回 事, 除 了 最 早 生 成 的 SSTable 外,SSTable 中 记 录 的 只 是 操 作, 而 不 是 最 终 的 结 果, 需 要 等 到 读 取 ( 随 机 或 者 顺 序 ) 时 才 合 并 得 到 最 终 结 果 Bigtable 的 Merge-dump 存 储 引 擎 对 于 NOSQL 存 储 系 统 来 说 基 本 已 经 足 够 通 用 了,Cassandra 也 采 用 了 类 似 的 做 法, 不 过 据 说 实 现 得 不 好, 没 有 控 制 SSTable 的 最 大 个 数 从 而 可 能 出 现 SSTable 个 数 特 别 多 以 至 于 永 远 都 合 并 不 成 功 的 问 题

5.1.3 单 机 存 储 优 化 软 件 有 一 个 特 点, 就 是 最 大 限 度 地 利 用 硬 件 资 源, 随 着 SSD,Fusion IO 等 各 种 技 术 的 发 展, 可 以 考 虑 在 单 机 层 面 上 通 过 搭 配 不 同 类 型 的 硬 件 来 整 体 优 化 存 储 系 统, 在 性 能 和 价 格 上 取 得 一 个 很 好 的 折 衷 我 所 在 部 门 的 CDN 团 队 做 了 极 其 出 色 的 工 作 他 们 在 Squid 服 务 器 上 使 用 SSD + SAS + SATA 混 合 存 储, 按 照 访 问 热 点 进 行 迁 移 : 最 热 的 进 SSD, 中 等 热 度 的 放 SAS, 轻 热 度 的 放 SATA, 并 适 当 考 虑 数 据 大 小, 最 后 的 效 果 是 绝 大 部 分 的 读 取 操 作 走 SSD, 在 保 证 性 能 的 前 提 下 节 省 了 成 本 百 度 在 Mysql 的 针 对 SSD 的 优 化 也 做 了 一 个 工 作, 简 单 来 说 就 是 将 对 SSD 的 随 机 写 变 成 顺 序 写 当 mysql 需 要 对 数 据 库 的 数 据 进 行 写 操 作 时, 它 并 不 是 直 接 写 原 来 的 data file, 而 是 把 写 好 的 page 放 在 内 存 中, 当 内 存 中 攒 满 了 几 个 page 后, 它 就 将 这 些 page 组 织 成 一 个 block, 将 这 个 block 以 append write 的 方 式 写 入 到 另 一 个 cache file 中 这 一 步 很 重 要, 因 为 它 将 本 来 是 随 机 写 入 原 始 data file 中 的 操 作 编 程 了 对 cache file 的 追 加 写 再 看 读 数 据, 内 存 中 会 维 护 一 份 page mapping, 这 样 当 database 需 要 读 某 个 page 的 数 据 的 时 候, 它 会 写 在 page mapping 中 查 找 这 个 page 是 在 data file 还 是 在 cache file 中, 然 后 再 从 相 应 的 file 中 将 数 据 取 出 来 虽 然 cache file 中 的 数 据 是 非 常 凌 乱 的 组 织, 但 由 于 SSD 的 随 机 读 性 能 很 好, 所 以 这 一 点 就 不 成 问 题 最 后,cache file 在 某 个 时 刻 要 合 并 到 原 始 的 data file 中 这 一 步 其 实 会 产 生 大 量 的 随 机 写 但 是, 系 统 可 以 通 过 调 度 和 控 制, 找 到 一 个 系 统 负 荷 很 小 的 时 刻 来 执 行 这 个 merge 操 作, 比 如 深 夜 这 样, 就 避 免 了 大 量 的 随 机 写 对 系 统 的 性 能 造 成 影 响 SSD 或 者 其 它 硬 件 会 发 展 成 什 么 样 还 是 一 个 未 知 数, 不 过 单 机 层 面 根 据 性 价 比 选 择 合 适 的 硬 件 并 针 对 硬 件 优 化 也 是 一 个 不 错 的 选 择 5.2 SQL 数 据 库 SQL 数 据 库 已 经 很 成 熟 了, 如 果 是 开 源 的 数 据 库, 比 如 使 用 最 为 广 泛 的 Mysql, 我 们 可 以 在 单 机 层 面 做 一 些 工 作, 比 如 5.1.3 提 到 的 针 对 SSD 的 优 化 由 于 SQL 定 义 的 语 法 集 合 过 于 复 杂, 其 中 很 多 语 法 支 持 都 影 响 扩 展 性, 比 如 存 储 过 程, 外 键, 因 此, 要 完 全 实 现 一 个 既 支 持 SQL 语 法 集 合 的, 又 能 扩 展 到 成 百 上 千 台 机 器 且 性 能 不 错 的 分 布 式 数 据 库 系 统 至 少 在 五 年 之 内 都 是 不 现 实 的 互 联 网 公 司 主 要 对 数 据 库 做 的 主 要 的 工 作 还 是 对 数 据 进 行 垂 直 切 分 和 水 平 切 分 垂 直 切 分 主 要 是 将 不 同 的 表 划 分 到 不 同 的 数 据 库 ( 主 机 ) 之 上 ; 水 平 切 分 是 将 同 一 个 表 的 数 据 按 照 某 种 条 件 拆 分 到 多 台 数 据 库 ( 主 机 ) 上 作 为 存 储 系 统 开 发 人 员, 我 们 需 要 开 发 一 套 数 据 库 中 间 层, 它 用 于 解 析 用 户 的 SQL 语 句, 并 根 据 拆 分 规 则 转 发 到 不 同 的 数 据 库 ( 主 机 ), 实 现 读 写 分 离, 合 并 多 台 数 据 库 分 库 的 返 回 结 果 数 据 库 中 间 层 可 以 通 过 访 问 每 个 分 库 的 主 库 来 提 供 强 一 致 性, 一 种 可 行 的 做 法 是 同 一 个 session 内 保 持 强 一 致 性, 也 就 是 说, 如 果 客 户 端 同 一 个 session 内 对 某 一 个 数 据 库 分 库 有 修 改 操 作, 后 续 的 读 取 操 作 都 转 发 到 这 个 分 库 的 主 库 数 据 库 中 间 层 主 要 有 几 个 部 分 : SQL 语 句 解 析,SQL 转 发, 结 果 合 并 排 序 属 性 过 滤 以 及 数 据 库 协 议 适 配 器 其 中,SQL 语 句 解 析 相 对 比 较 复 杂, 数 据 库 协 议 适 配 器 相 对 比 较 啰 嗦 数 据 拆 分 后, 不 能 很 好 地 支 持 事 务 操 作, 某 些 跨 表 join 和 排 序 分 页 功 能 也 不 能 高 效 地 支 持, 但 是 给 应 用 开 发 人 员 的 接 口 却 是 SQL 接 口, 应 用 开 发 人 员 需 要 仔 细 设 计

5.3 线 上 最 终 一 致 性 系 统 线 上 最 终 一 致 性 系 统 保 证 最 终 一 致 性, 读 服 务 1~30ms, 正 常 时 写 服 务 100ms 以 内, 机 器 出 现 故 障 时, 某 个 数 据 分 片 的 写 服 务 可 能 出 现 10~20s 的 服 务 中 断 为 了 便 于 介 绍, 将 系 统 命 名 为 KO KO 系 统 由 一 个 主 控 机 Master 和 大 量 的 机 器 group 组 成, 每 个 group 由 N(N 是 数 据 的 备 份 数 ) 台 工 作 机 Chunk Server, 同 一 个 group 中 同 一 时 刻 有 且 只 有 一 台 Chunk Server 提 供 写 服 务, 称 为 CS Master, 其 它 Chunk Server 与 CS Master 保 持 同 步, 称 为 CS Slave 一 般 来 说,N = 3, 任 何 一 个 写 操 作 只 需 要 写 成 功 其 中 一 台 CS Slave 和 CS Master 就 可 以 返 回 客 户 端 表 示 成 功 当 CS Master 宕 机 时, 同 一 个 group 中 与 它 保 持 同 步 最 快 的 CS Slave 接 替 它 成 为 CS Master, 并 触 发 一 个 运 维 操 作, 运 维 人 员 可 在 合 适 的 时 间 上 线 一 台 机 器 到 group 中 新 机 器 加 入 集 群 以 group 为 单 位 KO 系 统 包 含 如 下 几 个 角 色 : 1, Master(Config Master) 集 群 主 控 机, 通 过 Master/Slave 强 同 步 模 式 保 证 HA 2, CS Master 机 器 组 中 提 供 写 服 务 的 Chunk Server 3, CS Slave 机 器 组 中 提 供 CS Master 的 备 份, 可 以 提 供 读 服 务 4, API 客 户 端 请 求 API 整 个 系 统 大 致 的 架 构 图 如 下 : Lock Service acquire lock acquire lock Application Client Get tablet location Config Master replication Config Slave Read/write request Heartbeat & control msg ChunkServer Group ChunkServer Group Slave Master Slave Slave Master Slave 写 操 作 的 大 致 流 程 为 : 1, 请 求 Master 或 者 从 客 户 端 缓 存 中 获 取 待 操 作 行 所 在 的 Chunk Server Master 位 置 ; 2, 往 Chunk Server Master 发 送 写 操 作 ; 3, Chunk Server Master 将 写 操 作 同 步 到 同 一 个 group 下 的 Chunk Server Slave; 4, Chunk Server Master 收 到 至 少 一 个 Chunk Server Slave 的 成 功 返 回 信 息 时 写 本 地 操 作 日 志 并 应 用 到 内 存 中 ; 5, 返 回 客 户 端 写 操 作 成 功 或 者 失 败 原 因 ; 如 果 Chunk Server Master 返 回 客 户 端 待 操 作 行 不 在 服 务 范 围 内, 说 明 发 生 了 tablet 迁 移, 客 户 端 重 新 请 求 Master 获 取 Chunk Server Master 位 置 信 息 并 重 试, 同 时 更 新 客 户 端 缓 存 读 取 操 作 与 写 操 作 流 程 类 似, 不 同 的 是, 可 以 根 据 读 取 的 一 致 性 要 求 选 择 读 取 同 一 个 group 下 的 Chunk Server Master 或 者 Chunk Server Slave 在 数 据 模 型 方 面, 提 供 类 似 Bigtable 的 schema 支 持, 并 保 证 单 行 操 作 的 事 务 性 所 有

schema 的 更 新 都 在 Master 上 执 行,Master 更 新 完 成 后 推 送 到 Chunk Server 客 户 端 向 Master 查 询 每 一 行 所 在 的 Chunk Server 位 置 信 息 时,Master 会 返 回 schema 的 版 本 信 息, 后 续 客 户 端 查 询 Chunk Server 时 如 果 发 现 Chunk Server 的 版 本 低,Chunk Server 需 要 向 Master 请 求 最 新 的 schema 信 息 整 个 系 统 设 计 的 数 据 规 模 控 制 在 200TB 左 右, 集 群 规 模 在 两 百 台 左 右, 磁 盘 大 致 选 择 6 * 600GB 的 SAS 盘, 内 存 大 致 为 16GB, 磁 盘 内 存 比 大 致 为 100 ~ 200 : 1, 数 据 切 分 为 大 小 100MB ~ 200MB 左 右 的 子 表 tablet 当 子 表 太 大 时, 需 要 大 致 平 均 地 分 裂 为 两 个 子 表, 当 出 现 负 载 不 均 衡 时, 也 需 要 Master 指 导 子 表 迁 移 工 作 Master 和 Chunk Server 通 过 定 时 的 heartbeat 通 信,Chunk Server 将 负 载 相 关 的 信 息 汇 报 给 Master 分 裂 和 迁 移 的 做 法 可 以 参 考 3.3 和 3.4 的 描 述 为 了 同 时 支 持 随 机 读 取 和 顺 序 读 取 操 作, 单 机 存 储 引 擎 选 择 实 现 5.1.2 中 提 到 的 Merge-dump 存 储 引 擎 系 统 工 程 实 现 时 的 几 个 比 较 难 的 问 题 为 :Chunk Server Master 与 Chunk Server Slave 同 步, 子 表 分 裂 和 子 表 迁 移,schema 管 理 需 要 考 虑 的 细 节 比 较 多, 有 些 啰 嗦 细 心 的 读 取 可 能 会 发 现, 如 果 group 中 某 一 台 机 器 宕 机 并 且 出 现 磁 盘 故 障, 需 要 在 group 中 新 增 一 台 机 器, 假 设 机 器 中 有 1TB 的 数 据, 线 上 拷 贝 数 据 限 速 20MB/s, 那 么 拷 贝 数 据 时 间 为 1TB/20MB = 1MB/20 = 50000s, 也 就 是 十 几 个 小 时, 因 此 需 要 调 整 架 构 使 得 宕 机 后 数 据 和 服 务 能 够 迁 移 到 整 个 集 群 而 不 是 某 一 台 机 器 可 扩 展 的 分 布 式 系 统 设 计 的 难 点 就 在 于 稳 定 可 靠 的 地 方 存 储 操 作 日 志, 我 们 可 以 采 用 类 似 PNUTS 中 的 方 法 使 用 消 息 中 间 件 存 储 更 新 数 据, 大 致 的 架 构 如 下 : Lock Service acquire lock Config Master replication Get tablet location API API API acquire lock Heartbeat & control msg Config Slave Read/write request 读 写 服 务 集 群 Tablet Server Tablet Server Tablet Server Tablet Server 日 志 消 息 MQ Cluster 如 上 图, 数 据 划 分 为 tablet,tablet Server 提 供 tablet 读 写 服 务, 每 个 时 刻 对 同 一 个 tablet 有 一 台 Tablet Server 提 供 写 服 务, 称 为 Tablet Server Master, 其 它 几 个 副 本 提 供 保 证 最 终 一 致 性 的 读 服 务, 写 操 作 写 入 Tablet Server Master 和 消 息 中 间 件 后 成 功 返 回, 其 它 的 副 本 通 过 订 阅 消 息 中 间 件 的 消 息 回 放 操 作 日 志, 提 供 读 取 服 务 如 果 Tablet Server Master 宕 机, 可 以 选 择 一 个 副 本 回 放 完 操 作 日 志 后 成 为 新 的 Tablet Server Master Tablet 分 裂 也 可 以 通 过 将 分 裂 操 作 日 志 写 入 消 息 中 间 件 的 方 式 保 证 多 个 副 本 之 间 的 一 致 性 任 何 一 台 机 器 宕 机 都 只 会 停 止 十 几 秒 的 部 分 数 据 的 写 服 务, 读 服 务 不 受 影 响, 满 足 线 上 服 务 的 需 求

5.4 线 上 弱 一 致 性 系 统 线 上 弱 一 致 性 系 统 以 Dynamo 和 Cassandra 为 代 表 这 类 系 统 有 两 个 好 处 : 一 个 是 机 器 宕 机 不 需 要 停 写 服 务, 另 一 个 是 由 于 只 需 要 保 证 弱 一 致 性 可 以 采 用 P2P 的 方 法 实 现, 大 大 地 减 少 了 对 工 程 师 个 人 能 力 的 依 赖, 减 少 了 系 统 整 体 风 险 Dynamo 内 部 使 用 了 很 多 P2P 中 的 技 术, 这 些 技 术 都 可 以 单 独 应 用 到 其 它 系 统 的 开 发 过 程 中 一 个 分 布 式 系 统 在 设 计 时 必 须 想 好 这 个 系 统 将 来 如 何 测 试,Dynamo 和 Cassandra 这 样 的 弱 一 致 性 系 统 的 主 要 难 点 就 在 于 如 何 做 系 统 测 试 初 步 想 到 的 测 试 工 作 如 下 : 1, 模 块 级 别 的 测 试 需 要 做 得 比 较 细, 比 如 gossip 协 议 测 试,DHT 分 布 测 试, 机 器 上 下 线 模 块 测 试, 存 储 引 擎 测 试, 冲 突 处 理 测 试 ; 2, 专 门 为 测 试 提 供 额 外 的 信 息, 比 如 每 次 写 操 作 返 回 写 入 的 机 器 编 号, 写 入 时 刻 的 timestamp 等 额 外 信 息, 如 果 对 同 一 个 key 多 次 写 入 不 同 的 机 器, 可 以 在 客 户 端 模 拟 合 并 过 程, 将 合 并 结 果 与 读 取 到 的 数 据 进 行 对 比 ; 3, 模 拟 一 次 两 台 机 器 宕 机 的 情 形, 两 台 机 器 中 的 节 点 某 些 在 DHT 环 相 邻, 某 些 不 相 邻 ; 模 拟 网 络 分 区 的 情 况 ; Dynamo 实 现 时 需 要 使 用 到 如 下 技 术 点 : DHT DHT 全 称 Distributed Hash Table, 使 用 一 致 性 Hash (consistent hashing) 思 想 : 给 每 台 机 器 赋 予 固 定 数 量 的 token, 这 些 token 构 成 一 个 分 布 式 Hash 环 执 行 数 据 存 放 操 作 时, 先 计 算 key 的 hash 值, 然 后 存 放 到 第 一 个 包 含 大 于 或 者 等 于 该 Hash 值 的 token 的 节 点 这 种 方 法 的 好 处 就 在 于 机 器 上 下 线 时 只 会 影 响 到 在 DHT 中 相 邻 的 token 外 部 的 数 据 可 能 首 先 传 输 至 集 群 中 的 任 意 一 台 机 器, 为 了 找 到 数 据 所 属 机 器, 要 求 每 台 机 器 维 护 一 定 的 集 群 机 器 信 息 用 于 定 位 最 直 观 的 想 法 当 然 是 每 台 机 器 分 别 维 护 它 的 前 一 台 及 后 一 台 机 器 的 信 息, 机 器 的 编 号 可 以 为 机 器 IP 的 Hash 值, 定 位 机 器 最 坏 情 况 下 复 杂 度 为 O(N) 可 以 采 用 平 衡 化 思 想 来 优 化 ( 如 同 平 衡 二 叉 树 优 化 数 组 / 链 表 ), 使 每 一 台 机 器 存 储 O(logN) 的 集 群 机 器 信 息, 定 位 机 器 最 坏 情 况 下 复 杂 度 为 O(logN) 在 Dynamo 系 统 中, 每 台 机 器 尽 量 维 护 整 个 集 群 的 信 息, 客 户 端 也 缓 存 整 个 集 群 的 信 息, 从 而 大 多 数 请 求 都 能 直 接 发 送 到 目 标 机 器 Dynamo 中 通 过 gossip 协 议 发 现 机 器 上 下 线 信 息 从 而 更 新 每 台 机 器 缓 存 的 DHT 环 集 群 中 某 台 机 器 上 下 线 时, 部 分 机 器 先 发 现, 部 分 机 器 后 发 现, 从 而 集 群 中 每 台 机 器 缓 存 的 DHT 环 处 于 不 一 致 的 状 态 比 如 系 统 中 初 始 有 四 台 机 器 包 含 的 token 分 别 为 A, C, D, E, 现 在 上 线 一 台 机 器 token 为 B, 假 设 A 发 现 了 B 上 线 但 是 C, D, E 没 有 发 现, 这 时 原 本 属 于 B 的 数 据 可 能 写 入 B, C, D( 假 设 存 储 三 份 ), 也 可 能 写 入 C,D,E, 不 过 没 有 关 系, 以 后 E 将 发 现 B, 或 者 说 是 B 发 现 E, 从 而 触 发 操 作 将 错 误 写 入 到 E 的 数 据 同 步 到 B, 由 B 来 进 行 数 据 合 并, 合 并 的 过 程 中 可 能 需 要 处 理 冲 突 Gossip 协 议 Gossip 协 议 用 于 P2P 系 统 中 自 治 的 节 点 协 调 对 整 个 集 群 的 认 识, 比 如 集 群 的 节 点 状 态, 负 载 情 况 我 们 先 看 看 两 个 节 点 A 和 B 是 如 何 交 换 对 世 界 的 认 识 的 A 告 诉 B 其 管 理 的 所 有 节 点 的 版 本 ( 包 括 Down 状 态 和 Up 状 态 的 节 点 ) B 告 诉 A 哪 些 版 本 他 比 较 旧 了, 哪 些 版 本 他 有 最 新 的, 然 后 把 最 新 的 那 些 节 点 发 给 A( 处 于 Down 状 态 的 节 点 由 于 版 本 没 有 发 生 更 新 所 以 不 会 被 关 注 )

A 将 B 中 比 较 旧 的 节 点 发 送 给 B, 同 时 将 B 发 送 来 的 最 新 节 点 信 息 做 本 地 更 新 ; B 收 到 A 发 来 的 最 新 节 点 信 息 后, 对 本 地 缓 存 的 比 较 旧 的 节 点 做 更 新 ; 由 于 种 子 节 点 的 存 在, 新 节 点 加 入 可 以 做 得 比 较 简 单 新 节 点 加 入 时 首 先 与 种 子 节 点 交 换 世 界 观, 从 而 对 集 群 有 了 认 识 DHT 环 中 原 有 的 其 它 节 点 也 会 定 期 和 种 子 节 点 交 换 世 界 观, 从 而 发 现 新 节 点 的 加 入 世 界 不 断 变 化, 可 能 随 时 有 机 器 下 线, 因 此, 每 个 节 点 还 需 要 定 期 通 过 gossip 协 议 同 其 它 节 点 交 换 世 界 观 如 果 发 现 某 个 节 点 很 长 时 间 状 态 都 没 有 更 新, 比 如 距 离 上 次 更 新 的 时 间 间 隔 超 过 一 定 的 阀 值, 则 认 为 该 节 点 已 经 宕 机 了 Replication 为 了 处 理 节 点 失 效 的 情 况 (DHT 环 中 删 除 节 点 ), 需 要 对 节 点 的 数 据 进 行 replication 思 路 如 下 : 假 设 数 据 存 储 N 份,DHT 定 位 到 的 数 据 所 属 节 点 为 K, 则 数 据 存 储 在 节 点 K, K+1,..., K+N-1 上 如 果 第 K + i (0 <= i <= N-1) 台 机 器 宕 机, 则 往 后 找 一 台 机 器 K+N 临 时 替 代 如 果 第 K+i 台 机 器 重 启, 临 时 替 代 的 机 器 K+N 能 够 通 过 gossip 协 议 发 现, 它 会 将 这 些 临 时 数 据 归 还 N+i, 这 个 过 程 在 Dynamo 中 叫 做 Hinted handoff 机 器 K+i 宕 机 的 这 段 时 间 内, 所 有 的 读 写 均 落 入 到 机 器 [K, K+i-1] 和 [K+i+1, K+N] 中 如 果 机 器 K+i 永 久 失 效, 机 器 K+N 需 要 进 行 数 据 同 步 操 作 一 般 来 说, 从 机 器 K+i 宕 机 开 始 到 被 认 定 为 永 久 失 效 的 时 间 不 会 太 长, 积 累 的 写 操 作 也 不 会 太 多, 可 以 利 用 Merkle Tree 对 机 器 的 数 据 文 件 进 行 快 速 同 步 由 于 数 据 需 要 存 储 N 份, 机 器 宕 机 会 影 响 到 DHT 环 中 后 面 的 N 个 token 所 在 的 机 器 Quorum NWR NWR 是 Dynamo 中 的 一 个 亮 点, 其 中 N 表 示 复 制 的 备 份 数,R 指 成 功 读 操 作 的 最 少 节 点 数,W 指 成 功 写 操 作 的 最 少 节 点 数 只 要 满 足 W + R > N, 就 可 以 保 证 在 存 在 不 超 过 一 台 机 器 故 障 的 时 候, 至 少 能 够 读 到 一 份 有 效 的 数 据 如 果 应 用 重 视 读 效 率, 可 以 设 置 W = N, R = 1; 如 果 应 用 需 要 在 读 / 写 之 间 权 衡, 一 般 可 设 置 W = 2, R = 2,N = 3, 当 然 也 可 以 选 择 W = 1, R = 1, N = 3, 如 果 丢 失 最 后 的 一 些 更 新 也 不 会 有 影 响 的 话 NWR 看 似 很 完 美, 其 实 不 对 在 Dynamo 这 样 的 P2P 集 群 中, 由 于 每 个 节 点 对 集 群 的 认 识 不 同, 可 能 出 现 同 一 个 key 被 多 台 机 器 同 时 操 作 的 情 况, 在 多 台 机 器 上 执 行 的 顺 序 是 无 法 保 证 的, 需 要 依 赖 基 于 vector clock 的 冲 突 合 并 方 法 解 决 冲 突, 默 认 的 解 决 方 法 是 last write wins, 而 这 时 依 赖 于 两 台 机 器 之 间 的 时 钟 同 步 的 所 以,Dynamo 中 即 使 N + W > R, 这 里 所 谓 的 最 终 一 致 性 还 是 依 赖 冲 突 合 并 算 法, 最 后 读 取 的 结 果 和 客 户 期 望 的 结 果 可 能 不 一 致 关 于 这 一 点, 我 们 在 2.4 中 已 经 将 最 终 一 致 性 模 型 与 Dynamo 中 的 一 致 性 模 型 区 分 开 来 了 这 个 不 一 致 问 题 需 要 注 意, 因 为 影 响 到 了 应 用 程 序 的 设 计 和 对 整 个 系 统 的 测 试 工 作 读 写 流 程 客 户 端 的 读 / 写 请 求 首 先 传 输 到 缓 存 的 一 台 机 器, 根 据 预 先 配 置 的 N W 和 R 值, 对 于 写 请 求, 根 据 DHT 算 法 计 算 出 数 据 所 属 的 节 点 后 直 接 写 入 后 续 的 N 个 节 点, 等 到 W 个 节 点 返 回 成 功 时 返 回 客 户 端, 如 果 写 请 求 失 败 将 加 入 retry_list 不 断 重 试 如 果 某 台 机 器 发 生 了 临 时 性 异 常, 将 数 据 写 入 后 续 的 备 用 机 器 并 在 备 用 机 器 中 记 录 临 时 异 常 的 机 器 信 息 对 于 读 请 求, 根 据 DHT 算 法 计 算 出 数 据 所 属 节 点 后 根 据 负 载 策 略 选 择 R 个 节 点, 从 中 读 取 R 份 数 据, 如 果 数 据 一 致, 直 接 返 回 客 户 端 ; 如 果 数 据 不 一 致, 采 用 vector clock 的 方 法 解 决 冲 突 Dynamo 系 统 默 认 的 策 略 是 选 择 最 新 的 数 据, 当 然 用 户 也 可 以 自 定 义 冲 突 处 理 方 法 读 取 过 程 中 如 果 发 现 副 本 中 有 一 些 数 据 版 本 太 旧,Dynamo 内 部 异 步 发 起 一 次 read-repair 操 作, 更 新 过 期 的 数 据

异 常 处 理 Dynamo 中 把 异 常 分 为 两 种 类 型, 临 时 性 的 异 常 和 永 久 性 异 常 有 一 些 异 常 是 临 时 性 的, 比 如 机 器 假 死, 其 它 异 常 如 硬 盘 报 修 或 机 器 报 废 等 由 于 其 持 续 时 间 太 长, 称 之 为 永 久 性 的 Hinted handoff: 在 Dynamo 设 计 中, 一 份 数 据 被 写 到 K, K+1,... K+N-1 这 N 台 机 器 上, 如 果 机 器 K+i (0 <= i <= N-1) 宕 机, 原 本 写 入 该 机 器 的 数 据 转 移 到 机 器 K+N, 如 果 在 指 定 的 时 间 T 内 N+i 重 新 提 供 服 务, 机 器 K+N 将 通 过 gossip 协 议 发 现, 并 将 启 动 传 输 任 务 将 暂 存 的 数 据 发 送 给 机 器 N+i; Merkle Tree 同 步 : 如 果 超 过 了 时 间 T 机 器 N+i 还 是 处 于 宕 机 状 态, 这 种 异 常 被 认 为 是 永 久 性 的, 这 时 需 要 借 助 Merkle Tree 机 制 从 其 它 副 本 进 行 数 据 同 步 Merkle Tree 同 步 的 原 理 很 简 单, 每 个 非 叶 子 节 点 对 应 多 个 文 件, 为 其 所 有 子 节 点 值 组 合 以 后 的 Hash 值, 叶 子 节 点 对 应 单 个 数 据 文 件, 为 文 件 内 容 的 Hash 值 这 样, 任 何 一 个 数 据 文 件 不 匹 配 都 将 导 致 从 该 文 件 对 应 的 叶 子 节 点 到 根 节 点 的 所 有 节 点 值 不 同 每 台 机 器 对 每 一 段 范 围 的 数 据 维 护 一 颗 Merkle Tree, 机 器 同 步 时 首 先 传 输 Merkle Tree 信 息, 并 且 只 需 要 同 步 从 根 到 叶 子 的 所 有 节 点 值 均 不 相 同 的 文 件 Read repair: 假 设 N=3, W=2, R=2, 机 器 K 宕 机, 可 能 有 部 分 写 操 作 已 经 返 回 客 户 端 成 功 了 但 是 没 有 完 全 同 步 到 所 有 的 副 本, 如 果 机 器 K 出 现 永 久 性 异 常, 比 如 磁 盘 故 障, 三 个 副 本 之 间 的 数 据 一 直 都 不 一 致 客 户 端 的 读 取 操 作 如 果 发 现 了 某 些 副 本 版 本 太 老, 则 启 动 异 步 的 Read repair 任 务, 更 新 过 期 的 数 据 从 而 使 得 副 本 之 间 保 持 一 致 负 载 平 衡 Dynamo 的 负 载 平 衡 取 决 于 如 何 给 每 台 机 器 分 配 虚 拟 节 点 号, 即 token 由 于 集 群 环 境 的 异 构 性, 每 台 物 理 机 器 包 含 多 个 虚 拟 节 点 一 般 有 如 下 两 种 分 配 节 点 号 的 方 法 : 1. 随 机 分 配 每 台 物 理 节 点 加 入 时 根 据 其 配 置 情 况 随 机 分 配 S 个 Token( 节 点 号 ) 这 种 方 法 的 负 载 平 衡 效 果 还 是 不 错 的, 因 为 自 然 界 的 数 据 大 致 是 比 较 随 机 的, 虽 然 可 能 出 现 某 段 范 围 的 数 据 特 别 多 的 情 况 ( 如 baidu, sina 等 域 名 下 的 网 页 特 别 多 ), 但 是 只 要 切 分 足 够 细, 即 S 足 够 大, 负 载 还 是 比 较 均 衡 的 这 个 方 法 的 问 题 是 可 控 性 较 差, 新 节 点 加 入 / 离 开 系 统 时, 集 群 中 的 原 有 节 点 都 需 要 扫 描 所 有 的 数 据 从 而 找 出 属 于 新 节 点 的 数 据,Merkle Tree 也 需 要 全 部 更 新 ; 另 外, 增 量 归 档 / 备 份 变 得 几 乎 不 可 能 2. 数 据 范 围 等 分 + 随 机 分 配 为 了 解 决 方 法 1 的 问 题, 首 先 将 数 据 的 Hash 空 间 等 分 为 Q = N * S 份 (N= 机 器 个 数,S= 每 台 机 器 的 虚 拟 节 点 数 ), 然 后 每 台 机 器 随 机 选 择 S 个 分 割 点 作 为 Token 和 方 法 1 一 样, 这 种 方 法 的 负 载 也 比 较 均 衡, 且 每 台 机 器 都 可 以 对 属 于 每 个 范 围 的 数 据 维 护 一 个 逻 辑 上 的 Merkle Tree, 新 节 点 加 入 / 离 开 时 只 需 扫 描 部 分 数 据 进 行 同 步, 并 更 新 这 部 分 数 据 对 应 的 逻 辑 Merkle Tree, 增 量 归 档 也 变 得 简 单 另 外,Dynamo 对 单 机 的 前 后 台 任 务 资 源 分 配 也 做 了 一 些 工 作 Dynamo 中 同 步 操 作 写 操 作 重 试 等 后 台 任 务 较 多, 为 了 不 影 响 正 常 的 读 写 服 务, 需 要 对 后 台 任 务 能 够 使 用 的 资 源 做 出 限 制 Dynamo 中 维 护 一 个 资 源 授 权 系 统 该 系 统 将 整 个 机 器 的 资 源 切 分 成 多 个 片, 监 控 60s 内 的 磁 盘 读 写 响 应 时 间, 事 务 超 时 时 间 及 锁 冲 突 情 况, 根 据 监 控 信 息 算 出 机 器 负 载 从 而 动 态 调 整 分 配 给 后 台 任 务 的 资 源 片 个 数 单 机 存 储 引 擎 Dynamo 设 计 支 持 可 插 拔 的 存 储 引 擎, 比 如 Berkerly db, Mysql Innodb 等 Cassandra 中 实 现 了 一 个 5.1.2 中 提 到 的 Merge-dump 存 储 引 擎, 对 于 需 要 同 时 支 持 随 机 读 取 和 顺 序 读 取,

不 仅 仅 通 用 而 且 效 率 高 5.5 半 线 上 及 线 下 系 统 半 线 上 及 线 下 系 统 指 GFS + Bigtable, 开 源 的 实 现 有 HDFS + HBase/Hypertable, 不 过 开 源 的 实 现 远 没 有 达 到 GFS + Bigtable 应 有 的 高 度 这 里 之 所 以 将 GFS + Bigtable 划 分 为 半 线 上 及 线 下 系 统, 不 是 因 为 这 套 解 决 方 案 不 能 支 持 线 上 应 用, 而 是 因 为 这 套 应 用 在 并 发 量, 机 器 异 常 处 理 等 都 做 得 很 极 限, 如 果 支 持 线 上 的 低 延 迟, 永 远 不 停 读 服 务, 整 个 系 统 过 于 复 杂 我 们 姑 且 认 为 GFS + Bigtable 这 套 服 务 能 设 计 成 支 持 半 线 上 及 线 下 应 用, 如 增 量 建 网 页 库, 已 经 是 非 常 大 的 挑 战 了 5.5.1 两 层 结 构 GFS 和 Bigtable 采 用 两 层 结 构,GFS 关 注 文 件 存 储 文 件, 虽 然 对 外 提 供 文 件 接 口, 但 是 保 证 文 件 可 靠 性,Bigtable 关 注 用 户 接 口 问 题, 在 GFS 之 上 提 供 支 持 简 单 schema 的 NOSQL 访 问 接 口 GFS 和 Bigtable 两 层 结 构 非 常 巧 妙 地 解 决 了 一 致 性 的 问 题, 底 层 的 GFS 提 供 弱 一 致 性, 写 操 作 可 能 出 现 重 复 记 录,Bigtable 通 过 一 种 类 似 B+ 树 的 方 式 索 引 写 入 到 GFS 中 的 记 录, 很 好 地 解 决 了 一 致 性 问 题 Bigtable 中 同 一 个 tablet 同 一 时 刻 只 能 被 同 一 个 Tablet Server 工 作 机 服 务, 不 过 由 于 底 层 可 靠 的 GFS 存 储, 机 器 宕 机 时 只 需 要 在 其 它 机 器 中 将 GFS 中 持 久 化 的 内 容 加 载 到 内 存 中 即 可, 大 大 地 减 少 了 宕 机 恢 复 需 要 的 时 间 GFS 相 当 于 是 Bigtable 的 可 靠 的 共 享 存 储, 由 于 GFS 只 需 要 提 供 文 件 接 口, 所 以 内 存 操 作 简 单, 出 现 代 码 错 误 的 可 能 性 很 小, 并 且,GFS 可 以 提 供 类 似 Snapshot 的 功 能 ;Bigtable 内 部 逻 辑 和 内 存 操 作 非 常 复 杂, 有 了 GFS 的 Snapshot 功 能,Bigtable 可 以 用 来 备 份 数 据, 从 而 Bigtable 出 现 bug 时, 可 以 修 改 bug 后 回 滚 回 去 重 新 测 试 前 面 提 到 的 线 上 最 终 一 致 性 系 统 采 用 单 层 结 构 的 设 计, 把 分 裂 和 迁 移 看 成 是 一 种 不 是 特 别 常 见 的 情 况, 所 以 不 是 特 别 注 重 分 裂 和 迁 移 的 效 率, 且 为 了 解 决 一 致 性 引 入 了 Chunk Server group 的 概 念 而 GFS + Bigtable 的 设 计 中, 所 有 的 工 作 机, 即 Chunk Server 和 Tablet Server 都 是 完 全 对 等 的, 一 台 Tablet Server 机 器 宕 机 后, 整 个 集 群 中 的 所 有 的 机 器 都 可 以 加 载 这 个 机 器 上 服 务 的 子 表, 扩 展 性 基 本 做 到 了 极 限 集 群 的 规 模 越 大,GFS + Bigtable 的 解 决 方 案 越 有 优 势, 很 适 合 平 台 化, 唯 一 的 缺 点 就 是 过 于 复 杂 采 用 两 层 设 计, 底 层 的 GFS 可 以 简 化 很 多, 只 需 要 考 虑 批 量 的 读 写, 提 供 简 单 的 Append 模 型 上 层 的 Bigtable 负 责 将 写 请 求 聚 合 成 大 块, 随 机 读 取 操 作 的 缓 存 等 GFS + Bigtable 解 决 方 案 最 适 合 的 场 景 是 半 线 上 及 线 下 应 用, 比 如 搜 索 类 及 数 据 仓 库 类 应 用, 系 统 中 的 磁 盘 和 内 存 比 大 致 为 256 ~ 1000 : 1, 采 用 廉 价 的 SATA 盘 作 为 底 层 存 储, 一 般 单 机 12 * 1T SATA 盘 配 置 由 于 系 统 在 软 件 层 面 具 有 无 可 匹 敌 的 容 错 性, 可 以 极 大 地 降 低 运 维 成 本, 节 省 服 务 器 开 销

5.5.2 GFS 整 个 GFS 的 架 构 如 下, 如 上 图,GFS 系 统 包 含 三 个 模 块,API,Master,ChunkServer 为 了 对 GFS 系 统 进 行 运 维 操 作, 还 需 要 一 个 utility 模 块 提 供 实 用 工 具 用 户 通 过 API 模 块 向 Master 发 请 求 或 者 从 API 缓 存 中 获 取 Chunk Server 信 息, 以 后 直 接 与 Chunk Server 打 交 道, 将 数 据 追 加 到 Chunk Server 机 器 中 GFS 提 供 两 种 操 作 模 型,Append 追 加 模 型 与 Overwrite 模 型 由 于 GFS 的 用 户 可 以 认 为 是 MapReduce 计 算 系 统 和 Bigtable 系 统, 而 这 两 个 系 统 都 只 需 要 用 到 Append 模 型, 并 通 过 内 部 建 索 引 来 处 理 GFS 的 重 复 记 录 作 为 分 布 式 文 件 系 统,GFS 最 难 的 问 题 就 是 一 致 性 模 型, 也 就 是 GFS 的 Append 操 作 实 现 对 同 一 个 chunk, 在 GFS 中 通 过 Lease 机 制 来 保 证 同 一 时 刻 只 能 有 一 台 机 器 提 供 追 加 写 服 务, 这 台 Chunk Server 称 为 Primary Chunk Server, 用 户 的 数 据 先 发 送 到 Primary Chunk Server, 由 它 确 定 写 入 顺 序, 然 后 通 过 pipeline 的 方 式 同 步 到 其 它 的 Chunk Server 副 本, 等 到 所 有 副 本 都 写 成 功 时 返 回 成 功, 否 则, 客 户 端 可 能 重 试 写 操 作, 从 而 多 次 写 入 同 一 个 记 录, 即 重 复 记 录 如 果 写 入 的 过 程 中 Primary Chunk Server 出 现 异 常,chunk 上 未 完 成 的 写 操 作 全 部 失 败, 等 到 Lease 过 期 后,Master 将 写 权 限 授 给 其 它 服 务 该 chunk 的 Chunk Server, 客 户 端 也 将 重 试 写 操 作 GFS Master 管 理 的 数 据 包 括 文 件 元 数 据, 文 件 到 chunk 的 映 射,chunk 元 数 据, 如 chunk 版 本 号 chunk 所 在 的 chunk server 编 号,chunk server 数 据 GFS 的 设 计 中, 每 个 chunk 大 小 为 64MB, 因 此 存 储 1PB 数 据 的 chunk 个 数 为 1024 * 1024 * 1024 * 3 / 64 = 48MB, 即 接 近 5000 万 的 chunk 数, 在 Bigtable 的 设 计 中, 每 个 子 表 的 大 小 为 100MB ~ 200MB, 而 每 个 子 表 至 少 占 用 一 个 GFS 的 文 件, 因 此 存 储 1PB 数 据 需 要 的 文 件 个 数 为 1024 * 1024 * 1024 / 100 = 10MB, 也 是 千 万 级 别 所 以,GFS Master 元 数 据 管 理 数 据 结 构 需 要 高 效 地 支 持 千 万 级 别 的 数 据 插 入 查 找 删 除 操 作, 且 必 须 支 持 Snapshot 功 能, 比 较 好 的 数 据 结 构 就 是 支 持 Copy-on-write 的 B+ 树 GFS Master 需 要 实 现 replication 将 操 作 强 同 步 到 Slave 中, 从 而 宕 机 后 可 以 很 快 地 恢 复 另 外,GFS Master 还 需 要 能 够 定 期 将 内 存 状 态 生 成 一 份 checkpoint 文 件 存 储 到 磁 盘 中, 从 而 减 少 宕 机 恢 复 重 放 的 日 志 量 GFS Master 还 有 一 些 全 局 性 功 能 模 块, 比 如 chunk 复 制,chunk rebalance,garbage

collection, lease 管 理,heartbeat 等 等, 另 外, 为 了 支 持 大 规 模 集 群 的 运 维, 可 以 支 持 从 机 器 资 源 池 选 取 机 器, 发 送 二 进 制 程 序 并 启 动 chunk server 的 功 能 总 之,GFS Master 的 功 能 不 仅 复 杂, 而 且 啰 嗦 5.5.3 Bigtable 整 个 Bigtable 的 结 构 如 下 : 如 上 图,Bigtable 其 实 就 是 在 GFS 之 上 增 加 一 层 索 引 层, 并 对 外 提 供 带 有 schema 的 NOSQL 用 户 接 口 Bigtable 有 三 种 类 型 的 表 : 用 户 表 格 存 储 用 户 实 际 数 据,METADATA 表 格 存 储 用 户 表 格 的 元 数 据, 如 位 置 信 息,SSTable 及 操 作 日 志 文 件 编 号, 日 志 回 放 点 等,Root table 表 格 存 储 METADATA 表 格 的 元 数 据 Bigtable 系 统 将 每 个 表 切 分 为 大 小 在 100MB ~ 200MB 之 间 的 子 表 tablet 整 个 系 统 中 有 三 种 角 色 :Bigtable Master,Tablet Server 和 API 其 中,Bigtable Master 负 责 管 理 Tablet Server, 并 提 供 一 些 全 局 性 服 务, 比 如 负 载 均 衡, 用 户 和 schema 管 理,Tablet Server 宕 机 恢 复 等 ;Tablet Server 是 工 作 机, 将 每 一 个 子 表 加 载 到 内 存 中 对 外 提 供 服 务, 它 是 内 存 操 作 最 为 复 杂 的 模 块, 出 现 的 bug 也 最 多 ;API 用 于 找 到 子 表 所 在 的 Tablet Server 并 请 求 服 务 在 Bigtable 系 统 中, 用 户 表 在 进 行 某 些 操 作, 比 如 子 表 分 裂 的 时 候 需 要 修 改 METADATA 表,METADATA 表 的 某 些 操 作 需 要 修 改 Root 表, 因 此,Tablet Server 也 需 要 使 用 API 模 块, 它 以 动 态 库 的 方 式 链 接 到 Tablet Server 可 执 行 程 序 中 第 一 个 需 要 解 决 的 问 题 还 是 一 致 性 Bigtable 系 统 保 证 强 一 致 性, 同 一 个 时 刻 同 一 个 tablet 只 能 被 一 台 Tablet Server 服 务, 也 就 是 说,Master 将 tablet 分 配 给 某 个 Tablet Server 服 务 时 需 要 确 认 没 有 其 它 的 tablet 正 在 服 务 这 个 tablet 可 以 通 过 Lease 的 机 制 实 现, 每 个 Tablet Server 有 Lease 才 能 提 供 服 务, 当 Lease 快 要 到 期 时,Tablet Server 会 找 Master 重 新 请 求 延 长 Lease 期 限, 如 果 Master 发 现 Tablet Server 的 Lease 已 经 过 期 了, 可 以 安 全 地 将 它 服 务 的 tablet 分 配 给 其 它 Tablet Server, 同 样,Tablet Server 也 必 须 自 觉, 当 它 发 现 自 己 没 有 Lease 时 主 动 下 线, 不 要 影 响 全 局 一 致 性 第 二 个 需 要 解 决 的 是 宕 机 恢 复 问 题 Tablet Server 执 行 一 个 写 操 作 是, 需 要 先 写 操 作 日 志 然 后 应 用 到 MemTable, 当 MemTable 中 的 数 据 达 到 一 定 大 小 或 者 超 过 一 定 时 间 会 写 成 SSTable 存 储 到 GFS 文 件 系 统 中 这 里 我 们 看 到, 如 果 Tablet Server 宕 机, 需 要 将 原 来 服 务 的 tablet 迁 移 到 其 它 机 器, 而 部 分 内 存 中 的 数 据 没 有 序 列 化 成 SSTable, 加 载 时 需 要 回 放 操

作 日 志 的 数 据 为 了 更 好 地 利 用 GFS 文 件 系 统, 同 一 个 Tablet Server 的 操 作 日 志 写 到 了 同 一 个 GFS 文 件 由 于 多 个 tablet 的 日 志 混 在 一 起, 需 要 对 日 志 文 件 排 序 从 而 每 个 tablet 加 载 时 可 以 连 续 读 取 自 己 需 要 的 操 作 日 志 Master 需 要 有 一 个 模 块 专 门 用 于 调 度 Tablet Server 对 操 作 日 志 文 件 进 行 排 序 第 三 个 需 要 解 决 的 问 题 是 子 表 分 裂 和 迁 移 问 题 由 于 同 一 个 tablet 同 一 时 刻 只 被 一 个 Tablet Server 服 务, 子 表 分 裂 简 化 很 多 子 表 分 裂 之 前 先 将 MemTable 中 的 数 据 序 列 化 到 SSTable 中, 然 后 通 过 API 往 表 格 的 Metadata 中 加 入 一 行 表 示 新 生 成 的 tablet: 如 果 是 用 户 表 格, 需 要 修 改 METADATA 表 格 ; 如 果 是 METADATA 表 格, 需 要 修 改 Root 表 格 子 表 迁 移 也 需 要 先 将 MemTable 中 的 数 据 序 列 化 到 SSTable, 然 后 停 止 服 务,Master 会 把 它 分 配 给 其 它 Tablet Server 加 载, 因 为 此 时 MemTable 中 的 数 据 都 持 久 化 到 SSTable 中, 不 需 要 回 放 日 志 第 四 个 要 解 决 的 问 题 是 存 储 引 擎 问 题 采 用 5.1.2 节 中 的 Merge-dump 存 储 引 擎, Merge-dump 存 储 引 擎 每 次 操 作 都 是 大 块 读 写, 非 常 适 合 GFS 第 五 个 需 要 解 决 的 就 是 缓 存 和 内 存 管 理 问 题 由 于 Bigtable 的 内 存 操 作 非 常 复 杂, 要 求 每 个 模 块 都 从 全 局 统 一 的 内 存 池 中 申 请, 从 而 管 理 整 个 系 统 对 内 存 的 使 用 如 果 是 随 机 读 操 作,Tablet Server 还 需 要 进 行 缓 存 和 普 通 的 文 件 系 统 的 page cache 原 理 类 似, 需 要 缓 存 从 GFS 中 读 取 的 SSTable, 由 于 SSTable 是 以 块 ( 大 小 一 般 为 64KB) 为 单 位, 所 以, 有 一 个 块 缓 存 ; 另 外, 还 需 要 对 每 一 个 SSTable 文 件 缓 存 随 机 读 操 作 的 读 取 结 果 第 六 个 需 要 考 虑 的 问 题 是 压 缩 和 解 压 缩 Bigtable 支 持 的 应 用 比 如 网 页 库, 数 据 仓 库 的 数 据 重 复 读 很 高, 且 由 于 Bigtable 存 储 历 史 版 本 数 据,Google 里 面 使 用 了 Zippy 和 BMDiff 压 缩 算 法, 两 个 算 法 的 特 点 都 是 压 缩 和 解 压 缩 速 度 快 6 通 用 计 算 系 统 分 类 互 联 网 公 司 大 致 需 要 如 下 几 类 通 用 计 算 系 统 : 1, MapReduce Offline; 2, Online 计 算 ; 线 下 计 算, 挖 掘 类 应 用 MapReduce 基 本 上 可 以 包 打 天 下 了 MapReduce 的 批 处 理 能 力 可 扩 展 性 以 及 容 错 能 力 极 大 地 迎 合 了 线 下 计 算 应 用 的 需 求,MapReduce 模 型 本 身 简 单 高 效, 使 得 普 通 的 工 程 师 也 能 写 出 运 行 在 成 百 上 千 台 集 群 的 分 布 式 程 序 Online 实 时 计 算 与 线 下 批 处 理 有 本 质 的 区 别, 线 下 批 处 理 计 算 处 理 静 态 数 据, 发 展 出 了 通 用 的 MapReduce 模 型, 但 是 线 上 实 时 计 算 一 直 都 没 有 统 一 的 解 决 方 案 后 续 将 举 一 些 例 子 说 明 常 见 的 线 上 计 算 场 景, 如 下 : 1, 流 式 计 算 ; 2, 并 行 数 据 库 的 SQL 查 询 ; 3, 数 据 仓 库 复 杂 查 询 ;

7 典 型 计 算 系 统 工 程 实 现 7.1 MapReduce Offline MapReduce 的 架 构 如 下 : MapReduce 执 行 顺 序 如 下 : 1, 首 先 从 用 户 提 交 的 程 序 fork 出 Master 进 程,Master 进 程 启 动 后 将 切 分 任 务 并 根 据 输 入 文 件 所 在 的 位 置 和 集 群 信 息 选 择 机 器 fork 出 Map 或 者 Reduce Worker; 用 户 提 交 的 程 序 可 以 根 据 不 同 的 命 令 行 参 数 执 行 不 同 的 行 为 ; 2, Master 将 切 分 好 的 任 务 分 配 给 Map Worker 和 Reduce Worker 执 行, 任 务 切 分 和 任 务 分 配 可 以 并 行 执 行 ; 3, Map Worker 执 行 Map 任 务 : 读 取 相 应 的 输 入 文 件, 根 据 指 定 的 输 入 格 式 不 断 地 读 取 <key, value> 对 并 对 每 一 个 <key, value> 对 执 行 用 户 自 定 义 的 Map 函 数 ; 4, Map Worker 执 行 用 户 定 义 的 Map 函 数, 不 断 地 往 本 地 内 存 缓 冲 区 输 出 中 间 <key, value> 对 结 果, 等 到 缓 冲 区 超 过 一 定 大 小 时 写 入 到 本 地 磁 盘 中 由 于 Map 操 作 的 输 出 结 果 将 根 据 partition 函 数 分 配 给 R 个 Reduce Worker, 所 以 Map Worker 的 中 间 结 果 组 织 成 R 份 5, Map 任 务 执 行 完 成 时,Map Worker 通 过 heartbeat 定 期 向 Master 汇 报, 从 而 Master 通 知 Reduce Worker Reduce Worker 向 Map Worker 请 求 传 输 生 成 的 中 间 结 果 数 据 这 个 过 程 称 为 Shuffle 当 Reduce 获 取 完 所 有 的 Map 任 务 生 成 的 中 间 结 果 时, 需 要 进 行 排 序 操 作 如 果 数 据 量 太 大, 需 要 执 行 外 排 ;

6, Reduce Worker 执 行 Reduce 任 务 : 对 中 间 结 果 的 每 一 个 相 同 的 key 及 value 集 合, 执 行 用 户 自 定 义 的 Reduce 函 数 Reduce 函 数 的 输 出 结 果 被 写 入 到 最 终 的 输 出 结 果, 通 常 是 GFS 或 者 Bigtable; MapReduce 实 现 时 有 如 下 几 个 关 键 点 : 1, 输 入 任 务 划 分 :MapReduce 的 输 入 和 输 出 一 般 是 GFS 或 者 Bigtable, 如 果 输 入 为 GFS, 可 以 按 照 chunk 来 切 分 任 务 ; 如 果 输 入 为 Bigtable, 可 以 按 照 tablet 来 切 分 任 务 ; 2, Master 状 态 机 :Master 状 态 机 管 理 任 务 的 状 态 转 化,Map 或 者 Reduce Worker 的 状 态 转 化, 且 两 个 状 态 机 有 关 联, 设 计 时 需 要 画 出 状 态 转 化 图 ; 3, 用 户 代 码 和 框 架 代 码 的 结 合 : 例 如 任 务 划 分 操 作, 框 架 应 该 需 要 支 持 用 户 自 定 义 任 务 划 分 方 法, 且 有 默 认 的 任 务 划 分 实 现, 即 GFS 文 件 和 Bigtable 表 格 任 务 划 分 实 现 ; 4, Reduce Worker 往 Map Worker 获 取 中 间 结 果 的 压 力 应 该 分 散, 不 能 出 现 某 些 Map Worker 压 力 太 大 的 情 况 ; 另 外,Map Worker 出 现 宕 机 故 障 时, 可 能 有 部 分 Map 任 务 的 中 间 结 果 已 经 发 送 给 Reduce Worker, 部 分 没 有 发 送, 由 于 以 后 Map Worker 上 的 任 务 将 被 重 做, 所 以 Reduce Worker 需 要 支 持 回 滚 某 些 Map 任 务 生 成 的 中 间 结 果 ; 5, 备 份 任 务 的 支 持 : 大 集 群 环 境 中, 机 器 的 处 理 能 力 相 差 可 能 非 常 大, 备 份 任 务 对 整 个 作 业 的 总 体 执 行 时 间 有 很 大 的 优 化 ; 6, 本 地 化 : 尽 量 将 任 务 分 配 给 离 输 入 文 件 最 近 的 Map Worker, 如 同 一 台 机 器 或 者 同 一 个 机 架 ; 7.2 Online 计 算 MapReduce 解 决 了 大 部 分 线 下 批 处 理 计 算 的 问 题,SQL 语 句 基 本 能 够 表 达 所 有 的 计 算 问 题, 但 是 SQL 语 句 的 某 些 操 作 执 行 效 率 地 下, 线 上 计 算 系 统 一 般 选 择 性 地 支 持 部 分 SQL 操 作, 比 如 limit,order by,etc 7.2.1 流 式 计 算 流 式 计 算, 英 文 名 称 为 Stream Processing, 解 决 在 线 聚 合 (Online Aggregation), 在 线 过 滤 (Online Filter) 等 问 题, 流 式 计 算 同 时 具 有 存 储 系 统 和 计 算 系 统 的 特 点, 经 常 应 用 在 一 些 类 似 反 作 弊, 交 易 异 常 监 控 等 场 景 流 式 计 算 的 操 作 算 子 和 时 间 相 关, 处 理 最 近 一 段 时 间 窗 口 内 的 数 据 如 果 不 考 虑 机 器 故 障, 在 线 聚 合 和 在 线 过 滤 的 实 现 没 有 什 么 特 别 困 难 之 处 如 果 考 虑 机 器 故 障, 问 题 变 得 复 杂 上 游 的 机 器 出 现 故 障 时, 下 游 有 两 种 选 择 : 第 一 种 选 择 是 等 待 上 游 恢 复 服 务, 保 证 数 据 一 致 性 ; 第 二 种 选 择 是 继 续 处 理, 优 先 保 证 可 用 性, 等 到 上 游 恢 复 后 再 修 复 错 误 的 计 算 结 果 流 式 计 算 系 统 架 构 如 下 :

Source client Source client Source client 源 数 据 输 入 源 数 据 输 入 MB Group MB Group MB Master 钩 子 函 数 replication MB Slave MB Master 钩 子 函 数 replication MB Slave 流 数 据 转 发 MB Group 流 数 据 转 发 流 数 据 转 发 MB Group MB Master 钩 子 函 数 replication MB Slave MB Master 钩 子 函 数 replication MB Slave 结 果 数 据 输 出 结 果 数 据 输 出 Dest client Dest client Dest client 如 上 图, 源 数 据 写 入 到 Message Broker (MB) 处 理 节 点,MB 处 理 节 点 通 过 Master/Slave 的 方 式 保 证 可 靠 性 MB 处 理 节 点 内 部 运 行 用 户 定 义 的 钩 子 函 数 对 输 入 流 进 行 处 理, 处 理 完 后 根 据 一 定 的 规 则 转 发 给 下 游 的 MB 节 点 继 续 处 理 典 型 钩 子 函 数 包 括 : 1, 聚 合 函 数 : 计 算 最 近 一 段 时 间 窗 口 内 数 据 的 聚 合 指, 如 max, min, avg, sum, count 等 ; 2, 过 滤 函 数 : 过 滤 最 近 一 段 时 间 窗 口 内 满 足 某 些 特 性 的 数 据, 如 过 滤 1 秒 钟 内 重 复 的 点 击 ; 消 息 队 列 是 一 种 保 证 数 据 可 靠 有 序 传 输 的 基 础 设 施, 典 型 的 实 现 有 Active MQ,Mule MQ 等 如 果 在 消 息 传 输 过 程 中 注 入 Stream Processing 算 子, 可 以 实 现 流 式 计 算 7.2.2 并 行 数 据 库 的 SQL 查 询 并 行 数 据 库 与 NOSQL 系 统 区 别 主 要 在 于 关 注 点 不 同, 并 行 数 据 库 需 要 完 全 支 持 SQL,NOSQL 更 加 注 重 扩 展 性 和 异 常 情 况 处 理 并 行 数 据 库 中 limit, order by, group by, join 等 操 作 的 实 现 对 NOSQL 系 统 设 计 具 有 借 鉴 作 用 常 见 的 数 据 分 布 方 式 有 三 种 :

1, Range partitioning: 按 照 范 围 划 分 数 据 ; 2, Round-robin: 将 第 i 个 元 组 分 配 给 i % N 节 点 ; 3, Hashing: 根 据 hash 函 数 计 算 结 果 将 每 个 元 组 分 配 给 相 应 的 节 点 ; Merge 操 作 符 :limit, order by, group by, join 都 可 以 通 过 Merge 操 作 符 实 现, 在 系 统 中 增 加 一 个 合 并 节 点, 发 送 命 令 给 各 个 数 据 分 片 请 求 相 应 的 数 据, 每 个 数 据 节 点 扫 描 数 据, 排 序 后 回 复 合 并 节 点, 由 合 并 节 点 汇 总 数 据 并 执 行 limit, order by, group by, join 操 作 这 个 过 程 相 当 于 执 行 一 个 Reduce 任 务 个 数 为 1 的 MapReduce 作 业, 不 考 虑 机 器 出 现 故 障, 也 不 考 虑 数 据 分 布 不 均 而 启 动 备 份 任 务 Split 操 作 符 : 相 当 于 MapReduce 中 的 partition 函 数 由 于 Merge 节 点 处 理 的 数 据 可 能 特 别 大, 所 以 可 以 通 过 Split 操 作 符 将 数 据 分 散 到 多 个 Merge 节 点, 每 个 节 点 合 并 数 据 并 执 行 相 应 的 group by, join 操 作 比 如 执 行 select * from A, B where A.x = B.y, 可 以 根 据 A.x 的 hash 值 将 数 据 节 点 扫 描 到 的 数 据 分 散 到 不 同 的 合 并 节 点, 每 个 合 并 节 点 执 行 Join 操 作 并 行 数 据 库 的 SQL 查 询 和 MapReduce 计 算 有 些 类 似, 可 以 认 为 MapReduce 模 型 是 一 种 更 高 层 次 的 抽 象 由 于 考 虑 问 题 的 角 度 不 同, 并 行 数 据 库 处 理 的 SQL 查 询 执 行 时 间 通 常 很 短, 出 现 异 常 时 整 个 操 作 重 做 即 可, 不 需 要 像 MapReduce 实 现 那 样 引 入 一 个 Master 节 点 管 理 计 算 节 点, 监 控 计 算 节 点 故 障, 启 动 备 份 任 务 等 7.2.3 数 据 仓 库 复 杂 查 询 数 据 仓 库 线 上 查 询 模 型 需 要 支 持 order by, limit, group by, 计 算 模 型 和 并 行 数 据 库 类 似 另 外, 它 还 有 几 个 特 点 : 1, 使 用 列 式 存 储 : 列 式 存 储 符 合 数 据 仓 库 的 按 列 访 问 特 性, 且 增 大 了 数 据 压 缩 比 ; 2, 索 引 : 索 引 有 两 种 形 式 : 一 种 为 单 机 层 面 的 索 引, 另 一 种 为 分 布 式 层 面 的 索 引 单 机 层 面 索 引 指 的 是 在 单 机 存 储 引 擎 之 上 增 加 一 个 索 引 层, 索 引 和 数 据 绑 定, 这 样 做 的 优 点 是 索 引 维 护 成 本 较 低, 缺 点 是 执 行 按 索 引 访 问 操 作 需 要 访 问 所 有 的 数 据 分 片 ; 分 布 式 层 面 的 索 引 指