Привет, Хабр! Я Станислав Габдулгазиев, архитектор департамента поддержки продаж Arenadata. В этой статье рассмотрим, как большое количество мелких файлов влияет на производительность различных систем хранения, таких как HDFS и объектные хранилища с S3 API.

Разберём, какие технологии хранения лучше всего подходят для работы с мелкими файлами в архитектурах Data Lake и Lakehouse. Сравним производительность HDFS и объектных хранилищ с S3 API. На конкретных тестах покажем, почему именно HDFS эффективнее справляется с большим количеством небольших файлов. Обсудим также случаи, когда мелкие файлы становятся не просто нежелательной ситуацией, а неизбежной необходимостью, например в подходах типа Change Data Capture (CDC).
Хранение в Lakehouse
Часто звучит мнение, что для хранения датасетов с большим количеством мелких файлов лучше всего подходят объектные хранилища с S3 API. На практике это не всегда так. Реальные тесты показывают, что системы типа HDFS и Ozone с интерфейсом OFS в таких сценариях работают эффективнее и стабильнее.
Несмотря на ограничение HDFS по количеству файлов, связанное с хранением метаданных Name Node в памяти и особенностями работы Java GC, эта граница не является абсолютно жёсткой и может варьироваться в зависимости от настроек и сценариев использования, часто достигая сотен миллионов. Важно понимать, что это, скорее, практический предел, после превышения которого начинается существенная деградация производительности. Существуют механизмы федерализации для масштабирования, и наличие большого количества маленьких файлов всегда негативно сказывается на работе системы, поэтому их количество и время жизни должны быть строго ограничены. В связи с этим возникают ключевые вопросы: какой размер считать «маленьким» файлом и насколько критично размер файлов влияет на общую производительность Lakehouse?
Неожиданные показатели нагрузочного теста
Делаем небольшой «разведочный тест», а для имитации нагрузки будем использовать стандартный тест для оценки производительности систем TPC-DS. В качестве систем хранения возьмём HDFS, MinIO и Ozone. При этом для Ozone будем применять file system optimized (FSO) бакеты и доступ к ним по двум API OFS и S3 API.
Итак, что я сделал по шагам:
1. Сгенерировал два датасета TPC-DS 100, сохранил их в orc-формате в двух базах данных, назовём их условно tpcds-100 и tpcds-100-small. Для удобства можно использовать эти базы c датасетом 100 Гб. Они отличаются только количеством файлов, в которых лежат данные. В первой все данные лежат в 167 файлах, а во второй — в 14 тысячах. Получается, что средний объём файла в первой 133,6 Мб, а во второй 2,3 Мб.
hdfs dfs -count -h /apps/hive/hdd/*
25 167 21.8 G /…/[каталог с tpcds-100].db
25 14.0 K 31.2 G /…/[каталог с tpcds-100-small].db
2. Скопируем их на MinIO и Ozone, накинем внешние таблицы. Подсчитаем статистику.
3. Для нагрузки возьмём 72 тестовых запроса, которые исполняются в Impala. Будем использовать однопоточный режим, это несколько отличается от методики TPC. Необходимо оценить деградацию при работе с файлами, отличающимися от эталонного значения в меньшую сторону. Кстати, я призываю вас не сравнивать абсолютные значения производительности HDFS, MinIO и Ozone. Во-первых, аппаратное обеспечение отличалось, хоть и немного, во-вторых, это не цель данной статьи.
Ниже в таблице коротко представлены характеристики используемого тестового стенда.
Параметр |
Значение |
Примечание |
Коэффициент масштабирования |
100 |
100 Гб |
Формат оптимизации
|
orc
|
— |
Тестируемый сервис
|
ADH.HDFS 3.3.6_arenadata1 ADH.Ozone 1.4.1_arenadata1 MINIO RELEASE.2025-02-07 ADH.Impala 4.4.0_arenadata2
|
Impala mem_limit = 24G, 12 vcore 3 узла обработки
|
Запускаем нагрузочные запросы, результаты представлены в таблице ниже.
Результаты теста
|
Среднее время выполнения, сек большие файлы / маленькие файлы |
Среднее время выполнения, сек большие файлы / маленькие файлы |
Среднее время выполнения, сек большие файлы / маленькие файлы |
Среднее время выполнения, сек большие файлы / маленькие файлы |
Деградация в % |
|||||||
Impala.HDFS |
Impala.Ozone OFS |
Impala.MinIO |
Impala.Ozone S3 |
HDFS |
.Ozone OFS |
MinIO |
Ozone S3 |
|||||
query-1 |
1,5 |
3,0 |
1,91 |
5,8 |
2,6 |
9,6 |
3,53 |
8,779 |
99% |
207% |
271% |
149% |
query-2 |
3,9 |
24,3 |
2,83 |
15,1 |
8,5 |
113,5 |
11,98 |
75,52 |
531% |
435% |
1228% |
530% |
query-3 |
4,5 |
36,8 |
2,56 |
17,3 |
6,6 |
75,4 |
10,68 |
62,11 |
715% |
578% |
1043% |
482% |
query-4 |
30,4 |
42,5 |
26,64 |
58,1 |
60,3 |
582,9 |
85,73 |
405,1 |
40% |
118% |
867% |
372% |
query-6 |
2,1 |
5,8 |
2,63 |
11,3 |
5,5 |
65,9 |
8,714 |
55,7 |
179% |
330% |
1089% |
539% |
query-7 |
0,7 |
2,5 |
0,84 |
0,6 |
0,5 |
0,6 |
0,516 |
0,574 |
247% |
−25% |
16% |
11% |
query-8 |
1,5 |
2,8 |
2,14 |
11,8 |
5,3 |
75,0 |
8,456 |
65,07 |
84% |
450% |
1307% |
670% |
query-9 |
9,0 |
39,7 |
9,08 |
55,9 |
60,7 |
1137,0 |
84,71 |
731,6 |
339% |
515% |
1772% |
764% |
query-11 |
13,9 |
20,8 |
12,19 |
32,6 |
21,6 |
255,8 |
30,85 |
190,9 |
49% |
168% |
1082% |
519% |
query-13 |
2,4 |
3,1 |
2,54 |
0,7 |
0,7 |
0,8 |
2,314 |
0,7 |
30% |
−71% |
11% |
−70% |
query-15 |
1,6 |
4,2 |
1,80 |
8,0 |
4,0 |
51,5 |
5,004 |
41,05 |
161% |
341% |
1181% |
720% |
query-17 |
4,1 |
10,4 |
4,49 |
23,8 |
12,9 |
168,9 |
18,82 |
135,4 |
154% |
431% |
1209% |
619% |
query-18 |
1,1 |
3,7 |
1,07 |
0,9 |
1,2 |
1,4 |
1,121 |
1,049 |
235% |
-18% |
18% |
−6% |
query-19 |
2,5 |
6,3 |
2,99 |
14,3 |
8,6 |
109,3 |
13,93 |
87,41 |
149% |
378% |
1174% |
528% |
query-22 |
24,6 |
25,3 |
23,53 |
23,7 |
24,6 |
24,4 |
25,49 |
24,74 |
2% |
1% |
−1% |
−3% |
query-25 |
3,9 |
9,6 |
5,03 |
23,6 |
15,0 |
163,5 |
23,34 |
138,2 |
144% |
369% |
993% |
492% |
query-26 |
0,7 |
2,5 |
0,52 |
0,5 |
0,5 |
0,6 |
0,513 |
0,553 |
252% |
−4% |
18% |
8% |
query-27 |
0,8 |
2,8 |
0,87 |
0,5 |
0,6 |
0,6 |
0,808 |
0,559 |
241% |
−41% |
0% |
−31% |
query-28 |
9,1 |
24,6 |
8,65 |
44,8 |
56,1 |
893,4 |
83,02 |
588,9 |
170% |
418% |
1493% |
609% |
query-29 |
3,5 |
9,5 |
4,29 |
21,8 |
12,2 |
164,2 |
19,37 |
132,9 |
175% |
408% |
1248% |
586% |
query-30 |
1,1 |
1,4 |
1,23 |
1,5 |
1,7 |
7,1 |
2,29 |
5,242 |
31% |
20% |
317% |
129% |
query-31 |
5,8 |
11,3 |
5,72 |
22,3 |
20,5 |
295,6 |
30,26 |
204,1 |
96% |
289% |
1342% |
575% |
query-33 |
1,8 |
3,8 |
1,83 |
10,3 |
7,0 |
84,7 |
10,79 |
62,65 |
114% |
462% |
1107% |
480% |
query-34 |
0,7 |
2,7 |
0,80 |
0,4 |
0,5 |
0,5 |
0,717 |
0,505 |
279% |
−48% |
18% |
−30% |
query-38 |
4,0 |
11,1 |
4,02 |
16,7 |
5,3 |
98,3 |
6,218 |
76,55 |
175% |
315% |
1746% |
1131% |
query-41 |
0,6 |
1,4 |
0,63 |
0,6 |
0,4 |
0,6 |
0,716 |
0,595 |
137% |
−8% |
24% |
−17% |
query-42 |
1,7 |
3,9 |
2,33 |
10,6 |
7,2 |
75,2 |
11,96 |
61,44 |
130% |
357% |
948% |
414% |
query-43 |
2,9 |
5,2 |
3,33 |
12,1 |
4,9 |
81,9 |
7,623 |
65,72 |
79% |
265% |
1578% |
762% |
query-44 |
3,8 |
10,8 |
3,60 |
25,1 |
27,2 |
428,6 |
41,14 |
289,9 |
181% |
598% |
1476% |
605% |
query-45 |
1,5 |
4,4 |
1,66 |
5,3 |
3,3 |
30,8 |
4,412 |
24,61 |
185% |
217% |
841% |
458% |
query-46 |
3,5 |
8,9 |
4,07 |
18,7 |
10,7 |
162,1 |
14,22 |
125,6 |
154% |
359% |
1417% |
783% |
query-47 |
15,2 |
21,1 |
13,29 |
25,1 |
23,1 |
247,3 |
33,63 |
169,1 |
39% |
89% |
973% |
403% |
query-48 |
1,5 |
2,7 |
1,61 |
0,6 |
0,6 |
0,6 |
1,538 |
0,571 |
81% |
−61% |
9% |
−63% |
query-49 |
4,1 |
11,9 |
4,42 |
30,6 |
26,7 |
356,6 |
40,07 |
266,8 |
187% |
592% |
1233% |
566% |
query-50 |
2,5 |
6,6 |
3,21 |
15,0 |
7,5 |
99,5 |
11,16 |
83,14 |
171% |
366% |
1233% |
645% |
query-51 |
9,2 |
11,5 |
9,57 |
21,9 |
15,0 |
151,1 |
20,99 |
116,5 |
25% |
129% |
904% |
455% |
query-52 |
1,7 |
3,9 |
1,85 |
10,8 |
7,0 |
72,9 |
11,97 |
61,95 |
125% |
485% |
946% |
418% |
query-53 |
0,9 |
0,8 |
0,93 |
0,3 |
0,2 |
0,3 |
1,003 |
0,26 |
−8% |
−64% |
38% |
−74% |
query-54 |
0,8 |
1,2 |
0,77 |
0,4 |
0,4 |
0,6 |
0,867 |
0,433 |
48% |
−43% |
24% |
−50% |
query-55 |
1,7 |
4,0 |
2,21 |
10,6 |
7,0 |
72,5 |
11,91 |
61,2 |
141% |
378% |
928% |
414% |
query-56 |
2,3 |
4,5 |
2,65 |
14,0 |
10,3 |
117,3 |
16,4 |
91,43 |
94% |
426% |
1039% |
458% |
query-57 |
7,7 |
12,3 |
7,82 |
14,3 |
14,2 |
148,3 |
18,68 |
99,72 |
60% |
82% |
947% |
434% |
query-58 |
4,9 |
7,9 |
5,42 |
16,1 |
13,1 |
133,3 |
21,04 |
99,61 |
61% |
196% |
921% |
373% |
query-59 |
3,0 |
6,1 |
3,10 |
14,1 |
8,9 |
148,4 |
12,89 |
103,9 |
102% |
354% |
1563% |
707% |
query-60 |
2,3 |
4,4 |
2,52 |
14,1 |
10,4 |
116,5 |
16,34 |
91,55 |
97% |
460% |
1023% |
460% |
query-61 |
1,7 |
6,0 |
1,59 |
1,2 |
1,3 |
1,5 |
2,06 |
1,325 |
259% |
−26% |
10% |
−36% |
query-62 |
2,7 |
4,5 |
2,78 |
5,5 |
3,3 |
34,8 |
4,247 |
26,83 |
69% |
97% |
950% |
532% |
query-63 |
0,9 |
0,6 |
0,94 |
0,2 |
0,4 |
0,3 |
0,907 |
0,261 |
−32% |
−74% |
−21% |
−71% |
query-64 |
8,7 |
12,1 |
8,05 |
14,0 |
14,5 |
91,7 |
19,62 |
69,9 |
39% |
74% |
531% |
256% |
query-65 |
7,3 |
12,8 |
7,07 |
18,9 |
16,2 |
168,0 |
24,35 |
121,4 |
74% |
167% |
939% |
399% |
query-66 |
1,4 |
4,9 |
1,49 |
0,9 |
0,9 |
1,0 |
1,324 |
0,855 |
262% |
−41% |
11% |
−35% |
query-67 |
106,6 |
106,5 |
##### |
106,7 |
106,7 |
185,1 |
104,5 |
156,6 |
0% |
6% |
73% |
50% |
query-68 |
4,3 |
9,8 |
5,03 |
20,7 |
15,4 |
184,8 |
21,59 |
142,4 |
125% |
312% |
1101% |
560% |
query-69 |
2,2 |
7,3 |
2,33 |
12,7 |
5,5 |
100,2 |
6,095 |
75,19 |
226% |
444% |
1730% |
1134% |
query-71 |
1,0 |
4,0 |
0,92 |
0,7 |
1,0 |
0,8 |
0,975 |
0,716 |
283% |
−19% |
−18% |
−27% |
query-73 |
0,9 |
2,6 |
0,62 |
0,5 |
0,5 |
0,6 |
0,598 |
0,563 |
188% |
−27% |
19% |
−6% |
query-74 |
11,1 |
50,2 |
7,97 |
24,7 |
15,1 |
198,5 |
21,45 |
144,5 |
352% |
210% |
1211% |
574% |
query-75 |
3,1 |
4,5 |
2,88 |
3,6 |
6,2 |
21,2 |
6,167 |
15,77 |
45% |
24% |
244% |
156% |
query-76 |
10,6 |
41,2 |
4,00 |
22,2 |
19,4 |
261,5 |
27,77 |
185,5 |
287% |
456% |
1250% |
568% |
query-78 |
20,1 |
29,7 |
20,32 |
39,4 |
36,2 |
285,6 |
52,36 |
209,1 |
48% |
94% |
689% |
299% |
query-79 |
3,2 |
7,9 |
3,63 |
18,3 |
9,6 |
155,7 |
14,94 |
122,9 |
147% |
405% |
1528% |
723% |
query-81 |
1,5 |
1,8 |
1,42 |
1,9 |
2,2 |
10,9 |
3,072 |
8,706 |
17% |
33% |
401% |
183% |
query-83 |
1,7 |
1,9 |
1,40 |
2,3 |
2,5 |
12,0 |
2,873 |
8,904 |
11% |
65% |
380% |
210% |
query-84 |
0,9 |
3,2 |
0,80 |
1,1 |
1,3 |
6,3 |
1,716 |
3,323 |
273% |
33% |
406% |
94% |
query-85 |
2,3 |
5,2 |
1,89 |
5,9 |
4,5 |
40,8 |
7,601 |
32,74 |
126% |
214% |
800% |
331% |
query-88 |
9,7 |
31,4 |
9,20 |
34,1 |
24,1 |
546,6 |
27,42 |
346,9 |
223% |
270% |
2171% |
1165% |
query-89 |
1,0 |
0,9 |
0,95 |
0,4 |
0,2 |
0,3 |
0,979 |
0,287 |
−6% |
−60% |
36% |
−71% |
query-91 |
0,8 |
3,3 |
0,75 |
0,7 |
0,5 |
0,6 |
0,714 |
0,592 |
330% |
−1% |
10% |
−17% |
query-93 |
2,4 |
9,5 |
2,56 |
12,8 |
9,5 |
101,0 |
12,9 |
80,75 |
293% |
402% |
967% |
526% |
query-96 |
1,5 |
4,4 |
1,56 |
10,6 |
3,2 |
75,2 |
3,895 |
62,51 |
181% |
575% |
2241% |
1505% |
query-97 |
4,7 |
6,7 |
4,25 |
13,8 |
8,6 |
97,8 |
12,75 |
77,43 |
43% |
226% |
1041% |
507% |
query-99 |
6,5 |
5,6 |
6,09 |
9,6 |
5,2 |
65,9 |
7,121 |
48,67 |
−14% |
58% |
1163% |
583% |
Среднее |
|
|
|
|
|
|
|
|
148% |
210% |
812% |
389% |
Результат с MinIO удивил: мы ожидали падения производительности на мелких файлах, но не такого сильного. Для MinIO решили попробовать рекомендованный в различных статьях тюнинг, например, но не помогло.
Ozone и HDFS в тестах стабильно показывали хорошие результаты с минимальными отклонениями. Дополнительно аналогичные тесты провели в Trino. Результаты подтвердили тот же тренд: при работе с мелкими файлами производительность падает значительно.
Какой можно сделать из этого вывод? Похоже, что HDFS гораздо лучше справляется с обработкой маленьких файлов. Кроме того, Apache Ozone с OFS также показал лучшее значение, чем MinIO, что согласовывается с исследованием компании Cloudera.
Давайте отойдём от экспериментов и дадим этим наблюдениям теоретическое обоснование. Исследований на эту тему довольно много, но я приведу два, которые более релевантны и интересны, на мой взгляд.
Теоретические подтверждения неожиданных показателей
Результаты тестов заставили обратиться к существующим исследованиям и экспертам, чтобы разобраться в причинах. Главная причина разницы производительности — фундаментальные архитектурные различия между HDFS и S3.
HDFS оптимизирована для работы именно с большим количеством файлов, что обеспечивается централизованным управлением метаданными и пакетной обработкой операций. В свою очередь, объектные хранилища с S3 API изначально предназначены для объектного хранения и плохо подходят для аналитических сценариев с частым доступом к большому числу мелких файлов. Их основные проблемы — высокие накладные расходы на метаданные и значительные задержки при работе через HTTP-протокол.
Ожидаемо! Основная причина такой деградации производительности связана с эффектом «малых файлов» и накладными расходами на метаданные и сетевые запросы, особенно в объектных хранилищах.

Рассмотрим сравнение производительности операций с метаданными файловых систем HDFS, S3 и JuiceFS, таких как создание, открытие, переименование и удаление. Исследования показали кратное преимущество HDFS — от 10 до 20 раз в зависимости от параллельности нагрузки перед S3, а также значительно меньшую задержку. На графике выше показана задержка выполнения каждой операции при 20 одновременных операциях (не при полной нагрузке), и вы можете видеть, что S3 работает очень медленно.
Кроме этого, в статье сделаны выводы что HDFS в отличие от S3, который начинает проседать, показывает линейный рост производительности при увеличении числа параллельных операций. Пропускная способность (количество операций в секунду при высокой нагрузке) у S3 в 10–100 раз ниже, чем у HDFS. S3 требует больше ресурсов для достижения производительности, сопоставимой с HDFS. Если важна производительность операций с метаданными (например, при большом числе мелких файлов), HDFS будет намного предпочтительнее.
Сравним два решения: HBase и Phoenix, операционная база данных Cloudera (COD) с использованием в качестве слоя хранения двух вариантов HDFS или облачного хранилища. И облачное хранилище на графиках выглядит очень привлекательно по производительности. Для поддержки S3 используется высокопроизводительный кэш, а когда S3 используется без кэша, то производительность в разы меньше. Такие статьи нам не подходят, по ним невозможно оценить производительность самого объектного хранилища. Зачем тогда это всё? Продвижение технологии S3 очень выгодно определённому количеству производителей ПО, и часто они расставляют акценты так, что у невнимательного читателя происходит подмена понятий, как, например, здесь, когда производительность системы кэш и S3 выдают за производительность S3.
В исследовании представлена методология и набор инструментов для анализа производительности S3 API, а также возможности использования Minio для задач High Performance Computing (HPC). В нём выявлены интересные для нашего материала закономерности. Обработка мелких файлов через S3 API приводит к значительным потерям производительности из-за высоких накладных расходов на протокол HTTP и метаданные. Крупные файлы (от 1 МБ и выше) обрабатываются заметно быстрее, чем мелкие. Это подтверждается как в тестах MinIO, так и при анализе облачных решений. Для файлов размером 32 МБ и более производительность близка к теоретической пропускной способности сети, особенно в оптимизированных сценариях (S3Embedded).
Маленькие файлы (до 64 КБ) демонстрируют значительное падение производительности, особенно при работе через REST API и в стандартных S3-совместимых системах.


Как видно из приведённых изображений, полученные в статье результаты полностью согласуются с теми, что мы наблюдали в экспериментах. Напомню, получена хорошая производительность при размере файлов более 13 Мб и сильная деградация производительности при значении близком к 1 Мб.
Однако здесь также заметна явная зависимость между такими показателями, как Throughput (пропускная способность) и Ops/s (операций в секунду). Вопрос, который появляется, когда мы видим эту зависимость: «А как ведёт себя S3, если идёт речь не о большом количестве маленьких файлов, а о большом количестве файлов в датасете?»
Провести этот эксперимент достаточно дорого и существенно сложнее. Возможно, если будет интерес к теме и необходимость, сделаем более глубокое исследование. Могу только дать спойлер: статистически значимая зависимость имеется.
Требующий особого внимания побочный эффект большого количества файлов в датасете — это стоимость операций PUT, HEAD, LIST, POST и особенно GET. За небольшое время в течение суток и не слишком большое количество запросов счёт за эти операции превысил счёт за хранение в три раза.

Маленькие файлы в современных архитектурах загрузки и повседневной жизни производственного озера данных
Многие хорошо настроенные производственные системы стремятся избегать большого количества мелких файлов, но полностью устранить эту проблему невозможно. На практике можно выделить три типичных ситуации.
Первая — неизбежная действительность больших систем. Исследование B. Уэлча и Г. Ноера показало, что в реальных установках от 25% до 90% файлов имеют размер 64 КБ или меньше. При этом они занимают незначительный объём (обычно до 3%, иногда до 15%), но создают существенную нагрузку на файловую систему. Схожие результаты получили также исследователи Королевского технологического института вместе с Oracle и Spotify: около четверти файлов в производственных средах HDFS занимают менее 16 КБ, а на них приходится до 42% всех файловых операций.
Вторая ситуация связана с параллельной обработкой данных (MPP и MapReduce). Чем выше параллельность записи, тем больше одновременно создаваемых файлов, в том числе очень мелких.
Третий случай — это потоковая обработка данных, в частности архитектура Change Data Capture (CDC), и открытые табличные форматы вроде Iceberg или Hudi. Рассмотрим его детальнее.
Маленькие файлы в CDC-архитектуре
На изображении ниже схематически представлен процесс непрерывной обработки и загрузки в Iceberg-таблицу CDC-логов PostgreSQL в Debezium-формате. Она происходит с использованием микробатчей Spark Structuring Streaming с триггером срабатывания 50 сек. Для формирования таблицы в формате Iceberg на приёмнике используется механизм отслеживания изменений SCD1 (Slowly Changing Dimensions).

На приёмнике существует точная, самая актуальная копия таблицы, к которой задействуется затирание. Данные в таблице полностью заменяются на новые (самые актуальные). Для «накатки» актуальных данных я использовал SQL-выражение MERGE INTO
.
Эта модель загрузки предполагает существование сотен и тысяч файлов в определённый момент времени до того, как вы будете осуществлять операции обслуживания, например следующие: rewrite_data_files
, rewrite_manifests
. Эти операции не бесплатные, они потребляют ресурсы. Ниже на изображении показан пример операции обслуживания файловой системы — оптимизация, когда из множества промежуточных файлов данных и метаданных создаётся один большой файл данных (merge) и несколько оптимизированных файлов метаданных.
Далее «устаревшие» файлы со временем нужно удалить.

Рассмотрим результаты дополнительного теста, в котором замерили время выполнения операций «MERGE INTO
» и «rewrite_data_files
».
Сначала проверили, как зависит время выполнения SQL-команды «MERGE INTO» от количества файлов. Время росло линейно, но по-разному: на HDFS зависимость была слабой, а объектное хранилище MinIO демонстрировало гораздо более заметное увеличение времени обработки.

Целью теста было сравнить динамику изменения производительности MinIO и HDFS при равных начальных условиях и аналогичных ресурсах. В начале эксперимента скорость операции MERGE INTO
была сопоставима: 6 секунд у HDFS и 8,5 секунд у MinIO. Но с ростом количества файлов MinIO сильно замедлился — в 9,3 раза, а HDFS всего в 3,2 раза. Из-за этого MinIO перестал укладываться в заданное окно триггера в 50 секунд, которое пришлось увеличить до 90 секунд.
Операция «rewrite_data_files
» также показала похожую картину:
HDFS: 17 секунд при 3 тысячах файлов и 29 секунд при 9 тысячах (замедление в 1,7 раза).
MinIO: 81 секунда при 3 тысячах файлов и 162 секунды при 9 тысячах (замедление в 2 раза).
Абсолютные значения также важны: MinIO изначально был намного медленнее, и разница только увеличивалась по мере роста нагрузки.
Что делать?
Отказываться от объектных хранилищ с протоколом S3 не нужно. Такие системы отлично работают, когда речь идёт о точечной выборке небольшого числа объектов по ключу. Но в аналитических сценариях или задачах High Performance Computing, где происходит активная работа с большим числом мелких файлов, у S3 возникают существенные ограничения.
Если вы рассматриваете миграцию с HDFS на S3, обязательно проведите предварительный анализ распределения файлов по размерам. Если в вашей системе много файлов менее 10 Мб, миграция может привести к существенному падению производительности и росту стоимости. Именно поэтому крупные компании («экзабайтный клуб») не торопятся переходить на объектные хранилища полностью.
Для обеспечения стабильной работы Lakehouse нужно непрерывно контролировать состояние хранилища. Такой подход требует значительных ресурсов и опыта. Поэтому в некоторых случаях логичнее остаться на HDFS, используя механизмы агрегации файлов, например Hadoop Archive (HAR). HAR позволяет хранить и обрабатывать множество мелких файлов как единый архив без потерь в производительности. Кстати, для продвижения этой технологии руку приложил и наш разработчик Тигран (pull).
Кроме того, кажется вполне оправданным в некоторых случаях гибридный подход, где вы имеете «под ногами» как HDFS, так и объектное хранилище, например Ozone. В ADH это возможно!
Ну и наконец, решения класса «классическое MPP хранилище данных с проприетарным и жёстко связанным слоем хранения», например Greenplum, не имеют, очевидно, подобных проблем.
Список литературы
1. https://juicefs.com/en/blog/engineering/metadata-performance-comparisonhdfs-vs-s3-vs-juicefs.
3. https://www.mdpi.com/2076-3417/11/18/8540.
4. https://ru.wikipedia.org/wiki/Медленно_меняющееся_измерение.
5. https://iceberg.apache.org/docs/nightly/spark-procedures.
6. Welch, B.; Noer, G. Optimizing a hybrid SSD/HDD HPC storage system based on file size distributions. In Proceedings of the 2013 IEEE 29th Symposium on Mass Storage Systems and Technologies (MSST), Long Beach, CA, USA, 6–10 May 2013; pp. 1–12. [Google Scholar].
8. https://hadoop.apache.org/docs/r1.2.1/hadoop_archives.html.
9. https://issues.apache.org/jira/browse/SPARK-39910.
10. https://github.com/apache/spark/pull/43463.
11. https://ozone.apache.org/assets/04_Chuang_Performance_of_Apache.pdf.
13. https://github.com/hortonworks/hive-testbench.
14. https://ozone.apache.org/docs/edge/feature/prefixfso.html.
15. https://ozone.apache.org/docs/edge/interface/ofs.html.
16. https://min.io/resources/docs/MinIO-Throughput-Benchmarks-on-HDD-24-Node.pdf.
hard_sign
Вообще-то S3 — это всего лишь протокол. И ваше исследование говорит не о недостатках протокола как такового, а об отсутствии нормальных on-premise платформ, реализующих этот протокол.
StanislavRG Автор
Вы правы, S3 — это именно протокол, и напрямую он не ограничивает производительность. В статье речь не о самом протоколе, а о том, как его текущие on-premise реализации (в частности, MinIO) ведут себя в сценариях с большим количеством мелких файлов — и именно в этих реализациях возникают серьёзные узкие места.
При этом даже в облачных сервисах (AWS S3 и др.) при активной работе с мелкими файлами остаются фундаментальные ограничения из-за особенностей API (работа по HTTP, операции с метаданными и т. п.). Поэтому вопрос не только в реализации, но и в архитектурной природе подхода.
poige
Добавлю ещё, что брать Minio для чего-либо, кроме пресловутого SOHO в 2025 — ну так себе идейка. Можно было и не тестировать ничего, с оной давно всё понятно.