我指的是这个文档,它说,“每个碎片可以通过GetRecords支持最多每秒2 MiB的数据读取速率。如果对GetRecords的调用返回10 MiB,那么在接下来的5秒内进行的后续调用会抛出一个异常。”我正在试图理解,一个getRecords调用怎么可能得到(10 2mib ),这超过了2mib的碎片限制?碎片是否会在达到2 mib限制后停止/抛错?
提前感谢
发布于 2019-12-18 13:53:12
这句话看上去自相矛盾。他们应该换个说法。
为了理解上下文,您应该考虑文档中的前两条语句。
摘录自上述文件,
GetRecords可以从单个碎片中检索多达10 MiB的数据,每次调用最多可以检索10 000条记录。每个对GetRecords的调用都被计算为一个读取事务。 每个碎片每秒最多可以支持5个读事务。每个读取事务最多可以提供10,000条记录,每个事务的上限为10 MiB。 通过MiB,每个碎片最多可以支持每秒2 GetRecords的最大总数据读取速率。如果对GetRecords的调用返回10 MiB,则随后在5秒内进行的调用将引发异常。
根据我在GetRecords调用方面的经验,它们实际上的意思是,每个切分对于GetRecords调用有2秒钟/秒的读取速率限制,并且在GetRecords调用开始时,这个速率限制是在超过一个秒的窗口上计算的。
我不确定,但我知道卡夫卡的内部。在Kafka中,分区(与Kinesis中的碎片相同)被进一步划分为基本上是日志文件的段。因此,每条消息都作为一个条目存储在一个日志文件中。
我怀疑他们以如下方式实现了GetRecords服务器端API,
pythonish伪代码:
current_timestamp = datetime.now
seconds_diff = (LAST_SUCCESSFUL_CALL.timestamp - current_timestamp).total_seconds()
if LAST_SUCCESSFUL_CALL.data_size > (seconds_diff * 2 Mib):
LAST_SUCCESSFUL_CALL.data_size = LAST_SUCCESSFUL_CALL.data_size - (seconds_diff * 2 Mib)
throw Error
else
records = data_store.find_next_records_from_segments(10 MiB)
# Here, implementation does not limit the records because sequential disk reading is always faster.
# So, It will be better to get as much records it has with some upper cap of 10 MiB or till the end of segment.
LAST_SUCCESSFUL_CALL.data_size = records.data_size
LAST_SUCCESSFUL_CALL.timestamp = current_timestamp
return records通过将利率限制检查扩展到以前的调用,他们使其实现变得更简单。
对于流处理应用程序来说,它也是最好的,在这些应用程序中,用户可以快速地赶上记录。
例如,假设发生了下列事件
T1 -> Ingest 1 MiB in shard, Consumer is busy on processing fetched data, Pending data = 1 MiB
T2 -> Ingest 1 MiB in shard, Consumer is busy on processing fetched data, Pending data = 2 MiB
T3 -> Ingest 1 MiB in shard, Consumer is busy on processing fetched data, Pending data = 3 MiB
T4 -> Ingest 1 MiB in shard, Consumer is busy on processing fetched data, Pending data = 4 MiB
T5 -> Ingest 1 MiB in shard, Consumer is busy on processing fetched data, Pending data = 5 MiB
T6 -> Ingest 1 MiB in shard, Consumer becomes idle and does GetRecords, gets 5 MiB data, Pending data = 1 MiB
T7 -> No new data ingestion, Consumer is busy on processing fetched data
T8 -> No new data ingestion, Consumer is busy on processing fetched data
T9 -> Consumer becomes Idle and does GetRecords, gets 1 MiB data. Pending data = 0 MiB 因此,从T7到T8,消费者可以使用2秒来完全处理5 MiB的数据,而不是分别为每个数据的2 MiB制作GetRecords。在这里,我们保存网络调用和磁盘查找。
总之,
碎片是否会在达到2 mib限制后停止/抛错?
不,不会的。但是在随后的几秒钟内制造的GetRecords会抛出错误。但是,大多数情况下,您的使用者将花费随后的几秒钟时间来处理您在第一次MiB调用中接收到的10个GetRecords数据,而不是查询新的数据。所以,你不用那么担心。
https://stackoverflow.com/questions/59023548
复制相似问题