{T}

高性能架构 学习笔记(第 7 部分)

8.1 常见设计模式

8.1.1 读写分离

plaintext
读写分离架构:
 
写入请求(INSERT/UPDATE/DELETE)

    ┌─────────┐
    │ 主数据库  │
    └────┬────┘
         │ 数据同步
    ┌────┴────┐
    │         │
┌───┴───┐ ┌───┴───┐
│从数据库1│ │从数据库2│
└───────┘ └───────┘
    ↑         ↑
    │         │
  读取请求   读取请求

实现示例

javascript
// 读写分离实现
class DatabaseManager {
  constructor() {
    // 主库(写)
    this.master = mysql.createConnection({
      host: 'master.db.example.com',
      user: 'root',
      password: 'password',
      database: 'myapp'
    })
    
    // 从库(读)
    this.slaves = [
      mysql.createConnection({
        host: 'slave1.db.example.com',
        user: 'root',
        password: 'password',
        database: 'myapp'
      }),
      mysql.createConnection({
        host: 'slave2.db.example.com',
        user: 'root',
        password: 'password',
        database: 'myapp'
      })
    ]
    
    this.slaveIndex = 0
  }
  
  // 写操作 → 主库
  async write(sql, params) {
    return new Promise((resolve, reject) => {
      this.master.query(sql, params, (error, results) => {
        if (error) reject(error)
        else resolve(results)
      })
    })
  }
  
  // 读操作 → 从库(轮询)
  async read(sql, params) {
    const slave = this.slaves[this.slaveIndex]
    this.slaveIndex = (this.slaveIndex + 1) % this.slaves.length
    
    return new Promise((resolve, reject) => {
      slave.query(sql, params, (error, results) => {
        if (error) reject(error)
        else resolve(results)
      })
    })
  }
}

8.1.2 分库分表

plaintext
分库分表策略:
 
垂直分库:按业务拆分
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 用户库    │ │ 订单库    │ │ 商品库    │
└──────────┘ └──────────┘ └──────────┘
 
水平分表:按数据量拆分
┌──────────┐ ┌──────────┐ ┌──────────┐
│订单表_0   │ │订单表_1   │ │订单表_2   │
│ user_id   │ │ user_id   │ │ user_id   │
│ %3 = 0   │ │ %3 = 1    │ │ %3 = 2    │
└──────────┘ └──────────┘ └──────────┘

分片策略

javascript
// 分片策略实现
class ShardManager {
  constructor(shardCount) {
    this.shardCount = shardCount
    this.shards = this.initShards()
  }
  
  // 初始化分片
  initShards() {
    const shards = []
    for (let i = 0; i < this.shardCount; i++) {
      shards.push({
        connection: mysql.createConnection({
          host: `shard${i}.db.example.com`,
          database: `order_db_${i}`
        })
      })
    }
    return shards
  }
  
  // 根据 user_id 决定分片
  getShard(userId) {
    const shardIndex = userId % this.shardCount
    return this.shards[shardIndex]
  }
  
  // 插入订单
  async insertOrder(userId, orderData) {
    const shard = this.getShard(userId)
    
    return new Promise((resolve, reject) => {
      const sql = 'INSERT INTO orders SET ?'
      shard.connection.query(sql, orderData, (error, results) => {
        if (error) reject(error)
        else resolve(results)
      })
    })
  }
  
  // 查询订单
  async getOrders(userId) {
    const shard = this.getShard(userId)
    
    return new Promise((resolve, reject) => {
      const sql = 'SELECT * FROM orders WHERE user_id = ?'
      shard.connection.query(sql, [userId], (error, results) => {
        if (error) reject(error)
        else resolve(results)
      })
    })
  }
}