Erlang 如何在限制ETS表的总大小的同时自动终止表中的entires?

Erlang 如何在限制ETS表的总大小的同时自动终止表中的entires?,erlang,ets,Erlang,Ets,我有很多分析数据,我希望每隔一段时间(比如说一分钟)汇总一次。这些数据被发送到一个进程,该进程将其存储在ETS表中,每隔一段时间,计时器就会向其发送一条消息,以处理该表并删除旧数据 问题是输入的数据量变化很大,我基本上需要做两件事: 如果传入的数据量太大,请删除最旧的数据,然后推入新数据。这可以被看作是一个固定大小的队列,如果数据量达到极限,队列将在新数据返回时开始从前面丢弃数据 如果队列未满,但数据已经在那里存放了一段时间,则自动丢弃它(在固定超时后) 如果这两个条件保持不变,我基本上可以

我有很多分析数据,我希望每隔一段时间(比如说一分钟)汇总一次。这些数据被发送到一个进程,该进程将其存储在ETS表中,每隔一段时间,计时器就会向其发送一条消息,以处理该表并删除旧数据

问题是输入的数据量变化很大,我基本上需要做两件事:

  • 如果传入的数据量太大,请删除最旧的数据,然后推入新数据。这可以被看作是一个固定大小的队列,如果数据量达到极限,队列将在新数据返回时开始从前面丢弃数据
  • 如果队列未满,但数据已经在那里存放了一段时间,则自动丢弃它(在固定超时后)
如果这两个条件保持不变,我基本上可以假设表的大小不变,并且表中的所有内容都比X更新

问题是我还没有找到一个有效的方法来同时做这两件事。我知道我可以使用match Spec删除所有早于X的entires,如果索引是时间戳,那么这应该非常快。虽然我不确定这是否是定期修剪桌子的最佳方式

第二个问题是将表的总大小保持在一定的限制之下,我不知道该怎么做。想到的一个解决方案是在每次插入时使用一个自动递增字段,在修剪表时,查看第一个和最后一个索引,计算差异,然后再次使用“匹配规格”删除阈值以下的所有内容


说到这里,我觉得我可能是在用ETS表做一些它不是设计来做的事情。有没有更好的方法来存储这样的数据,或者我是否正确地处理了这个问题?

我没有使用ETS来存储这样的数据,但在其他NoSQL DBs(DynamoDB)中,一个简单的解决方案是使用多个表:如果您保留24小时的数据,那么就保留24个表,每天每小时一个表。如果要删除数据,请删除整个表。

您可以使用
ets:info(选项卡,内存)
确定占用的数据量。结果是字数。但有一个陷阱。如果要存储二进制文件,则只包括堆二进制文件。因此,如果您存储的大部分是普通的Erlang术语,那么您可以使用它,并使用您描述的时间戳,这是一种方法。对于以字节为单位的大小,只需乘以erlang:system\u info(wordsize)

即可:创建一个负责

  • 接收所有数据存储消息。这些消息应该由客户机进程加上时间戳(因此,它是否在消息队列中等待一点并不重要)。然后,服务器将存储在ETS中,配置为有序_集,并使用时间戳(转换为整数)作为密钥(如果时间戳由函数erlang传递:现在在一个VM中,它们将不同,如果您使用多个节点,则需要添加一些信息,例如节点名,以确保唯一性)
  • 接收一个勾号(例如,使用定时器:发送间隔),然后处理最近Nµs内收到的消息(使用键=当前时间-N),并查找ets:next(表,键),然后继续处理最后一条消息。最后,您可以通过ets丢弃所有消息:删除所有对象(表)。如果必须添加节点名等信息,仍然可以使用下一个函数(例如,键为{TimeStamp:int(),node:atom()},您可以将其与{Time:int(),0}进行比较,因为数字小于任何原子)

通常如何访问数据?您使用ets是因为您通常需要按键查找数据吗?@SteveVinoski否,我使用ets只是因为在进程状态下存储大量数据似乎不是一个合理的想法。