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

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

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

Это прекрасно работает в локальной базе данных MongoDatabase.

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

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

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

или

MongoDB.Driver.MongoCommandException: Ошибка вставки команды: размер BSONObj: 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"

решение1

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

На панели инструментов Kubernetes относительно статуса POD имелись следующие подсказки:

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

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

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

Поэтому я решил, что ошибка связана с 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 развертывания не было поля Memory Request. Это проблема, поскольку может случиться так, что даже если есть три узла без рабочей нагрузки, может случиться так, что все POD будут запущены на одном и том же узле, поскольку они теоретически подходят.

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

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

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

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

Связанный контент