数据放置 #

一、放置概述 #

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