Apache Hudi — это платформа озера данных потоковой передачи, которая переносит основные функции хранилища и базы данных непосредственно в озеро данных. Не желая называть себя открытым форматом файлов, таким как Delta или Apache Iceberg, Hudi предоставляет таблицы, транзакции, обновление/удаление, расширенную индексацию, услуги потоковой обработки, оптимизацию кластеризации/сжатия данных и параллелизм. Запущенный в 2016 году, Hudi прочно укоренился в экосистеме Hadoop, что объясняет смысл названия: Hadoop Upserts, удаления и инкременты. Он был разработан для управления хранением больших наборов аналитических данных в HDFS. Основная цель Hudi — уменьшить задержку при приеме потоковых данных.
Со временем Худи эволюционировала, чтобы использовать облачное хранилище[1] и объектное хранилище, в том числе MinIO。Hudi от HDFS Трансформация идет рука об руку с общей мировой тенденцией, трансформируя традиционные HDFS Оставьте все позади ради высокопроизводительного, масштабируемого и облачного объектного хранилища. Худи Обязательство обеспечить оптимизацию, чтобы Apache Spark、Flink、Presto、Trino и другие аналитические рабочие нагрузки быстрее, что соответствует MinIO Обещание производительности облачных приложений в любом масштабе вполне оправдано. используется в производстве Hudi компаний включают Uber[2], Amazon[3], ByteDance[4] и Робинхуд[5]. Это одни из крупнейших озер потоковых данных в мире [6]. Худи В этом случае использованияв Ключ Вэто обеспечиваетПриращениестек обработки данных,Обеспечивает обработку данных столбца с малой задержкой.。Нормальная системаиспользовать Apache Parquet или ORC Ожидание открытия Формат файл Запишите данные один раз и сохраните их в хорошо масштабируемой памяти. объекты распределенной файловой системы. Худи Служит плоскостью данных для приема,преобразования и управления этими данными. Худи использовать Hadoop FileSystem API[7] Для взаимодействия с хранилищем API иот HDFS Совместимость (но не обязательно оптимальная) с различными реализациями объектных хранилищ в файловых системах в памяти.
Hudi Использовать базовый файл и Применить файл журнала для хранения обновлений/изменений данного базового файла. Основной файл может быть Паркет (Список) или HFile (индекс), инкрементный журнал сохраняется как Avro (строка), потому что имеет смысл регистрировать изменения в базовом файле по мере их возникновения. Худи Закодируйте все изменения в данном базовом файле как последовательность фрагментов. Блоки могут быть блоками данных, блоками удаления или блоками отката. Эти блоки объединяются для получения обновленного базового файла. Эта кодировка также создает отдельный журнал.
Формат таблицы состоит из макета файла таблицы, схемы таблицы и метаданных, которые отслеживают изменения в таблице. Худи Обеспечьте принудительное написание схемы с упором на потоковую обработку, чтобы гарантировать, что конвейеры не будут нарушены изменениями, не имеющими обратной совместимости. Худи Группируйте файлы вместе для данной таблицы/раздела и сопоставляйте ключи записей и группы файлов. Как упоминалось выше, все обновления записываются в файлы дельта-логов для определенной файловой группы. Этот дизайн более Hive ACID Более эффективный вариант заключается в том, что последний должен объединить все записи данных со всеми базовыми файлами для обработки запросов. Худи Ожидается, что конструкция будет основана на ВБыстрое обновление вставки ключаиудалить,Потому что он использует файловую группу Приращение журнала,а не весь набор данных.
Временная шкала имеет решающее значение для понимания Худи, как и всего остального. Hudi Источник реальных журналов событий для метаданных таблицы. Временная шкала хранится в .hoodie
Папка, в нашем случае ведро. События будут оставаться на временной шкале до тех пор, пока они не будут удалены. Временная шкала существует для всей таблицы и файловой группы, и файловую группу можно восстановить, применив дельта-журналы к исходным базовым файлам. Чтобы оптимизировать частые операции записи/фиксации, Hudi Благодаря такой конструкции метаданные остаются небольшими по сравнению с размером всей таблицы. Новые события на временной шкале сохраняются во внутренних таблицах метаданных и реализуются как серия таблиц, объединяемых при чтении, что обеспечивает низкое усиление записи. Поэтому Худи Быстрые изменения в метаданных можно быстро адаптировать. Также использовать таблицу метаданных HFile Базовый формат файла, который дополнительно оптимизирует производительность за счет поиска набора индексных ключей, чтобы избежать чтения всей таблицы метаданных. Все физические пути к файлам, являющиеся частью таблицы, включаются в метаданные, чтобы избежать дорогостоящих и трудоемких списков файлов в облаке.
Hudi Схема записи имеет ACID Высокопроизводительный уровень записи, поддерживаемый транзакциями, который обеспечивает очень быстрые дополнительные изменения, такие как обновления и удаления. типичный Hudi Зависимости архитектуры Spark или Flink Канал передает данные в Hudi поверхность. Худи Путь записи оптимизирован так, чтобы быть лучше, чем простое размещение Parquet или Avro Файлы записываются на диск более эффективно. Худи Проанализируйте операции записи и классифицируйте их как инкрементные операции (вставка, upsert, удалить) и пакетную операцию (insert_overwrite, insert_overwrite_table, delete_partition, Bulk_insert), а затем применить необходимые оптимизации [8]. Худи Авторы также несут ответственность за поддержание метаданных. Для каждой записи записывается время отправки и порядковый номер, уникальный для этой записи (это аналогично Kafka смещение), и можно получить изменения на уровне записи. Пользователи также могут указывать поля времени события во входящем потоке данных и использовать метаданные. Hudi Временная шкала отслеживает их. Это может значительно улучшить обработку потока, поскольку Hudi Содержит время прибытия и время события каждой записи, что позволяет создавать мощные водяные знаки для сложных конвейеров обработки потоков [9].
Моментальная изоляция между писателями и читателями позволяет от всех основных озер механизм запросов данных (включает Spark、Hive、Flink、Prest、Trino и Последовательно запрашивайте снимки таблиц в Impala. и Parquet и Avro То же, Худи Стол может быть Snowflake[10] и SQL Server[11] и т. д. читать как внешнюю таблицу. Худи Программа чтения очень легкая, по возможности используйте векторизованную программу чтения для конкретного В-движка и кеша, например. Presto и Искра. когда Hudi Когда для запросов необходимо объединить базовые файлы и файлы журналов, Hudi Такие механизмы, как использование переполняемого сопоставления и отложенное чтение, повышают производительность слияния, а также обеспечивают запросы оптимизации чтения. Худи Содержит множество очень мощных инкрементных Функциональность запроса, в основе которой лежат метаданные, позволяет разбивать большие коммиты на более мелкие фрагменты и полностью отделяет запись данных в инкрементном режиме. запрос. Путешествие во времени очень легко реализовать с помощью метаданных validuse, которые являются еще одним инкрементом с определенной начальной и конечной точкой. запрос。Hudi Атомарно сопоставляйте ключи с одной группой файлов в любой момент времени, поддерживая Hudi Полное на столе CDC Функция. как указано выше Hudi Как обсуждалось в разделе «Писатели», каждая таблица состоит из файловых групп, каждая из которых имеет свои автономные метаданные.
Hudi Самым большим преимуществом является скорость, с которой он может принимать потоковые и пакетные данные. предоставлено upsert Особенности, Худи Скорость выполнения задачи на порядки быстрее, чем перезапись всей таблицы или раздела. чтобы воспользоваться Hudi Скорость приема, библиотеке озера данных требуется высокая IOPS уровень хранения пропускной способности. Мин ИО Сочетание масштабируемости и высокой производительности Hudi необходимый. Мин ИО Способен обеспечить производительность, необходимую для работы озер корпоративных данных в режиме реального времени — недавний эталон [12] GET реализовано на 325 GiB/s (349 ГБ/с), в PUT реализовано на 165 GiB/s (177 GB/s) 32 готовый NVMe SSD узел. активный бизнес Hudi Озера данных хранят большое количество мелких Parquet и Avro документ. Мин ИО Включает в себя множество небольших оптимизаций файлов[13] для более быстрого озера. данные. Небольшие объекты сохраняются с метаданными, что сокращает чтение и запись небольших файлов (таких как Hudi метаданные и индекс) обязательны IOPS. Схема это каждый Hudi Ключевые компоненты таблицы. Худи Схемы можно применять принудительно или позволять им развиваться, чтобы конвейеры потоковой передачи данных могли адаптироваться без сбоев. Кроме того, Худи обеспечивать соблюдение Schema-on-Writer чтобы гарантировать, что изменения не нарушат конвейер. Худи полагаться на Avro Приходите с хранилищем, моделью стола управления и разработки. Худи Предусмотрено для озер данных ACID-гарантии транзакций。Hudi Обеспечьте атомарную запись: отправьте фиксацию на временную шкалу атомарно и с указанием временной метки, которая представляет время, когда операция считается произошедшей. Худи Изолированные писатели, таблицы и Снимки между процессами чтения, поэтому каждый процесс работает с согласованным снимком таблицы. Худи Оптимистичный контроль параллелизма между авторами (OCC) и инфраструктура между табличными службами и устройствами записи, а также между несколькими табличными службами. MVCC Неблокирующий контроль параллелизма для улучшения этой ситуации.
В этом руководстве вы узнаете, как настроить Spark、Hudi и MinIO и познакомимся с некоторыми базовыми Hudi Функция. Это руководство основано на Apache Hudi Spark Рекомендации [14] для облачных технологий MinIO хранилище объекты. Обратите внимание, что использование версии ведро увеличится. Hudi некоторые расходы на техническое обслуживание. Любой удаленный объект создает метку удаления [15]. вместе с Hudi использовать Cleaner Утилиты [16] очищают файлы, и количество пометок об удалении со временем увеличивается. Важно правильно настроить управление жизненным циклом [17] для очистки этих маркеров удаления, поскольку если количество маркеров удаления достигнет 1000 , Список Операция может заблокироваться. Худи Специалисты по сопровождению проекта рекомендуют, чтобы правило жизненного цикла использования удаляло пометки удаления через один день.
/opt/spark/jars
。использовать MinIO Client Создать хранилище Hudi Сегмент данных:
mc alias set myminio http://<your-MinIO-IP:port> <your-MinIO-access-key> <your-MinIO-secret-key>
mc mb myminio/hudi
использоватьнастроен какиспользовать MinIO хранится Hudi запускать Spark оболочка. Обязательно используйте свой MinIO установлен на S3A Записи конфигурации.
spark-shell \
--packages org.apache.hudi:hudi-spark3.3-bundle_2.12:0.12.0,org.apache.hadoop:hadoop-aws:3.3.4 \
--conf 'spark.serializer=org.apache.spark.serializer.KryoSerializer' \
--conf 'spark.sql.catalog.spark_catalog=org.apache.spark.sql.hudi.catalog.HoodieCatalog' \
--conf 'spark.sql.extensions=org.apache.spark.sql.hudi.HoodieSparkSessionExtension' \
--conf 'spark.hadoop.fs.s3a.access.key=<your-MinIO-access-key>' \
--conf 'spark.hadoop.fs.s3a.secret.key=<your-MinIO-secret-key>'\
--conf 'spark.hadoop.fs.s3a.endpoint=<your-MinIO-IP>:9000' \
--conf 'spark.hadoop.fs.s3a.path.style.access=true' \
--conf 'fs.s3a.signing-algorithm=S3SignerType'
Затем инициализируйте Hudi в Spark.
import org.apache.hudi.QuickstartUtils._
import scala.collection.JavaConversions._
import org.apache.spark.sql.SaveMode._
import org.apache.hudi.DataSourceReadOptions._
import org.apache.hudi.DataSourceWriteOptions._
import org.apache.hudi.config.HoodieWriteConfig._
import org.apache.hudi.common.model.HoodieRecord
Обратите внимание, что возможна настройка внешних файлов конфигурации [22] Упрощенная конфигурация.
Попробуйте Scala DataGenerator — это быстрый и простой способ генерировать образцы вставок и обновлений на основе образца образца штриха.
val tableName = "hudi_trips_cow"
val basePath = "s3a://hudi/hudi_trips_cow"
val dataGen = new DataGenerator
Далее новые данные о поездке будут сгенерированы и загружены в DataFrame и добавьте тот, который мы только что создали DataFrame как Hudi запись в таблицу Мини ИО. Если таблица уже существует, то схема (перезапись) перезапишется и создаст заново. таблица. Данные о поездке зависят от ключа записи (uuid), поля раздела (регион/страна/город) и логики (ts), чтобы гарантировать уникальность записи о поездке для каждого раздела. Мы будем использовать операцию записи по умолчанию. оспорить. использовать, когда нет обновленных рабочих нагрузок insert или bulk_insert , что будет быстрее.
val inserts = convertToStringList(dataGen.generateInserts(10))
val df = spark.read.json(spark.sparkContext.parallelize(inserts, 2))
df.write.format("hudi").
options(getQuickstartWriteConfigs).
option(PRECOMBINE_FIELD_OPT_KEY, "ts").
option(RECORDKEY_FIELD_OPT_KEY, "uuid").
option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath").
option(TABLE_NAME, tableName).
mode(Overwrite).
save(basePath)
Откройте браузер ииспользоватьваш ключ доступаи Ключ находится вhttp://<your-MinIO-IP>:<port>
Авторизоваться Мини ИО. Ты увидишь в ведре Hudi поверхность.
В ведре также находится .hoodie
путь,и содержитamericas
、asia
путь к данным。
Взгляните на метаданные, это после завершения всего руководства. .hoodie
путьскриншот。мы видим, что я 2022 Год 9 луна 13 вторник 9:02、10:37、10:48、10:52 и 10:56 Модифицированная поверхность.
Давайте загрузим данные Hudi в DataFrame и выполним пример запроса.
// spark-shell
val tripsSnapshotDF = spark.
read.
format("hudi").
load(basePath)
tripsSnapshotDF.createOrReplaceTempView("hudi_trips_snapshot")
spark.sql("select fare, begin_lon, begin_lat, ts from hudi_trips_snapshot where fare > 20.0").show()
spark.sql("select _hoodie_commit_time, _hoodie_record_key, _hoodie_partition_path, rider, driver, fare from hudi_trips_snapshot").show()
мы можем пойти и посмотреть 1988 Годиз Hootie and the Blowfish концерт. каждая запись Hudi Для таблицы будет создан новый снимок. Думайте о снимке как о версии таблицы, которую можно использовать для запросов о путешествиях во времени. Попробуйте выполнить несколько запросов о путешествиях во времени (вам придется изменить временную метку, чтобы она была актуальной для вас).
spark.read.
format("hudi").
option("as.of.instant", "2022-09-13 09:02:08.200").
load(basePath)
Этот процесс аналогичен нашему предыдущему процессу вставки новых данных. для показа Hudi Обновить возможности данных, мы будем генерировать обновления существующих записей о поездках, загружая их в DataFrame , затем измени DataFrame Запись сохранена в MinIO в Hudi стол. Обратите внимание, что наше использование находится в режиме сохранения добавления. Общая рекомендация — использовать режим добавления, если вы не создаете новую таблицу, поэтому никакие записи не будут перезаписаны. использовать Hudi Типичный способ сделать это — принимать потоковые данные в режиме реального времени, добавлять их в таблицу, а затем писать некоторую логику, которая объединяет и обновляет существующие записи на основе того, что было только что добавлено. или Если таблица уже существует, используйте режим перезаписи, записывайте удаление и создайте заново. таблицу。
// spark-shell
val updates = convertToStringList(dataGen.generateUpdates(10))
val df = spark.read.json(spark.sparkContext.parallelize(updates, 2))
df.write.format("hudi").
options(getQuickstartWriteConfigs).
option(PRECOMBINE_FIELD_OPT_KEY, "ts").
option(RECORDKEY_FIELD_OPT_KEY, "uuid").
option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath").
option(TABLE_NAME, tableName).
mode(Append).
save(basePath)
В данных запроса будет отображена обновленная история поездок.
Hudi Можетиспользоватьинкрементный запрос предоставляет поток записей, измененных с заданной временной метки. Все, что нам нужно сделать, это указать время начала, в которое изменения будут передаваться в потоковом режиме, чтобы увидеть изменения после текущего коммита, и мы можем ограничить поток временем окончания. инкрементный запросверно В Hudi очень важен, поскольку позволяет строить потоковые конвейеры для пакетных данных.
// spark-shell
// reload data
spark.
read.
format("hudi").
load(basePath).
createOrReplaceTempView("hudi_trips_snapshot")
val commits = spark.sql("select distinct(_hoodie_commit_time) as commitTime from hudi_trips_snapshot order by commitTime").map(k => k.getString(0)).take(50)
val beginTime = commits(commits.length - 2) // commit time we are interested in
// incrementally query data
val tripsIncrementalDF = spark.read.format("hudi").
option(QUERY_TYPE_OPT_KEY, QUERY_TYPE_INCREMENTAL_OPT_VAL).
option(BEGIN_INSTANTTIME_OPT_KEY, beginTime).
load(basePath)
tripsIncrementalDF.createOrReplaceTempView("hudi_trips_incremental")
spark.sql("select `_hoodie_commit_time`, fare, begin_lon, begin_lat, ts from hudi_trips_incremental where fare > 20.0").show()
Hudi может запрашивать данные за определенное время и дату.
// spark-shell
val beginTime = "000" // Represents all commits > this time.
val endTime = commits(commits.length - 2) // commit time we are interested in
//incrementally query data
val tripsPointInTimeDF = spark.read.format("hudi").
option(QUERY_TYPE_OPT_KEY, QUERY_TYPE_INCREMENTAL_OPT_VAL).
option(BEGIN_INSTANTTIME_OPT_KEY, beginTime).
option(END_INSTANTTIME_OPT_KEY, endTime).
load(basePath)
tripsPointInTimeDF.createOrReplaceTempView("hudi_trips_point_in_time")
spark.sql("select `_hoodie_commit_time`, fare, begin_lon, begin_lat, ts from hudi_trips_point_in_time where fare > 20.0").show()
Hudi Поддерживает два разных способа удаления записей. Мягкое удаление сохраняет ключ записи и очищает значения всех остальных полей. Обратимое удаление остается в MinIO в и только использовать жесткое удалениеотозеро данныхсерединаудалить.
// spark-shell
spark.
read.
format("hudi").
load(basePath).
createOrReplaceTempView("hudi_trips_snapshot")
// fetch total records count
spark.sql("select uuid, partitionpath from hudi_trips_snapshot").count()
spark.sql("select uuid, partitionpath from hudi_trips_snapshot where rider is not null").count()
// fetch two records for soft deletes
val softDeleteDs = spark.sql("select * from hudi_trips_snapshot").limit(2)
// prepare the soft deletes by ensuring the appropriate fields are nullified
val nullifyColumns = softDeleteDs.schema.fields.
map(field => (field.name, field.dataType.typeName)).
filter(pair => (!HoodieRecord.HOODIE_META_COLUMNS.contains(pair._1)
&& !Array("ts", "uuid", "partitionpath").contains(pair._1)))
val softDeleteDf = nullifyColumns.
foldLeft(softDeleteDs.drop(HoodieRecord.HOODIE_META_COLUMNS: _*))(
(ds, col) => ds.withColumn(col._1, lit(null).cast(col._2)))
// simply upsert the table after setting these fields to null
softDeleteDf.write.format("hudi").
options(getQuickstartWriteConfigs).
option(OPERATION_OPT_KEY, "upsert").
option(PRECOMBINE_FIELD_OPT_KEY, "ts").
option(RECORDKEY_FIELD_OPT_KEY, "uuid").
option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath").
option(TABLE_NAME, tableName).
mode(Append).
save(basePath)
// reload data
spark.
read.
format("hudi").
load(basePath).
createOrReplaceTempView("hudi_trips_snapshot")
// This should return the same total count as before
spark.sql("select uuid, partitionpath from hudi_trips_snapshot").count()
// This should return (total - 2) count as two records are updated with nulls
spark.sql("select uuid, partitionpath from hudi_trips_snapshot where rider is not null").count()
Напротив, жесткое удаление — это то, что мы называем удалением. Ключ записи и связанные поля будут находиться в таблице «от».
// spark-shell
// fetch total records count
spark.sql("select uuid, partitionpath from hudi_trips_snapshot").count()
// fetch two records to be deleted
val ds = spark.sql("select uuid, partitionpath from hudi_trips_snapshot").limit(2)
// issue deletes
val deletes = dataGen.generateDeletes(ds.collectAsList())
val hardDeleteDf = spark.read.json(spark.sparkContext.parallelize(deletes, 2))
hardDeleteDf.write.format("hudi").
options(getQuickstartWriteConfigs).
option(OPERATION_OPT_KEY,"delete").
option(PRECOMBINE_FIELD_OPT_KEY, "ts").
option(RECORDKEY_FIELD_OPT_KEY, "uuid").
option(PARTITIONPATH_FIELD_OPT_KEY, "partitionpath").
option(TABLE_NAME, tableName).
mode(Append).
save(basePath)
// run the same read query as above.
val roAfterDeleteViewDF = spark.
read.
format("hudi").
load(basePath)
roAfterDeleteViewDF.registerTempTable("hudi_trips_snapshot")
// fetch should return (total - 2) records
spark.sql("select uuid, partitionpath from hudi_trips_snapshot").count()
Когда озеро данных получает возможность обновлять существующие данные, оно становится Lakehouse. Мы сгенерируем новые данные о поездке, а затем перезапишем существующие данные. Эта операция лучше, чем Hudi Вычисляет для вас весь целевой раздел сразу upsert Быстрее. Здесь мы указываем конфигурацию для обхода upsert Автоматическое индексирование будет выполнено за вас、предварительно смешанныйи Передел。
// spark-shell
spark.
read.format("hudi").
load(basePath).
select("uuid","partitionpath").
sort("partitionpath","uuid").
show(100, false)
val inserts = convertToStringList(dataGen.generateInserts(10))
val df = spark.
read.json(spark.sparkContext.parallelize(inserts, 2)).
filter("partitionpath = 'americas/united_states/san_francisco'")
df.write.format("hudi").
options(getQuickstartWriteConfigs).
option(OPERATION.key(),"insert_overwrite").
option(PRECOMBINE_FIELD.key(), "ts").
option(RECORDKEY_FIELD.key(), "uuid").
option(PARTITIONPATH_FIELD.key(), "partitionpath").
option(TBL_NAME.key(), tableName).
mode(Append).
save(basePath)
// Should have different keys now for San Francisco alone, from query before.
spark.
read.format("hudi").
load(basePath).
select("uuid","partitionpath").
sort("partitionpath","uuid").
show(100, false)
Эволюция схемы позволяет изменять Hudi Создайте схему таблицы, учитывающую изменения данных с течением времени. Вот несколько примеров того, как запрашивать режимы разработки и разделы. Более подробное обсуждение см. Schema Evolution | Apache Худи[23]. Обратите внимание, что если вы запустите эти команды, они изменятся. Hudi схему таблицы, чтобы она отличалась от этой схемы.
-- Alter table name
ALTER TABLE oldTableName RENAME TO newTableName
-- Alter table add columns
ALTER TABLE tableIdentifier ADD COLUMNS(colAndType (,colAndType)*)
-- Alter table column type
ALTER TABLE tableIdentifier CHANGE COLUMN colName colName colType
-- Alter table properties
ALTER TABLE tableIdentifier SET TBLPROPERTIES (key = 'value')
#Alter table examples
--rename to:
ALTER TABLE hudi_cow_nonpcf_tbl RENAME TO hudi_cow_nonpcf_tbl2;
--add column:
ALTER TABLE hudi_cow_nonpcf_tbl2 add columns(remark string);
--change column:
ALTER TABLE hudi_cow_nonpcf_tbl2 change column uuid uuid bigint;
--set properties;
alter table hudi_cow_nonpcf_tbl2 set tblproperties (hoodie.keep.max.commits = '10');
в настоящий момент,show partitions
Подходит только дляиспользуется для файловой системы, поскольку она основана на пути к таблице файловой системы. Бен Учебное пособиеиспользовать Spark показать Hudi функция. Но Худи Может поддерживать несколько типов таблиц/типов запросов и может Hive、Spark、Presto Дождитесь запроса механизма запросов Hudi поверхность. Худи В проекте имеется демонстрационное видео [24], в основе которого лежит Docker Все это отображается при установке, при этом все соответствующие системы работают локально.
Apache Hudi — это первый формат открытых таблиц для озер данных, и его стоит рассмотреть в потоковых архитектурах. Худи Сообщество и экосистема активны, и пользователям уделяется все больше и больше внимания. Худи/замена хранилища объектов Hadoop/HDFS для облачных озер потоковой передачи данных. Воля MinIO используется для Hudi хранилищедля пасмурноозеро Анализ данных прокладывает путь. Мин ИО Включает активно-активное копирование для синхронизации данных между локальными, публичными/частными облаками и периферийными расположениями, предоставляя замечательные функции, необходимые предприятиям, такие как географическая балансировка нагрузки и быстрое переключение между горячими средами.
[1]
Облачное хранилище: [https://hudi.apache.org/docs/cloud](https://hudi.apache.org/docs/cloud)
[2]
Uber: [https://eng.uber.com/uber-big-data-platform/](https://eng.uber.com/uber-big-data-platform/)
[3]
Амазонка: [https://aws.amazon.com/blogs/big-data/how-amazon-transportation-service-enabled-near-real-time-event-analytics-at-petabyte-scale-using-aws-glue-with-apache-hudi/](https://aws.amazon.com/blogs/big-data/how-amazon-transportation-service-enabled-near-real-time-event-analytics-at-petabyte-scale-using-aws-glue-with-apache-hudi/)
[4]
Байт Данс: [http://hudi.apache.org/blog/2021/09/01/building-eb-level-data-lake-using-hudi-at-bytedance](http://hudi.apache.org/blog/2021/09/01/building-eb-level-data-lake-using-hudi-at-bytedance)
[5]
Robinhood: [https://s.apache.org/hudi-robinhood-talk](https://s.apache.org/hudi-robinhood-talk)
[6]
Потоковое озеро данных: [https://hudi.apache.org/blog/2021/07/21/streaming-data-lake-platform/](https://hudi.apache.org/blog/2021/07/21/streaming-data-lake-platform/)
[7]
Hadoop FileSystem API: [https://hadoop.apache.org/docs/stable/api/org/apache/hadoop/fs/FileSystem.html](https://hadoop.apache.org/docs/stable/api/org/apache/hadoop/fs/FileSystem.html)
[8]
оптимизация: [https://hudi.apache.org/blog/2021/07/21/streaming-data-lake-platform/#writers](https://hudi.apache.org/blog/2021/07/21/streaming-data-lake-platform/#writers)
[9]
Водяной знак: [https://ci.apache.org/projects/flink/flink-docs-release-1.13/docs/dev/datastream/event-time/generating_watermarks/](https://ci.apache.org/projects/flink/flink-docs-release-1.13/docs/dev/datastream/event-time/generating_watermarks/)
[10]
Snowflake: [https://blog.min.io/minio_and_snowflake/](https://blog.min.io/minio_and_snowflake/)
[11]
SQL Server: [https://blog.min.io/sqlserver2022/](https://blog.min.io/sqlserver2022/)
[12]
Недавний тест производительности: [https://min.io/resources/docs/MinIO-Throughput-Benchmarks-on-NVMe-SSD-32-Node.pdf](https://min.io/resources/docs/MinIO-Throughput-Benchmarks-on-NVMe-SSD-32-Node.pdf)
[13]
Оптимизация небольших файлов: [https://blog.min.io/minio-optimizes-small-objects/](https://blog.min.io/minio-optimizes-small-objects/)
[14]
Apache Hudi Spark гид: [https://hudi.apache.org/docs/next/quick-start-guide](https://hudi.apache.org/docs/next/quick-start-guide)
[15]
Удалить отметку: [https://blog.min.io/minio-versioning-metadata-deep-dive/](https://blog.min.io/minio-versioning-metadata-deep-dive/)
[16]
Cleaner Утилиты: [https://hudi.apache.org/docs/hoodie_cleaner](https://hudi.apache.org/docs/hoodie_cleaner)
[17]
Управление жизненным циклом: [https://docs.min.io/docs/minio-bucket-lifecycle-guide.html](https://docs.min.io/docs/minio-bucket-lifecycle-guide.html)
[18]
Загрузите и установите: [https://spark.apache.org/downloads.html](https://spark.apache.org/downloads.html)
[19]
Загрузите и установите: [https://min.io/download](https://min.io/download)
[20]
Загрузите и установите: [https://min.io/download](https://min.io/download)
[21]
скачать Jar документ: [https://jar-download.com/artifacts/org.apache.hadoop/hadoop-aws/3.3.4](https://jar-download.com/artifacts/org.apache.hadoop/hadoop-aws/3.3.4)
[22]
Документ внешней конфигурации: [https://hudi.apache.org/docs/next/configurations#externalized-config-file](https://hudi.apache.org/docs/next/configurations#externalized-config-file)
[23]
Schema Evolution | Apache Hudi: https://hudi.apache.org/docs/next/schema_evolution
[24]
Демонстрационное видео: [https://www.youtube.com/watch?v=VhNgUsxdrD0](https://www.youtube.com/watch?v=VhNgUsxdrD0)