Kafka Streams - 如何高效地加入大型非共分区 store/topic
Kafka Streams - How to efficiently join with a large, non-copartitioned store/topic
我们有一系列网络事件。
事件按(域,uid)分区。
此处说明的所有事件均来自同一域。域数以千计,流量非常不均匀(因此进行分区)。
假设我们有来自一个未注册用户 (uid1) 的事件。
我们有来自不同设备的同一未注册用户的事件,这会创建一个新的 uid(我们称之为 uid2)。
当我们在 uid1 上进行注册时,它会使用电子邮件 (email1) 进行注册。
后来,它从第二个设备登录 - 所以我们可以知道两个 uid 来自同一个用户。
发生这种情况时,我们可以在登录时检查用户标识符(例如电子邮件)的状态存储,看看它是否存在,从而获得正确的用户。
但是,由于它们是不同的 uid,因此它们不会共分区。仅按域而不是 (domain, uid) 进行分区是不可取的。
另外,这样的用户存储的大小可能非常大,无法保存在每个应用程序实例中(数百万条记录),因此对于 GlobalKTable 存储来说可能太多了。
如何解决这个问题?
我想到的是,如果我们有对应于 uid2 的 uid1,那么我们可以将 uid1 的用户数据存储在 uid2 实例上的本地 KTable 中。因为 uid2 总是指向那个实例,所以我们只需要将 uid1 存储在该实例的 KTable 中(而不是全局 KTable 中)。
因此您可以在 Kafka 之外拥有一个全局存储,也许在分布式内存中 key/value 存储中。在收到 uid2 并且不知道用户但有电子邮件地址时,您检查 KTable,如果不存在,则在 Kafka 外部的全局存储中查找它,然后将其存储在 KTable 中以供将来本地访问。从那时起,您将始终拥有其实例本地 uid2 的用户数据。
这样一来,您只需在第一次看到来自未知 uid 的新登录时支付对 key/value 存储的网络调用费用。
我们有一系列网络事件。
事件按(域,uid)分区。
此处说明的所有事件均来自同一域。域数以千计,流量非常不均匀(因此进行分区)。
假设我们有来自一个未注册用户 (uid1) 的事件。 我们有来自不同设备的同一未注册用户的事件,这会创建一个新的 uid(我们称之为 uid2)。
当我们在 uid1 上进行注册时,它会使用电子邮件 (email1) 进行注册。 后来,它从第二个设备登录 - 所以我们可以知道两个 uid 来自同一个用户。
发生这种情况时,我们可以在登录时检查用户标识符(例如电子邮件)的状态存储,看看它是否存在,从而获得正确的用户。
但是,由于它们是不同的 uid,因此它们不会共分区。仅按域而不是 (domain, uid) 进行分区是不可取的。
另外,这样的用户存储的大小可能非常大,无法保存在每个应用程序实例中(数百万条记录),因此对于 GlobalKTable 存储来说可能太多了。
如何解决这个问题?
我想到的是,如果我们有对应于 uid2 的 uid1,那么我们可以将 uid1 的用户数据存储在 uid2 实例上的本地 KTable 中。因为 uid2 总是指向那个实例,所以我们只需要将 uid1 存储在该实例的 KTable 中(而不是全局 KTable 中)。
因此您可以在 Kafka 之外拥有一个全局存储,也许在分布式内存中 key/value 存储中。在收到 uid2 并且不知道用户但有电子邮件地址时,您检查 KTable,如果不存在,则在 Kafka 外部的全局存储中查找它,然后将其存储在 KTable 中以供将来本地访问。从那时起,您将始终拥有其实例本地 uid2 的用户数据。
这样一来,您只需在第一次看到来自未知 uid 的新登录时支付对 key/value 存储的网络调用费用。