4.2 使 用 Table Service Table Service 相 对 来 说 是 三 个 Storage Service 中 最 好 理 解 和 最 易 于 接 受 的, 它 主 要 用 来 存 储 结 构 化 数 据 但 是 Table Service 却 并 不 是 一 个 关 系 型 数 据 库 Table Service 由 两 个 部 分 组 成 :Table 和 Entity 当 用 户 创 建 了 一 个 Storage Service 的 时 候 就 同 时 创 建 了 Table Service 而 在 一 个 Table Service 内 用 户 可 以 创 建 多 个 Table, 有 些 类 似 于 数 据 库 中 的 表 而 在 一 个 Table 下 面 可 创 建 多 个 Entity, 类 似 于 数 据 库 中 的 记 录 每 一 个 Entity 都 可 以 创 建 多 个 Property, 类 似 于 数 据 库 中 的 字 段 它 们 之 间 的 关 系 如 图 4-6 所 示 图 4-6 Table Service 的 结 构 关 系 用 户 可 以 创 建 一 个 新 的 Table, 然 后 添 加 修 改 或 删 除 Entity 同 样, 用 户 也 可 以 删 除 Table 这 些 操 作 非 常 类 似 于 使 用 普 通 的 数 据 库 但 是 Table Service 和 普 通 的 数 据 库 是 有 很 大 区 别 的 4.2.1 Table Service 的 特 点 Table Service 主 要 是 存 储 结 构 化 数 据 的, 所 有 的 数 据 都 是 一 个 个 Entity, 多 个 Entity 在 一 起 作 为 一 个 Table 而 每 一 个 Entity 中 最 多 包 含 255 个 Property 每 个 Property 以 键 值 对 (Key-Value Pair) 的 方 式 保 存,Key 是 字 符 串 类 型 而 Value 可 以 是 任 意 的.NET 标 准 类 型, 比 如 字 符 串 整 型 日 期 等 但 是,Storage Service 要 求 每 一 个 Entity 必 须 包 含 下 面 三 个 Property:Partition Key Row Key 和 Timestamp
Partition Key: 字 符 串 类 型, 表 示 当 前 Entity 的 分 区 信 息 这 个 Property 对 于 Table Service 自 动 纵 向 和 横 向 扩 展 至 关 重 要 Row Key: 字 符 串 类 型, 在 给 定 Partition Key 的 分 区 下,Row Key 要 能 唯 一 确 定 一 个 Entity 也 就 是 说,Partition Key 和 Row Key 可 以 作 为 Entity 的 联 合 主 键 同 时 Entity 也 是 基 于 Partition Key 和 Row Key 值 的 顺 序 保 存 的, 类 似 于 SQL Server 里 面 的 聚 集 索 引 的 概 念 Timestamp:DateTime 类 型, 作 为 版 本 控 制 信 息 表 明 当 前 Entity 最 后 被 操 作 的 时 间 使 用 者 无 法 修 改, 由 Windows Azure 平 台 维 护 从 表 面 上 看,Table Service 和 关 系 型 数 据 库 很 类 似, 但 是 它 并 不 是 一 个 关 系 型 的 数 据 存 储 服 务 这 主 要 表 现 在 如 下 几 点 : 同 一 个 Table 下 面 的 Entity 可 以 拥 有 不 同 的 Property 也 就 是 说 Entity 里 面 包 含 什 么 Property 不 是 在 Table 中 确 定 的, 而 是 每 个 Entity 自 己 确 定 的 这 一 点 和 关 系 型 数 据 库 中 数 据 表 的 概 念 是 不 一 样 的 同 一 个 Table 下 面 的 Entity, 即 使 拥 有 同 名 的 Property, 它 们 的 类 型 也 可 以 是 不 同 的 无 法 像 关 系 型 数 据 库 那 样 为 一 个 Table 建 立 多 个 索 引 Table Service 不 支 持 外 键 约 束 等 关 系 数 据 库 的 功 能 Table Service 仅 支 持 非 常 有 限 的 事 务 操 作 虽 然 Table Service 没 有 上 述 关 系 型 数 据 库 的 特 性, 但 是 它 也 拥 有 自 己 特 殊 的 功 能, 而 这 些 功 能 都 是 目 前 关 系 型 数 据 库 所 不 具 备 的 4.2.1.1 Table Service 的 动 态 扩 展 Windows Azure 平 台 为 Table Service 提 供 了 自 动 的 纵 向 和 横 向 扩 展 功 能 之 前 讲 到, 一 个 Table Service Entity 必 须 包 含 三 个 Property, 即 Partition Key Row Key 以 及 Timestamp 其 中,
Partition Key 就 是 用 来 进 行 自 动 纵 向 和 横 向 扩 展 的 以 用 户 信 息 为 例, 在 Member Entity 中 以 用 户 所 在 国 家 作 为 Partition Key, 以 用 户 注 册 的 E-mail 地 址 作 为 Row Key 应 用 程 序 刚 刚 开 始 运 行 的 阶 段, 由 于 注 册 用 户 量 不 是 很 大,Windows Azure 平 台 会 将 所 有 的 用 户 信 息 都 保 存 在 一 个 存 储 节 点 中, 也 就 是 说 所 有 的 用 户 信 息 都 保 存 在 一 起, 如 图 4-7 所 示 图 4-7 所 有 Partition Key 都 在 一 个 存 储 节 点 中 而 随 着 用 户 的 不 断 增 加, 这 个 Table 的 数 据 量 开 始 大 幅 度 上 升 Storage Service 不 断 侦 测 每 一 个 Account 下 面 每 个 Table 的 容 量 以 及 访 问 量, 同 时 还 会 侦 测 每 个 Entity 下 面 每 种 Partition Key 所 包 含 的 数 据 量 和 访 问 量 如 果 发 现 某 个 Partition Key 的 数 据 量 或 访 问 量 非 常 高, 已 经 影 响 到 了 所 在 存 储 节 点 的 性 能,Windows Azure 将 会 自 动 进 行 横 向 扩 展, 也 就 是 说 针 对 访 问 量 或 数 据 量 很 高 的 Partition Key, 将 其 所 有 的 Entity 迁 移 到 一 个 负 载 较 小 的 存 储 节 点 上 面 并 且, 这 些 操 作 都 无 须 使 用 者 控 制,Windows Azure 全 部 在 后 台 自 动 完 成 而 且 基 于 存 储 节 点 的 负 载 均 衡 和 路 由, 无 论 是 应 用 程 序 还 是 RESTful API, 都 使 用 相 同 的 URL 和 命 令 访 问 已 经 被 迁 移 的 数 据 这 就 意 味 着 应 用 程 序 代 码 不 需 要 做 任 何 调 整 而 随 着 应 用 在 全 世 界 都 很 受 欢 迎, 很 多 国 家 的 注 册 用 户 已 经 非 常 多 了, 这 时 候 Windows Azure 就 会 依 照 不 同 Partition Key 的 负 载 分 别 进 行 横 向 扩 展 例 如, 中 国 的 用 户 最 多 将 会 被 分 到 一 个 存 储 节 点, 英 国 和 美 国 的 用 户 被 分 配 到 另 一 个 存 储 节 点, 而 剩 下 的 用 户 可 能 会 被 分 配 到 第 三 个 存 储 节 点, 如 图 4-8 所 示
图 4-8 Table Service 根 据 Partition Key 进 行 横 向 扩 展 在 上 述 横 向 扩 展 的 同 时,Table Service 还 支 持 纵 向 扩 展, 即 将 热 点 数 据 迁 移 到 运 行 能 力 更 强 的 存 储 节 点 中 去 而 且, 纵 向 扩 展 和 横 向 扩 展 一 样 也 是 完 全 自 动 且 对 使 用 者 透 明 的 比 如 当 前 来 自 中 国 的 用 户 非 常 多, 那 么 Windows Azure 则 会 将 Partition Key 为 China 的 Entity 迁 移 到 处 理 能 力 更 大 的 节 点 中 以 保 证 访 问 速 度, 如 图 4-9 所 示 图 4-9 Table Service 的 纵 向 扩 展 由 于 Table Storage 的 动 态 纵 向 及 横 向 扩 展 功 能 都 是 基 于 Partition Key 来 完 成 的, 因 此 在 选 择 Partition Key 的 时 候 要 非 常 注 意 如 果 应 用 程 序 使 用 完 全 一 样 的 字 符 串 作 为 Partition Key, 那 么 Windows Azure 平 台 就 会 将 所 有 数 据 作 为 一 个 扩 展 单 元 处 理 而 无 法 对 其 进 行 横 向 扩 展, 这 样 无 疑
对 性 能 的 提 升 是 很 有 限 的 但 是 如 果 应 用 程 序 对 每 一 个 Entity 都 使 用 不 同 的 Partition Key( 例 如 使 用 GUID 作 为 Partition Key), 由 于 每 一 个 Partition Key 的 使 用 频 度 都 不 会 很 大,Windows Azure 平 台 很 可 能 就 不 会 对 其 进 行 任 何 扩 展 一 般 来 说, 开 发 人 员 可 以 考 虑 将 如 下 类 型 的 数 据 作 为 Partition Key: 自 然 属 性 : 比 如 国 家 名 人 名 的 姓 日 期 ( 年 份 ) 部 门 名 称 等 基 于 算 法 : 基 于 Row Key 的 哈 希 值 基 于 自 增 数 的 取 模 算 法 等 无 论 何 种 方 式,Partition Key 的 选 取 需 要 针 对 具 体 的 业 务 逻 辑 和 未 来 应 用 程 序 的 发 展 趋 势 来 决 定, 而 没 有 一 个 绝 对 的 最 佳 实 践 比 如 当 前 的 业 务 需 求 是 做 一 个 面 向 全 球 的 在 线 照 片 分 享 网 站, 那 么 用 户 信 息 的 Partition Key 就 可 以 使 用 国 家 名 称 或 国 家 ID, 而 相 册 信 息 的 Partition Key 则 可 以 使 用 用 户 的 注 册 邮 箱 或 用 户 ID 4.2.1.2 事 务 支 持 Table Service 包 含 有 限 的 事 务 支 持 和 关 系 型 数 据 库 不 一 样,Table Service 只 允 许 在 Table 和 Partition Key 相 同 的 情 况 下 对 Entity 进 行 事 务 操 作 因 此, 如 果 某 些 业 务 逻 辑 需 要 事 务 支 持, 那 么 参 与 这 些 操 作 的 Entity 必 须 拥 有 相 同 的 Partition Key, 但 是 参 与 事 务 的 Entity 的 Property 可 以 不 相 同 例 如 在 修 改 用 户 信 息 的 时 候, 业 务 逻 辑 需 要 记 录 修 改 操 作 日 志, 一 般 来 说 会 创 建 一 个 Member Table 和 一 个 Member Log Table, 分 别 存 储 用 户 信 息 和 修 改 日 志 信 息 如 果 需 要 这 两 个 修 改 操 作 必 须 在 一 个 事 务 内 完 成, 则 应 保 证 参 与 操 作 的 Partition Key 必 须 相 同 4.2.1.3 查 询 Windows Azure Storage Service 均 支 持 通 过 REST API 进 行 访 问, 包 括 对 数 据 的 增 加 删 除 修 改 和 查 询 对 于 Table Service 而 言,Windows Azure 平 台 基 于 OData 协 议 来 实 现 数 据 服 务 同 时,Windows Azure SDK 为 开 发 人 员 提 供 了 基 于 LINQ 的 方 式 访 问 Table Service REST API 的 功
能 参 考 关 于 完 整 的 Table Service REST API, 请 参 考 http://msdn.microsoft.com/ en-us/library/dd179405.aspx 关 于 OData 协 议, 请 参 考 http://www.odata. 在 之 前 的 介 绍 中 提 到 过,Partition Key 在 动 态 扩 展 中 有 着 至 关 重 要 的 作 用 同 样 的,Partition Key 在 查 询 的 时 候 也 非 常 重 要 由 于 Table Service 的 自 动 横 向 扩 展, 不 同 Partition Key 的 Entity 有 可 能 保 存 在 不 同 的 存 储 节 点 中, 那 么 如 果 查 询 操 作 需 要 跨 存 储 节 点 执 行, 性 能 将 会 大 打 折 扣 所 以 说 开 发 人 员 在 进 行 Table Service 查 询 的 时 候, 应 尽 可 能 地 将 Partition Key 作 为 查 询 条 件 的 一 部 分, 以 保 证 Windows Azure 尽 可 能 地 在 单 一 存 储 节 点 中 完 成 操 作 另 外, 为 了 防 止 客 户 端 的 一 次 查 询 所 返 回 的 结 果 过 多 而 造 成 网 络 堵 塞,Table Service 引 入 了 Continuation Token 机 制 所 谓 Continuation Token 就 是 指 在 查 询 结 果 过 多 的 情 况 下,Table Service 只 会 返 回 结 果 集 的 一 部 分, 同 时 返 回 一 个 Continuation Token 来 表 示 还 有 剩 余 结 果 没 有 返 回 客 户 端 可 以 使 用 此 Continuation Token 对 Table Service 再 次 发 起 请 求 来 获 得 后 续 的 结 果, 直 到 没 有 Continuation Token 返 回 为 止 而 具 体 来 说,Table Service 会 在 下 列 几 种 情 况 下 返 回 Continuation Token: 如 果 查 询 操 作 出 现 了 跨 存 储 节 点 访 问 的 情 况 比 如 没 有 指 定 Partition Key 的 查 询,Table Service 会 轮 流 查 询 所 需 要 的 所 有 存 储 节 点, 而 在 每 个 存 储 节 点 查 询 之 后 返 回 Continuation Token 单 次 查 询 结 果 超 过 1000 个 记 录 的 时 候 单 次 查 询 所 耗 费 的 时 间 超 过 5 分 钟 则 会 把 目 前 为 止 得 到 的 结 果 返 回, 并 返 回 Continuation Token 接 下 来 本 书 将 通 过 示 例 来 演 示 如 何 访 问 Table Service 并 且 基 于 它 的 功 能 创 建 一 个 用 来 共 享
照 片 的 小 网 站 Aurora