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

Плохая производительность MongoDB и ZFS: диск всегда занят чтением, а делает только запись

У меня огромные проблемы с производительностью при использовании MongoDB (я считаю, что это mmapped DB) с ZFSonlinux.

Наш Mongodb почти только пишет. На репликах без ZFS диск полностью загружен из-за всплесков ~ 5 секунд, когда приложение записывает в БД каждые 30 секунд, и между ними нет активности на диске, поэтому я беру это в качестве базового поведения для сравнения.
На репликах с ZFS диск полностью занят все время, при этом реплики изо всех сил стараются не отставать от первичной базы данных MongoDB. У меня включено сжатие lz4 на всех репликах, и экономия места велика, поэтому на диск должно быть гораздо меньше данных.

Итак, на этих серверах ZFS у меня сначала был размер записи по умолчанию = 128 КБ. Затем я стер данные и установил Recordsize = 8k перед повторной синхронизацией данных Mongo. Затем я снова вытер и попробовал recordize = 1k. Я также пробовал recordsize = 8k без контрольных сумм

Тем не менее, это ничего не решало, диск всегда был занят на 100%. Только один раз на одном сервере с recordize = 8k диск был намного менее занят, чем любые реплики, отличные от ZFS, но после попытки другой настройки и повторной попытки с recordsize = 8k диск был 100%, я не мог видеть предыдущее хорошее поведение, и не мог увидеть его ни на одной другой реплике.

Причем там должна быть почти только запись, но посмотрите, что на всех репликах при разных настройках, диск полностью занят: 75% чтения и только 25% записи

(Обратите внимание, я считаю, что MongoDB - это mmapped DB. Мне сказали попробовать MongoDB в режиме AIO, но я не нашел, как его установить, а с другим сервером, на котором запущен MySQL InnoDB, я понял, что ZFSonLinux все равно не поддерживает AIO.)

Мои серверы - это ядро ​​CentOS 6.5 2.6.32-431.5.1.el6.x86_64. spl-0.6.2-1.el6.x86_64 zfs-0.6.2-1.el6.x86_64

#PROD 13:44:55 root@rum-mongo-backup-1:~: zfs list
NAME                     USED  AVAIL  REFER  MOUNTPOINT
zfs                      216G  1.56T    32K  /zfs
zfs/mongo_data-rum_a    49.5G  1.56T  49.5G  /zfs/mongo_data-rum_a
zfs/mongo_data-rum_old   166G  1.56T   166G  /zfs/mongo_data-rum_old

#PROD 13:45:20 root@rum-mongo-backup-1:~: zfs list -t snapshot
no datasets available

#PROD 13:45:29 root@rum-mongo-backup-1:~: zfs list -o atime,devices,compression,copies,dedup,mountpoint,recordsize,casesensitivity,xattr,checksum
ATIME  DEVICES  COMPRESS  COPIES          DEDUP  MOUNTPOINT               RECSIZE         CASE  XATTR   CHECKSUM
  off       on       lz4       1            off  /zfs                        128K    sensitive     sa        off
  off       on       lz4       1            off  /zfs/mongo_data-rum_a         8K    sensitive     sa        off
  off       on       lz4       1            off  /zfs/mongo_data-rum_old       8K    sensitive     sa        off

Что там могло происходить? На что следует обратить внимание, чтобы понять, что делает ZFS или какой параметр установлен неправильно?

РЕДАКТИРОВАТЬ1:
оборудование: это арендованные серверы, 8 ядер на Xeon 1230 или 1240, 16 или 32 ГБ ОЗУ, с zfs_arc_max=2147483648, используя аппаратный RAID1 HP. Итак, ZFS zpool находится на / dev / sda2 и не знает, что существует базовый RAID1. Даже будучи неоптимальной настройкой для ZFS, я все еще не понимаю, почему диск задыхается при чтении, в то время как БД делает только запись.
Я понимаю множество причин, которые нам не нужно снова раскрывать, что это плохо и плохо ... для ZFS, и скоро у меня будет сервер JBOD / NORAID, на котором я могу проводить те же тесты с собственным RAID1 ZFS. реализация на разделе sda2, с разделами /, / boot и swap, выполняющими программный RAID1 с mdadm.

Прежде всего, стоит отметить, что ZFS не является поддерживаемой файловой системой для MongoDB в Linux - рекомендуемые файловые системы - ext4 или XFS. Поскольку ZFS даже не проверяется в Linux (см. СЕРВЕР-13223 например) он не будет использовать разреженные файлы, вместо этого будет пытаться предварительно выделить (заполнить нулями), и это будет означать ужасную производительность на Корова файловая система. Пока это не будет исправлено, добавление новых файлов данных приведет к значительному снижению производительности ZFS (что вы будете часто пытаться делать при записи). Пока вы этого не делаете, производительность должна улучшиться, но если вы добавляете данные достаточно быстро, вы никогда не сможете восстановиться между попаданиями в распределение.

Кроме того, ZFS не поддерживает Direct IO, поэтому вы будете многократно копировать данные в память (mmap, ARC и т. Д.) - я подозреваю, что это источник ваших чтений, но мне нужно будет проверить, чтобы убедиться. В последний раз, когда я видел какое-либо тестирование с MongoDB / ZFS в Linux, производительность была низкой, даже с ARC на SSD - ext4 и XFS были значительно быстрее. ZFS может быть жизнеспособным для производственного использования MongoDB в Linux в будущем, но сейчас он не готов.

Мы изучали запуск Mongo на ZFS и увидели, что этот пост вызывает серьезные опасения по поводу доступной производительности. Два года спустя мы хотели увидеть, как новые версии Mongo, использующие WiredTiger поверх mmap, работают на официально поддерживаемой файловой системе ZFS, которая поставляется с последней версией Ubuntu Xenial.

Таким образом, было ясно, что ZFS работает не так хорошо, как EXT4 или XFS, однако разрыв в производительности не так велик, особенно если учесть дополнительные функции, которые предлагает ZFS.

Я сделал Сообщение блога о наших выводах и методологии. Надеюсь, вы найдете это полезным!

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

Мое решение?!?

XFS на верхняя из ZFS zvols.

Зачем?!?

Поскольку XFS работает хорошо и устраняет проблемы, связанные с конкретными приложениями, с которыми я столкнулся при использовании собственной ZFS. ZFS zvols позволяет мне тонко выделять тома, добавлять сжатие, включать моментальные снимки и эффективно использовать пул хранения. Что еще более важно для моего приложения, ARC-кэширование zvol уменьшило нагрузку ввода-вывода на диски.

Посмотрите, сможете ли вы следить за этим выводом:

# zpool status
  pool: vol0
 state: ONLINE
  scan: scrub repaired 0 in 0h3m with 0 errors on Sun Mar  2 12:09:15 2014
config:

        NAME                                            STATE     READ WRITE CKSUM
        vol0                                            ONLINE       0     0     0
          mirror-0                                      ONLINE       0     0     0
            scsi-SATA_OWC_Mercury_AccOW140128AS1243223  ONLINE       0     0     0
            scsi-SATA_OWC_Mercury_AccOW140128AS1243264  ONLINE       0     0     0
          mirror-1                                      ONLINE       0     0     0
            scsi-SATA_OWC_Mercury_AccOW140128AS1243226  ONLINE       0     0     0
            scsi-SATA_OWC_Mercury_AccOW140128AS1243185  ONLINE       0     0     0

ZFS zvol, созданный с помощью: zfs create -o volblocksize=128K -s -V 800G vol0/pprovol (обратите внимание, что автоматические снимки включены)

# zfs get all vol0/pprovol
NAME          PROPERTY               VALUE                  SOURCE
vol0/pprovol  type                   volume                 -
vol0/pprovol  creation               Wed Feb 12 14:40 2014  -
vol0/pprovol  used                   273G                   -
vol0/pprovol  available              155G                   -
vol0/pprovol  referenced             146G                   -
vol0/pprovol  compressratio          3.68x                  -
vol0/pprovol  reservation            none                   default
vol0/pprovol  volsize                900G                   local
vol0/pprovol  volblocksize           128K                   -
vol0/pprovol  checksum               on                     default
vol0/pprovol  compression            lz4                    inherited from vol0
vol0/pprovol  readonly               off                    default
vol0/pprovol  copies                 1                      default
vol0/pprovol  refreservation         none                   default
vol0/pprovol  primarycache           all                    default
vol0/pprovol  secondarycache         all                    default
vol0/pprovol  usedbysnapshots        127G                   -
vol0/pprovol  usedbydataset          146G                   -
vol0/pprovol  usedbychildren         0                      -
vol0/pprovol  usedbyrefreservation   0                      -
vol0/pprovol  logbias                latency                default
vol0/pprovol  dedup                  off                    default
vol0/pprovol  mlslabel               none                   default
vol0/pprovol  sync                   standard               default
vol0/pprovol  refcompressratio       4.20x                  -
vol0/pprovol  written                219M                   -
vol0/pprovol  snapdev                hidden                 default
vol0/pprovol  com.sun:auto-snapshot  true                   local

Свойства блочного устройства ZFS zvol. Том 900 ГБ (фактический размер на диске 143 ГБ):

# fdisk -l /dev/zd0

Disk /dev/zd0: 966.4 GB, 966367641600 bytes
3 heads, 18 sectors/track, 34952533 cylinders
Units = cylinders of 54 * 512 = 27648 bytes
Sector size (logical/physical): 512 bytes / 131072 bytes
I/O size (minimum/optimal): 131072 bytes / 131072 bytes
Disk identifier: 0x48811e83

    Device Boot      Start         End      Blocks   Id  System
/dev/zd0p1              38    34952534   943717376   83  Linux

Информация XFS о блочном устройстве ZFS:

# xfs_info /dev/zd0p1
meta-data=/dev/zd0p1             isize=256    agcount=32, agsize=7372768 blks
         =                       sectsz=4096  attr=2, projid32bit=0
data     =                       bsize=4096   blocks=235928576, imaxpct=25
         =                       sunit=32     swidth=32 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=65536, version=2
         =                       sectsz=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

Варианты монтирования XFS:

# mount
/dev/zd0p1 on /ppro type xfs (rw,noatime,logbufs=8,logbsize=256k,nobarrier)

Примечание. В некоторых случаях я также делаю это поверх аппаратного RAID HP Smart Array.

Создание пула выглядит так:

zpool create -o ashift=12 -f vol1 wwn-0x600508b1001ce908732af63b45a75a6b

Результат выглядит так:

# zpool status  -v
  pool: vol1
 state: ONLINE
  scan: scrub repaired 0 in 0h14m with 0 errors on Wed Feb 26 05:53:51 2014
config:

        NAME                                      STATE     READ WRITE CKSUM
        vol1                                      ONLINE       0     0     0
          wwn-0x600508b1001ce908732af63b45a75a6b  ONLINE       0     0     0

Я считаю, что ваш диск занят чтением из-за

zfs_arc_max=2147483648

настройка. Здесь вы явно ограничиваете ARC до 2 ГБ, даже если у вас 16-32 ГБ. ZFS чрезвычайно требовательна к памяти и рьяна, когда дело касается ARC. Если у вас есть реплики, отличные от ZFS, идентичные репликам ZFS (HW RAID1 внизу), выполнение некоторых математических расчетов даст

5s spike @ (200Mb/s writes (estimated 1 hdd throughput) * 2 (RAID1)) = 2Gb over 5sec

что означает, что вы, вероятно, аннулируете весь кеш ARC за 5 секунд. ARC (до некоторой степени) «интеллектуален» и будет пытаться сохранить как самые недавно записанные блоки, так и наиболее используемые, поэтому ваш том ZFS вполне может пытаться предоставить вам приличный кеш данных с ограниченным пространством, которое у него есть. Попробуйте увеличить zfs_arc_max до половины вашей RAM (или даже больше) и использовать arc_shrink_shift для более агрессивного удаления данных кэша ARC.

Вот вы можете найти чтение блога из 17 частей для настройки и понимания файловых систем ZFS.

Вот вы можете найти объяснение настройки ARC shrink shift (первый абзац), которое позволит вам освободить больше RAM ARC после выселения и держать это под контролем.

Я не уверен в надежности решения XFS на zvol. Несмотря на то, что ZFS - это COW, XFS - нет. Предположим, что XFS обновляет свои метаданные, и компьютер теряет питание. ZFS прочитает последнюю хорошую копию данных благодаря функции COW, но XFS не узнает об этом изменении. Ваш том XFS может оставаться «снэпшотом» до версии до сбоя питания на половину и до версии после сбоя питания для другой (поскольку ZFS не знает, что все эти 8 МБ записи должны быть атомарными и содержать только inodes) .

[EDIT] arc_shrink_shift и другие параметры доступны как параметры модуля для ZFSonlinux. Пытаться

modinfo zfs

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

Каковы ваши настройки ZFS, особенно primarycache, logbias и sync?

Убедитесь, что primarycache = all, logbias = throughput.

sync = disabled значительно ускорит запись, но может потерять до 5 секунд последних записанных данных в случае сбоя. Учитывая описанные вами симптомы, вы также можете отключить предварительную выборку ZFS.

Я написал статью на основе моего недавнего выступления о беге MySQL на ZFS который может оказаться полезным.