分布式数据库分库分表策略与一致性保障
· 更新于 2026-07-26
⏱️ 阅读约 2 分钟 (632 字)
数据库
分布式
Go
深入探讨分布式数据库场景下的分库分表设计策略,涵盖哈希分片、范围分片及分布式事务一致性保障方案。
一、分库分表策略
当单库数据量达到 TB 级别时,分库分表成为必然选择。常见的分片策略包括哈希分片、范围分片和一致性哈希。选择合适的分片键是设计的核心。
二、Go 分片逻辑实现
以下示例展示了一个使用 Go 实现的一致性哈希分片路由器,负责将请求路由到正确的数据库分片。
Go 分片逻辑
package shard
import (
"crypto/sha256"
"fmt"
"hash/crc32"
)
type Router struct {
shards []string
}
func NewRouter(nodes []string) *Router {
return &Router{shards: nodes}
}
// ShardKey 根据用户ID计算目标分片
func (r *Router) ShardKey(userID string) string {
h := crc32.ChecksumIEEE([]byte(userID))
idx := int(h) % len(r.shards)
return r.shards[idx]
}
// ShardKeyConsistent 一致性哈希分片
func (r *Router) ShardKeyConsistent(userID string) string {
hash := sha256.Sum256([]byte(userID))
value := int(hash[0])<<24 | int(hash[1])<<16 |
int(hash[2])<<8 | int(hash[3])
idx := value % len(r.shards)
// 虚拟节点支持(简化)
return r.shards[idx]
}
func main() {
nodes := []string{"shard-0", "shard-1", "shard-2", "shard-3"}
router := NewRouter(nodes)
userIDs := []string{"user_1001", "user_1002", "user_1003"}
for _, uid := range userIDs {
shard := router.ShardKeyConsistent(uid)
fmt.Printf("User %s -> %s\n", uid, shard)
}
}
go
package shard
import (
"crypto/sha256"
"fmt"
"hash/crc32"
)
type Router struct {
shards []string
}
func NewRouter(nodes []string) *Router {
return &Router{shards: nodes}
}
// ShardKey 根据用户ID计算目标分片
func (r *Router) ShardKey(userID string) string {
h := crc32.ChecksumIEEE([]byte(userID))
idx := int(h) % len(r.shards)
return r.shards[idx]
}
// ShardKeyConsistent 一致性哈希分片
func (r *Router) ShardKeyConsistent(userID string) string {
hash := sha256.Sum256([]byte(userID))
value := int(hash[0])<<24 | int(hash[1])<<16 |
int(hash[2])<<8 | int(hash[3])
idx := value % len(r.shards)
// 虚拟节点支持(简化)
return r.shards[idx]
}
func main() {
nodes := []string{"shard-0", "shard-1", "shard-2", "shard-3"}
router := NewRouter(nodes)
userIDs := []string{"user_1001", "user_1002", "user_1003"}
for _, uid := range userIDs {
shard := router.ShardKeyConsistent(uid)
fmt.Printf("User %s -> %s\n", uid, shard)
}
}SQL 查询示例
-- 创建分片表
CREATE TABLE IF NOT EXISTS orders_0000 (
id BIGINT PRIMARY KEY,
user_id VARCHAR(64) NOT NULL,
amount DECIMAL(12,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id)
);
-- 跨分片查询(需在应用层合并结果)
-- 查询语句将在每个分片上独立执行
SELECT user_id, SUM(amount) as total
FROM orders_0000
WHERE created_at >= '2026-01-01'
GROUP BY user_id;
sql
-- 创建分片表
CREATE TABLE IF NOT EXISTS orders_0000 (
id BIGINT PRIMARY KEY,
user_id VARCHAR(64) NOT NULL,
amount DECIMAL(12,2) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_user_id (user_id)
);
-- 跨分片查询(需在应用层合并结果)
-- 查询语句将在每个分片上独立执行
SELECT user_id, SUM(amount) as total
FROM orders_0000
WHERE created_at >= '2026-01-01'
GROUP BY user_id;三、一致性保障
分布式事务推荐使用 TCC 或 Saga 模式,结合最终一致性补偿机制。对于读场景,可使用读写分离与缓存预热策略提升性能。
本文作者:技术领航员 | 许可协议:CC BY-NC-SA 4.0
本文链接:https://sre-ai-blog.pages.dev/zh/posts/database-sharding/(转载请注明出处)