数据库按实际用量计费
每个需要存储数据的 Mythex 应用都会获得自己的 Postgres 数据库,而已发布应用的数据库用量与构建应用消耗的是同一个积分余额。直到 9 月下旬,我们一直是估算这部分用量:依据是应用服务器运行了多长时间。事实证明,这种估算在一个关键方面出了错,于是我们把它换掉了:现在,每个数据库都根据其服务提供商实际测得的计算量计费,按已完成的每一小时计算,并且每个小时只能被计费一次。
数据库如何工作
每个数据库都运行在无服务器的 Postgres 上,并且可以缩容至零:闲置几分钟后会进入休眠,并在下一次查询时被唤醒。在运行期间,它会随着负载自动伸缩计算资源。这正是“每个应用一个数据库”能够负担得起的原因——大多数应用大部分时间都很安静,而休眠的数据库几乎不产生费用。
这也意味着,数据库的费用取决于两件我们从外部看不到的事情:它保持唤醒的时长,以及它在唤醒期间的规模大小。
估算出错在哪里
我们最初的计量做了一个假设:已发布应用的服务器每运行一个小时,就按最小的计算规格收取一小时的数据库费用。
这个假设在三个方面都不对:
- 规格不对。 数据库实际运行时的默认规格比估算所假设的更大。
- 数据库会自动伸缩。 在负载下,它们会扩容,而估算从未考虑到这一点。
- 数据库并不跟随应用服务器运行。 只要任何东西在查询它——应用本身、定时任务,或者一个不停轮询它的脚本——数据库就会保持唤醒,无论应用的服务器是否在运行。
最终结果是:估算向用户收取的费用,大约只有数据库实际成本的一半。这对我们来说不可持续,同时也让应用中显示的用量数字与人们的理解不一致。
测量而不是猜测
我们的数据库提供商会报告每个项目的每小时计算单元秒数——也就是它实际使用的计算量,包括规格在内。因此,计量现在的工作方式如下:
- 对于每个带数据库的已发布应用,获取自应用上线以来每个已完成小时的实测用量。
- 按提供商的价格将用量换算为费用,应用套餐费率,并从应用所有者的积分中扣除。
- 每次最多回溯一天,因此在我们的 API 重启期间遗漏的小时,之后仍会被计费。
存储则单独计费,按大小收费,因为它不依赖于活动量。
绝不重复计费一个小时
运行在多台服务器上、并且可能崩溃和重试的计费计量,必须小心避免重复收费。每个数据库的每个小时,都会先在它自己的数据库行中被认领,然后才会收费,并且在(数据库,小时)这一对上设有唯一性约束。如果两台服务器或一次重试试图为同一个小时计费,只有一次认领会成功。
对于罕见的失败情况,我们也做了一个有意的选择:如果进程在认领一个小时之后、收费之前崩溃,该小时会保持已认领但未计费的状态。在极少数的崩溃中损失一点点收入,好过向某人重复收费。
此外,当实测计费开启时,它是从下一个完整小时开始的。之前的那些小时已经按旧的估算收过费了;如果再根据实测数据重新计费,那段时间就会被重复收费。
如果你在 Mythex 上构建应用,这意味着什么
- 你的数据库账单现在反映的是你的数据库实际做了什么。 一个很少使用的应用费用很低;一个不断查询数据库的应用会让数据库保持唤醒,因此费用更高。
- 影响最大的因素是你的应用如何使用数据库。 每隔几秒轮询一次数据库,会让它全天候保持唤醒。而让 AI 按需获取数据,或者对数据进行缓存,则可以让数据库休眠。我们的什么是数据库指南涵盖了基础知识。
- Pro 套餐的托管、数据库和存储费率是 Free 套餐的一半。详情请参阅积分文档。
我们的收获
- 对按用量计费的成本进行估算,会逐渐偏离实际。 当上游提供商能告诉你实际用量时,就应当以它为准计费。
- 在你收费的最小单位上保证计费的幂等性。 对我们来说,这个单位就是一个数据库小时。
- 不得不出错时,要偏向客户。