gpt4 book ai didi

data-modeling - CouchDB 的推荐文档结构

转载 作者:行者123 更新时间:2023-12-04 11:17:20 25 4
gpt4 key购买 nike

我们目前正在考虑将 Postgres 更改为 CouchDB 以用于使用情况监控应用程序。一些数字:

大约 2000 个连接,每 5 分钟轮询一次,每天大约有 600,000 个新行。在 Postgres 中,我们存储这些数据,按天分区:

t_usage {service_id, timestamp, data_in, data_out}
t_usage_20100101 继承了 t_usage。
t_usage_20100102 继承了 t_usage。等等。

我们使用乐观存储过程写入数据,该过程假定分区存在并在必要时创建它。我们可以非常快速地插入。

为了读取数据,我们的用例按重要性和当前性能排序是:
* 单次服务,单日使用:性能良好
* 多项服务,每月使用量:性能不佳
* 单一服务,月使用:性能不佳
* 多个服务,多个月:性能很差
* 多服务,单日:良好的表现

这是有道理的,因为分区已经优化了几天,这是迄今为止我们最重要的用例。但是,我们正在研究改进次要要求的方法。

我们经常也需要按小时参数化查询,例如,只在上午 8 点到下午 6 点之间给出结果,因此汇总表的用途有限。 (这些参数变化的频率足够高,以至于无法创建多个数据汇总表)。

有了这样的背景,第一个问题是:CouchDB 是否适合这些数据?如果是,鉴于上述用例,您将如何最好地对 CouchDB 文档中的数据进行建模?到目前为止,我们正在进行基准测试的一些选项是(_id,_rev 排除在外):

每个连接每天一份文档

{
service_id:555
day:20100101
usage: {1265248762: {in:584,out:11342}, 1265249062: {in:94,out:1242}}
}

每月大约有 60,000 个新文件。大多数新数据是对现有文件的更新,而不是新文件。

(这里,使用中的对象以轮询的时间戳为键,以及字节输入和字节输出的值)。

每月每个连接一份文档
{
service_id:555
month:201001
usage: {1265248762: {in:584,out:11342}, 1265249062: {in:94,out:1242}}
}

每月大约有 2,000 个新文件。需要对现有文件进行适度更新。

收集的每行数据一个文档
{
service_id:555
timestamp:1265248762
in:584
out:11342
}
{
service_id:555
timestamp:1265249062
in:94
out:1242
}

每月大约有 15,000,000 个新文档。所有数据都将插入到新文档中。插入速度更快,但我对处理数亿个文档一年或两年后的效率有疑问。文件 IO 似乎令人望而却步(尽管我是第一个承认我不完全了解它的机制的人)。

我试图以面向文档的方式来解决这个问题,尽管打破 RDMS 习惯很困难:) 你只能最小化参数化 View 的事实也让我有点担心。也就是说,以上哪一个最合适?是否还有其他我没有考虑过的格式会表现得更好?

提前致谢,

杰米。

最佳答案

我不认为这是一个可怕的想法。

让我们考虑您的连接/月份方案。

考虑到一个条目的长度约为 40(这是慷慨的)字符,并且您每月获得约 8,200 个条目,您的最终文档大小将在月底时约 350K。

这意味着,完全无聊,您每 5 分钟就要读写 2000 个 350K 文档。

I/O 方面,考虑到读取和写入,这小于 6 MB/s,平均为 5m 时间窗口。即使在今天的低端硬件中,这也很好。

然而,还有另一个问题。当您存储该文档时,Couch 将评估其内容以构建其 View ,因此 Couch 将解析 350K 文档。我担心的是(最后一次检查,但已经有一段时间了)我认为 Couch 不能很好地跨 CPU 内核扩展,因此这很容易固定 Couch 将使用的单个 CPU 内核。我希望 Couch 能够以 2 MB/s 的速度读取、解析和处理,但坦率地说,我不知道。尽管有它的所有好处,但 erlang 并不是直线计算机语言中最好的。

最后一个问题是跟上数据库。这将在月底每 5 分钟写入 700 MB。使用 Couchs 架构(仅附加),您将每 5 分钟写入 700MB 的数据,即每小时 8.1GB,24 小时后写入 201GB。

DB 压缩后,它会压缩到 700MB(一个月),但在此过程中,该文件会变大,而且很快。

在检索方面,这些大文件并没有吓到我。加载一个 350K 的 JSON 文档,是的,它很大,但没有那么大,在现代硬件上不行。在比那更大的公告板上有头像。因此,我认为您对一个月内的连接事件想做的任何事情都会非常快。跨连接,显然你获取的越多,它就会越贵(所有 2000 个连接为 700MB)。 700MB 是一个具有实际影响力的实数。此外,您的流程需要积极地丢弃您不关心的数据,以便它可以扔掉渣滓(除非您想在报告流程中加载 700MB 的堆)。

鉴于这些数字,连接/天可能是更好的选择,因为您可以更好地控制粒度。然而,坦率地说,我会去寻找最粗糙的文件,因为我认为这可以从数据库中获得最大的值(value),仅仅因为今天所有的磁头搜索和盘片旋转都会杀死很多 I/O 性能,许多磁盘流数据非常好。较大的文档(假设数据位置很好,因为 Couch 不断被压缩,这应该不是问题)流比搜索更多。与磁盘相比,在内存中查找是“免费的”。

一定要在我们的硬件上运行您自己的测试,但请牢记所有这些考虑因素。

编辑:

经过更多的实验...

几个有趣的观察。

在导入大文件期间,CPU 对 I/O 速度同样重要。这是因为将 JSON 转换为供 View 使用的内部模型所消耗的编码和 CPU 数量。通过使用大型 (350k) 文档,我的 CPU 几乎达到了最大值 (350%)。相比之下,对于较小的文档,它们以 200% 的速度嗡嗡作响,尽管总的来说,它是相同的信息,只是组合方式不同。

对于 I/O,在 350K 文档期间,我绘制了 11MB/秒的图表,但对于较小的文档,它仅为 8MB/秒。

压缩似乎几乎受 I/O 限制。我很难在 I/O 潜力上获得好的数字。缓存文件的副本推送 40+MB/秒。压缩运行速度约为 8MB/秒。但这与原始负载一致(假设沙发正在一条一条消息地移动东西)。 CPU 较低,因为它执行的处理较少(它不解释 JSON 有效负载或重建 View ),而且它是一个 CPU 完成工作。

最后,为了阅读,我尝试转储整个数据库。为此只使用了一个 CPU,而我的 I/O 非常低。我强调要确保 CouchDB 文件实际上没有被缓存,我的机器有很多内存,所以很多东西都被缓存了。通过 _all_docs 的原始转储只有大约 1 MB/秒。这几乎就是所有的搜索和旋转延迟。当我对大型文档执行此操作时,I/O 达到 3 MB/秒,这仅显示了我提到的对大型文档的好处的流影响。

应该注意的是,Couch 网站上有一些我没有遵循的关于提高性能的技术。值得注意的是,我使用的是随机 ID。最后,这不是作为衡量 Couch 性能的指标,而是衡量负载似乎结束的地方。我认为大与小的文档差异很有趣。

最后,最终性能并不像简单地为您的硬件应用程序表现得足够好那么重要。正如你提到的,你正在做你自己的测试,这才是真正重要的。

关于data-modeling - CouchDB 的推荐文档结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2197095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com