【发布时间】:2017-11-22 15:03:40
【问题描述】:
我正在使用 Firebase 实时数据库,并且超时后其中有很多过时的数据,我编写了一个脚本来删除过时的内容。
我的节点结构如下所示:
store
- {store_name}
- products
- {product_name}
- data
- {date} e.g. 01_Sep_2017
- some_event
数据规模
#Stores: ~110K
#Products: ~25
上下文
我想清理 30 个月前的所有数据。我尝试了以下方法:-
对于每个商店,遍历所有产品,对于每个日期,删除节点
我运行了大约 30 个线程/脚本实例,每个线程负责删除该月中特定日期的数据。整个脚本运行约 12 小时以删除具有上述结构的一个月数据。
我已经对每个脚本中的挂起调用数量设置了限制/上限,从日志中可以明显看出,每个脚本都很快达到了限制,并且触发删除调用的速度比删除速度快得多所以这里是 firebase成为瓶颈。
很明显,我在客户端运行清除脚本并获得性能脚本应该在靠近数据的地方执行以节省网络往返时间。
问题
第一季度。如何有效地删除 firebase 旧节点?
第二季度。有没有办法在每个节点上设置一个 TTL 以便它自动清理?
第三季度。我已从多个节点确认数据已从节点中删除,但 firebase 控制台未显示数据减少。我还尝试备份数据,它仍然显示一些当我手动检查节点时不存在的数据。我想知道这种不一致背后的原因。
firebase 是否进行软删除所以当我们进行备份时,数据实际上存在但通过 firebase sdk 或 firebase 控制台不可见,因为它们可以处理软删除但备份不能?
第四季度。在我的脚本运行的整个期间,我的带宽部分持续上升。使用下面的脚本,我只触发删除调用,我没有读取任何数据,但我看到与数据库读取的一致性。看看这张截图?
这是因为删除节点的回调吗?
代码
var stores = [];
var storeIndex = 0;
var products = [];
var productIndex = -1;
const month = 'Oct';
const year = 2017;
if (process.argv.length < 3) {
console.log("Usage: node purge.js $beginDate $endDate i.e. node purge 1 2 | Exiting..");
process.exit();
}
var beginDate = process.argv[2];
var endDate = process.argv[3];
var numPendingCalls = 0;
const maxPendingCalls = 500;
/**
* Url Pattern: /store/{domain}/products/{product_name}/data/{date}
* date Pattern: 01_Jan_2017
*/
function deleteNode() {
var storeName = stores[storeIndex],
productName = products[productIndex],
date = (beginDate < 10 ? '0' + beginDate : beginDate) + '_' + month + '_' + year;
numPendingCalls++;
db.ref('store')
.child(storeName)
.child('products')
.child(productName)
.child('data')
.child(date)
.remove(function() {
numPendingCalls--;
});
}
function deleteData() {
productIndex++;
// When all products for a particular store are complete, start for the new store for given date
if (productIndex === products.length) {
if (storeIndex % 1000 === 0) {
console.log('Script: ' + beginDate, 'PendingCalls: ' + numPendingCalls, 'StoreIndex: ' + storeIndex, 'Store: ' + stores[storeIndex], 'Time: ' + (new Date()).toString());
}
productIndex = 0;
storeIndex++;
}
// When all stores have been completed, start deleting for next date
if (storeIndex === stores.length) {
console.log('Script: ' + beginDate, 'Successfully deleted data for date: ' + beginDate + '_' + month + '_' + year + '. Time: ' + (new Date()).toString());
beginDate++;
storeIndex = 0;
}
// When you have reached endDate, all data has been deleted call the original callback
if (beginDate > endDate) {
console.log('Script: ' + beginDate, 'Deletion script finished successfully at: ' + (new Date()).toString());
process.exit();
return;
}
deleteNode();
}
function init() {
console.log('Script: ' + beginDate, 'Deletion script started at: ' + (new Date()).toString());
getStoreNames(function() {
getProductNames(function() {
setInterval(function() {
if (numPendingCalls < maxPendingCalls) {
deleteData();
}
}, 0);
});
});
}
PS:这不是我所拥有的确切结构,但它与我们所拥有的非常相似(我已更改节点名称并试图使示例成为现实示例)
【问题讨论】:
标签: performance firebase firebase-realtime-database purge