如何使用 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]
}
}
池中的连接会定期回收,这会触发传播到集群中引入的新副本。
它并不理想,因为大多数时候它会无缘无故地被回收,当你添加副本来处理数据库上越来越大的压力时,你可能希望它早日生效,但这是我的穷人解决方案这一刻,它帮助我们度过了最近流量激增的时期。
这里为了简单起见,我对主控和读者使用相同的池配置,但显然不应该这样。
如果有人有更好的主意,我会洗耳恭听 ;)
我们正在为流量激增做准备,但这个问题也是一个通用问题:
知道您可以像这样设置 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]
}
}
池中的连接会定期回收,这会触发传播到集群中引入的新副本。
它并不理想,因为大多数时候它会无缘无故地被回收,当你添加副本来处理数据库上越来越大的压力时,你可能希望它早日生效,但这是我的穷人解决方案这一刻,它帮助我们度过了最近流量激增的时期。
这里为了简单起见,我对主控和读者使用相同的池配置,但显然不应该这样。
如果有人有更好的主意,我会洗耳恭听 ;)