5

我正在设计一个系统,该系统应该分析大量用户事务并生成汇总度量(例如趋势等)。该系统应该工作快速、健壮和可扩展。系统是基于java的(基于Linux)。

数据来自生成用户事务日志文件(基于 CSV)的系统。系统每分钟生成一个文件,每个文件包含不同用户的交易(按时间排序),每个文件可能包含数千个用户。

CSV 文件的示例数据结构:

10:30:01,用户 1,...
10:30:01,用户 1,...
10:30:02,用户 78,...
10:30:02,用户 2,...
10: 30:03,用户 1,...
10:30:04,用户 2,
... . .

我计划的系统应该处理文件并实时执行一些分析。它必须收集输入,将其发送到几个算法和其他系统,并将计算结果存储在数据库中。数据库不保存实际的输入记录,而只保存有关事务的高级聚合分析。例如趋势等。

我计划使用的第一个算法需要至少 10 条用户记录以实现最佳操作,如果 5 分钟后找不到 10 条记录,它应该使用任何可用的数据。

我想使用 Storm 来实现,但我更愿意尽可能将这个讨论留在设计级别。

系统组件列表:

  1. 每分钟监视传入文件的任务。

  2. 读取文件、解析文件并使其可用于其他系统组件和算法的任务。

  3. 一个组件为用户缓冲 10 条记录(不超过 5 分钟),当收集到 10 条记录或 5 分钟过去时,是时候将数据发送到算法进行进一步处理了。由于要求为算法提供至少 10 条记录,我想到了使用 Storm Field Grouping(这意味着为同一用户调用相同的任务)并跟踪任务中 10 条用户记录的集合,当然我计划有几个这样的任务,每个处理一部分用户。

  4. 还有其他组件可以处理单个事务,对于它们,我计划创建其他任务来接收每个被解析的事务(与其他任务并行)。

#3 我需要你的帮助。

设计这样一个组件的最佳实践是什么?很明显,它需要为每个用户维护 10 条记录的数据。键值映射可能会有所帮助,是在任务本身中管理映射还是使用分布式缓存更好?例如 Redis 一个键值存储(我以前从未使用过它)。

谢谢你的帮助

4

2 回答 2

5

我曾经使用过很多 redis。所以,我会评论你使用redis的想法

#3 有 3 个要求

  1. 每个用户的缓冲区

  2. 10 个任务的缓冲区

  3. 应该每 5 分钟过期一次

1. 每个用户的缓冲区: Redis 只是一个键值存储。尽管它支持多种数据类型,但它们始终是映射到 STRING 键的值。因此,您应该决定如何唯一地识别用户,以防您需要每个用户缓冲区。因为在 redis 中,当你覆盖一个新的键值时,你永远不会出错。一种解决方案可能是在写入之前检查是否存在。

2. 10个任务的缓冲:你显然可以在redis中实现一个队列。但是限制它的大小是留给你的。例如:使用LPUSHLTRIM或使用LLEN来检查长度并决定是否触发您的流程。与此队列关联的键应该是您在第 1 部分中决定的键。

3. Buffer Expires in 5 min:这是一项最艰巨的任务。在 redis 中,每个键(无论其值具有何种基础数据类型)都可以具有expiry. 但是到期过程是沉默的。您不会在任何密钥到期时收到通知。因此,如果您使用此属性,您将默默地丢失缓冲区。解决此问题的一种方法是拥有一个索引。意味着,索引会将时间戳映射到所有需要在该时间戳值处过期的键。然后在后台您可以每分钟读取一次索引并手动从redis中删除键[读取后]并使用缓冲区数据调用您想要的进程。要拥有这样的索引,您可以查看Sorted Sets。时间戳将在哪里score设置member将是您希望在该时间戳删除的键[在第 1 部分中决定的每个用户的唯一键映射到队列]。您可以zrangebyscore读取具有指定时间戳的所有集合成员

总体:

使用 Redis List 实现队列。

使用 LLEN 确保您没有超过 10 的限制。

Current Timestamp + 5 min每当您创建一个新列表时,请使用 Score as和 Value 作为列表的键进入索引 [Sorted Set] 。

当 LLEN 达到 10 时,请记住从索引 [排序集] 和 db [删除键->列表] 中读取然后删除键。然后用数据触发您的流程。

每隔一分钟,生成当前时间戳,读取索引和每个键,读取数据,然后从数据库中删除键并触发您的进程。

这可能是我实现它的方式。可能还有其他更好的方法可以在 redis 中对数据进行建模

于 2012-07-25T08:57:35.133 回答
0

对于您的要求 1 和 2:[Apache Flume 或 Kafka]

满足您的要求#3:[在 Storm 中使用 Esper Bolt。在 Redis 中,为了实现这一点,您将不得不重写 Esper Logic。]

于 2013-07-22T06:55:16.117 回答