如何使用 Sequelize 处理 RDS 集群中的新副本?

How to handle new replica in RDS Cluster with Sequelize?

我们正在为流量激增做准备,但这个问题也是一个通用问题:

知道您可以像这样设置 Sequelize 来使用 RDS 数据库集群(在我们的例子中是 Aurora):

const master = { rdsClusterWriterEndpoint, username, password, port, database }
const replica = { rdsClusterReaderEndpoint, username, password, port, database }
const Sequelize = require('sequelize')
const sequelize = new Sequelize(null, null, null, {
  dialect: 'mysql',
  pool: {
    handleDisconnects: true,
    min: 0,
    max: 10,
    idle: 10000,
  },
  replication: {
    write: master,
    read: [replica],
  },
})

如何在不重新加载应用程序的情况下将新的 RDS 实例添加到集群以负载平衡读取更多?

我四处寻找,但找不到好的方法。 DNS解析好像是在启动的时候做一次,我还没找到每隔一段时间刷新一次的方法。

有人找到安全的方法了吗?

谢谢

我最终得到了这样的配置:

const getRandomWithinRange = (min, max) => {
  min = Math.ceil(min)
  max = Math.floor(max)
  return Math.floor(Math.random() * (max - min + 1)) + min // The maximum is inclusive and the minimum is inclusive
}
const maxConnectionAge = moment.duration(10, 'minutes').asSeconds()
const pool =     {
  handleDisconnects: true,
  min: pool.min || 1, // Keep one connection open
  max: pool.max || 10, // Max 10 connections
  idle: pool.idle || 9000, // 9 secondes
  validate: (obj) => {
    // Recycle connexions periodically
    if (!obj.recycleWhen) {
      // Setup expiry on new connexions and return the connexion as valid
      obj.recycleWhen = moment().add(getRandomWithinRange(maxConnectionAge, maxConnectionAge * 2), 'seconds')
      return true
    }
    // Recycle the connexion if it has expired
    return moment().diff(obj.recycleWhen, 'seconds') < 0
  }
}
const master = { rdsClusterWriterEndpoint, username, password, port, database, pool }
const replica = { rdsClusterReaderEndpoint, username, password, port, database, pool }
const sequelize = new Sequelize(null, null, null, {
  dialect: 'mysql',
  replication: {
    write: master,
    read: [replica]
  }
}

池中的连接会定期回收,这会触发传播到集群中引入的新副本。

它并不理想,因为大多数时候它会无缘无故地被回收,当你添加副本来处理数据库上越来越大的压力时,你可能希望它早日生效,但这是我的穷人解决方案这一刻,它帮助我们度过了最近流量激增的时期。

这里为了简单起见,我对主控和读者使用相同的池配置,但显然不应该这样。

如果有人有更好的主意,我会洗耳恭听 ;)