Data.table: Превышен размер SHM Ошибка

Созданный на 14 июл. 2017  ·  3Комментарии  ·  Источник: Rdatatable/data.table

Запрос функции, проверьте размер /dev/shm, чтобы убедиться, что он соответствует размеру mmap. В моем случае я использовал R внутри док-контейнера, а размер по умолчанию для /dev/shm — 64M. Когда код выполняет mmap для конвейерного потока (например, с помощью hadoop fs -cat /myfile.csv), он будет считывать только байты размера shm из канала в mmap. Он не сообщает об ошибке через C API, что, как я подозреваю, нормально. Однако отладка, почему fread жаловалась на формат файла, привела к глубокому погружению в код R и C data.table, чтобы обнаружить, что он использует этот механизм. Сообщение об ошибке (случайное сообщение, основанное на том, где моя труба была отрезана):

 (ERROR):Expected sep (',') but ' ' ends field 0 when detecting types from point 10: 14183667

Это можно воспроизвести, выполнив следующие действия:

  • Создайте файл размером ~ 5 мегабайт, чем /dev/shm
  • Настройте /dev/shm на что-то вроде 64M (это значение по умолчанию для контейнера Docker).
  • Запустите fread на "cat ~/myfile.csv" <-- cat создает канал
  • Докер версии 1.12+
  • Последний образ Centos из докер-хаба
  • R-open v3.4.0 (Майкрософт)

В коде: https://github.com/Rdatatable/data.table/blob/master/src/fread.c
Около строки 788, возможно, следует проверить размер /dev/shm, чтобы убедиться, что он соответствует файлу, который он только что прочитал в память. В моем случае в докере вот подробный вывод условия неудачного теста:

 > dat.df3<-fread("/opt/cloudera/parcels/CDH/bin/hadoop fs -cat /user/tcederquist/tim_pop_comm_14_5 | head -3668850" ,sep=",", header=TRUE, verbose=TRUE)
 Input contains no \n. Taking this to be a filename to open
 File opened, filesize is 0.062500 GB.
 Memory mapping ... ok
 ....basic output
 Type codes (point  8): 1111
 Type codes (point  9): 1111
 (ERROR):Expected sep (',') but ' ' ends field 0 when detecting types from point 10: 14183667

Ожидаемые результаты:

 File opened, filesize is 0.373524 GB.

Кроме того, в случае сбоя он внутренне знает строку # и другую полезную информацию о сбое. Мне пришлось обнулить значение вручную, прежде чем я обнаружил подробный флаг. Было бы неплохо, если бы обычные сообщения об ошибках указывали строку #. vebose=T показывает местоположение, когда вычисляет количество разделителей, например, для этого тестового примера было бы полезным вывод при ошибке (так как я знал, что в файле 20M записей):

 Count of eol: 3668839 (including 0 at the end)
 nrow = MIN( nsep [11006514] / (ncol [4] -1), neol [3668839] - endblanks [0] ) = 3668838

Самый полезный комментарий

Ребята, это я сообщил о zUMIS/19 . Я пробовал ваш dev 1.10.5, и он отлично работает. Отличная работа, ребята!

Все 3 Комментарий

Для тех, кто обнаружит эту же проблему, краткосрочное решение состоит в том, чтобы увеличить размер общей памяти контейнера или в вашей ОС, если ваш /dev/shm слишком мал. Типичные современные ОС используют 50% доступной памяти. В моем экземпляре 64G amazon ec2 я установил контейнер докеров для использования:

 docker run --shm-size="30g" ... other stuff ...

Согласованный. Извини за это.
Недавнее изменение в dev из новостей:

RAM-диск (/dev/shm) больше не используется для вывода ввода системных команд. Хотя он работал быстрее, он вызывал слишком много ошибок переполнения устройства; например, #1139 и zUMIs/19. Спасибо Кайлу Чангу за репортаж. Теперь используется стандартный tempdir(). Если вы хотите использовать оперативный диск, установите TEMPDIR в /dev/shm; см. ?tempdir.

Пожалуйста, попробуйте dev 1.10.5 и откройте новую проблему, если это все еще проблема.

Ребята, это я сообщил о zUMIS/19 . Я пробовал ваш dev 1.10.5, и он отлично работает. Отличная работа, ребята!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги