假设有大约10,000个密钥,其中每个密钥对应一个事件流。我想支持以下操作:
push(key, timestamp, event)
- 将事件推送到事件队列以获取密钥,并使用给定的时间戳进行标记。可以保证特定键的事件时间戳按排序或几乎按顺序排列。tail(key, timestamp)
- 获取自给定时间戳以来密钥的所有事件。通常,对给定密钥的时间戳请求几乎是单调增加的,几乎与推送相同密钥同步。这个东西必须是持久的(虽然不一定要立即保持推送并且保持尾部严格同步推送),所以我将使用某种数据库。
此任务的最佳数据库结构类型是什么?使用关系数据库,键值存储或其他什么更好?
答案 0 :(得分:2)
使用财务数据? ;)我有一个应用程序在这里测试150万个这样的流(CME完整饲料);)
关系 - 你可以做到,但这是浪费。我所做的是一个二进制存储PER STREAM并将这些元素放入一个二进制效率的delta格式(时间戳总是上升 - 所以不需要保持它们总数,只有来自alst的小ldelta)。我将它们存储在15分钟的切片中,并且检索尾部的系统知道如何获取数据。同时也减少了关系方面的负担。
为此专门的数据库,但它们是淫秽的(每处理器核心10.000美元,最低许可证8核心 - 是的,是的)。
某些应用程序使用平面文件(每个密钥一个),甚至是应用程序样式。我个人不喜欢。
答案 1 :(得分:2)
你对将要使用的硬件有什么意见吗? 假设这将有更多的读取而不是写入,这可能是SSD的理想应用程序,再加上TomTom提到的 - 将事件作为文件存储在专用目录中。
如果你这样做,我建议为每个“Key”创建一个目录,并在子目录中组织它们。
即,假设你有这样的钥匙:HJ029084930A
你应该:
/streams
/streams/HJ02
/streams/HJ02/9084
/streams/HJ02/9084/930A/HJ029084930A
/streams/HJ02/9084/930A/HJ029084930A/20100315/230257.trc
/streams/HJ02/9084/930A/HJ029084930A/20100316/000201.trc
/streams/HJ02/9084/930A/HJ029084930A/20100316/000203.trc
/streams/HJ02/9084/930A/HJ029084930A/20100316/010054.trc
...
/streams/HJ02/9084/930A/HJ029084930A/20100317/010230.trc
我所暗示的是,您应该尽力避免在目录中包含“太多”文件(或目录),否则操作系统可能会降低检索内容的速度。
一个可能的问题是当流从一天结束到下一天的开始重叠时。 看看你是否可以拆分它,以便你可以在23:59:59完成它并在第二天从00:00:00开始创建一个新的。这取决于你的情况下“tail()”的语义。