我在 2 周前发布了一款名为 MyPetrol 的 Android 应用程序,并在三天内在马来西亚吸引了大约 90,000 名用户。之后,由于巨大的 Firebase 数据库带宽消耗(3 天 117GB),我关闭了该应用程序。我是一个没有IT相关背景的自学成才的爱好者,所以我真的为此感到困扰。希望有人能帮忙。
该应用程序是一款用于汽油价格的众包应用程序。用户可以输入特定加油站的汽油价格,其他同意该价格的用户可以“点赞”。价格更新后,“喜欢”计数会重置。
打开应用程序后,它会向 Google Places API 网络服务查询附近的加油站(最多 20 个加油站)。这样,它将听众 Hook 到 Firebase 数据库中的电台数据。每个站的数据结构如下所示。
prices{
ChIJpXJ4phI4zDERJqFTBzawpXk={
placeID='ChIJpXJ4phI4zDERJqFTBzawpXk',
company=500,
lat=3.2095573,
lng=101.7185698,
name='Shell Malaysia (Iznora Enterprise)',
firebaseID='xxx',
userName='xxx',
time=1491833181946,
ron95=2.0,
ron97=1.7,
diesel=2.0,
isValid=true
}
}
为了跟踪点赞数,有一段数据为
likes{
ChIJpXJ4phI4zDERJqFTBzawpXk={
firebaseID1=true,
firebaseID2=true,
firebaseID3=true
}
}
我读了Firebase database bandwidth usage when read with Query我们可以使用 (Firebase.getDefaultConfig().setLogLevel(Level.DEBUG))
进行流量检查,但我没有在 logcat 中看到有关上传和下载带宽的任何信息。只有这样的东西......
04-10 22:39:19.250 3015-3192/? D/RepoOperation: onDataUpdate: /prices/ChIJpXJ4phI4zDERJqFTBzawpXk
04-10 22:39:19.250 3015-3192/? D/RepoOperation: onDataUpdate: /prices/ChIJpXJ4phI4zDERJqFTBzawpXk {time=1491833181946, firebaseID=xxx, valid=true, diesel=2, ron97=1.7000000476837158, ron95=2, placeID=ChIJpXJ4phI4zDERJqFTBzawpXk, name=Shell Malaysia (Iznora Enterprise), userName=xxx, company=500, lat=3.2095573, lng=101.7185698}
04-10 22:39:19.268 3015-3015/? D/EventRaiser: Raising /prices/ChIJpXJ4phI4zDERJqFTBzawpXk: VALUE: {time=1491833181946, firebaseID=xxx, valid=true, diesel=2, ron97=1.7000000476837158, ron95=2, placeID=ChIJpXJ4phI4zDERJqFTBzawpXk, name=Shell Malaysia (Iznora Enterprise), userName=xxx, company=500, lat=3.2095573, lng=101.7185698}
04-10 22:39:19.273 3015-3015/? D/EventRaiser: Raising /likes/ChIJpXJ4phI4zDERJqFTBzawpXk: VALUE: null
最后,我使用 Android Device Monitor 检查每个操作的流量。以下是仅 Firebase 的平均结果。不包括 Google map 和其他 http 查询。
+----------------------------+-----------+-----------+-----------------------------------------+
| Action | Rx(bytes) | Tx(bytes) | Notes |
+----------------------------+-----------+-----------+-----------------------------------------+
| onPause | 2942 | 4680 | detach all listeners |
| onResume | 10143 | 5204 | reattach all listeners for 15 stations |
| click "like" by self | 620 | 535 | write action + download /likes/placeID |
| update price by self | 1642 | 1783 | write action + download /places/placeID |
| click "like" by other user | 382 | 112 | download /likes/placeID |
| update price by other user | 423 | 104 | download /places/placeID |
+----------------------------+-----------+-----------+-----------------------------------------+
就在我关闭应用程序之前,数据库中有 5.7MB 的数据。我可以保证我直接为每个站连接了监听器作为/prices/placeID,所以我没有检索整个“站”数据,而是只检索该特定站的数据。同样对于“喜欢”。监听器也在暂停时分离。
我没有任何可用的用户操作日志,因此我很难追溯发生的事情。但是,每当用户打开应用程序时,都必须查询 Google Place API,所以我知道在这 3 天内,我有 245k 个查询。因此对于每个用户 session 。
117GB / 245k session = ~480kB/session
这看起来很大。我对带宽等的经验为零,所以我可能是错的。即使我假设所有用户都执行了以下极不可能的操作,我仍然无法填满带宽。
+----------------------------+-----------+-------+--------------+----------------------------------------------------------+
| Action | Rx(bytes) | Times | Total(bytes) | Notes |
+----------------------------+-----------+-------+--------------+----------------------------------------------------------+
| onPause | 2942 | 10 | 29420 | Pause and resume 10 times, this does not update the map. |
| onResume | 10143 | 10 | 101430 | |
| click "like" by self | 620 | 15 | 9300 | Click like on all 15 stations |
| update price by self | 1642 | 15 | 24630 | Update price on all 15 stations |
| click "like" by other user | 382 | 100 | 38200 | 100 other users clicked per session |
| update price by other user | 423 | 100 | 42300 | 100 other users updated the price per session |
| Total | | | 245280 | |
+----------------------------+-----------+-------+--------------+----------------------------------------------------------+
对于普通用户,我预计每个 session 最多只有 50kB 左右,因此 Firebase 似乎消耗了 10 倍的带宽。所以我的问题:
- 我是否正确计算了每个 session 的带宽?
- 使用 Android Device Monitor 确定的流量是否正确?我错过了什么吗?有没有更好的检查方法?
- Firebase 如何计算带宽?它也包括上传吗?有没有隐藏的带宽?
抱歉发了这么长的帖子。感谢有人可以提供帮助。 谢谢。
最佳答案
所以,回到高带宽消耗。它与 Firebase 数据库的 Query
有关。当新用户注册时,我在下面有一个查询。
Query priceQuery = getPricesRef().orderByChild("firebaseID").equalTo(myFirebaseID);
这是我噩梦的开始,因为我没有为该数据库设置 .indexOn
。阅读官方 Firebase 文档 here .关于 Query
的文档非常少。它只说没有索引性能会很差,但没有提到带宽:
根据上面的陈述,我的假设是没有.indexOn
,对 Firebase 的查询可能需要更长的时间才能回复,因为 Firebase 服务器可能需要更长的时间来提供搜索结果。强>
但是,正如 Firebase database bandwidth usage when read with Query 中的回答,整个数据库首先从 Firebase 下载,然后在客户端进行排序和查询!我想这就是他们所说的实时客户端库可以在不指定索引的情况下执行临时查询.
随着我的数据库的增长,每个注册用户开始通过下载整个prices
数据库来消耗更高的带宽。到最后,每个用户仅注册就消耗约 800kB。 因此请确保始终使用 .indexOn
!
关于android - Firebase 数据库带宽计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43327934/