- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们有一个有用户的应用;每个用户每次使用我们的应用程序大约 10-40 分钟,我想根据发生的特定事件(例如“此用户转换”、“此用户”)计算每次此类 session 发生的事件的分布/发生次数上次 session 有问题”,“该用户上次 session 成功”)。
(在此之后我想每天计算这些更高级别的事件,但这是一个单独的问题)
为此,我一直在研究 session 窗口;但所有docs似乎适合全局 session 窗口,但我想为每个用户创建它们(这也是一种自然分区)。
我找不到有关如何执行此操作的文档(首选 Python)。你能给我指出正确的方向吗?
或者换句话说:如何创建可以输出更多结构化(丰富)事件的每用户每 session 窗口?
class DebugPrinter(beam.DoFn):
"""Just prints the element with logging"""
def process(self, element, window=beam.DoFn.WindowParam):
_, x = element
logging.info(">>> Received %s %s with window=%s", x['jsonPayload']['value'], x['timestamp'], window)
yield element
def sum_by_event_type(user_session_events):
logging.debug("Received %i events: %s", len(user_session_events), user_session_events)
d = {}
for key, group in groupby(user_session_events, lambda e: e['jsonPayload']['value']):
d[key] = len(list(group))
logging.info("After counting: %s", d)
return d
# ...
by_user = valid \
| 'keyed_on_user_id' >> beam.Map(lambda x: (x['jsonPayload']['userId'], x))
session_gap = 5 * 60 # [s]; 5 minutes
user_sessions = by_user \
| 'user_session_window' >> beam.WindowInto(beam.window.Sessions(session_gap),
timestamp_combiner=beam.window.TimestampCombiner.OUTPUT_AT_EOW) \
| 'debug_printer' >> beam.ParDo(DebugPrinter()) \
| beam.CombinePerKey(sum_by_event_type)
INFO:root:>>> Received event_1 2019-03-12T08:54:29.200Z with window=[1552380869.2, 1552381169.2)
INFO:root:>>> Received event_2 2019-03-12T08:54:29.200Z with window=[1552380869.2, 1552381169.2)
INFO:root:>>> Received event_3 2019-03-12T08:54:30.400Z with window=[1552380870.4, 1552381170.4)
INFO:root:>>> Received event_4 2019-03-12T08:54:36.300Z with window=[1552380876.3, 1552381176.3)
INFO:root:>>> Received event_5 2019-03-12T08:54:38.100Z with window=[1552380878.1, 1552381178.1)
如你所见; Session() 窗口不会扩展窗口,但只会将非常接近的事件组合在一起...哪里做错了?
最佳答案
您可以通过在开窗后添加一个 Group By Key 转换来让它工作。您已将键分配给记录,但实际上并未按键将它们组合在一起, session 窗口(按键工作)不知道这些事件需要合并在一起。
为了证实这一点,我使用一些内存中的虚拟数据做了一个可重现的示例(以将 Pub/Sub 与问题隔离开来并能够更快地对其进行测试)。所有五个事件都将具有相同的 key 或 user_id
,但它们将依次“到达”彼此相隔 1、2、4 和 8 秒。当我使用 5 秒的 session_gap
时,我希望前 4 个元素合并到同一个 session 中。第 5 个事件将在第 4 个事件之后花费 8 秒,因此它必须降级到下一个 session (超过 5 秒的差距)。数据是这样创建的:
data = [{'user_id': 'Thanos', 'value': 'event_{}'.format(event), 'timestamp': time.time() + 2**event} for event in range(5)]
我们使用 beam.Create(data)
初始化管道,使用 beam.window.TimestampedValue
分配“假”时间戳。同样,我们只是用它来模拟流式传输行为。之后,我们通过 user_id
字段创建键值对,我们进入 window.Sessions
并添加缺少的 beam.GroupByKey()
步骤。最后,我们使用稍微修改过的 DebugPrinter
版本记录结果:管道现在看起来像这样:
events = (p
| 'Create Events' >> beam.Create(data) \
| 'Add Timestamps' >> beam.Map(lambda x: beam.window.TimestampedValue(x, x['timestamp'])) \
| 'keyed_on_user_id' >> beam.Map(lambda x: (x['user_id'], x))
| 'user_session_window' >> beam.WindowInto(window.Sessions(session_gap),
timestamp_combiner=window.TimestampCombiner.OUTPUT_AT_EOW) \
| 'Group' >> beam.GroupByKey()
| 'debug_printer' >> beam.ParDo(DebugPrinter()))
DebugPrinter
是:
class DebugPrinter(beam.DoFn):
"""Just prints the element with logging"""
def process(self, element, window=beam.DoFn.WindowParam):
for x in element[1]:
logging.info(">>> Received %s %s with window=%s", x['value'], x['timestamp'], window)
yield element
如果我们在不按键分组的情况下进行测试,我们会得到相同的行为:
INFO:root:>>> Received event_0 1554117323.0 with window=[1554117323.0, 1554117328.0)
INFO:root:>>> Received event_1 1554117324.0 with window=[1554117324.0, 1554117329.0)
INFO:root:>>> Received event_2 1554117326.0 with window=[1554117326.0, 1554117331.0)
INFO:root:>>> Received event_3 1554117330.0 with window=[1554117330.0, 1554117335.0)
INFO:root:>>> Received event_4 1554117338.0 with window=[1554117338.0, 1554117343.0)
但是在添加它之后,窗口现在可以正常工作了。事件 0 到 3 在扩展的 12 秒 session 窗口中合并在一起。事件 4 属于单独的 5 秒 session 。
INFO:root:>>> Received event_0 1554118377.37 with window=[1554118377.37, 1554118389.37)
INFO:root:>>> Received event_1 1554118378.37 with window=[1554118377.37, 1554118389.37)
INFO:root:>>> Received event_3 1554118384.37 with window=[1554118377.37, 1554118389.37)
INFO:root:>>> Received event_2 1554118380.37 with window=[1554118377.37, 1554118389.37)
INFO:root:>>> Received event_4 1554118392.37 with window=[1554118392.37, 1554118397.37)
完整代码 here
还有两件事值得一提。第一个是,即使使用 DirectRunner 在一台机器上本地运行它,记录也可能是无序的(在我的例子中,event_3 在 event_2 之前处理)。这样做是为了模拟分布式处理,如文档所述here .
最后一个是,如果你得到这样的堆栈跟踪:
TypeError: Cannot convert GlobalWindow to apache_beam.utils.windowed_value._IntervalWindowBase [while running 'Write Results/Write/WriteImpl/WriteBundles']
从 2.10.0/2.11.0 SDK 降级到 2.9.0。看这个answer例如。
关于python - Apache Beam 每用户 session 窗口未合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55219481/
我正在使用 Apache Beam 从 Kafka 读取数据。由于乱序写入 Kafka,我想使用有效负载中的事件时间戳而不是默认的 LogAppendTime。 我看到了一个解决方案 Apache B
我有一个通用输入请求,其中包含需要转换和保存的输入。如果需要转换生成的输出,我会为它实现一个新的处理器(转换器)。 class Request { Input input; Transform
我已经在 Apache Beam 上工作了几天。我想快速迭代我正在工作的应用程序,并确保我正在构建的管道没有错误。在 Spark 中我们可以使用 sc.parallelise当我们应用一些 Actio
我有一个简单的波束管道,它使用带有 tf 变换的通用句子编码器获取一些文本并获得嵌入。与使用 tf 1 制作的演示非常相似。 import tensorflow as tf import apache
使用Apache Beam丰富数据时,对每个数据项都进行一次API调用会不会出错? (我是 Apache Beam 的新手) 最佳答案 不,但您可以批处理 API 调用以获得更好的性能。查看 this
我的任务是为一款应用添加支持,以便通过 Android 上的“NFC”在设备之间传输大型数据文件(数十兆字节)。 我知道 Android 上真正的 NFC 非常慢,但我知道 ICS 支持将批量数据传输
NFC:S-beam 和 Android beam 有什么区别?有人可以解释 Wifi-Direct/Bluetooth 激活和传输数据的确切流程吗? 最佳答案 在 stackexchanged 上解
我正在使用 Beam 管道计算流式数据的电话号码频率。我使用的滑动窗口每 5 分钟重复一次,总周期为 15 分钟,因此正如预期的那样,对于某些输入,当输入落在多个窗口中时,我会得到多个输出。 计算出现
输入的PCollection是http requests,是一个有界数据集。我想在 ParDo 中进行异步 http 调用(Java),解析响应并将结果放入输出 PCollection 中。我的代码如
输入的PCollection是http requests,是一个有界数据集。我想在 ParDo 中进行异步 http 调用(Java),解析响应并将结果放入输出 PCollection 中。我的代码如
在使用 PAssert 为我的光束管道编写单元测试时,管道输出对象很好,但在与以下断言错误进行比较时测试失败: java.lang.AssertionError: Decode pubsub mess
我正在尝试从 here 运行 Wordcount 演示与 Samza Runner。这是我的build.gradle plugins { id 'eclipse' id 'java' id
我正在尝试使用 Beam 和 Flink runner 设置流处理管道。 Flink 是一个本地 session 部署,包含以下 docker-compose 文件: version: "3" ser
在尝试编译我的 Phoenix 项目的发行版时,出现以下错误: $ mix release .... ==> Generated .appup for myapp 0.0.1 -> 0.0.2 ===
我正在尝试使用 Apache beam-dataflow 连接到安装在云实例中的配置单元实例。当我运行它时,出现以下异常。当我使用 Apache Beam 访问此数据库时,就会发生这种情况。我见过很多
我正在使用 zsh,并且我已经安装了 gcloud,以便通过我的 Mac 上的本地终端与 GCP 进行交互。我遇到了这个错误“zsh:找不到匹配项:apache-beam[gcp]”。但是,当我在 G
主要记录两种不同的beam search版本 版本一 使用类似层次遍历的方式进行搜索,用队列进行维护,每次循环对当前层的所有节点进行搜索,这些节点每个分别对应topk个节点作为下一层候选节点,取
我的目标是创建一个每秒调用后端(云托管)服务最多次数的管道......我该如何实现? 背景故事:想象一下后端服务使用单个输入调用并返回单个输出。该服务具有与其关联的配额,允许每秒最大请求数(假设每秒
我想写入一个 gs 文件,但在编译时我不知道文件名。它的名称基于在运行时定义的行为。我该如何继续? 最佳答案 如果你使用 Beam Java,你可以使用 FileIO.writeDynamic()为此
我试图弄清楚如何使用Apache Beam读取大型CSV文件。 “大”是指几千兆字节(因此一次将整个CSV读取到内存中是不切实际的)。 到目前为止,我已经尝试了以下选项: 使用TextIO.read(
我是一名优秀的程序员,十分优秀!