数据放置 #
一、放置概述 #
1.1 放置策略 #
text
数据放置策略
┌─────────────────────────────────────────────────────────────┐
│ │
│ 放置目标: │
│ ├── 降低延迟: 数据靠近用户 │
│ ├── 合规要求: 数据存储在特定区域 │
│ ├── 高可用: 跨区域容灾 │
│ └── 成本优化: 冷数据放低成本存储 │
│ │
│ CockroachDB 放置能力: │
│ ├── Zone配置 │
│ ├── 放置约束 │
│ ├── 区域感知 │
│ └── 多区域部署 │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 放置层级 #
| 层级 | 说明 |
|---|---|
| 集群级 | 默认配置 |
| 数据库级 | 特定数据库配置 |
| 表级 | 特定表配置 |
| 分区级 | 特定分区配置 |
二、Zone配置 #
2.1 基本Zone配置 #
sql
-- 查看默认Zone配置
SHOW ZONE CONFIGURATION FOR RANGE default;
-- 修改默认配置
ALTER RANGE default CONFIGURE ZONE USING
num_replicas = 5,
gc.ttlseconds = 90000;
-- 数据库级配置
ALTER DATABASE mydb CONFIGURE ZONE USING
num_replicas = 3,
gc.ttlseconds = 259200; -- 3天
-- 表级配置
ALTER TABLE users CONFIGURE ZONE USING
num_replicas = 5,
gc.ttlseconds = 604800; -- 7天
-- 索引级配置
ALTER INDEX users@idx_email CONFIGURE ZONE USING
num_replicas = 3;
2.2 Zone配置参数 #
text
Zone配置参数
┌─────────────────────────────────────────────────────────────┐
│ │
│ num_replicas: 副本数量 │
│ ├── 默认: 3 │
│ └── 建议: 奇数 (3, 5, 7) │
│ │
│ constraints: 节点约束 │
│ ├── 必须满足: [+key=value] │
│ └── 优先满足: [key=value] │
│ │
│ replica_constraints: 副本级约束 │
│ └── 为每个副本指定约束 │
│ │
│ gc.ttlseconds: 垃圾回收时间 │
│ ├── 默认: 90000 (25小时) │
│ └── 单位: 秒 │
│ │
│ range_min_bytes / range_max_bytes: Range大小 │
│ └── 控制数据分片大小 │
│ │
└─────────────────────────────────────────────────────────────┘
2.3 删除Zone配置 #
sql
-- 删除自定义配置,恢复默认
ALTER TABLE users CONFIGURE ZONE USING NULL;
-- 查看所有Zone配置
SHOW ALL ZONE CONFIGURATIONS;
三、放置约束 #
3.1 节点约束 #
bash
# 启动节点时设置约束
cockroach start \
--locality=region=us-east,zone=us-east-1 \
--store=path=/data
cockroach start \
--locality=region=us-west,zone=us-west-1 \
--store=path=/data
cockroach start \
--locality=region=eu-west,zone=eu-west-1 \
--store=path=/data
3.2 约束类型 #
sql
-- 必须约束 (+前缀)
ALTER DATABASE mydb CONFIGURE ZONE USING
constraints = '[+region=us-east]';
-- 副本必须放在 region=us-east 的节点
-- 优先约束 (无+前缀)
ALTER DATABASE mydb CONFIGURE ZONE USING
constraints = '[region=us-east]';
-- 优先放在 region=us-east 的节点,但不强制
-- 多个约束
ALTER DATABASE mydb CONFIGURE ZONE USING
constraints = '[+region=us-east,+zone=us-east-1]';
-- 必须同时满足 region=us-east 和 zone=us-east-1
3.3 副本级约束 #
sql
-- 为每个副本指定约束
ALTER DATABASE mydb CONFIGURE ZONE USING
num_replicas = 5,
replica_constraints = '[
[+region=us-east],
[+region=us-east],
[+region=us-west],
[+region=us-west],
[+region=eu-west]
]';
-- 结果:
-- 2个副本在 us-east
-- 2个副本在 us-west
-- 1个副本在 eu-west
四、多区域部署 #
4.1 多区域架构 #
text
多区域部署架构
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 应用层 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ US-East │ │ US-West │ │ EU-West │ │
│ │ │ │ │ │ │ │
│ │ Node 1 │ │ Node 4 │ │ Node 7 │ │
│ │ Node 2 │ │ Node 5 │ │ Node 8 │ │
│ │ Node 3 │ │ Node 6 │ │ Node 9 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ 数据分布: │
│ ├── 热数据: 就近访问 │
│ ├── 冷数据: 低成本区域 │
│ └── 合规数据: 特定区域 │
│ │
└─────────────────────────────────────────────────────────────┘
4.2 配置多区域 #
sql
-- 配置数据库在多个区域
ALTER DATABASE mydb CONFIGURE ZONE USING
num_replicas = 5,
replica_constraints = '[
[+region=us-east],
[+region=us-east],
[+region=us-west],
[+region=eu-west],
[+region=eu-west]
]';
-- 配置特定表在特定区域
ALTER TABLE users CONFIGURE ZONE USING
num_replicas = 3,
constraints = '[+region=us-east]';
-- 配置归档数据
ALTER TABLE logs_archive CONFIGURE ZONE USING
num_replicas = 3,
constraints = '[+region=archive]';
4.3 租约持有者放置 #
sql
-- 租约持有者影响读性能
-- 将租约持有者放在用户附近的区域
-- 查看当前租约持有者
SELECT
range_id,
lease_holder,
lease_holder_locality
FROM crdb_internal.ranges
WHERE start_key >= '/Table/53'
AND start_key < '/Table/54';
-- 转移租约到特定节点
ALTER RANGE 123 TRANSFER LEASE TO 2;
-- 配置租约偏好
ALTER TABLE users CONFIGURE ZONE USING
lease_preferences = '[[+region=us-east]]';
五、数据本地性 #
5.1 本地读取 #
sql
-- 使用 AS OF SYSTEM TIME 进行本地读取
-- 从最近的副本读取,减少延迟
SELECT * FROM users
AS OF SYSTEM TIME '-1s'
WHERE id = 'user-id';
-- 在事务中使用
BEGIN AS OF SYSTEM TIME '-5s';
SELECT * FROM users WHERE region = 'us-east';
COMMIT;
5.2 区域感知查询 #
sql
-- 创建区域感知的表
CREATE TABLE regional_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100),
region VARCHAR(50),
data JSONB
) PARTITION BY LIST (region);
-- 创建分区并配置放置
CREATE TABLE users_us_east PARTITION OF regional_users
FOR VALUES IN ('us-east');
ALTER TABLE users_us_east CONFIGURE ZONE USING
constraints = '[+region=us-east]';
CREATE TABLE users_us_west PARTITION OF regional_users
FOR VALUES IN ('us-west');
ALTER TABLE users_us_west CONFIGURE ZONE USING
constraints = '[+region=us-west]';
CREATE TABLE users_eu_west PARTITION OF regional_users
FOR VALUES IN ('eu-west');
ALTER TABLE users_eu_west CONFIGURE ZONE USING
constraints = '[+region=eu-west]';
六、合规与监管 #
6.1 数据驻留 #
sql
-- 强制数据存储在特定区域
-- 满足GDPR等合规要求
-- 欧盟用户数据必须存储在欧盟
CREATE TABLE eu_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100),
email VARCHAR(100),
gdpr_data JSONB
);
ALTER TABLE eu_users CONFIGURE ZONE USING
num_replicas = 3,
constraints = '[+region=eu-west]',
replica_constraints = '[
[+region=eu-west],
[+region=eu-west],
[+region=eu-central]
]';
6.2 数据隔离 #
sql
-- 不同租户的数据隔离
CREATE TABLE tenant_data (
tenant_id VARCHAR(50),
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
data JSONB
) PARTITION BY LIST (tenant_id);
-- 为每个租户创建分区
CREATE TABLE tenant_a PARTITION OF tenant_data
FOR VALUES IN ('tenant-a');
ALTER TABLE tenant_a CONFIGURE ZONE USING
constraints = '[+tenant=a]';
CREATE TABLE tenant_b PARTITION OF tenant_data
FOR VALUES IN ('tenant-b');
ALTER TABLE tenant_b CONFIGURE ZONE USING
constraints = '[+tenant=b]';
七、监控与调优 #
7.1 监控放置状态 #
sql
-- 查看Range分布
SELECT
r.range_id,
r.replicas,
n.locality,
n.region
FROM crdb_internal.ranges r
CROSS JOIN UNNEST(r.replicas) AS replica
JOIN crdb_internal.kv_node_status n ON n.node_id = replica
WHERE r.start_key >= '/Table/53'
AND r.start_key < '/Table/54'
ORDER BY r.range_id;
-- 查看Zone配置
SHOW ZONE CONFIGURATION FOR TABLE users;
-- 查看约束满足情况
SELECT
zone,
config,
CASE
WHEN config LIKE '%constraints%' THEN 'Has constraints'
ELSE 'No constraints'
END AS constraint_status
FROM crdb_internal.zones;
7.2 放置优化 #
sql
-- 检查租约分布
SELECT
lease_holder_locality->>'region' AS region,
COUNT(*) AS range_count
FROM crdb_internal.ranges
GROUP BY lease_holder_locality->>'region'
ORDER BY range_count DESC;
-- 优化租约分布
-- 将热点表的租约放在用户附近
ALTER TABLE hot_table CONFIGURE ZONE USING
lease_preferences = '[[+region=us-east]]';
八、最佳实践 #
8.1 放置策略建议 #
text
放置策略建议
┌─────────────────────────────────────────────────────────────┐
│ │
│ 1. 热数据就近放置 │
│ ├── 用户数据放在用户附近 │
│ └── 减少访问延迟 │
│ │
│ 2. 冷数据低成本存储 │
│ ├── 历史数据放低成本区域 │
│ └── 减少存储成本 │
│ │
│ 3. 合规数据特定区域 │
│ ├── GDPR数据放欧盟 │
│ └── 满足合规要求 │
│ │
│ 4. 高可用跨区域 │
│ ├── 副本分布在不同区域 │
│ └── 提高容灾能力 │
│ │
│ 5. 定期审查 │
│ ├── 监控放置效果 │
│ └── 调整放置策略 │
│ │
└─────────────────────────────────────────────────────────────┘
8.2 常见配置示例 #
sql
-- 示例1: 全球应用
ALTER DATABASE global_app CONFIGURE ZONE USING
num_replicas = 5,
replica_constraints = '[
[+region=us-east],
[+region=us-west],
[+region=eu-west],
[+region=ap-southeast],
[+region=ap-northeast]
]';
-- 示例2: 区域应用
ALTER DATABASE us_app CONFIGURE ZONE USING
num_replicas = 3,
constraints = '[+region=us-east]';
-- 示例3: 归档数据
ALTER TABLE archive_data CONFIGURE ZONE USING
num_replicas = 3,
constraints = '[+storage=archive]',
gc.ttlseconds = 31536000; -- 1年
-- 示例4: 高可用配置
ALTER TABLE critical_data CONFIGURE ZONE USING
num_replicas = 7,
replica_constraints = '[
[+region=us-east],
[+region=us-east],
[+region=us-west],
[+region=us-west],
[+region=eu-west],
[+region=eu-west],
[+region=ap-southeast]
]';
九、总结 #
数据放置要点:
| 特性 | 说明 |
|---|---|
| Zone配置 | 数据放置策略 |
| 放置约束 | 节点选择规则 |
| 多区域 | 跨区域部署 |
| 数据本地性 | 就近访问 |
| 合规性 | 数据驻留 |
下一步,让我们学习高级特性!
最后更新:2026-03-27