Spanner最佳实践 #
一、Schema设计最佳实践 #
1.1 主键设计 #
text
主键设计原则:
├── 使用位反转序列
│ └── 避免写入热点
│
├── 复合主键分散写入
│ └── 第一列分散写入
│
├── 避免单调递增
│ └── 会导致热点
│
├── 保持主键简短
│ └── 减少存储和传输
│
└── 考虑查询模式
└── 支持范围查询
sql
-- 推荐: 使用位反转序列
CREATE TABLE users (
user_id INT64 NOT NULL
DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE user_bit_seq)),
name STRING(100)
) PRIMARY KEY (user_id);
-- 推荐: 复合主键分散写入
CREATE TABLE orders (
shard_id INT64 NOT NULL,
order_id INT64 NOT NULL,
user_id INT64
) PRIMARY KEY (shard_id, order_id);
-- 不推荐: 单调递增主键
CREATE TABLE bad_design (
id INT64 NOT NULL, -- 单调递增会产生热点
name STRING(100)
) PRIMARY KEY (id);
1.2 交错表设计 #
text
交错表使用场景:
├── 父子关系明确
├── 经常一起查询
├── 需要级联删除
├── 层级不超过7层
└── 主键包含父表主键
sql
-- 父表
CREATE TABLE users (
user_id INT64 NOT NULL,
name STRING(100)
) PRIMARY KEY (user_id);
-- 子表(交错)
CREATE TABLE orders (
user_id INT64 NOT NULL,
order_id INT64 NOT NULL,
amount FLOAT64
) PRIMARY KEY (user_id, order_id)
INTERLEAVE IN PARENT users ON DELETE CASCADE;
1.3 索引设计 #
text
索引设计原则:
├── 选择高选择性列
├── 复合索引注意顺序
│ ├── 等值条件列在前
│ └── 范围条件列在后
├── 使用存储索引避免回表
├── 避免过多索引
└── 定期评估索引使用
sql
-- 复合索引设计
-- 查询: WHERE status = 'active' AND created_at > ?
CREATE INDEX idx_users_status_created ON users(status, created_at);
-- 存储索引避免回表
CREATE INDEX idx_users_email_storing ON users(email)
STORING (name, created_at);
二、查询优化最佳实践 #
2.1 使用索引 #
sql
-- 创建合适的索引
CREATE INDEX idx_users_email ON users(email);
-- 使用索引查询
SELECT * FROM users WHERE email = 'john@example.com';
-- 强制使用索引
SELECT * FROM users@{FORCE_INDEX=idx_users_email}
WHERE email = 'john@example.com';
2.2 避免全表扫描 #
sql
-- 不推荐: 全表扫描
SELECT * FROM users;
-- 推荐: 使用主键或索引
SELECT * FROM users WHERE user_id = 1;
-- 不推荐: 函数导致索引失效
SELECT * FROM users WHERE UPPER(name) = 'JOHN';
-- 推荐: 避免在条件列上使用函数
SELECT * FROM users WHERE name = 'John';
2.3 分页优化 #
sql
-- 不推荐: OFFSET分页(大数据量性能差)
SELECT * FROM users ORDER BY user_id LIMIT 10 OFFSET 10000;
-- 推荐: 游标分页
SELECT * FROM users
WHERE user_id > 10000 -- 上一页最后的user_id
ORDER BY user_id
LIMIT 10;
2.4 使用EXPLAIN分析 #
sql
-- 查看执行计划
EXPLAIN SELECT * FROM users WHERE email = 'john@example.com';
-- 查看实际执行统计
EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'john@example.com';
三、事务最佳实践 #
3.1 减少事务大小 #
java
// 不推荐: 大事务
client.readWriteTransaction().run(transaction -> {
// 处理大量数据
for (int i = 0; i < 100000; i++) {
transaction.buffer(...);
}
return null;
});
// 推荐: 批量写入
List<Mutation> mutations = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
mutations.add(...);
}
client.write(mutations);
3.2 使用只读事务 #
java
// 推荐: 只读事务性能更好
try (ReadOnlyTransaction transaction = client.readOnlyTransaction()) {
ResultSet rs = transaction.executeQuery(...);
// 处理结果
}
3.3 处理冲突重试 #
java
// 设置重试策略
TransactionOptions options = TransactionOptions.newBuilder()
.setCommitRetrySettings(
RetrySettings.newBuilder()
.setMaxAttempts(5)
.build())
.build();
四、成本控制最佳实践 #
4.1 节点规划 #
text
节点规划建议:
├── 根据存储需求计算
│ └── 每1TB数据约需1个节点
│
├── 根据CPU需求计算
│ └── 每1000 QPS约需1个节点
│
├── 预留20%余量
│ └── 应对峰值和增长
│
└── 定期评估调整
└── 根据实际使用调整
4.2 存储优化 #
text
存储优化建议:
├── 合理设置字符串长度
├── 删除不需要的数据
├── 使用分区过期
├── 监控存储使用
└── 定期清理备份
4.3 网络优化 #
text
网络优化建议:
├── 使用私有IP
├── 选择就近区域
├── 批量操作减少请求
├── 使用过期读
└── 监控网络流量
五、高可用最佳实践 #
5.1 多区域部署 #
text
多区域部署建议:
├── 根据用户分布选择配置
├── 使用多区域配置
├── 配置自动故障转移
├── 测试故障恢复
└── 监控复制延迟
5.2 备份策略 #
text
备份策略建议:
├── 配置自动备份
├── 设置合适的保留时间
├── 定期测试恢复
├── 重要变更前创建备份
└── 跨区域备份复制
5.3 监控告警 #
text
监控告警建议:
├── 监控关键指标
│ ├── CPU使用率
│ ├── 延迟
│ ├── 存储使用量
│ └── 错误率
│
├── 配置合理告警
│ ├── 多级告警
│ └── 多通知渠道
│
└── 定期审查优化
六、安全最佳实践 #
6.1 权限管理 #
text
权限管理建议:
├── 使用最小权限原则
├── 使用服务账号
├── 定期审查权限
├── 及时撤销不需要的权限
└── 安全存储密钥
6.2 数据安全 #
text
数据安全建议:
├── 使用加密连接
├── 使用私有IP
├── 敏感数据加密
├── 审计日志记录
└── 定期安全评估
七、运维最佳实践 #
7.1 变更管理 #
text
变更管理建议:
├── 使用版本控制
├── 测试环境验证
├── 灰度发布
├── 准备回滚方案
└── 记录变更历史
7.2 监控运维 #
text
监控运维建议:
├── 监控关键指标
├── 配置告警通知
├── 定期巡检
├── 建立应急预案
└── 定期演练
7.3 性能优化 #
text
性能优化建议:
├── 定期分析慢查询
├── 优化Schema设计
├── 更新统计信息
├── 评估索引使用
└── 调整节点数量
八、开发最佳实践 #
8.1 代码规范 #
text
代码规范建议:
├── 使用参数化查询
├── 处理所有错误
├── 实现重试逻辑
├── 使用连接池
└── 添加日志记录
8.2 测试规范 #
text
测试规范建议:
├── 单元测试
├── 集成测试
├── 性能测试
├── 压力测试
└── 混沌测试
8.3 部署规范 #
text
部署规范建议:
├── CI/CD流水线
├── 自动化测试
├── 灰度发布
├── 监控告警
└── 回滚机制
九、总结 #
最佳实践要点:
| 领域 | 关键点 |
|---|---|
| Schema | 主键设计、交错表、索引 |
| 查询 | 使用索引、避免全扫描 |
| 事务 | 减少大小、只读事务 |
| 成本 | 节点规划、存储优化 |
| 高可用 | 多区域、备份、监控 |
| 安全 | 权限管理、数据安全 |
| 运维 | 变更管理、监控优化 |
核心原则:
text
1. 设计优先
└── 好的Schema设计是基础
2. 性能优化
└── 持续监控和优化
3. 成本控制
└── 合理规划资源
4. 高可用性
└── 多区域、备份、监控
5. 安全合规
└── 权限管理和数据安全
6. 持续改进
└── 定期评估和优化
恭喜你完成了Spanner学习之旅!
最后更新:2026-03-27