Rails работает медленно в среде Docker на основе Rancher с Postgresql - PullRequest
2 голосов
/ 19 апреля 2019

Мы используем среду Docker на основе Rancher.Сервер хорошо оборудован, и я не чувствую проблем с производительностью.Но начальная производительность и производительность консоли очень низкая.

  • 62 секунды для запуска сервера puma (на моей локальной виртуальной машине: 9 секунд)
  • 51 секунда для доступаконсоль rails c (на моей локальной ВМ: 7 секунд)
  • 17 минут!обновить 70000 из 100000 записей с этим "oneliner" в консоли rails. Всего 70 записей в секунду .Сам выбор занимает всего 31 мс.
Object.where(view: 0).each{ |obj| obj.update_columns(view: 1) }

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

Я также сравнил свою локальную виртуальную машину (2 ядра, 3 ГБ ОЗУ)

Benchmark.bm do |x|
  x.report { 1000.times do Object.first.update_columns(view: 0) end }
end

Локальный

       user     system      total        real
   2.472000   0.216000   2.688000 (  4.719130)

Сервер

       user     system      total        real
   1.961856   0.164141   2.125997 ( 14.161671)

Так у кого-нибудь есть идея, что может так сильно все замедлить?

Согласно PgHero, с базой данных все в порядке, бесполезных индексов нет.

Пожалуйста, спросите, нужна ли вам дополнительная информация.

Аппаратное обеспечение
Процессор и оперативная память на 30% - все тихо.
Процессупомянутый "oneliner" использовал 5,7% одного ядра
ЦП : четырехъядерный процессор Intel® Core ™ i7-6700
RAM : 64 ГБ DDR4 RAM
HDD : 1 ТБ SSD

Среда
ОС : Ubuntu 18.04.1
Ruby :2.5.5
Rails : 5.3
PostgreSQL : 10.6

PostgreSQL хранится не в модуле, а непосредственно на компьютере.

Rancher : v2.2.3
Пользователь Интерфейс: v2.2.41
Шлем : v2.10.0-rancher10
Machine : v0.15.0-rancher6-1

Проект
Проект среднего размера, содержащий около 80 драгоценных камней, 146 таблиц и 986 маршрутов.

time bundle exec rake environment
real    0m1.793s
user    0m1.486s
sys     0m0.252s
Benchmark.ms { Rails.application.eager_load! }
=> 27.172662317752838

Основной Dockerfile использует стандартное изображение ruby-slim-image.

Dockerfiles

mytag / my_ruby_2_5_5:

LABEL maintainer="my@email.com"

WORKDIR /app

EXPOSE 3000

# Set the locale
RUN apt-get update && \
    apt-get install -y locales

RUN sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen && \
    locale-gen de_DE.UTF-8

ENV LANG=de_DE.UTF-8 \
    LANGUAGE=de_DE:de \
    LC_ALL=de_DE.UTF-8

RUN echo "set input-meta on" >> /etc/inputrc && \
    echo "set output-meta on" >> /etc/inputrc && \
    echo "set convert-meta off" >> /etc/inputrc && \
    echo "export LANG=de_DE.utf8" >> /etc/profile && \
    cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime

# install bundler
RUN gem install bundler

# install some tools
RUN apt-get install -y cron build-essential git nodejs imagemagick libpq-dev

# Rails ENV
ARG RAILS_ENV=production

# BUNDLER options
ARG BUNDLER_OPTS=" --without development test"

# clean up
RUN apt-get autoremove -y

# dummy start command
CMD ["/bin/bash"]
FROM mytag/my_ruby_2_5_5
LABEL maintainer="my@email.com"

ARG RAILS_ENV=production

COPY Gemfile* /app/

RUN bundle config git.allow_insecure true && \
    bundle install --jobs 20 $BUNDLER_OPTS

COPY . /app

RUN rails assets:precompile

CMD [ "rails", "application:start" ]

Приложение с граблями: запуск - простая задача

desc 'migrate and start up'
task start: ['db:migrate', :up]

desc 'start rails in prod env'
task up: :environment do
  sh "rails server -b 0.0.0.0 -p 3000"
end

Rancher YAML (извлечение // анонимный)

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "58"
  creationTimestamp: "2019-06-03T19:03:28Z"
  generation: 75
  labels:
    workload.user.cattle.io/workloadselector: deployment-railsapp-railsapp
  name: railsapp
  namespace: railsapp
  resourceVersion: "2133509"
  selfLink: /apis/apps/v1beta2/namespaces/railsapp/deployments/railsapp
spec:
  progressDeadlineSeconds: 600
  replicas: 5
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: deployment-railsapp-railsapp
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      annotations:
        cattle.io/timestamp: "2019-06-18T12:40:43Z"
      creationTimestamp: null
      labels:
        workload.user.cattle.io/workloadselector: deployment-railsapp-railsapp
    spec:
      affinity: {}
      containers:
      - env:
        - name: DB_HOST
          value: 172.17.0.1
        image: myapp/railsapp:master-4996
        imagePullPolicy: Always
        livenessProbe:
          failureThreshold: 10
          initialDelaySeconds: 70
          periodSeconds: 5
          successThreshold: 1
          tcpSocket:
            port: 3000
          timeoutSeconds: 2
        name: railsapp
        readinessProbe:
          failureThreshold: 10
          initialDelaySeconds: 70
          periodSeconds: 5
          successThreshold: 2
          tcpSocket:
            port: 3000
          timeoutSeconds: 2
        resources: {}
        securityContext:
          allowPrivilegeEscalation: false
          capabilities: {}
          privileged: false
          procMount: Default
          readOnlyRootFilesystem: false
          runAsNonRoot: false
        stdin: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        tty: true
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 5
  conditions:
  - lastTransitionTime: "2019-06-18T12:33:27Z"
    lastUpdateTime: "2019-06-18T12:33:27Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2019-06-11T08:22:59Z"
    lastUpdateTime: "2019-06-21T13:11:49Z"
    message: ReplicaSet "railsapp-958579c56" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 75
  readyReplicas: 5
  replicas: 5
  updatedReplicas: 5

1 Ответ

0 голосов
/ 19 апреля 2019

Видите, что "resources: {}" в вашем YAML?Вы забыли указать это, и это, скорее всего, причина.Я никогда не использовал Rancher, но в Kubernetes, если вы не указываете ресурсы - он укажет его для вас и, скорее всего, он будет использовать какое-то низкое значение.

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

resources:
  requests:
    memory: "8Gi"
    cpu: "2"
  limits:
    memory: "8Gi"
    cpu: "2"

Подробнее о вычислительных ресурсах для контейнеров здесь: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

...