Enhance operational efficiencies of Apache Iceberg tables constructed on Amazon S3 knowledge lakes

Apache Iceberg is an open desk format for big datasets in Amazon Easy Storage Service (Amazon S3) and offers quick question efficiency over massive tables, atomic commits, concurrent writes, and SQL-compatible desk evolution. Once you construct your transactional knowledge lake utilizing Apache Iceberg to unravel your practical use circumstances, it’s essential give attention to operational use circumstances on your S3 knowledge lake to optimize the manufacturing atmosphere. Among the necessary non-functional use circumstances for an S3 knowledge lake that organizations are specializing in embrace storage value optimizations, capabilities for catastrophe restoration and enterprise continuity, cross-account and multi-Area entry to the info lake, and dealing with elevated Amazon S3 request charges.

On this put up, we present you enhance operational efficiencies of your Apache Iceberg tables constructed on Amazon S3 knowledge lake and Amazon EMR large knowledge platform.

Optimize knowledge lake storage

One of many main benefits of constructing fashionable knowledge lakes on Amazon S3 is it gives decrease value with out compromising on efficiency. You should use Amazon S3 Lifecycle configurations and Amazon S3 object tagging with Apache Iceberg tables to optimize the price of your total knowledge lake storage. An Amazon S3 Lifecycle configuration is a algorithm that outline actions that Amazon S3 applies to a bunch of objects. There are two sorts of actions:

  • Transition actions – These actions outline when objects transition to a different storage class; for instance, Amazon S3 Customary to Amazon S3 Glacier.
  • Expiration actions – These actions outline when objects expire. Amazon S3 deletes expired objects in your behalf.

Amazon S3 makes use of object tagging to categorize storage the place every tag is a key-value pair. From an Apache Iceberg perspective, it helps customized Amazon S3 object tags that may be added to S3 objects whereas writing and deleting into the desk. Iceberg additionally allow you to configure a tag-based object lifecycle coverage on the bucket stage to transition objects to completely different Amazon S3 tiers. With the s3.delete.tags config property in Iceberg, objects are tagged with the configured key-value pairs earlier than deletion. When the catalog property s3.delete-enabled is ready to false, the objects are usually not hard-deleted from Amazon S3. That is anticipated for use together with Amazon S3 delete tagging, so objects are tagged and eliminated utilizing an Amazon S3 lifecycle coverage. This property is ready to true by default.

The instance pocket book on this put up reveals an instance implementation of S3 object tagging and lifecycle guidelines for Apache Iceberg tables to optimize storage value.

Implement enterprise continuity

Amazon S3 provides any developer entry to the identical extremely scalable, dependable, quick, cheap knowledge storage infrastructure that Amazon makes use of to run its personal international community of internet sites. Amazon S3 is designed for 99.999999999% (11 9’s) of sturdiness, S3 Customary is designed for 99.99% availability, and Customary – IA is designed for 99.9% availability. Nonetheless, to make your knowledge lake workloads extremely out there in an unlikely outage scenario, you may replicate your S3 knowledge to a different AWS Area as a backup. With S3 knowledge residing in a number of Areas, you need to use an S3 multi-Area entry level as an answer to entry the info from the backup Area. With Amazon S3 multi-Area entry level failover controls, you may route all S3 knowledge request site visitors by a single international endpoint and instantly management the shift of S3 knowledge request site visitors between Areas at any time. Throughout a deliberate or unplanned regional site visitors disruption, failover controls allow you to management failover between buckets in numerous Areas and accounts inside minutes. Apache Iceberg helps entry factors to carry out S3 operations by specifying a mapping of bucket to entry factors. We embrace an instance implementation of an S3 entry level with Apache Iceberg later on this put up.

Enhance Amazon S3 efficiency and throughput

Amazon S3 helps a request charge of three,500 PUT/COPY/POST/DELETE or 5,500 GET/HEAD requests per second per prefix in a bucket. The assets for this request charge aren’t mechanically assigned when a prefix is created. As an alternative, because the request charge for a prefix will increase progressively, Amazon S3 mechanically scales to deal with the elevated request charge. For sure workloads that want a sudden enhance within the request charge for objects in a prefix, Amazon S3 may return 503 Gradual Down errors, often known as S3 throttling. It does this whereas it scales within the background to deal with the elevated request charge. Additionally, if supported request charges are exceeded, it’s a finest observe to distribute objects and requests throughout a number of prefixes. Implementing this answer to distribute objects and requests throughout a number of prefixes entails adjustments to your knowledge ingress or knowledge egress functions. Utilizing Apache Iceberg file format on your S3 knowledge lake can considerably cut back the engineering effort by enabling the ObjectStoreLocationProvider characteristic, which provides an S3 hash [0*7FFFFF] prefix in your specified S3 object path.

Iceberg by default makes use of the Hive storage structure, however you may change it to make use of the ObjectStoreLocationProvider. This feature will not be enabled by default to offer flexibility to decide on the situation the place you wish to add the hash prefix. With ObjectStoreLocationProvider, a deterministic hash is generated for every saved file and a subfolder is appended proper after the S3 folder specified utilizing the parameter write.knowledge.path (write.object-storage-path for Iceberg model 0.12 and beneath). This ensures that recordsdata written to Amazon S3 are equally distributed throughout a number of prefixes in your S3 bucket, thereby minimizing the throttling errors. Within the following instance, we set the write.knowledge.path worth as s3://my-table-data-bucket, and Iceberg-generated S3 hash prefixes can be appended after this location:

CREATE TABLE my_catalog.my_ns.my_table
( id bigint,
knowledge string,
class string)
( 'write.object-storage.enabled'=true,

Your S3 recordsdata can be organized below MURMUR3 S3 hash prefixes like the next:

2021-11-01 05:39:24 809.4 KiB 7ffbc860/my_ns/my_table/00328-1642-5ce681a7-dfe3-4751-ab10-37d7e58de08a-00015.parquet
2021-11-01 06:00:10 6.1 MiB 7ffc1730/my_ns/my_table/00460-2631-983d19bf-6c1b-452c-8195-47e450dfad9d-00001.parquet
2021-11-01 04:33:24 6.1 MiB 7ffeeb4e/my_ns/my_table/00156-781-9dbe3f08-0a1d-4733-bd90-9839a7ceda00-00002.parquet

Utilizing Iceberg ObjectStoreLocationProvider will not be a foolproof mechanism to keep away from S3 503 errors. You continue to must set acceptable EMRFS retries to offer extra resiliency. You’ll be able to modify your retry technique by growing the utmost retry restrict for the default exponential backoff retry technique or enabling and configuring the additive-increase/multiplicative-decrease (AIMD) retry technique. AIMD is supported for Amazon EMR releases 6.4.0 and later. For extra info, discuss with Retry Amazon S3 requests with EMRFS.

Within the following sections, we offer examples for these use circumstances.

Storage value optimizations

On this instance, we use Iceberg’s S3 tags characteristic with the write tag as write-tag-name=created and delete tag as delete-tag-name=deleted. This instance is demonstrated on an EMR model emr-6.10.0 cluster with put in functions Hadoop 3.3.3, Jupyter Enterprise Gateway 2.6.0, and Spark 3.3.1. The examples are run on a Jupyter Pocket book atmosphere hooked up to the EMR cluster. To be taught extra about create an EMR cluster with Iceberg and use Amazon EMR Studio, discuss with Use an Iceberg cluster with Spark and the Amazon EMR Studio Administration Information, respectively.

The next examples are additionally out there within the pattern pocket book within the aws-samples GitHub repo for fast experimentation.

Configure Iceberg on a Spark session

Configure your Spark session utilizing the %%configure magic command. You should use both the AWS Glue Information Catalog (advisable) or a Hive catalog for Iceberg tables. On this instance, we use a Hive catalog, however we are able to change to the Information Catalog with the next configuration:


Earlier than you run this step, create a S3 bucket and an iceberg folder in your AWS account with the naming conference <your-iceberg-storage-blog>/iceberg/.

Replace your-iceberg-storage-blog within the following configuration with the bucket that you just created to check this instance. Be aware the configuration parameters s3.write.tags.write-tag-name and s3.delete.tags.delete-tag-name, which is able to tag the brand new S3 objects and deleted objects with corresponding tag values. We use these tags in later steps to implement S3 lifecycle insurance policies to transition the objects to a lower-cost storage tier or expire them based mostly on the use case.

%%configure -f { "conf":{ "spark.sql.extensions":"org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions", "spark.sql.catalog.dev":"org.apache.iceberg.spark.SparkCatalog", "spark.sql.catalog.dev.catalog-impl":"org.apache.iceberg.hive.HiveCatalog", "spark.sql.catalog.dev.io-impl":"org.apache.iceberg.aws.s3.S3FileIO", "spark.sql.catalog.dev.warehouse":"s3://&amp;amp;lt;your-iceberg-storage-blog&amp;amp;gt;/iceberg/", "spark.sql.catalog.dev.s3.write.tags.write-tag-name":"created", "spark.sql.catalog.dev.s3.delete.tags.delete-tag-name":"deleted", "spark.sql.catalog.dev.s3.delete-enabled":"false" } }

Create an Apache Iceberg desk utilizing Spark-SQL

Now we create an Iceberg desk for the Amazon Product Critiques Dataset:

spark.sql(""" DROP TABLE if exists dev.db.amazon_reviews_iceberg""")
spark.sql(""" CREATE TABLE dev.db.amazon_reviews_iceberg (
market string,
customer_id string,
review_id string,
product_id string,
product_parent string,
product_title string,
star_rating int,
helpful_votes int,
total_votes int,
vine string,
verified_purchase string,
review_headline string,
review_body string,
review_date date,
12 months int)
USING iceberg
location 's3://<your-iceberg-storage-blog>/iceberg/db/amazon_reviews_iceberg'
PARTITIONED BY (years(review_date))""")

Within the subsequent step, we load the desk with the dataset utilizing Spark actions.

Load knowledge into the Iceberg desk

Whereas inserting the info, we partition the info by review_date as per the desk definition. Run the next Spark instructions in your PySpark pocket book:

df = spark.learn.parquet("s3://amazon-reviews-pds/parquet/product_category=Electronics/*.parquet")


Insert a single report into the identical Iceberg desk in order that it creates a partition with the present review_date:

spark.sql("""insert into dev.db.amazon_reviews_iceberg values ("US", "99999999","R2RX7KLOQQ5VBG","B00000JBAT","738692522","Diamond Rio Digital",3,0,0,"N","N","Why simply half-hour?","RIO is de facto nice",date("2023-04-06"),2023)""")

You’ll be able to verify the brand new snapshot is created after this append operation by querying the Iceberg snapshot:

spark.sql("""SELECT * FROM dev.db.amazon_reviews_iceberg.snapshots""").present()

You will note an output much like the next displaying the operations carried out on the desk.

Verify the S3 tag inhabitants

You should use the AWS Command Line Interface (AWS CLI) or the AWS Administration Console to verify the tags populated for the brand new writes. Let’s verify the tag similar to the thing created by a single row insert.

On the Amazon S3 console, verify the S3 folder s3://your-iceberg-storage-blog/iceberg/db/amazon_reviews_iceberg/knowledge/ and level to the partition review_date_year=2023/. Then verify the Parquet file below this folder to verify the tags related to the info file in Parquet format.

From the AWS CLI, run the next command to see that the tag is created based mostly on the Spark configuration spark.sql.catalog.dev.s3.write.tags.write-tag-name":"created":

xxxx@3c22fb1238d8 ~ % aws s3api get-object-tagging --bucket your-iceberg-storage-blog --key iceberg/db/amazon_reviews_iceberg/knowledge/review_date_year=2023/00000-43-2fb892e3-0a3f-4821-a356-83204a69fa74-00001.parquet

You will note an output, much like the beneath, displaying the related tags for the file

{ "VersionId": "null", "TagSet": [{ "Key": "write-tag-name", "Value": "created" } ] }

Delete a report and expire a snapshot

On this step, we delete a report from the Iceberg desk and expire the snapshot similar to the deleted report. We delete the brand new single report that we inserted with the present review_date:

spark.sql("""delete from dev.db.amazon_reviews_iceberg the place review_date="2023-04-06"""")

We will now verify {that a} new snapshot was created with the operation flagged as delete:

spark.sql("""SELECT * FROM dev.db.amazon_reviews_iceberg.snapshots""").present()

That is helpful if we wish to time journey and verify the deleted row sooner or later. In that case, now we have to question the desk with the snapshot-id similar to the deleted row. Nonetheless, we don’t focus on time journey as a part of this put up.

We expire the previous snapshots from the desk and hold solely the final two. You’ll be able to modify the question based mostly in your particular necessities to retain the snapshots:

spark.sql ("""CALL dev.system.expire_snapshots(desk => 'dev.db.amazon_reviews_iceberg', older_than => DATE '2024-01-01', retain_last => 2)""")

If we run the identical question on the snapshots, we are able to see that now we have solely two snapshots out there:

spark.sql("""SELECT * FROM dev.db.amazon_reviews_iceberg.snapshots""").present()

From the AWS CLI, you may run the next command to see that the tag is created based mostly on the Spark configuration spark.sql.catalog.dev.s3. delete.tags.delete-tag-name":"deleted":

xxxxxx@3c22fb1238d8 ~ % aws s3api get-object-tagging --bucket avijit-iceberg-storage-blog --key iceberg/db/amazon_reviews_iceberg/knowledge/review_date_year=2023/00000-43-2fb892e3-0a3f-4821-a356-83204a69fa74-00001.parquet

You will note output much like beneath displaying the related tags for the file

{ "VersionId": "null", "TagSet": [ { "Key": "delete-tag-name", "Value": "deleted" }, { "Key": "write-tag-name", "Value": "created" } ] }

You’ll be able to view the present metadata recordsdata from the metadata log entries metatable after the expiration of snapshots:

spark.sql("""SELECT * FROM dev.db.amazon_reviews_iceberg.metadata_log_entries""").present()

The snapshots which have expired present the newest snapshot ID as null.

Create S3 lifecycle guidelines to transition the buckets to a special storage tier

Create a lifecycle configuration for the bucket to transition objects with the delete-tag-name=deleted S3 tag to the Glacier Immediate Retrieval class. Amazon S3 runs lifecycle guidelines one time day-after-day at midnight Common Coordinated Time (UTC), and new lifecycle guidelines can take as much as 48 hours to finish the primary run. Amazon S3 Glacier is effectively suited to archive knowledge that wants instant entry (with milliseconds retrieval). With S3 Glacier Immediate Retrieval, it can save you as much as 68% on storage prices in comparison with utilizing the S3 Customary-Rare Entry (S3 Customary-IA) storage class, when the info is accessed as soon as per quarter.

Once you wish to entry the info again, you may bulk restore the archived objects. After you restore the objects again in S3 Customary class, you may register the metadata and knowledge as an archival desk for question functions. The metadata file location might be fetched from the metadata log entries metatable as illustrated earlier. As talked about earlier than, the newest snapshot ID with Null values signifies expired snapshots. We will take one of many expired snapshots and do the majority restore:

spark.sql("""CALL dev.system.register_table(desk => 'db.amazon_reviews_iceberg_archive', metadata_file => 's3://avijit-iceberg-storage-blog/iceberg/db/amazon_reviews_iceberg/metadata/00000-a010f15c-7ac8-4cd1-b1bc-bba99fa7acfc.metadata.json')""").present()

Capabilities for catastrophe restoration and enterprise continuity, cross-account and multi-Area entry to the info lake

As a result of Iceberg doesn’t assist relative paths, you need to use entry factors to carry out Amazon S3 operations by specifying a mapping of buckets to entry factors. That is helpful for multi-Area entry, cross-Area entry, catastrophe restoration, and extra.

For cross-Area entry factors, we have to moreover set the use-arn-region-enabled catalog property to true to allow S3FileIO to make cross-Area calls. If an Amazon S3 useful resource ARN is handed in because the goal of an Amazon S3 operation that has a special Area than the one the shopper was configured with, this flag have to be set to ‘true‘ to allow the shopper to make a cross-Area name to the Area specified within the ARN, in any other case an exception can be thrown. Nonetheless, for a similar or multi-Area entry factors, the use-arn-region-enabled flag ought to be set to ‘false’.

For instance, to make use of an S3 entry level with multi-Area entry in Spark 3.3, you can begin the Spark SQL shell with the next code:

spark-sql --conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog 
--conf spark.sql.catalog.my_catalog.warehouse=s3://my-bucket2/my/key/prefix 
--conf spark.sql.catalog.my_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
--conf spark.sql.catalog.my_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO 
--conf spark.sql.catalog.my_catalog.s3.use-arn-region-enabled=false 
--conf spark.sql.catalog.take a look at.s3.access-points.my-bucket1=arn:aws:s3::123456789012:accesspoint:mfzwi23gnjvgw.mrap 
--conf spark.sql.catalog.take a look at.s3.access-points.my-bucket2=arn:aws:s3::123456789012:accesspoint:mfzwi23gnjvgw.mrap

On this instance, the objects in Amazon S3 on my-bucket1 and my-bucket2 buckets use the arn:aws:s3::123456789012:accesspoint:mfzwi23gnjvgw.mrap entry level for all Amazon S3 operations.

For extra particulars on utilizing entry factors, discuss with Utilizing entry factors with appropriate Amazon S3 operations.

Let’s say your desk path is below mybucket1, so each mybucket1 in Area 1 and mybucket2 in Area have paths of mybucket1 contained in the metadata recordsdata. On the time of the S3 (GET/PUT) name, we change the mybucket1 reference with a multi-Area entry level.

Dealing with elevated S3 request charges

When utilizing ObjectStoreLocationProvider (for extra particulars, see Object Retailer File Format), a deterministic hash is generated for every saved file, with the hash appended instantly after the write.knowledge.path. The issue with that is that the default hashing algorithm generates hash values as much as Integer MAX_VALUE, which in Java is (2^31)-1. When that is transformed to hex, it produces 0x7FFFFFFF, so the primary character variance is restricted to solely [0-8]. As per Amazon S3 suggestions, we must always have the utmost variance right here to mitigate this.

Ranging from Amazon EMR 6.10, Amazon EMR added an optimized location supplier that makes positive the generated prefix hash has uniform distribution within the first two characters utilizing the character set from [0-9][A-Z][a-z].

This location supplier has been not too long ago open sourced by Amazon EMR through Core: Enhance bit density in object storage structure and ought to be out there ranging from Iceberg 1.3.0.

To make use of, be sure that the iceberg.enabled classification is ready to true, and write.location-provider.impl is ready to org.apache.iceberg.emr.OptimizedS3LocationProvider.

The next is a pattern Spark shell command:

spark-shell --conf spark.driver.reminiscence=4g 
--conf spark.executor.cores=4 
--conf spark.dynamicAllocation.enabled=true 
--conf spark.sql.catalog.my_catalog=org.apache.iceberg.spark.SparkCatalog 
--conf spark.sql.catalog.my_catalog.warehouse=s3://my-bucket/iceberg-V516168123 
--conf spark.sql.catalog.my_catalog.catalog-impl=org.apache.iceberg.aws.glue.GlueCatalog 
--conf spark.sql.catalog.my_catalog.io-impl=org.apache.iceberg.aws.s3.S3FileIO 
--conf spark.sql.catalog.my_catalog.table-override.write.location-provider.impl=org.apache.iceberg.emr.OptimizedS3LocationProvider

The next instance reveals that if you allow the thing storage in your Iceberg desk, it provides the hash prefix in your S3 path instantly after the situation you present in your DDL.

Outline the desk write.object-storage.enabled parameter and supply the S3 path, after which you wish to add the hash prefix utilizing write.knowledge.path (for Iceberg Model 0.13 and above) or write.object-storage.path (for Iceberg Model 0.12 and beneath) parameters.

Insert knowledge into the desk you created.

The hash prefix is added proper after the /present/ prefix within the S3 path as outlined within the DDL.

Clear up

After you full the take a look at, clear up your assets to keep away from any recurring prices:

  1. Delete the S3 buckets that you just created for this take a look at.
  2. Delete the EMR cluster.
  3. Cease and delete the EMR pocket book occasion.


As firms proceed to construct newer transactional knowledge lake use circumstances utilizing Apache Iceberg open desk format on very massive datasets on S3 knowledge lakes, there can be an elevated give attention to optimizing these petabyte-scale manufacturing environments to cut back value, enhance effectivity, and implement excessive availability. This put up demonstrated mechanisms to implement the operational efficiencies for Apache Iceberg open desk codecs operating on AWS.

To be taught extra about Apache Iceberg and implement this open desk format on your transactional knowledge lake use circumstances, discuss with the next assets:

In regards to the Authors

Avijit Goswami is a Principal Options Architect at AWS specialised in knowledge and analytics. He helps AWS strategic prospects in constructing high-performing, safe, and scalable knowledge lake options on AWS utilizing AWS managed companies and open-source options. Exterior of his work, Avijit likes to journey, hike within the San Francisco Bay Space trails, watch sports activities, and hearken to music.

Rajarshi Sarkar is a Software program Growth Engineer at Amazon EMR/Athena. He works on cutting-edge options of Amazon EMR/Athena and can also be concerned in open-source initiatives similar to Apache Iceberg and Trino. In his spare time, he likes to journey, watch motion pictures, and hang around with buddies.

Prashant Singh is a Software program Growth Engineer at AWS. He’s curious about Databases and Information Warehouse engines and has labored on Optimizing Apache Spark efficiency on EMR. He’s an lively contributor in open supply initiatives like Apache Spark and Apache Iceberg. Throughout his free time, he enjoys exploring new locations, meals and climbing.

Leave a Reply

Your email address will not be published. Required fields are marked *