arrow-left

All pages
gitbookPowered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Pinot On Kubernetes FAQ

This page has a collection of frequently asked questions about Pinot on Kubernetes with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, make a pull requestarrow-up-right.

hashtag
How to increase server disk size on AWS

The following is an example using Amazon Elastic Kubernetes Service (Amazon EKS).

hashtag
1. Update Storage Class

In the Kubernetes (k8s) cluster, check the storage class: in Amazon EKS, it should be gp2.

Then update StorageClass to ensure:

Once StorageClass is updated, it should look like this:

hashtag
2. Update PVC

Once the storage class is updated, then we can update the PersistentVolumeClaim (PVC) for the server disk size.

Now we want to double the disk size for pinot-server-3.

The following is an example of current disks:

The following is the output of data-pinot-server-3:

Now, let's change the PVC size to 2T by editing the server PVC.

Once updated, the specification's PVC size is updated to 2T, but the status's PVC size is still 1T.

hashtag
3. Restart pod to let it reflect

Restart the pinot-server-3 pod:

Recheck the PVC size:

PVC data-pinot-server-3
allowVolumeExpansion: true
kubectl edit pvc data-pinot-server-3 -n pinot

Frequently Asked Questions (FAQs)

This page lists pages with frequently asked questions with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, .

make a pull requestarrow-up-right
Generalchevron-right
Pinot On Kubernetes FAQchevron-right
Ingestion FAQchevron-right
Query FAQchevron-right
Operations FAQchevron-right

General

This page has a collection of frequently asked questions of a general nature with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, make a pull requestarrow-up-right.

hashtag
How does Apache Pinot use deep storage?

When data is pushed to Apache Pinot, Pinot makes a backup copy of the data and stores it on the configured deep-storage (S3/GCP/ADLS/NFS/etc). This copy is stored as tar.gz Pinot segments. Note, that Pinot servers keep a (untarred) copy of the segments on their local disk as well. This is done for performance reasons.

hashtag
How does Pinot use Zookeeper?

Pinot uses Apache Helix for cluster management, which in turn is built on top of Zookeeper. Helix uses Zookeeper to store the cluster state, including Ideal State, External View, Participants, and so on. Pinot also uses Zookeeper to store information such as Table configurations, schemas, Segment Metadata, and so on.

hashtag
Why am I getting "Could not find or load class" error when running Quickstart using 0.8.0 release?

Check the JDK version you are using. You may be getting this error if you are using an older version than the current Pinot binary release was built on. If so, you have two options: switch to the same JDK release as Pinot was built with or download the for the Pinot release and it locally.

hashtag
How to change TimeZone when running Pinot?

There are 2 ways to do it:

  1. Setting an environment variable: TZ=UTC.

E.g.

  1. Setting JVM argument: user.timezone

  1. TODO:

Plan to add a configuration to change time zone using cluster config or pinot component config

source codearrow-up-right
buildarrow-up-right
https://github.com/apache/pinot/issues/12299arrow-up-right
export TZ=UTC
-Duser.timezone=UTC

Query FAQ

This page has a collection of frequently asked questions about queries with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, make a pull requestarrow-up-right.

hashtag
Querying

hashtag
I get the following error when running a query, what does it mean?

This implies that the Pinot Broker assigned to the table specified in the query was not found. A common root cause for this is a typo in the table name in the query. Another uncommon reason could be if there wasn't actually a broker with required broker tenant tag for the table.

hashtag
What are all the fields in the Pinot query's JSON response?

See this page explaining the Pinot response format: .

hashtag
SQL Query fails with "Encountered 'timestamp' was expecting one of..."

"timestamp" is a reserved keyword in SQL. Escape timestamp with double quotes.

Other commonly encountered reserved keywords are date, time, table.

hashtag
Filtering on STRING column WHERE column = "foo" does not work?

For filtering on STRING columns, use single quotes:

hashtag
ORDER BY using an alias doesn't work?

The fields in the ORDER BY clause must be one of the group by clauses or aggregations, BEFORE applying the alias. Therefore, this will not work:

But, this will work:

hashtag
Does pagination work in GROUP BY queries?

No. Pagination only works for SELECTION queries.

hashtag
How do I increase timeout for a query ?

You can add this at the end of your query: option(timeoutMs=X). Tthe following example uses a timeout of 20 seconds for the query:

You can also use SET "timeoutMs" = 20000; SELECT COUNT(*) from myTable.

For changing the timeout on the entire cluster, set this property pinot.broker.timeoutMs in either broker configs or cluster configs (using the POST /cluster/configs API from Swagger).

hashtag
How do I cancel a query?

Add these two configs for Pinot server and broker to start tracking of running queries. The query tracks are added and cleaned as query starts and ends, so should not consume much resource.

Then use the Rest APIs on Pinot controller to list running queries and cancel them via the query ID and broker ID (as query ID is only local to broker), like in the following:

hashtag
How do I optimize my Pinot table for doing aggregations and group-by on high cardinality columns ?

In order to speed up aggregations, you can enable metrics aggregation on the required column by adding a in the corresponding schema and setting aggregateMetrics to true in the table configuration. You can also use a star-tree index config for columns like these ().

hashtag
How do I verify that an index is created on a particular column ?

There are two ways to verify this:

  1. Log in to a server that hosts segments of this table. Inside the data directory, locate the segment directory for this table. In this directory, there is a file named index_map which lists all the indexes and other data structures created for each segment. Verify that the requested index is present here.

  2. During query: Use the column in the filter predicate and check the value of numEntriesScannedInFilter. If this value is 0, then indexing is working as expected (works for Inverted index).

hashtag
Does Pinot use a default value for LIMIT in queries?

Yes, Pinot uses a default value of LIMIT 10 in queries. The reason behind this default value is to avoid unintentionally submitting expensive queries that end up fetching or processing a lot of data from Pinot. Users can always overwrite this by explicitly specifying a LIMIT value.

hashtag
Does Pinot cache query results?

Pinot does not cache query results. Each query is computed in its entirety. Note though, running the same or similar query multiple times will naturally pull in segment pages into memory making subsequent calls faster. Also, for real-time systems, the data is changing in real-time, so results cannot be cached. For offline-only systems, caching layer can be built on top of Pinot, with invalidation mechanism built-in to invalidate the cache when data is pushed into Pinot.

hashtag
I'm noticing that the first query is slower than subsequent queries. Why is that?

Pinot memory maps segments. It warms up during the first query, when segments are pulled into the memory by the OS. Subsequent queries will have the segment already loaded in memory, and hence will be faster. The OS is responsible for bringing the segments into memory, and also removing them in favor of other segments when other segments not already in memory are accessed.

hashtag
How do I determine if the star-tree index is being used for my query?

The query execution engine will prefer to use the star-tree index for all queries where it can be used. The criteria to determine whether the star-tree index can be used is as follows:

  • All aggregation function + column pairs in the query must exist in the star-tree index.

  • All dimensions that appear in filter predicates and group-by should be star-tree dimensions.

For queries where above is true, a star-tree index is used. For other queries, the execution engine will default to using the next best index available.

https://docs.pinot.apache.org/users/api/querying-pinot-using-standard-sql/response-formatarrow-up-right
metric fieldarrow-up-right
see here for more about star-treearrow-up-right
{'errorCode': 410, 'message': 'BrokerResourceMissingError'}
select "timestamp" from myTable
SELECT COUNT(*) from myTable WHERE column = 'foo'
SELECT count(colA) as aliasA, colA from tableA GROUP BY colA ORDER BY aliasA
SELECT count(colA) as sumA, colA from tableA GROUP BY colA ORDER BY count(colA)
SELECT COUNT(*) from myTable option(timeoutMs=20000)
pinot.server.enable.query.cancellation=true // false by default
pinot.broker.enable.query.cancellation=true // false by default
GET /queries: to show running queries as tracked by all brokers
Response example: `{
  "Broker_192.168.0.105_8000": {
    "7": "select G_old from baseballStats limit 10",
    "8": "select G_old from baseballStats limit 100"
  }
}`

DELETE /query/{brokerId}/{queryId}[?verbose=false/true]: to cancel a running query 
with queryId and brokerId. The verbose is false by default, but if set to true, 
responses from servers running the query also return.

Response example: `Cancelled query: 8 with responses from servers: 
{192.168.0.105:7501=404, 192.168.0.105:7502=200, 192.168.0.105:7500=200}`

Operations FAQ

This page has a collection of frequently asked questions about operations with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, make a pull requestarrow-up-right.

hashtag
Memory

hashtag
How much heap should I allocate for my Pinot instances?

Typically, Apache Pinot components try to use as much off-heap (MMAP/DirectMemory) wherever possible. For example, Pinot servers load segments in memory-mapped files in MMAP mode (recommended), or direct memory in HEAP mode. Heap memory is used mostly for query execution and storing some metadata. We have seen production deployments with high throughput and low-latency work well with just 16 GB of heap for Pinot servers and brokers. The Pinot controller may also cache some metadata (table configurations etc) in heap, so if there are just a few tables in the Pinot cluster, a few GB of heap should suffice.

hashtag
DR

hashtag
Does Pinot provide any backup/restore mechanism?

Pinot relies on deep-storage for storing a backup copy of segments (offline as well as real-time). It relies on Zookeeper to store metadata (table configurations, schema, cluster state, and so on). It does not explicitly provide tools to take backups or restore these data, but relies on the deep-storage (ADLS/S3/GCP/etc), and ZK to persist these data/metadata.

hashtag
Alter Table

hashtag
Can I change a column name in my table, without losing data?

Changing a column name or data type is considered backward incompatible change. While Pinot does support schema evolution for backward compatible changes, it does not support backward incompatible changes like changing name/data-type of a column.

hashtag
How to change number of replicas of a table?

You can change the number of replicas by updating the table configuration's section. Make sure you have at least as many servers as the replication.

For offline tables, update :

For real-time tables, update :

After changing the replication, run a .

Note that if you are using replica groups, it's expected these configurations equal numReplicaGroups. If they do not match, Pinot will use numReplicaGroups.

hashtag
How to set or change table retention?

By default there is no retention set for a table in Apache Pinot. You may however, set retention by setting the following properties in the section inside table configs:

  • retentionTimeUnit

  • retentionTimeValue

Updating the retention value in the table config should be good enough, there is no need to rebalance the table or reload its segments.

hashtag
Rebalance

hashtag
How to run a rebalance on a table?

See .

hashtag
Why does my real-time table not use the new nodes I added to the cluster?

Likely explanation: num partitions * num replicas < num servers.

In real-time tables, segments of the same partition always remain on the same node. This sticky assignment is needed for replica groups and is critical if using upserts. For instance, if you have 3 partitions, 1 replica, and 4 nodes, only ¾ nodes will be used, and all of p0 segments will be on 1 node, p1 on 1 node, and p2 on 1 node. One server will be unused, and will remain unused through rebalances.

There’s nothing we can do about CONSUMING segments, they will continue to use only 3 nodes if you have 3 partitions. But we can rebalance such that completed segments use all nodes. If you want to force the completed segments of the table to use the new server use this config:

hashtag
Segments

hashtag
How to control the number of segments generated?

The number of segments generated depends on the number of input files. If you provide only 1 input file, you will get 1 segment. If you break up the input file into multiple files, you will get as many segments as the input files.

hashtag
What are the common reasons my segment is in a BAD state ?

This typically happens when the server is unable to load the segment. Possible causes: out-of-memory, no disk space, unable to download segment from deep-store, and similar other errors. Check server logs for more information.

hashtag
How to reset a segment when it runs into a BAD state?

Use the segment reset controller REST API to reset the segment:

hashtag
How do I pause real-time ingestion?

Refer to .

hashtag
What's the difference between Reset, Refresh, and Reload?

  • Reset: Gets a segment in ERROR state back to ONLINE or CONSUMING state. Behind the scenes, the Pinot controller takes the segment to the OFFLINE state, waits for External View to stabilize, and then moves it back to ONLINE or CONSUMING state, thus effectively resetting segments or consumers in error states.

In addition, RESET brings the segment OFFLINE temporarily; while REFRESH and RELOAD swap the segment on server atomically without bringing down the segment or affecting ongoing queries.

hashtag
Tenants

hashtag
How can I make brokers/servers join the cluster without the DefaultTenant tag?

Set this property in your controller.conf file:

Now your brokers and servers should join the cluster as broker_untagged and server_untagged. You can then directly use the POST /tenants API to create the tenants you want, as in the following:

hashtag
Minion

hashtag
How do I tune minion task timeout and parallelism on each worker?

There are two task configurations, but they are set as part of cluster configurations, like in the following example. One controls the task's overall timeout (1hr by default) and one sets how many tasks to run on a single minion worker (1 by default). The <taskType> is the task to tune, such as MergeRollupTask or RealtimeToOfflineSegmentsTask etc.

hashtag
How to I manually run a Periodic Task?

See .

hashtag
Tuning and Optimizations

hashtag
Do replica groups work for real-time?

Yes, replica groups work for real-time. There's 2 parts to enabling replica groups:

  1. Replica groups segment assignment.

  2. Replica group query routing.

Replica group segment assignment

Replica group segment assignment is achieved in real-time, if number of servers is a multiple of number of replicas. The partitions get uniformly sprayed across the servers, creating replica groups. For example, consider we have 6 partitions, 2 replicas, and 4 servers.

r1
r2

As you can see, the set (S0, S2) contains r1 of every partition, and (s1, S3) contains r2 of every partition. The query will only be routed to one of the sets, and not span every server. If you are are adding/removing servers from an existing table setup, you have to run for segment assignment changes to take effect.

Replica group query routing

Once replica group segment assignment is in effect, the query routing can take advantage of it. For replica group based query routing, set the following in the table config's section, and then restart brokers

hashtag
Overwrite index configs at tier level

When using , user may want to have different encoding and indexing types for a column in different tiers to balance query latency and cost saving more flexibly. For example, segments in the hot tier can use dict-encoding, bloom filter and all kinds of relevant index types for very fast query execution. But for segments in the cold tier, where cost saving matters more than low query latency, one may want to use raw values and bloom filters only.

The following two examples show how to overwrite encoding type and index configs for tiers. Similar changes are also demonstrated in the .

  1. Overwriting single-column index configs using fieldConfigList. All top level fields in can be overwritten, and fields not overwritten are kept intact.

  1. Overwriting star-tree index configurations using tableIndexConfig. The StarTreeIndexConfigs is overwritten as a whole. In fact, all top level fields defined in can be overwritten, so single-column index configs defined in tableIndexConfig can also be overwritten but it's less clear than using fieldConfigList.

hashtag
Credential

hashtag
How do I update credentials for real-time upstream without downtime?

  1. .

  2. Wait for the pause status to change to success.

  3. Update the credential in the table config.

Ingestion FAQ

This page has a collection of frequently asked questions about ingestion with answers from the community.

circle-info

This is a list of questions frequently asked in our troubleshooting channel on Slack. To contribute additional questions and answers, make a pull requestarrow-up-right.

hashtag
Data processing

hashtag
What is a good segment size?

While Apache Pinot can work with segments of various sizes, for optimal use of Pinot, you want to get your segments sized in the 100MB to 500MB (un-tarred/uncompressed) range. Having too many (thousands or more) tiny segments for a single table creates overhead in terms of the metadata storage in Zookeeper as well as in the Pinot servers' heap. At the same time, having too few really large (GBs) segments reduces parallelism of query execution, as on the server side, the thread parallelism of query execution is at segment level.

hashtag
Can multiple Pinot tables consume from the same Kafka topic?

Yes. Each table can be independently configured to consume from any given Kafka topic, regardless of whether there are other tables that are also consuming from the same Kafka topic.

hashtag
If I add a partition to a Kafka topic, will Pinot automatically ingest data from this partition?

Pinot automatically detects new partitions in Kafka topics. It checks for new partitions whenever RealtimeSegmentValidationManager periodic job runs and starts consumers for new partitions.

You can configure the interval for this job using thecontroller.realtime.segment.validation.frequencyPeriod property in the controller configuration.

hashtag
Does Pinot support partition pruning on multiple partition columns?

Pinot supports multi-column partitioning for offline tables. Map multiple columns under Pinot assigns the input data to each partition according to the partition configuration individually for each column.

The following example partitions the segment based on two columns, memberID and caseNumber. Note that each partition column is handled separately, so in this case the segment is partitioned on memberID (partition ID 1) and also partiitoned on caseNumber (partition ID 2).

For multi-column partitioning to work, you must also set routing.segementPrunerTypes as follows:

hashtag
How do I enable partitioning in Pinot when using Kafka stream?

Set up partitioner in the Kafka producer:

The partitioning logic in the stream should match the partitioning config in Pinot. Kafka uses murmur2, and the equivalent in Pinot is the Murmur function.

Set the partitioning configuration as below using same column used in Kafka:

and also set:

To learn how partition works, see .

hashtag
How do I store BYTES column in JSON data?

For JSON, you can use a hex encoded string to ingest BYTES.

hashtag
How do I flatten my JSON Kafka stream?

See the function which can store a top level json field as a STRING in Pinot.

Then you can use these during query time, to extract fields from the json string.

circle-exclamation

NOTE This works well if some of your fields are nested json, but most of your fields are top level json keys. If all of your fields are within a nested JSON key, you will have to store the entire payload as 1 column, which is not ideal.

hashtag
How do I escape Unicode in my Job Spec YAML file?

To use explicit code points, you must double-quote (not single-quote) the string, and escape the code point via "\uHHHH", where HHHH is the four digit hex code for the character. See for more details.

hashtag
Is there a limit on the maximum length of a string column in Pinot?

By default, Pinot limits the length of a String column to 512 bytes. If you want to overwrite this value, you can set the maxLength attribute in the schema as follows:

hashtag
When are new events queryable when getting ingested into a real-time table?

Events are available to queries as soon as they are ingested. This is because events are instantly indexed in memory upon ingestion.

The ingestion of events into the real-time table is not transactional, so replicas of the open segment are not immediately consistent. Pinot trades consistency for availability upon network partitioning (CAP theorem) to provide ultra-low ingestion latencies at high throughput.

However, when the open segment is closed and its in-memory indexes are flushed to persistent storage, all its replicas are guaranteed to be consistent, with the .

hashtag
How to reset a CONSUMING segment stuck on an offset which has expired from the stream?

This typically happens if:

  1. The consumer is lagging a lot.

  2. The consumer was down (server down, cluster down), and the stream moved on, resulting in offset not found when consumer comes back up.

In case of Kafka, to recover, set property "auto.offset.reset":"earliest" in the streamConfigs section and reset the CONSUMING segment. See for more details about the configuration.

You can also also use the "Resume Consumption" endpoint with "resumeFrom" parameter set to "smallest" (or "largest" if you want). See for more details.

hashtag
Indexing

hashtag
How to set inverted indexes?

Inverted indexes are set in the tableConfig's tableIndexConfig -> invertedIndexColumns list. For more info on table configuration, see . For an example showing how to configure an inverted index, see .

Applying inverted indexes to a table configuration will generate an inverted index for all new segments. To apply the inverted indexes to all existing segments, see

hashtag
How to apply an inverted index to existing segments?

  1. Add the columns you want to index to the tableIndexConfig-> invertedIndexColumns list. To update the table configuration use the Pinot Swagger API: .

  2. Invoke the reload API: .

Once you've done that, you can check whether the index has been applied by querying the segment metadata API at . Don't forget to include the names of the column on which you have applied the index.

The output from this API should look something like the following:

hashtag
Can I retrospectively add an index to any segment?

Not all indexes can be retrospectively applied to existing segments.

If you want to add or change the or adjust you will need to manually re-load any existing segments.

hashtag
How to create star-tree indexes?

Star-tree indexes are configured in the table config under the tableIndexConfig -> starTreeIndexConfigs (list) and enableDefaultStarTree (boolean). See here for more about how to configure star-tree indexes:

The new segments will have star-tree indexes generated after applying the star-tree index configurations to the table configuration.

hashtag
Handling time in Pinot

hashtag
How does Pinot’s real-time ingestion handle out-of-order events?

Pinot does not require ordering of event time stamps. Out of order events are still consumed and indexed into the "currently consuming" segment. In a pathological case, if you have a 2 day old event come in "now", it will still be stored in the segment that is open for consumption "now". There is no strict time-based partitioning for segments, but star-indexes and hybrid tables will handle this as appropriate.

See the for more details about how hybrid tables handle this. Specifically, the time-boundary is computed as max(OfflineTIme) - 1 unit of granularity. Pinot does store the min-max time for each segment and uses it for pruning segments, so segments with multiple time intervals may not be perfectly pruned.

When generating star-indexes, the time column will be part of the star-tree so the tree can still be efficiently queried for segments with multiple time intervals.

hashtag
What is the purpose of a hybrid table not using max(OfflineTime) to determine the time-boundary, and instead using an offset?

This lets you have an old event up come in without building complex offline pipelines that perfectly partition your events by event timestamps. With this offset, even if your offline data pipeline produces segments with a maximum timestamp, Pinot will not use the offline dataset for that last chunk of segments. The expectation is if you process offline the next time-range of data, your data pipeline will include any late events.

hashtag
Why are segments not strictly time-partitioned?

It might seem odd that segments are not strictly time-partitioned, unlike similar systems such as Apache Druid. This allows real-time ingestion to consume out-of-order events. Even though segments are not strictly time-partitioned, Pinot will still index, prune, and query segments intelligently by time intervals for the performance of hybrid tables and time-filtered data.

When generating offline segments, the segments generated such that segments only contain one time interval and are well partitioned by the time column.

Refresh: Replaces the segment with a new one, with the same name but often different data. Under the hood, the Pinot controller sets new segment metadata in Zookeeper, and notifies brokers and servers to check their local states about this segment and update accordingly. Servers also download the new segment to replace the old one, when both have different checksums. There is no separate rest API for refreshing, and it is done as part of the SegmentUpload API.
  • Reload: Loads the segment again, often to generate a new index as updated in the table configuration. Underlying, the Pinot server gets the new table configuration from Zookeeper, and uses it to guide the segment reloading. In fact, the last step of REFRESH as explained above is to load the segment into memory to serve queries. There is a dedicated rest API for reloading. By default, it doesn't download segments, but the option is provided to force the server to download the segment to replace the local one cleanly.

  • p5

    S0

    S1

    p6

    S2

    S3

    Resume the consumption.

    p1

    S0

    S1

    p2

    S2

    S3

    p3

    S0

    S1

    p4

    S2

    S3

    segmentsConfigarrow-up-right
    replicationarrow-up-right
    replicasPerPartitionarrow-up-right
    table rebalance
    segmentsConfigarrow-up-right
    Rebalance
    Pause Stream Ingestionarrow-up-right
    Running a Periodic Task Manually
    rebalance
    routingarrow-up-right
    tiered storagearrow-up-right
    MultiDirQuickStart examplearrow-up-right
    FieldConfig classarrow-up-right
    IndexingConfig classarrow-up-right
    Pause the stream ingestionarrow-up-right
    tableIndexConfig.segmentPartitionConfig.columnPartitionMaparrow-up-right
    .
    https://docs.confluent.io/current/clients/producer.htmlarrow-up-right
    routing tuning
    json_format(field)arrow-up-right
    json functionsarrow-up-right
    https://yaml.org/spec/spec.html#escaping/in%20double-quoted%20scalars/arrow-up-right
    commit protocolarrow-up-right
    Real-time table configsarrow-up-right
    Pause Stream Ingestionarrow-up-right
    Table Config Reference
    Inverted Index
    How to apply an inverted index to existing segments?
    http://localhost:9000/help#!/Table/updateTableConfigarrow-up-right
    http://localhost:9000/help#!/Segment/reloadAllSegmentsarrow-up-right
    http://localhost:9000/help#/Segment/getServerMetadataarrow-up-right
    sorted index column
    the dictionary encoding of the default forward index
    https://docs.pinot.apache.org/basics/indexing/star-tree-index#index-generationarrow-up-right
    Components > Brokerarrow-up-right
    { 
        "tableName": "pinotTable", 
        "tableType": "OFFLINE", 
        "segmentsConfig": {
          "replication": "3", 
          ... 
        }
        ..
    { 
        "tableName": "pinotTable", 
        "tableType": "REALTIME", 
        "segmentsConfig": {
          "replicasPerPartition": "3", 
          ... 
        }
        ..
    "instanceAssignmentConfigMap": {
          "COMPLETED": {
            "tagPoolConfig": {
              "tag": "DefaultTenant_OFFLINE"
            },
            "replicaGroupPartitionConfig": {
            }
          }
        },
    curl -X POST "{host}/segments/{tableNameWithType}/{segmentName}/reset"
    cluster.tenant.isolation.enable=false
    curl -X POST "http://localhost:9000/tenants" 
    -H "accept: application/json" 
    -H "Content-Type: application/json" 
    -d "{\"tenantRole\":\"BROKER\",\"tenantName\":\"foo\",\"numberOfInstances\":1}"
    Using "POST /cluster/configs API" on CLUSTER tab in Swagger, with this payload:
    {
    	"<taskType>.timeoutMs": "600000",
    	"<taskType>.numConcurrentTasksPerInstance": "4"
    }
    {
        "tableName": "pinotTable", 
        "tableType": "REALTIME",
        "routing": {
            "instanceSelectorType": "replicaGroup"
        }
        ..
    }
    {
      ...
      "fieldConfigList": [    
        {
          "name": "ArrTimeBlk",
          "encodingType": "DICTIONARY",
          "indexes": {
            "inverted": {
              "enabled": "true"
            }
          },
          "tierOverwrites": {
            "hotTier": {
              "encodingType": "DICTIONARY",
              "indexes": { // change index types for this tier
                "bloom": {
                  "enabled": "true"
                }
              }
            },
            "coldTier": {
              "encodingType": "RAW", // change encoding type for this tier
              "indexes": { } // remove all indexes
            }
          }
        }
      ],
      "tableIndexConfig": {
        "starTreeIndexConfigs": [
          {
            "dimensionsSplitOrder": [
              "AirlineID",
              "Origin",
              "Dest"
            ],
            "skipStarNodeCreationForDimensions": [],
            "functionColumnPairs": [
              "COUNT__*",
              "MAX__ArrDelay"
            ],
            "maxLeafRecords": 10
          }
        ],
    ...
        "tierOverwrites": {
          "hotTier": {
            "starTreeIndexConfigs": [ // create different STrTree index on this tier
              {
                "dimensionsSplitOrder": [
                  "Carrier",
                  "CancellationCode",
                  "Origin",
                  "Dest"
                ],
                "skipStarNodeCreationForDimensions": [],
                "functionColumnPairs": [
                  "MAX__CarrierDelay",
                  "AVG__CarrierDelay"
                ],
                "maxLeafRecords": 10
              }
            ]
          },
          "coldTier": {
            "starTreeIndexConfigs": [] // removes ST index for this tier
          }
        }
      },
     ...
    "tableIndexConfig": {
          ..
          "segmentPartitionConfig": {
            "columnPartitionMap": {
              "memberId": {
                "functionName": "Modulo",
                "numPartitions": 3 
              },
              "caseNumber": {
                "functionName": "Murmur",
                "numPartitions": 12 
              }
            }
          }
    "routing": {
          "segmentPrunerTypes": ["partition"]
        }
    "tableIndexConfig": {
          ..
          "segmentPartitionConfig": {
            "columnPartitionMap": {
              "column_foo": {
                "functionName": "Murmur",
                "numPartitions": 12 // same as number of kafka partitions
              }
            }
          }
    "routing": {
          "segmentPrunerTypes": ["partition"]
        }
        {
          "dataType": "STRING",
          "maxLength": 1000,
          "name": "textDim1"
        },
    {
      "<segment-name>": {
        "segmentName": "<segment-name>",
        "indexes": {
          "<columnName>": {
            "bloom-filter": "NO",
            "dictionary": "YES",
            "forward-index": "YES",
            "inverted-index": "YES",
            "null-value-vector-reader": "NO",
            "range-index": "NO",
            "json-index": "NO"
          }
        }
      }
    }