
如何设计 Spanner 主键避免写入热点【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills为 Cloud Spanner 设计表结构时主键的第一段决定写入流量如何分布如果这一段是单调递增或递减的值例如顺序 ID 或时间戳所有插入流量会被集中到单个服务器上形成瓶颈。本文依据本仓库 Spanner Basics 技能文档SKILL.md中明确给出的 Schema Design 指南说明如何识别这类易产生热点的主键设计、采用哪些手法打散写入以及如何用 gcloud 应用变更并核对结果。内容适用于 Spanner 支持的 GoogleSQL 与 PostgreSQL 两种方言。先判断主键是否会产生热点Schema Design 文档 对热点成因的描述是以单调递增或递减的键如 timestamp作为主键第一段时会把全部插入流量导向单台服务器。仓库给出的性能检查清单Performance Checklist也把这一项列为首要核对项主键的第一段不能是单调递增或递减的值顺序 ID、时间戳等如果已经是改用 UUIDv4、bit-reversed sequence位反转序列或哈希。另外注意方言差异PostgreSQL 方言说明 把SERIAL列为不受支持的特性即在 PostgreSQL 方言下不能靠SERIAL自动生成顺序主键单调性问题必须在设计阶段就按下面的方案处理。文档给出的四种写入打散手法1. 使用 UUID Version 4文档建议使用UUID Version 4使用随机值存储类型为UUID列。因为随机值不会在相关记录之间保持相邻性locality写入不会持续落在同一批键值区间上。文档同时指出了这一手法的代价相关记录不再彼此相邻如果业务依赖按键相邻访问相关记录需要权衡。2. 使用位反转的顺序值避免使用顺序递增/递减的数值主键改为对顺序值做位反转bit-reverse使主键值均匀分布在整个键空间。文档说明 Spanner 支持 bit-reversed sequences但未给出具体 SQL 语法实际建表时以 gcloud/官方文档中的语法为准。3. 交换键的顺序把高基数、非单调的列放在前面让写入在键空间上分布得更均匀。文档给出的例子是先按UserId排序再按时间顺序的LastAccess时间戳排序即主键写作PRIMARY KEY (UserId, LastAccess)其中UserId为高基数非单调列LastAccess为文档示例中的时间戳列名。4. 对唯一键做哈希新建一列存放真实唯一键的哈希值再把这个哈希列用作主键把写入分散到不同的逻辑分片上。时间戳键何时用 DESC 降序文档说明在以下两种情况下可考虑对时间戳键使用降序DESC你需要读取最近的历史记录且读取发生在一张 interleave交错表的父行上你需要按逆时间顺序读取顺序条目例如最近 N 条事件。主键可用的数据类型主键列的类型受限制。文档列出的数据类型为GoogleSQLARRAY、BOOL、BYTES、DATE、ENUM、FLOAT32、FLOAT64、INT64、JSON、NUMERIC、PROTO、STRING、STRUCT、TIMESTAMP、UUIDPostgreSQLarray、bool、bytea、date、float4、float8、int8/bigint、jsonb、numeric、timestamptz、uuid、varchar/text文档的结论是除FLOAT32、ARRAY、JSON、PROTO、STRUCT之外的类型都可以用作主键。给主键第一段以及后续各段选类型时先排除这几种类型。交错表与交错索引的处理热点逻辑同样作用于索引和表结构文档给出两条规则避免在单调递增/递减的列如非主键时间戳上创建非交错索引使用交错索引让 last access 行交错存放在对应的 user 行之下对应文档中出现的INTERLEAVE IN PARENT语法。按文档示例交错表可以写成表名User、LastAccess为示意请替换为你库中的实际表名列名取自文档示例CREATE TABLE LastAccess ( UserId INT64, LastAccess TIMESTAMP, PRIMARY KEY (UserId, LastAccess) ) INTERLEAVE IN PARENT User;两点限制要注意交错深度Spanner 支持最多 7 层交错但文档建议保持最小化避免过多开销二级索引为频繁查询模式建立二级索引如果查询需要按时间戳排序检查索引是否应使用DESC。应用 DDL 并验证按 SKILL.md 的 Schema Evolution DDL 工作流表与索引的 CREATE、ALTER、DROP 等变更通过以下命令应用gcloud spanner databases ddl update该文档只给出命令名具体参数以 gcloud CLI 帮助为准。执行前注意该技能文档的安全规则对非 emulator 环境的 DML/DDL 变更或破坏性操作删除表、索引等必须先取得用户明确确认做法是先输出命令并等待确认而不是直接自动执行。变更应用后用文档提供的三种方式核对按性能清单自查来自 schema-design.md主键第一段不是单调递增/递减值若是已替换为 UUIDv4、位反转序列或哈希强关联且经常一起访问的父子数据使用了INTERLEAVE IN PARENT交错表交错深度保持最小上限 7 层频繁查询模式有二级索引按时间戳排序的索引已考虑DESC各列类型为合法主键类型不在FLOAT32、ARRAY、JSON、PROTO、STRUCT之列。查 CPU 热点用SPANNER_SYS表定位慢查询或资源占用高的查询文档给出的例子是查询SPANNER_SYS.QUERY_STATS_TOP_HOUR找出 CPU 占用最高的查询。CLI 冒烟查询cli-usage.md 给出的查询命令my-instance、my-database为文档示例值替换为实际实例与数据库名gcloud spanner databases execute-sql my-database --instancemy-instance --sqlSELECT 1文档未覆盖的部分仓库文档没有给出性能基准数据因此“去掉热点后写入提升多少”没有可引用的固定数值验证只能依靠上面的清单核对与SPANNER_SYS查询统计bit-reversed sequence 也只说明 Spanner 支持未附 SQL 语法。这些缺口在动手前需要自行在官方渠道补齐而不是凭经验假设。【免费下载链接】skillsAgent Skills for Google products and technologies项目地址: https://gitcode.com/GitHub_Trending/skills29/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考