Назад | Перейти на главную страницу

Mongodb в Kubernetes Тайм-ауты при вставке большого количества данных

У нас есть запущенный api, который получает один раз в день несколько пакетов больших данных, которые вставляются в mongodb. Мы используем cvallance/mongo-k8s-sidecar для конфигурации набора репликации

Это отлично работает в локальной базе монгоданных.

в базе данных также нет производственного трафика, который мог бы повысить условия или около того.

Теперь мы развернули его на движке контейнеров Google. Там вообще импорт работает. Но время от времени бывали такие исключения:

Невозможно запустить replSetReconfig, потому что узел в настоящее время обновляет свою конфигурацию

или

MongoDB.Driver.MongoCommandException: Ошибка при вставке команды: BSONObj size: 16793637 (0x1004025) недействителен. Размер должен быть от 0 до 16793600 (16 МБ). Первый элемент: вставить: «LandingPageConnectionSet_Stage».

или

Ошибка в рабочем цикле {MongoError: время ожидания подключения 0 к 127.0.0.1:27017 истекло в Function.MongoError.create (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/error.js:29:11) в Socket. (/opt/cvallance/mongo-k8s-sidecar/node_modules/mongodb-core/lib/connection/connection.js:198:20) в Object.onceWrapper (events.js: 254: 19) в Socket.emit (events. js: 159: 13) в Socket._onTimeout (net.js: 411: 8) в ontimeout (timers.js: 478: 11) в tryOnTimeout (timers.js: 302: 5) в Timer.listOnTimeout (timers.js: 262: 5)

Я вижу, что процессор, похоже, не на пределе своих возможностей.

Конфигурация Kubernetes для mongodb

---
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: fast
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
---
apiVersion: v1
kind: Service
metadata:
  name: mongo
  labels:
    name: mongo
spec:
  ports:
  - port: 27017
    targetPort: 27017
  clusterIP: None
  selector:
    role: mongo
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: mongo
spec:
  serviceName: "mongo"
  replicas: 3
  template:
    metadata:
      labels:
        role: mongo
        environment: test
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mongo
          image: mongo:3.6
          command:
            - mongod
            - "--replSet"
            - rs0
            - "--bind_ip"
            - 0.0.0.0
            - "--smallfiles"
            - "--noprealloc"
          ports:
            - containerPort: 27017
          volumeMounts:
            - name: mongo-persistent-storage
              mountPath: /data/db
        - name: mongo-sidecar
          image: cvallance/mongo-k8s-sidecar
          env:
            - name: MONGO_SIDECAR_POD_LABELS
              value: "role=mongo,environment=test"
  volumeClaimTemplates:
  - metadata:
      name: mongo-persistent-storage
      annotations:
        volume.beta.kubernetes.io/storage-class: "fast"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 32Gi

мы также немного изменили конфигурацию, ограничив размер кеша Wiretiger и удалив опции smallfiles, чтобы часть в конфигурации выглядела так:

   - mongod
    - "--replSet"
    - rs0
    - "--bind_ip"
    - 0.0.0.0
    - "--noprealloc"
    - "--wiredTigerCacheSizeGB"
    - "1.5"

Я проверил журналы и панель управления kubernetes с Боасом Энклером.

В панели управления Kubernetes относительно статуса POD были следующие подсказки:

Pod Name: kube-lego-*****-***     
Status: Evicted 
Reason: The node was low on resource: memory.

Вы могли бы получить ту же информацию через kubectl describe pod [podname]

Обратите внимание, что цитируя документация: "Если kubelet не может освободить достаточно ресурсов на узле, kubelet начинает выселение Pod'ов."

Поэтому я считал, что это ошибка Mongodb, поскольку он работал в помещении без каких-либо проблем, чтобы дважды проверить, мы просмотрели журналы ядра, показанные последовательным выводом консоли, и обнаружили:

Memory cgroup out of memory: Kill process 4**7 (mongod) score 1494 or sacrifice child
...
Memory cgroup out of memory: Kill process 1**8 (mongod) score 1538 or sacrifice child

Мы также заметили, что в YAML-файле развертывания нет поля запроса памяти. Это проблема, поскольку может случиться так, что даже при наличии трех узлов без нагрузки может случиться так, что все POD будут запущены на одном узле, поскольку они теоретически подходят.

Чтобы смягчить это поведение, есть несколько возможных решений:

  • Вертикальное масштабирование кластера и введение значений запросов к памяти

  • Инструктировать процесс mongodb потребляет меньше памяти, чем запрошенная.

  • Введение ограничения памяти необходимо, если на одном узле работает больше контейнеров, и вы хотите избежать их гибели. Учтите, что таким образом он иногда будет отключен, даже если на узле все еще есть доступная память.