Компонент сервера Apache Pinot потребляет непредвиденный объем памяти

Описание проблемы:

Docker используется для развертывания Apache Pinot на рабочих серверах (ВМ).

Для этой цели использовалась официальная документация Пино .

Что было сделано

Серверы Pinot потребляют больше памяти, чем данные и фактор репликации, которые у нас есть.

Были опробованы следующие вещи:

  • ОпределениеXmsиXmxфлаги для JVM в переменных окружения ‍JAVA_OPTS
  • Настройте мониторинг на машинах, чтобы добиться наблюдаемости
  • Удалите индексы (например, инвертированный индекс) из определения таблицы.

Спецификация системы: у нас есть 3 сервера, 2 контроллера и 2 брокера со следующими характеристиками:

  • 24-ядерный процессор
  • 64 гигабайта памяти
  • 738 гигабайт SSD-диска

Пример файла Docker-compose на одном из серверов:

      version: '3.7'
services:
  pinot-server:
    image: apachepinot/pinot:0.11.0
    command: "StartServer -clusterName bigdata-pinot-ansible -zkAddress 172.16.24.14:2181,172.16.24.15:2181 -configFileName /server.conf"
    restart: unless-stopped
    hostname: server1
    container_name: server1
    ports:
      - "8096-8099:8096-8099"
      - "9000:9000"
      - "8008:8008"
    environment:
      JAVA_OPTS: "-Dplugins.dir=/opt/pinot/plugins -Xms4G -Xmx20G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-server.log -javaagent:/opt/pinot/etc/jmx_prometheus_javaagent/jmx_prometheus_javaagent-0.12.0.jar=8008:/opt/pinot/etc/jmx_prometheus_javaagent/configs/pinot.yml"
    volumes:
      - ./server.conf:/server.conf
      - ./data/server_data/segment:/var/pinot/server/data/segment
      - ./data/server_data/index:/var/pinot/server/data/index

конфигурация таблицы:

      {
    "tableName": "<table-name>",
    "tableType": "REALTIME",
    "segmentsConfig": {
      "schemaName": "<schema-name>",
      "retentionTimeUnit": "DAYS",
      "retentionTimeValue": "60",
      "replication": "3",
      "timeColumnName": "date",
      "allowNullTimeValue": false,
      "replicasPerPartition": "3",
      "segmentPushType": "APPEND",
      "completionConfig": {
        "completionMode": "DOWNLOAD"
      }
    },
    "tenants": {
      "broker": "DefaultTenant",
      "server": "DefaultTenant",
      "tagOverrideConfig": {
        "realtimeCompleted": "DefaultTenant_OFFLINE"
      }
    },
    "tableIndexConfig": {
      "noDictionaryColumns": [
        <some-fileds>
      ],
      "rangeIndexColumns": [
        <some-fileds>
      ],
      "rangeIndexVersion": 1,
      "autoGeneratedInvertedIndex": false,
      "createInvertedIndexDuringSegmentGeneration": false,
      "sortedColumn": [
        "date",
        "id"
      ],
      "bloomFilterColumns": [],
      "loadMode": "MMAP",
      "onHeapDictionaryColumns": [],
      "varLengthDictionaryColumns": [],
      "enableDefaultStarTree": false,
      "enableDynamicStarTreeCreation": false,
      "aggregateMetrics": false,
      "nullHandlingEnabled": false
    },
    "metadata": {},
    "routing": {
      "instanceSelectorType": "strictReplicaGroup"
    },
    "query": {},
    "fieldConfigList": [],
    "upsertConfig": {
      "mode": "FULL",
      "hashFunction": "NONE"
    },
    "ingestionConfig": {
      "streamIngestionConfig": {
        "streamConfigMaps": [
          {
            "streamType": "kafka",
            "stream.kafka.topic.name": "<topic-name>",
            "stream.kafka.broker.list": "<kafka-brokers-list>",
            "stream.kafka.consumer.type": "lowlevel",
            "stream.kafka.consumer.prop.auto.offset.reset": "smallest",
            "stream.kafka.consumer.factory.class.name": "org.apache.pinot.plugin.stream.kafka20.KafkaConsumerFactory",
            "stream.kafka.decoder.class.name": "org.apache.pinot.plugin.stream.kafka.KafkaJSONMessageDecoder",
            "stream.kafka.decoder.prop.format": "JSON",
            "realtime.segment.flush.threshold.rows": "0",
            "realtime.segment.flush.threshold.time": "1h",
            "realtime.segment.flush.segment.size": "300M"
          }
        ]
      }
    },
    "isDimTable": false
}

файл server.conf:

      pinot.server.netty.port=8098
pinot.server.adminapi.port=8097
pinot.server.instance.dataDir=/var/pinot/server/data/index
pinot.server.instance.segmentTarDir=/var/pinot/server/data/segment
pinot.set.instance.id.to.hostname=true

После приема данных из потока в реальном времени (в нашем случае Kafka) данные растут в памяти, и контейнеры столкнулись с ошибкой OOMKilled:

Мы понятия не имеем о том, что происходит на сервере, может ли кто-нибудь помочь нам найти основную причину этой проблемы?

PS 1: Чтобы проследить весь процесс развертывания Pinot, вы можете посмотреть этот репозиторий на github.

PS 2: Известно, что размер данных в Pinot можно рассчитать по следующей формуле:

      Data size = size of data (retention) * retention period * replication factor

Например, если у нас есть данные с ретенцией 2d (два дня), и каждый день у нас есть примерно 2 гигабайта данных, а коэффициент репликации равен 3, размер данных составляет около 2 * 2 * 3 = 12 гигабайт.

1 ответ

Как описано в вопросе, проблема заключается в создании таблицы, а не в самом Apache Pinot. Apache Pinot хранит ключи дляUpsertоперация с кучей. Чтобы масштабировать производительность, необходимо увеличить разделы Kafka. Согласно документации, режим upsert по умолчанию равен None.

Другие вопросы по тегам