| e:[["$","script",null,{"type":"application/ld+json","dangerouslySetInnerHTML":{"__html":"{\"@context\":\"https://schema.org\",\"@type\":\"BlogPosting\",\"headline\":\"Apache Pinot™ 0.11 - Pausing Real-Time Ingestion\",\"datePublished\":\"2022-11-28T00:00:00.000Z\",\"dateModified\":\"2022-11-28T00:00:00.000Z\",\"description\":\"Learn about a feature that lets you pause and resume real-time data ingestion in Apache Pinot\",\"image\":\"/static/images/twitter-card.png\",\"url\":\"https://pinot.apache.org/blog/2022-11-28-Apache-Pinot-Pausing-Real-Time-Ingestion\",\"author\":[{\"@type\":\"Person\",\"name\":\"Mark Needham\"}]}"}}],["$","section",null,{"className":" px-5 pt-10 md:px-[13.313rem] md:py-16","children":[["$","$L10",null,{}],["$","article",null,{"className":"","children":["$","div",null,{"className":"mx-auto lg:flex","children":[["$","div",null,{"className":"lg:pr-12","children":[["$","header",null,{"className":"pt-6 md:pr-10","children":[["$","h1",null,{"className":"text-4xl font-semibold","children":"Apache Pinot™ 0.11 - Pausing Real-Time Ingestion"}],["$","p",null,{"className":"pt-2 text-lg","children":["By: ","Mark Needham"]}],["$","p",null,{"className":"py-2 text-sm","children":["November 28th, 2022"," • ","7 min read"]}]]}],["$","div",null,{"className":"flex flex-col lg:flex-row","children":["$","main",null,{"className":"","children":["$","div",null,{"className":"prose max-w-[45rem] pb-8 pt-10 dark:prose-invert","children":[["$","p",null,{"children":["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://youtu.be/u9CwDpMZRog","children":["$","img",null,{"alt":"Watch the video","src":"https://i3.ytimg.com/vi/u9CwDpMZRog/maxresdefault.jpg"}]}]}],["$","p",null,{"children":["The Apache Pinot community recently released version ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://medium.com/apache-pinot-developer-blog/apache-pinot-0-11-released-d564684df5d4","children":"0.11.0"}],", which has lots of goodies for you to play with."]}],["$","p",null,{"children":["In this post, we will learn about a feature that lets you pause and resume real-time data ingestion. Sajjad Moradi has ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://medium.com/apache-pinot-developer-blog/pause-stream-consumption-on-apache-pinot-772a971ef403","children":"also written a blog post about this feature"}],", so you can treat this post as a complement to that one."]}],["$","h2",null,{"id":"how-does-real-time-ingestion-work","children":[["$","a",null,{"href":"#how-does-real-time-ingestion-work","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"How does real-time ingestion work?"]}],["$","p",null,{"children":"Before we get into this feature, let’s first recap how real-time ingestion works."}],["$","p",null,{"children":"This only applies to tables that have the REALTIME type. These tables ingest data that comes in from a streaming platform (e.g., Kafka)."}],["$","p",null,{"children":"Pinot servers ingest rows into consuming segments that reside in volatile memory."}],["$","p",null,{"children":["Once a segment reaches the ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://dev.startree.ai/docs/pinot/recipes/configuring-segment-threshold","children":"segment threshold,"}]," it will be persisted to disk as a completed segment, and a new consuming segment will be created. This new segment takes over the ingestion of new events from the streaming platform."]}],["$","p",null,{"children":"The diagram below shows what things might look like when we’re ingesting data from a Kafka topic that has 3 partitions:"}],["$","p",null,{"children":["$","img",null,{"alt":"Apache pinot 0.11 Real Time Data Ingestion","src":"https://www.datocms-assets.com/75153/1669733133-pinot_0-11-realtime_injestion-diagram-v1.png","title":"Apache pinot 0.11 Real Time Data Ingestion"}]}],["$","p",null,{"children":"A table has one consuming segment per partition but would have many completed segments."}],["$","h2",null,{"id":"why-do-we-need-to-pause-and-resume-ingestion","children":[["$","a",null,{"href":"#why-do-we-need-to-pause-and-resume-ingestion","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"Why do we need to pause and resume ingestion?"]}],["$","p",null,{"children":"There are many reasons why you might want to pause and resume ingestion of a stream. Some of the common ones are described below:"}],["$","ul",null,{"children":[["$","li",null,{"children":"There’s a problem with the underlying stream, and we need to restart the server, reset offsets, or recreate a topic"}],["$","li",null,{"children":"We want to ingest data from different streams into the same table."}],["$","li",null,{"children":"We made a mistake in our ingestion config in Pinot, and it’s now throwing exceptions and isn’t able to ingest any more data."}]]}],["$","p",null,{"children":"The 0.11 release adds the following REST API endpoints:"}],["$","ul",null,{"children":[["$","li",null,{"children":["$","code",null,{"children":"/tables/{tableName}/pauseCompletion"}]}],["$","li",null,{"children":["$","code",null,{"children":"/tables/{tableName}/resumeCompletion"}]}]]}],["$","p",null,{"children":["As the names suggest, these endpoints can be used to pause and resume streaming ingestion for a specific table. This release also adds the ",["$","code",null,{"children":"/tables/{tableName}/pauseStatus"}]," endpoint, which returns the pause status for a table."]}],["$","p",null,{"children":"Let’s see how to use this functionality with help from a worked example."}],["$","h2",null,{"id":"data-generation","children":[["$","a",null,{"href":"#data-generation","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"Data Generation"]}],["$","p",null,{"children":"Let’s imagine that we want to ingest events generated by the following Python script:"}],["$","$L11",null,{"className":"language-python","children":["$","code",null,{"className":"code-highlight language-python","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token keyword","children":"import"}]," datetime\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token keyword","children":"import"}]," uuid\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token keyword","children":"import"}]," random\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token keyword","children":"import"}]," json\n"]}],["$","span",null,{"className":"code-line","children":"\n"}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token keyword","children":"while"}]," ",["$","span",null,{"className":"token boolean","children":"True"}],["$","span",null,{"className":"token punctuation","children":":"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ts ",["$","span",null,{"className":"token operator","children":"="}]," datetime",["$","span",null,{"className":"token punctuation","children":"."}],"datetime",["$","span",null,{"className":"token punctuation","children":"."}],"now",["$","span",null,{"className":"token punctuation","children":"("}],["$","span",null,{"className":"token punctuation","children":")"}],["$","span",null,{"className":"token punctuation","children":"."}],"strftime",["$","span",null,{"className":"token punctuation","children":"("}],["$","span",null,{"className":"token string","children":"\"%Y-%m-%dT%H:%M:%S.%fZ\""}],["$","span",null,{"className":"token punctuation","children":")"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token builtin","children":"id"}]," ",["$","span",null,{"className":"token operator","children":"="}]," ",["$","span",null,{"className":"token builtin","children":"str"}],["$","span",null,{"className":"token punctuation","children":"("}],"uuid",["$","span",null,{"className":"token punctuation","children":"."}],"uuid4",["$","span",null,{"className":"token punctuation","children":"("}],["$","span",null,{"className":"token punctuation","children":")"}],["$","span",null,{"className":"token punctuation","children":")"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" count ",["$","span",null,{"className":"token operator","children":"="}]," random",["$","span",null,{"className":"token punctuation","children":"."}],"randint",["$","span",null,{"className":"token punctuation","children":"("}],["$","span",null,{"className":"token number","children":"0"}],["$","span",null,{"className":"token punctuation","children":","}]," ",["$","span",null,{"className":"token number","children":"1000"}],["$","span",null,{"className":"token punctuation","children":")"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token keyword","children":"print"}],["$","span",null,{"className":"token punctuation","children":"("}],"\n"]}],["$","span",null,{"className":"code-line","children":[" json",["$","span",null,{"className":"token punctuation","children":"."}],"dumps",["$","span",null,{"className":"token punctuation","children":"("}],["$","span",null,{"className":"token punctuation","children":"{"}],["$","span",null,{"className":"token string","children":"\"tsString\""}],["$","span",null,{"className":"token punctuation","children":":"}]," ts",["$","span",null,{"className":"token punctuation","children":","}]," ",["$","span",null,{"className":"token string","children":"\"uuid\""}],["$","span",null,{"className":"token punctuation","children":":"}]," ",["$","span",null,{"className":"token builtin","children":"id"}],["$","span",null,{"className":"token punctuation","children":","}]," ",["$","span",null,{"className":"token string","children":"\"count\""}],["$","span",null,{"className":"token punctuation","children":":"}]," count",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":")"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":")"}],"\n"]}]]}]}],["$","p",null,{"children":"We can view the data generated by this script by pasting the above code into a file called datagen.py and then running the following command:"}],["$","p",null,{"children":"python datagen.py 2>/dev/null | head -n3 | jq"}],["$","p",null,{"children":"We’ll see the following output:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tsString\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"2022-11-23T12:08:44.127481Z\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"uuid\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"e1c58795-a009-4e21-ae76-cdd66e090797\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"count\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token number","children":"203"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tsString\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"2022-11-23T12:08:44.127531Z\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"uuid\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"4eedce04-d995-4e99-82ab-6f836b35c580\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"count\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token number","children":"216"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tsString\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"2022-11-23T12:08:44.127550Z\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"uuid\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"6d72411b-55f5-4f9f-84e4-7c8c5c4581ff\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"count\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token number","children":"721"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"We’re going to pipe this data into a Kafka stream called ‘events’ like this:"}],["$","p",null,{"children":"python datagen.py | kcat -P -b localhost:9092 -t events"}],["$","p",null,{"children":["We’re not setting a key for these messages in Kafka for simplicity’s sake, but Robin Moffat has an ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://rmoff.net/2020/09/30/setting-key-value-when-piping-from-jq-to-kafkacat/","children":"excellent blog post that explains how to do it"}],"."]}],["$","h2",null,{"id":"pinot-schematable-config","children":[["$","a",null,{"href":"#pinot-schematable-config","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"Pinot Schema/Table Config"]}],["$","p",null,{"children":"We want to ingest this data into a Pinot table with the same name. Let’s first define a schema:"}],["$","p",null,{"children":"Schema:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"schemaName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"events\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"dimensionFieldSpecs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token punctuation","children":"{"}]," ",["$","span",null,{"className":"token property","children":"\"name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"uuid\""}],["$","span",null,{"className":"token punctuation","children":","}]," ",["$","span",null,{"className":"token property","children":"\"dataType\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"STRING\""}]," ",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":"]"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"metricFieldSpecs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token punctuation","children":"{"}]," ",["$","span",null,{"className":"token property","children":"\"name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"count\""}],["$","span",null,{"className":"token punctuation","children":","}]," ",["$","span",null,{"className":"token property","children":"\"dataType\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"INT\""}]," ",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":"]"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"dateTimeFieldSpecs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"ts\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"dataType\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"TIMESTAMP\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"format\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"1:MILLISECONDS:EPOCH\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"granularity\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"1:MILLISECONDS\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"Note that the timestamp field is called ts and not tsString, as it is in the Kafka stream. We will transform the DateTime string value held in that field into a proper timestamp using a transformation function."}],["$","p",null,{"children":"Our table config is described below:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tableName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"events\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tableType\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"REALTIME\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"segmentsConfig\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"timeColumnName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"ts\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"schemaName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"events\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"replication\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"1\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"replicasPerPartition\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"1\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tableIndexConfig\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"loadMode\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"MMAP\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"streamConfigs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"streamType\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"kafka\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.topic.name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"events\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.broker.list\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"kafka-pause-resume:9093\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.consumer.type\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"lowlevel\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.consumer.prop.auto.offset.reset\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"smallest\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.consumer.factory.class.name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"org.apache.pinot.plugin.stream.kafka20.KafkaConsumerFactory\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"stream.kafka.decoder.class.name\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"org.apache.pinot.plugin.stream.kafka.KafkaJSONMessageDecoder\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"ingestionConfig\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"transformConfigs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"columnName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"ts\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"transformFunction\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"FromDateTime(tsString, 'YYYY-MM-dd''T''HH:mm:ss.SS''Z''')\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"tenants\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],["$","span",null,{"className":"token punctuation","children":"}"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"metadata\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"Our transformation has a subtle error. The second parameter passed to the FromDateTime function describes the format of the DateTime string, which we defined as:"}],["$","p",null,{"children":"YYYY-MM-dd''T''HH:mm:ss.SS''Z''"}],["$","p",null,{"children":"But tsString has values in the following format:"}],["$","p",null,{"children":"2022-11-23T12:08:44.127550Z"}],["$","p",null,{"children":"i.e., we don’t have enough S values - there should be 5 rather than 2."}],["$","p",null,{"children":"If we create the table using the following command:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"docker"}]," run ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"--network"}]," pause-resume ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-v"}]," ",["$","span",null,{"className":"token constant environment","children":"$$PWD"}],"/pinot/config:/config ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" apachepinot/pinot:0.11.0-arm64 AddTable ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-schemaFile"}]," /config/schema.json ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-tableConfigFile"}]," /config/table.json ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-controllerHost"}]," pinot-controller-pause-resume ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-exec"}],"\n"]}]]}]}],["$","p",null,{"children":"Pinot will immediately start trying to ingest data from Kafka, and it will throw a lot of exceptions that look like this:"}],["$","$L11",null,{"className":"language-log","children":["$","code",null,{"className":"code-highlight language-log","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token property","children":"java.lang.RuntimeException:"}]," ",["$","span",null,{"className":"token property","children":"Caught exception while executing function:"}]," fromDateTime",["$","span",null,{"className":"token operator","children":"("}],"tsString",["$","span",null,{"className":"token punctuation","children":","}],["$","span",null,{"className":"token string","children":"'YYYY-MM-dd'"}],"T",["$","span",null,{"className":"token string","children":"'HH:mm:ss.SS'"}],"Z",["$","span",null,{"className":"token string","children":"''"}],["$","span",null,{"className":"token operator","children":")"}],"\n"]}],["$","span",null,{"className":"code-line","children":"…\n"}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token property","children":"Caused by:"}]," ",["$","span",null,{"className":"token property","children":"java.lang.IllegalStateException:"}]," ",["$","span",null,{"className":"token property","children":"Caught exception while invoking method:"}]," public static long org",["$","span",null,{"className":"token punctuation","children":"."}],"apache",["$","span",null,{"className":"token punctuation","children":"."}],"pinot",["$","span",null,{"className":"token punctuation","children":"."}],"common",["$","span",null,{"className":"token punctuation","children":"."}],"function",["$","span",null,{"className":"token punctuation","children":"."}],"scalar",["$","span",null,{"className":"token punctuation","children":"."}],"DateTimeFunctions",["$","span",null,{"className":"token punctuation","children":"."}],"fromDateTime",["$","span",null,{"className":"token operator","children":"("}],"java",["$","span",null,{"className":"token punctuation","children":"."}],"lang",["$","span",null,{"className":"token punctuation","children":"."}],"String",["$","span",null,{"className":"token punctuation","children":","}],"java",["$","span",null,{"className":"token punctuation","children":"."}],"lang",["$","span",null,{"className":"token punctuation","children":"."}],"String",["$","span",null,{"className":"token operator","children":")"}]," with arguments",["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token number date","children":"2022-11-23T"}],["$","span",null,{"className":"token number time","children":"11:12:34.682504Z"}],["$","span",null,{"className":"token punctuation","children":","}]," YYYY",["$","span",null,{"className":"token operator","children":"-"}],"MM",["$","span",null,{"className":"token operator","children":"-"}],"dd",["$","span",null,{"className":"token string","children":"'T'"}],"HH",["$","span",null,{"className":"token operator","children":":"}],"mm",["$","span",null,{"className":"token operator","children":":"}],"ss",["$","span",null,{"className":"token punctuation","children":"."}],"SS",["$","span",null,{"className":"token string","children":"'Z'"}],["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":"\n"}]]}]}],["$","p",null,{"children":"At this point, we’d usually be stuck and would need to fix the transformation function and then restart the Pinot server. With the pause/resume feature, we can fix this problem without resorting to such drastic measures."}],["$","h2",null,{"id":"the-pauseresume-flow","children":[["$","a",null,{"href":"#the-pauseresume-flow","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"The Pause/Resume Flow"]}],["$","p",null,{"children":"Instead, we can follow these steps:"}],["$","ul",null,{"children":[["$","li",null,{"children":"Pause ingestion for the table"}],["$","li",null,{"children":"Fix the transformation function"}],["$","li",null,{"children":"Resume ingestion"}],["$","li",null,{"children":"Profit $$$"}]]}],["$","p",null,{"children":"We can pause ingestion by running the following command:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"curl"}]," ",["$","span",null,{"className":"token parameter variable","children":"-X"}]," POST ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token string","children":"\"http://localhost:9000/tables/events/pauseConsumption\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"accept: application/json\""}],"\n"]}]]}]}],["$","p",null,{"children":"The response should be something like this:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"pauseFlag\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token boolean","children":"true"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"consumingSegments\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token string","children":"\"events__0__0__20221123T1106Z\""}],["$","span",null,{"className":"token punctuation","children":"]"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"description\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"Pause flag is set. Consuming segments are being committed. Use /pauseStatus endpoint in a few moments to check if all consuming segments have been committed.\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"Let’s follow the response’s advice and check the consuming segments status:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"curl"}]," ",["$","span",null,{"className":"token parameter variable","children":"-X"}]," GET ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token string","children":"\"http://localhost:9000/tables/events/pauseStatus\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"accept: application/json\""}],"\n"]}]]}]}],["$","p",null,{"children":"We’ll see the following response:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"pauseFlag\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token boolean","children":"true"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"consumingSegments\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"So far, so good. Now we need to fix the table. We have a config, table-fixed.json, that contains a working transformation config. These are the lines of interest:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"ingestionConfig\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"transformConfigs\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"columnName\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"ts\""}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"transformFunction\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"FromDateTime(tsString, 'YYYY-MM-dd''T''HH:mm:ss.SSSSSS''Z''')\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"We now have five S values rather than two, which should sort out our ingestion."}],["$","p",null,{"children":"Update the table config:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"curl"}]," ",["$","span",null,{"className":"token parameter variable","children":"-X"}]," PUT ",["$","span",null,{"className":"token string","children":"\"http://localhost:9000/tables/events\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"accept: application/json\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"Content-Type: application/json\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-d"}]," @pinot/config/table-fixed.json\n"]}]]}]}],["$","p",null,{"children":"And then resume ingestion. You can pass in the query string parameter consumeFrom, which takes a value of smallest or largest. We’ll pass in smallest since no data has been consumed yet:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"curl"}]," ",["$","span",null,{"className":"token parameter variable","children":"-X"}]," POST ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token string","children":"\"http://localhost:9000/tables/events/resumeConsumption?consumeFrom=smallest\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"accept: application/json\""}],"\n"]}]]}]}],["$","p",null,{"children":"The response will be like this:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"pauseFlag\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token boolean","children":"false"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"consumingSegments\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token punctuation","children":"]"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"description\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token string","children":"\"Pause flag is cleared. Consuming segments are being created. Use /pauseStatus endpoint in a few moments to double check.\""}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":"Again, let’s check the consuming segments status:"}],["$","$L11",null,{"className":"language-bash","children":["$","code",null,{"className":"code-highlight language-bash","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token function","children":"curl"}]," ",["$","span",null,{"className":"token parameter variable","children":"-X"}]," GET ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token string","children":"\"http://localhost:9000/tables/events/pauseStatus\""}]," ",["$","span",null,{"className":"token punctuation","children":"\\"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token parameter variable","children":"-H"}]," ",["$","span",null,{"className":"token string","children":"\"accept: application/json\""}],"\n"]}]]}]}],["$","p",null,{"children":"This time we will see some consuming segments:"}],["$","$L11",null,{"className":"language-json","children":["$","code",null,{"className":"code-highlight language-json","children":[["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"{"}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"pauseFlag\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token boolean","children":"false"}],["$","span",null,{"className":"token punctuation","children":","}],"\n"]}],["$","span",null,{"className":"code-line","children":[" ",["$","span",null,{"className":"token property","children":"\"consumingSegments\""}],["$","span",null,{"className":"token operator","children":":"}]," ",["$","span",null,{"className":"token punctuation","children":"["}],["$","span",null,{"className":"token string","children":"\"events__0__22__20221123T1124Z\""}],["$","span",null,{"className":"token punctuation","children":"]"}],"\n"]}],["$","span",null,{"className":"code-line","children":[["$","span",null,{"className":"token punctuation","children":"}"}],"\n"]}]]}]}],["$","p",null,{"children":["Navigate to ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"http://localhost:9000/#/query","children":"http://localhost:9000/#/query"}]," and click on the events table. You should see the following:"]}],["$","p",null,{"children":["$","img",null,{"alt":"Sample events table containing records","src":"https://www.datocms-assets.com/75153/1669668611-image2.png","title":"Sample events table containing records"}]}],["$","p",null,{"children":"We have records! We can also run our data generator again, and more events will be ingested."}],["$","h2",null,{"id":"summary","children":[["$","a",null,{"href":"#summary","aria-hidden":"true","tabIndex":"-1","children":["$","span",null,{"className":"icon icon-link"}]}],"Summary"]}],["$","p",null,{"children":"This feature makes real-time data ingestion a bit more forgiving when things go wrong, which has got to be a good thing in my book."}],["$","p",null,{"children":"When you look at the name of this feature, it can seem a bit esoteric and perhaps not something that you’d want to use, but I think you’ll find it to be extremely useful."}],["$","p",null,{"children":["So give it a try and let us know how you get on. If you have any questions about this feature, feel free to join us on ",["$","a",null,{"target":"_blank","rel":"noopener noreferrer","href":"https://stree.ai/slack","children":"Slack"}],", where we’ll be happy to help you out."]}]]}]}]}]]}],["$","aside",null,{"className":"mt-10 hidden border-l-2 pl-5 lg:sticky lg:top-1 lg:block lg:h-full","children":["$","section",null,{"className":"sticky top-0 mb-4 w-[15.375rem]","children":[["$","div",null,{"className":"flex flex-col space-y-1.5 pb-3","children":["$","h3",null,{"className":"text-sm font-semibold leading-snug text-neutral-500 dark:text-neutral-100","children":"Table of Contents"}]}],["$","$L12",null,{"chapters":[{"value":"How does real-time ingestion work?","url":"#how-does-real-time-ingestion-work","depth":2},{"value":"Why do we need to pause and resume ingestion?","url":"#why-do-we-need-to-pause-and-resume-ingestion","depth":2},{"value":"Data Generation","url":"#data-generation","depth":2},{"value":"Pinot Schema/Table Config","url":"#pinot-schematable-config","depth":2},{"value":"The Pause/Resume Flow","url":"#the-pauseresume-flow","depth":2},{"value":"Summary","url":"#summary","depth":2}]}]]}]}]]}]}]]}]] |