Domain 1 of 4 · Chapter 1 of 3

Collect and store data

From scattered sources to ML-ready storage

Suppose, for example, a churn-prediction team gathers customer rows from Amazon RDS, order history from Amazon DynamoDB, call recordings from an Amazon EFS share and click events from a stream; the DynamoDB table alone can be read with a Scan, which consumes read capacity units[3], or with an export to S3, which does not[4]. The AWS MLA-C02 exam guide[5] names this work 'Task 1.1: Collect and store data.' (Data Preparation for ML and AI, 28%), with skills covering extraction, storage decisions and data formats; 'Task 1.2: Perform data transformation, feature engineering, and pre-processing.' (see Transform data and engineer features) and 'Task 1.3: Validate data quality and manage bias.' (see Validate data quality and manage bias) follow it.

Data sources and copy paths into Amazon S3

By how they are read, the sources form families (an organizing model, not an AWS classification):

  • File storage includes Amazon EFS and NFS or SMB file servers. Amazon EBS sits outside this family: an attached EBS volume is exposed as a block device[6] (a raw disk), and its files are read through the file system mounted on an EC2 instance.
  • Databases and search indexes (Amazon RDS, Amazon DynamoDB, Amazon OpenSearch Service) are read by AWS Glue; an Amazon RDS read over a JDBC connection or an OpenSearch Service read runs against the live source, so size and schedule it with the source application's capacity in mind.
  • Event streams (Amazon Kinesis Data Streams; Apache Kafka topics, run on AWS as Amazon Managed Streaming for Apache Kafka, or Amazon MSK) deliver records continuously. A streaming service captures them, and Amazon Data Firehose (formerly Kinesis Data Firehose) delivers them into storage.

AWS DataSync transfers NFS, SMB and Amazon EFS data to Amazon S3[7]; AWS Glue for Spark reads Amazon RDS through a JDBC connection[8], DynamoDB through its export connector[9] and OpenSearch Service through an OpenSearch Service connection[10]; Amazon Data Firehose reads a Kinesis data stream[11] or an Amazon MSK topic and loads it into an S3 destination[12].

Where the data lands

Amazon S3 is the landing place: first a raw copy of each source, then an analytical copy, meaning the same data rewritten in a columnar storage format such as Apache Parquet or Apache ORC[13] and partitioned for the reads that feature jobs repeat. AWS Glue writes Parquet or ORC files to Amazon S3, partitioned while writing[14], turning the raw copy into the analytical copy, as the figure below shows. Amazon S3 is also a source: a dataset already there can be read in place, for example by an AWS Glue job transforming data from Amazon S3 to Amazon S3, which needs no additional VPC configuration if it does not need to run in a VPC subnet[8]. Two specialized stores sit downstream when the workload needs them: Amazon SageMaker AI Feature Store, which serves feature values to training and inference, and a vector store, which holds embeddings for retrieval in generative AI applications.

Takeaway, as a working heuristic rather than an AWS rule: identify how each source is read before choosing its copy path, then choose the storage layout by how the data will be read.

Source familyCopy pathStorage in Amazon S3File storageEFS, NFS or SMBDatabases and search indexesRDS, DynamoDB, OpenSearchEvent streamsKinesis Data Streams, Amazon MSKAWS DataSyncAWS Glue for SparkJDBC, DynamoDB export andOpenSearch Service connectionsAmazon Data FirehoseS3 destinationRaw copyof each sourceAnalytical copyParquet or ORC,partitioned
Example collect-and-store pipeline: each source family's copy path into an Amazon S3 raw copy, then a partitioned Parquet or ORC analytical copy.

Extracting from file and block storage

This section covers sources that hold files: Amazon EBS volumes, Amazon EFS file systems, and file servers that speak NFS or SMB. The rule is to move files as files and leave parsing to a later job.

Amazon EBS: read the mounted file system

An EBS volume is not an object store. After you attach an Amazon EBS volume to your instance it is exposed as a block device[6] (a raw disk), and its files become readable only once the file system on it is mounted on the EC2 instance. The documented procedure formats and then mounts a volume, but formatting applies only to an empty volume. A volume created from a snapshot may already carry a file system and the dataset: check for an existing file system, then mount it without formatting and point the extraction process at the mounted path. Formatting it would overwrite the data you came to extract.

AWS DataSync: file servers and Amazon EFS

AWS DataSync copies files from a source location to a destination location. Whether a transfer needs a DataSync agent (a virtual machine you deploy next to self-managed storage) depends on the location pair: NFS or SMB to Amazon S3 requires an agent, while Amazon EFS or Amazon FSx to Amazon S3 does not[7] for transfers within the same AWS account, and between AWS storage services in the same account no agent is required, whether in the same AWS Region or across AWS Regions in the same partition[15] (here an AWS partition, which is a group of AWS Regions[16], unrelated to the S3 and stream partitions later on this page). For an EFS source, DataSync mounts your file system as a root user from your VPC using network interfaces[17], so the EFS location's subnet must be in the same Availability Zone as at least one mount target, and its security groups must allow inbound NFS traffic on port 2049. Treating managed EFS like an on-premises NFS server and deploying an agent adds infrastructure the transfer does not need.

DataSync moves bytes. It does not parse CSV rows, extract text or compute features; a downstream processing job does that once the files are in S3. The reverse mistake also appears in scenarios: an AWS Glue JDBC connection cannot copy an SMB document share, because JDBC connects to database records, not to file shares (the next section covers JDBC sources).

In short: an EBS volume is mounted, file shares and EFS move with DataSync, and the agent question is answered by the location pair, not by the protocol name alone.

Extracting from databases and search indexes

Databases serve an application, so the extraction rule is: read the data without starving that application, and without re-reading what you already have. This section walks three database and index sources (Amazon RDS, Amazon DynamoDB and Amazon OpenSearch Service), each with a different mechanism.

Amazon RDS through an AWS Glue JDBC connection

An AWS Glue job reads a relational table through a JDBC connection that matches the database engine. Credentials are only half of the connection. When a job reads from a JDBC data store in a private subnet, AWS Glue sets up elastic network interfaces[8] in the subnet named in the connection and applies the connection's security groups to them, and all JDBC data stores the job accesses must be reachable from that subnet. A connection timeout therefore calls for checking network configuration and endpoint reachability, including routing and security-group rules; rotating the database password changes neither.

For repeated runs, job bookmarks let Glue read only the rows added since the previous run by comparing saved progress with the values of one or more bookmark keys. User-defined bookmark keys must each be strictly monotonically increasing or decreasing[18]; a revision number or minor-version field fails this test because its values repeat across the dataset. The rule has a consequence: an update to an old row whose bookmark key does not change is invisible to the bookmark, so a bookmarked incremental read using those unchanged keys misses the updates.

When the target is a data lake and nobody should have to write that job, an AWS Lake Formation blueprint generates it. Workflows generate AWS Glue crawlers, jobs, and triggers[19] from a blueprint: the database snapshot blueprint loads or reloads all tables from a JDBC source, and the incremental database blueprint loads only new rows based on bookmark columns (Lake Formation's term for the columns that, like the bookmark keys above, track what was already loaded), which the same page recommends only when previous rows are not updated. A Kinesis data stream is not a substitute for either: producers put records into Amazon Kinesis Data Streams[1], so something would still have to read and publish every database row.

Amazon DynamoDB: export instead of scan

A table scan reads through the table's capacity: Scan operations consume read capacity units[3], and a parallel scan can consume available read capacity faster. The export path avoids this. DynamoDB export to S3[4] requires point-in-time recovery (PITR) on the table, writes the table as of any time in the PITR window to an S3 bucket, runs asynchronously, and does not consume read capacity units. Export and S3 storage charges still apply, and an asynchronous export completes when it completes, not at a guaranteed time.

The AWS Glue DynamoDB export connector[9] requests that export on behalf of a job, and the exported data persists in S3 after the job run finishes, so later jobs can reuse it without additional DynamoDB exports. Reuse the export when several preprocessing experiments should see the same snapshot; request a new export when the dataset must reflect later table changes.

Amazon OpenSearch Service through a Glue connection

When documents already indexed in OpenSearch must feed a dataset, AWS Glue for Spark can read from OpenSearch Service in AWS Glue 4.0 and later versions[10]. You name the source index, set pushdown, which instructs Spark to pass read queries down to OpenSearch so the database only returns relevant documents[10], and can supply an OpenSearch query in opensearch.query so that only matching documents come back as a DynamicFrame (Glue's distributed table structure). The same page states that this feature is not compatible with OpenSearch Serverless, so confirm the source is an OpenSearch Service domain before choosing it.

Takeaway: of these mechanisms, only the DynamoDB export reads no table capacity; a JDBC read, bookmarked or not, still queries the live database, and a pushed-down OpenSearch query still runs on the domain, so size and schedule those two with the application's load in mind.

Merging sources: joins, unions and Glue Spark jobs

When two sources in S3 need to become one table, two common ways to combine tabular datasets are side by side or end to end. AWS Glue's documentation puts it in one line: you use Union to combine rows, and you use Join to combine columns[20].

  • A join matches rows from two datasets on a key and places their columns side by side: each transaction gains the attributes of the customer it belongs to.
  • A union appends rows that share one logical schema: this month's transactions stacked under last month's. Align column meanings and data types before appending. Appending customer profiles under transactions attaches no customer to any transaction; it only mixes two kinds of row in one table.

Which join keeps which rows

The join type decides which training examples survive. In SQL terms, an inner join returns matching rows only, and an outer join returns those rows plus the non-matching rows from the left table, the right table, or both, with NULL values filling the gaps[21].

Join type Rows in the output Use it when
Inner Only keys present in both datasets Every example must have the enrichment
Left (outer) Every left row, with NULL right-side columns where unmatched Every training example must survive enrichment
Cross Every left row paired with every right row You deliberately want all combinations, such as a candidate grid

Put the training examples on the left of a left join when optional profile fields are being added; an inner join would silently drop every example whose profile key has no match. A left join cleans nothing, though: inspect the NULL enrichment values, and check the right side for repeated keys, which duplicate a left row once per match. A cross join is the trap at the other extreme: cross-joins are unqualified joins that return the Cartesian product of the two tables[21], so using one to attach customer attributes to transactions multiplies rows instead of matching them, and inflates intermediate data and processing cost.

Running the merge in AWS Glue

AWS Glue jobs authored in AWS Glue Studio run on the Apache Spark-based serverless ETL engine in AWS Glue[22], so a merge scales out without a cluster to manage. In the visual editor, the Join transform combines two datasets into one on the key names you specify[23]; it accepts exactly two parent nodes and offers inner, left, right, outer, left semi and left anti joins. The Union transform requires all inputs to have the same schema[20] (an ApplyMapping transform can align mismatched schemas first) and has two types: ALL, the default, keeps duplicate rows, and DISTINCT removes them. Appending sources does not deduplicate by itself; choose DISTINCT when the merged output must not repeat rows.

Takeaway: decide rows versus columns first (union or join), then decide which unmatched rows must survive (the join type), and only then pick the tool that runs it.

Choosing file formats and partition layout

This section covers the two layout decisions for data at rest in S3: the file format and the partition scheme. Both follow one rule: choose by how the data will be read, not by how it arrived.

Formats by access pattern

Format Layout Choose it when
Apache Parquet, Apache ORC Columnar, compressed per column Jobs repeatedly read a few columns of a wide table
JSON Named fields, nested objects and arrays Records are semi-structured or nested
CSV Flat rows and columns Simple interchange with a consumer that expects it

Parquet and ORC store each column's values together. That brings compression by column, with the compression algorithm selected for the column data type[13], and predicate pushdown, which lets a query engine such as Amazon Athena fetch only the blocks it needs. A feature job that reads a handful of columns from a wide table can therefore read less data from a columnar copy than from CSV, where every row must be read in full. CSV stays useful for interchange; being human-readable does not make it efficient for repeated wide-table scans.

JSON keeps nested structure that CSV cannot express without an agreed flattening or encoding convention. The deciding question is what the consumer accepts. SageMaker AI built-in algorithms, for example, take content types such as text/csv, application/json and application/x-recordio-protobuf, and XGBoost supports only text/csv from that list[24] (plus text/libsvm). Nested JSON is no use to an algorithm that reads only CSV.

Converting a stream to Parquet on the way in

Amazon Data Firehose can write the columnar copy directly: it can convert the format of your input data from JSON to Apache Parquet or Apache ORC before storing the data in Amazon S3[25], using a schema it reads from the AWS Glue Data Catalog. Two constraints follow from the same page. The input must be JSON, so CSV records are first transformed to JSON with an AWS Lambda function. And the catalog schema governs the output: attributes that are not in the schema do not appear in the converted data.

Partitions that match the query filters

An S3 partition is a group of files under a shared key prefix such as year=2026/month=10/. (It is unrelated to a stream's partitions, such as the shards that make up a Kinesis data stream[1].) By partitioning your data, you can restrict the amount of data scanned by each query[26]: when a query names the partition in its WHERE clause, Athena scans only that partition. Partition by the fields downstream queries filter on, most often event date, sometimes a customer or region field. Partitions and columnar formats are complementary: partitions decide which files are read, and the columnar format decides which columns are read within those files.

Takeaway: an analytical copy is Parquet or ORC, partitioned by the query filters; JSON and CSV serve the consumers that need them.

S3 storage classes by when data is next read

The AWS MLA-C02 exam guide[5] asks for storage decisions 'based on cost, performance, data structure, and data compliance'; for data in S3, the storage class settles the cost-versus-access part of that choice.

The storage class must match when the data will be read next: archive classes offer low storage rates for suitable rarely accessed data, but S3 Glacier Flexible Retrieval and S3 Glacier Deep Archive objects must be restored before a job can read them. The table lists the classes this page uses; S3 offers others, such as S3 One Zone-IA and S3 Express One Zone.

Storage class Access Fits a dataset that is
S3 Standard Milliseconds Read often
S3 Standard-IA Milliseconds, with a retrieval fee Read rarely but needed at once when read
S3 Intelligent-Tiering Milliseconds in its default tiers Read on a pattern nobody can predict
S3 Glacier Instant Retrieval Milliseconds Archived but occasionally needed at once
S3 Glacier Flexible Retrieval, S3 Glacier Deep Archive Restore first Archived and read only after a planned restore

S3 Glacier Flexible Retrieval and S3 Glacier Deep Archive objects are archived, and not available for real-time access[27], while S3 Glacier Instant Retrieval serves long-term data that requires millisecond retrieval. Putting the only copy of next week's training data in Deep Archive without completing a restore before the run breaks the immediate-read requirement; the lower storage charge does not remove the need to plan that restore.

S3 Intelligent-Tiering, for a small monthly monitoring and automation fee, watches access patterns and automatically moves objects between access tiers as access changes; its optional Archive Access and Deep Archive Access tiers again require a restore before reading. S3 Standard-IA is a different kind of choice: a class you select because you already know the access is infrequent, not a mechanism that moves anything automatically.

Takeaway: restore-based archive classes trade access time for lower storage rates, so choose the class from the date of the next read.

S3 Object Lock retention and legal holds

Suppose, for example, a training-set version must stay unaltered for a fixed period no administrator can shorten, and an open-ended investigation may extend that; S3 Object Lock[28] covers both, blocking deletion and overwrite of object versions, and works only in buckets with S3 Versioning enabled. It has two retention modes and legal holds:

Legal holds are independent of retention periods, so when a retention period expires an active legal hold still protects the version. Object Lock also protects versions, not keys: retention periods and legal holds don't prevent new versions of the object from being created. A PUT to the same key creates a new version while the locked version stays intact.

Takeaway: compliance mode is the only Object Lock retention no one can bypass, and a legal hold protects a version until someone removes it.

Dataset versions and lineage

A model can be reproduced only if the exact data it was trained on can be found again. The AWS Well-Architected Machine Learning Lens calls for automated version control for training data, so you can precisely recreate a model version and keep a clear audit trail of data transformations[29]. In practice, record for each prepared dataset version its source identities, the source versions or extraction points (an export time, a bookmark position), and the transformations applied, and retain the relevant source and output versions under the dataset's retention policy. Source metadata says where data came from; transformation lineage says how it became the prepared artifact. Keeping only the preparation code while overwriting inputs and outputs preserves the logic but loses the data an earlier run used.

Takeaway: reproducibility needs versioned data plus its lineage, not just versioned code.

Streaming sources as partitioned logs: Kinesis and Kafka

Suppose, for example, that two teams must read the same card-payment events independently; with Kinesis Data Streams, each application can consume data from the stream independently and concurrently[1]. Amazon Kinesis Data Streams and Apache Kafka (run on AWS as Amazon Managed Streaming for Apache Kafka, or Amazon MSK) both serve that need, and they share one model, so learn the model once. Think of each as a partitioned log (a general streaming term, not an AWS feature name): the stream is split into partitions, each partition is an append-only sequence of records. Kinesis calls the partitions shards; Kafka calls them topic partitions. A stream partition has nothing to do with an S3 partition, the file-prefix grouping from Choosing file formats and partition layout above.

Kinesis Data Streams: shards and partition keys

A Kinesis data stream is a set of shards[1], and Kinesis places records on shards in one of two ways. In partition-key-based distribution, the producer attaches a partition key to each record and that key picks the shard. In service-managed distribution (the AUTO setting), a partition key a producer still supplies is one the service accepts and ignores for shard placement[30], so no ordering relationship between records may be assumed[31]. Everything below about keys, order and hot keys assumes partition-key-based distribution.

Kinesis maps the key through an MD5 hash to choose the shard, unless an explicit hash key overrides that mapping. Within the shard each record receives a sequence number that is unique per partition key within its shard, and the key concepts page[1] notes that sequence numbers cannot be used as indexes to sets of data within the same stream. Sequence order is shard-local, not a guarantee of source-event order across the stream. Keep events whose relative order matters under one partition key, account for producer retries that can reorder writes, and never sort a multi-shard stream by sequence number as though it were one global counter.

Each shard provides sustained capacity of up to 1,000 records or 1 MB per second for writes, and up to 2 MB per second for reads[1]; intermittent large records can temporarily burst beyond the sustained write throughput[32]. Write-side and read-side capacity problems have different fixes:

  • Hot partition key (producer side). One sufficiently hot key can exceed a shard's write capacity while other shards have spare capacity. The producer troubleshooting guidance[33] is to choose a partition key that distributes puts evenly across all shards and to check whether one key is hitting the limits while the rest are not. Adding shards does not fix a single key exceeding one shard's write capacity; spread that traffic over more key values.
  • Reader contention (consumer side). Default shared-throughput consumers split each shard's 2 MB per second read allowance. Enhanced fan-out[2] gives each registered consumer up to 2 MB per second per shard of dedicated throughput, with up to 20 registered consumers per stream in On-demand Standard and Provisioned modes (50 in On-demand Advantage mode). It fixes readers competing with each other, not a hot key on the write side.

Records stay readable for the stream's retention period, 24 hours by default and up to 8,760 hours (365 days)[1], and each consumer tracks its own position. That makes Kinesis Data Streams a replay log: several applications can read and re-read the same records within retention. Amazon Data Firehose, by contrast, delivers records to destinations and offers no such consumer model.

Kafka: topics, consumer groups and offsets

Kafka maps onto the same model. Producers append records to a named topic divided into partitions, and consumers read each partition sequentially. Amazon EventBridge Pipes, an AWS service that connects sources to targets[34], is one Kafka consumer among many: when it consumes from Amazon MSK, it reads the messages sequentially for each partition[35]. Ordering, again, is per partition; parallel partitions do not form one ordered topic log.

A consumer group is the set of workers sharing one workload. When other active consumers share a consumer group ID, Apache Kafka distributes messages across all consumers[35], rather than broadcasting every message to every member, and to preserve per-partition order the maximum is one consumer per partition. Two rules follow: the partition count caps useful parallelism within a group, and independent applications that each need the whole stream use separate consumer groups. Raising the topic's replication factor adds copies of each partition for durability (Amazon MSK recommends a replication factor of at least 3[36]); it adds no partitions for the group to share.

A committed offset is the group's saved position in each partition. A consumer that rejoins an existing group ID begins processing records according to the committed offset of the consumer group[35], so keep the group identity when restarting an ingestion consumer. A saved offset does not keep records alive: replay works only while the records are still within the topic's retention.

The figure below shows Kinesis partition-key-based distribution: partition keys hash to shards, and consumers read either through the shared allowance or through dedicated enhanced fan-out throughput.

Takeaway: for throttling or ordering problems, start with the relevant shard or partition; a few limits, such as the number of registered enhanced fan-out consumers, apply per stream.

Partition-key-based distributionProducersrecord + partition keyMD5 hash of thepartition keyKinesis data streamShard 1records in orderShard 2records in orderShard 3records in orderShared-throughputconsumers share2 MB/s per shardEnhanced fan-outdedicated 2 MB/s pershard per consumer
Kinesis Data Streams with partition-key-based distribution: the partition key picks the shard, and consumers read through shared or enhanced fan-out throughput.

Event time in streaming features with Apache Flink

A streaming feature such as 'payments per card in the last 5 minutes' raises a time-window question: which clock defines the window? This section covers that choice in Amazon Managed Service for Apache Flink[37] (formerly Amazon Kinesis Data Analytics for Apache Flink), which runs Apache Flink applications over streams such as Kinesis Data Streams or Kafka topics. Stream transforms are a separate skill in the AWS MLA-C02 exam guide[5], 'Skill 1.2.3: Transform streaming data (for example, by using AWS Lambda, Spark).' Flink distinguishes three notions of time[38]:

Time basis Meaning A window then reflects
Event time When each event occurred on its producing device What happened when
Ingestion time When the event entered the Managed Service for Apache Flink service When data arrived
Processing time The system time of the machine executing the operation When the operator ran

A payment delayed by the network belongs to the minute in which it happened. With processing-time windows a delay that crosses a window boundary can place it in a later window; with event-time windows it can be counted where it occurred, subject to the watermark (which propagates information about event time from the source to all other operators[39]) and to how the application handles late events.

Takeaway: choose the time basis that matches the feature's business meaning, which for statistics about when events occurred is event time.

Delivering streams to storage with Amazon Data Firehose

Amazon Data Firehose is the managed path from a stream into storage: it delivers real-time streaming data to destinations such as Amazon S3, Amazon Redshift and Amazon OpenSearch Service[40] with no applications or resources to manage. Its delivery model is the opposite of the replay log in the Kinesis and Kafka section: Firehose pushes records into a destination; it does not keep a log for consumers to re-read.

Buffering decides freshness

Firehose collects records before writing them. It buffers incoming streaming data in memory to a certain size and for a certain period of time before delivering it[41], and whichever buffer condition is met first triggers delivery. Larger buffers produce fewer, larger objects, which suit downstream readers. For a low-volume stream, though, the time condition is the one that fires, so a longer interval only delays when records appear in S3. Firehose accepting a record is not the record being visible at the destination; set the interval from the freshness the consumer needs. When dynamic partitioning (building S3 prefixes from record fields, described in the next subsection) is enabled, multi-stage buffering, which Firehose uses internally to deliver maximum size objects[42], means the end-to-end delay might be 1.5 times the configured buffer interval.

Dynamic partitioning: prefixes from record content

Dynamic partitioning builds each record's S3 prefix from fields inside the record, so delivered objects are already laid out as S3 partitions. Partition keys come either from inline parsing with a jq expression for JSON records, or from an AWS Lambda function[43], and the S3 prefix expression references them, for example customer_id=!{partitionKeyFromQuery:customer_id}/. In that example, customer_id= is literal prefix text, and the expression format is !{namespace:value}, where the namespace is partitionKeyFromQuery for keys created by inline parsing or partitionKeyFromLambda for keys returned by a Lambda function[44]; the value, customer_id again, is the key's ID. Firehose evaluates the expression at runtime and groups records that match the same evaluated S3 prefix expression into a single data set[44]. Deriving year, month and day from the record's own event timestamp files a late event under the day it occurred, not the day it arrived: the event-time idea from the previous section.

Every distinct evaluated prefix is an active partition with its own buffer. A new buffer is created for each active partition[42], each buffer is delivered as its own object when its own size or time condition is met, and a partition Firehose cannot deliver stays active until it can. Once the number of active partitions reaches a limit of 500 per Firehose stream (the API still calls the resource a delivery stream: CreateDeliveryStream creates a Firehose stream[45]), the remaining records go to the S3 error bucket prefix (error type activePartitionExceeded); the quota can be raised to 2,500 on request. The capacity trap here is cardinality, not throughput: partitioning modest traffic by a high-cardinality field such as customer ID creates many small buffers, many small objects and a high active-partition count. Lengthening the buffer interval makes this worse, because each buffer stays active longer.

The S3 error prefix

Enabling dynamic partitioning requires an S3 error bucket prefix. If Firehose cannot parse a record, extract the specified partitioning keys, or evaluate the expressions in the S3 prefix, the record is delivered to the S3 error bucket prefix[46], organized by error type and delivered together with information about the error. A producer that renames or drops the field a key is extracted from shows up here: compare the failed records' field names and structure with the extraction expression, then fix the producer or the expression. Requesting a higher active-partition quota does nothing for a missing-key error.

Processing order, record boundaries and Redshift

KPL is the Kinesis Producer Library, whose built-in aggregation is available when the Firehose stream has a Kinesis data stream as its source[47]. Firehose applies its optional stages in a fixed order before the final Amazon S3 delivery: KPL (protobuf) deaggregation, JSON or delimiter deaggregation, Lambda processing, data partitioning, data format conversion, and Amazon S3 delivery[47]. The figure below traces that order and the error-prefix branch. Two settings touch record boundaries, in opposite directions:

For an Amazon Redshift destination, streaming data is delivered to your S3 bucket first, and Firehose then issues an Amazon Redshift COPY command[40] to load it. The S3 bucket is a required staging step, and a successful S3 delivery does not yet mean the Redshift load succeeded. The optional source-record backup, offered when data transformation is enabled, is a separate copy with a separate purpose.

Takeaway: Firehose trades latency for batch size through its buffers, and its distinctive failures, active-partition exhaustion and key-extraction errors, both land in the S3 error prefix, where the error type tells you which one you have.

Optional stages in processing order, then Amazon S3 deliveryKPLdeaggregationJSON or delimiterdeaggregationLambdaprocessingDynamicpartitioningFormatconversionAmazon S3deliveryfailureS3 error prefixparse or key failures,active partition limit
Amazon Data Firehose processing order for S3 delivery, with records that fail dynamic partitioning branching to the S3 error prefix.

Vector stores for AI retrieval

A retrieval-augmented generation (RAG) application turns documents into embeddings (lists of numbers that place similar content close together) and, at query time, finds the stored vectors nearest to the query's vector. The AWS MLA-C02 exam guide lists producing embeddings as 'Skill 1.2.5: Configure and use embedding models to transform text and image data into numerical representations.' (see Transform data and engineer features) and storing them as 'Skill 1.1.7: Configure scalable vector databases for AI applications (for example, OpenSearch Service, Amazon RDS with pgvector, Amazon S3) based on specifications.' The three AWS options below illustrate how different requirements guide the choice:

Moving relational records into an OpenSearch index only to gain vector search breaks a stated requirement to keep SQL integration inside the existing database; replacing exact keyword matching with similarity search breaks a requirement for both behaviours. One related distinction: if the vectors must back an Amazon Bedrock knowledge base, the PostgreSQL option in Bedrock's vector store setup documentation[52] is Amazon Aurora PostgreSQL, alongside OpenSearch and S3 Vectors among others.

OpenSearch Service: k-NN indexes

In OpenSearch Service, k-NN, short for its associated k-nearest neighbors algorithm, finds the nearest neighbors for points in a vector space[53]. You create an index with the index.knn setting and add one or more fields of the knn_vector data type[53], each with a required dimension, and search by Euclidean distance or cosine similarity. Keep the searchable text and structured fields in the same documents so that lexical queries and filters work alongside similarity. Embedding generation remains a separate preparation step unless you configure a model integration; OpenSearch integrates with Amazon Bedrock and Amazon SageMaker AI for generating embeddings[54].

Comparing a query with every stored vector (exact k-NN search) gets slower as the collection grows. Approximate k-NN uses algorithms like HNSW (Hierarchical Navigable Small World) for faster searches on large datasets[54], at the price of possibly missing a neighbour that exact search would return; OpenSearch documentation describes its tuning as a balance of recall versus latency[55]. Measure recall as well as latency, keep exact search for cases where the result guarantee and dataset size justify exhaustive comparison, and do not treat approximate results as identical to exhaustive search just because both return k neighbours.

S3 Vectors: buckets, indexes and fixed settings

S3 Vectors introduces the vector bucket, a bucket type purpose-built to store and query vectors, and vector indexes inside it where similarity queries run[51]. Uploading embedding arrays as ordinary objects into a general purpose bucket stores the bytes but creates no similarity index: listing objects is not nearest-neighbour search.

Besides the index name, three settings are chosen at creation, and after you create a vector index, you can't update the vector index name, dimension, distance metric, or non-filterable metadata keys[56]; changing one means creating a new index.

  • Dimension: the number of values in a vector, an integer between 1 and 4,096. All vectors added to the index must have exactly this number of values, so set it to the embedding model's output dimension. A model with a different output dimension needs a new index; padding shorter vectors with arbitrary values changes what they represent.
  • Distance metric: Cosine measures the angle between vectors and suits normalized vectors where direction matters more than magnitude; Euclidean measures straight-line distance and suits cases where magnitude matters too. Follow the embedding model's recommendation.
  • Non-filterable metadata keys: metadata is filterable by default. Keys you declare non-filterable are returned with results but cannot be used as query filters; the original source text is the documented example of a good candidate. Never mark a field you must filter on, such as document category, as non-filterable.

Takeaway: choose the store by the queries that must run beside similarity search, then match dimension and metric to the embedding model and choose filterable metadata for the application before loading anything.

Ingesting text, images and audio

Machine learning and generative AI workloads ingest more than tables. The AWS MLA-C02 exam guide[5] lists 'Skill 1.1.8: Ingest and store diverse data types (for example, text, images, audio) for AI and ML applications.'

Text: documents, web pages and knowledge bases

A PDF can have an embedded text layer that ordinary PDF text extraction reads, including text added by optical character recognition (OCR) to scanned pages, or pages that are only images. A text-only parser finds nothing to extract from an image-only scanned page without an existing text layer; OCR has to run first. Amazon Textract analyzes image files and PDF files[57] and returns the lines and words of detected text, the page they appear on, and their location on the page[58]. Inspect the output, because document layout can affect reading order and how fields are interpreted.

Web pages can carry boilerplate and navigation menus. Extract the passages that bear on the page's content rather than keeping a raw HTML dump, so that a model sees the parts that matter and spends less of its input on boilerplate and navigation[59], and keep the headings, because clear headings and subheadings help RAG models understand the structure of documents[60]. When menus repeat across pages, a dump of every visible string can overrepresent those menus rather than each page's subject.

When documents feed an Amazon Bedrock knowledge base, editing the files in the data source is not enough: each time you add, modify, or remove files, you must sync the data source, and syncing is incremental[61], so only documents added, modified or deleted since the last sync are processed. Recreating the knowledge base after every edit is unnecessary.

Images: decodable assets linked to their origin

An image corpus is usable only if its files decode, in formats and dimensions the consuming workflow supports. SageMaker Data Wrangler[62], now used through Amazon SageMaker Canvas[63], imports images from an S3 directory and offers built-in transforms including ResizeImage, DropCorruptedImages and DropImageDuplicates. The dataset-versioning rule[29] from Dataset versions and lineage above applies to images too: keep the originals instead of overwriting them with resized copies, and keep a reference from each prepared image to its source. An Amazon SageMaker Ground Truth input manifest records such references: each JSON line's source-ref key names the Amazon S3 object, used when the object is binary, such as an image[64]. Labeling is its own exam-guide skill, 'Skill 1.3.2: Label and annotate data.' (see Validate data quality and manage bias). Replacing images with OCR text keeps the characters and loses the visual content an image model needs.

Audio: Amazon Transcribe input and output

Amazon Transcribe[65] has two modes with different rules: batch transcription reads media files stored in an S3 bucket, and streaming transcription reads a live media stream. Their input requirements differ:

Requirement Batch Streaming
Supported formats AMR, FLAC, M4A, MP3, MP4, Ogg, WebM, WAV FLAC, Ogg Opus, PCM encoding
Sample rate in the request Optional Required

A WAV file that a batch job accepts is not a valid stream as it is: the same page recommends PCM signed 16-bit little-endian audio for streaming and notes that this does not include WAV. Whenever a sample rate is supplied, it must match the actual audio; a mismatched value can make the job fail, and raising the declared number does not resample a low-fidelity recording.

Two features separate speakers, for two different recordings. Speaker partitioning (diarization) labels multiple speakers who share one audio channel; channel identification handles speech that is already on separate channels. Choose by how the audio is laid out, not by how many transcript files you expect.

For transcripts that become training data, choose the output location deliberately. If you name an S3 bucket you own and give Transcribe write permission, the transcript remains in that bucket until you remove it. Without one, Transcribe uses a service-managed bucket and returns a temporary URI that is valid for 15 minutes, and the transcript is deleted when the job expires after 90 days. A temporary download link is not a durable dataset location.

Takeaway: choose the steps each input needs beyond file copying (OCR or boilerplate removal for text, decoding and resizing for images, mode and encoding checks for audio), and for this training pipeline, the durable copy should go to storage you control.

Ingesting into SageMaker AI Feature Store

Amazon SageMaker AI Feature Store keeps feature values so that training and inference read the same data. The AWS MLA-C02 exam guide lists 'Skill 1.1.9: Ingest data into SageMaker Feature Store.' separately from 'Skill 1.2.2: Create and manage features by using AWS tools (for example, SageMaker Feature Store).'; for the second, see Transform data and engineer features.

Two stores, two read patterns

A feature group, Feature Store's main resource, can be configured with an online store, an offline store, or both. The online store retains only the latest records and is designed for real-time predictions that need low millisecond latency reads; the offline store keeps all records as a historical database for data exploration, model training and batch predictions[66], and it stores that history in your S3 bucket. Querying the offline store for every latency-sensitive inference request substitutes an analytical scan for the lookup the online store exists to serve.

The feature group contract

Before anything is ingested, the feature group defines its record schema. Each feature definition consists of a name and one of the data types integral, string or fractional[67]. The record identifier names the feature that identifies the entity, such as a customer ID. The event time is the timestamp of when the record's event occurred, and every record must carry one. A combination of record identifier and event time uniquely identifies a record within the feature group. Validate incoming data against this contract; a feature group is not a schemaless document collection. Using an ingestion job's run ID as every row's record identifier collapses unrelated entities under one lookup key.

Streaming and batch ingestion

Feature Store accepts data in two ways: streaming, where records are pushed with the synchronous PutRecord API as soon as an update is detected, or batches[66], for example features authored in SageMaker Data Wrangler and ingested by a SageMaker AI Processing job. Both populate the same feature groups, so a batch arrival pattern is no reason to build a separate feature repository.

Event time decides what is current

Event time here is the same idea as the Flink event time above: when the event happened, not when the record arrived. If a new record's EventTime is greater, the new record is written to both the OnlineStore and OfflineStore; otherwise, the record is a historic record and it is written only to the OfflineStore[68]. The figure below traces that decision. A historical backfill therefore lands in the offline history without overwriting newer online values, and the last record to arrive does not become current merely by arriving last.

To restrict a write explicitly, the TargetStores request parameter names the store or stores to write; by default, Feature Store adds the record to all of the stores the feature group uses. Targeting only the offline store is the clean way to load history. Targeting cannot create a store the feature group was never configured with.

Whole-record writes

PutRecord writes a whole record: send every feature value the resulting record must contain, because omitted features are not merged in from the previous version. The Standard_V2 online store tier adds partial updates: it supports partial updates to individual features using the UpdateRecord operation, without rewriting the entire record[69], which the Standard tier does not.

Reading history back for training

The offline store is an append-only store, and its data is stored in Parquet format[66], so a raw query returns every version of every entity. An entity-level training snapshot needs one chosen version per entity at a chosen point in time. The SageMaker Python SDK's create_dataset() helper does not include deleted or duplicated records by default[70] and offers selectors such as as_of, which builds the dataset up to a timestamp you specify. Using every historical row as a current independent training example mixes feature versions into the training population.

Takeaway: define the contract (record identifier, event time, data types), ingest by stream or batch into the stores you configured, and let event time, not arrival order, decide what is current.

PutRecordrecord with event timeEvent time later than thecurrent record's event time?YesNoOnline store andoffline storeOffline store only(historic record)
How Feature Store routes a PutRecord write by event time, for a feature group with both stores and the default TargetStores.

Vector stores for AI retrieval: OpenSearch Service vs RDS for PostgreSQL with pgvector vs S3 Vectors

Decision factorAmazon OpenSearch ServiceAmazon RDS for PostgreSQL with pgvectorAmazon S3 Vectors
Storage modelknn_vector fields in a k-NN index on an OpenSearch Service domainVector columns added to PostgreSQL tables by the pgvector extensionVector indexes inside a vector bucket
Queries next to similarity searchFull-text (lexical) search, filters and hybrid lexical-plus-vector queriesSQL over the same relational rows (joins, filters, transactions)Similarity queries with metadata filters on filterable keys
Pick it whenKeyword matching and vector similarity are both requiredAn existing PostgreSQL application must keep vectors next to its relational dataYou want S3-native vector storage with no infrastructure to provision
Settings to plan up frontVector dimension per knn_vector field; approximate (HNSW) or exact search trades recall against latencyAn RDS for PostgreSQL engine version that supports the pgvector extensionDimension, distance metric (Cosine or Euclidean) and non-filterable metadata keys are fixed at index creation

Decision tree

Does the source deliverrecords continuously?Does the sourcehold files?Must several applicationsreplay the records?Is the source anEBS volume?Is the source aDynamoDB table?NoYesYesNoYesNoYesNoYesNoMount file systemon an EC2 instanceAWS DataSyncagent for NFS or SMBDynamoDB exportuses no read capacityAWS Glue connectionJDBC or OpenSearchKinesis Data Streamsor Kafka as replay log,then Firehose into S3Amazon Data Firehosedelivery, no replay

Sharp facts the exam loves — give these one last read before exam day.

Cheat sheet

Sharp facts the exam loves — scan these before test day.

A cross join generates combinations rather than matching entity keys

A Cartesian cross join combines every row of one dataset with every row of the other. Use it only when all combinations are intended, such as constructing an explicit candidate grid. For ordinary enrichment, join on the relevant key to avoid an unintended explosion in intermediate data and processing cost.

Trap Selecting a Cartesian cross join to merge customer attributes into transaction rows, which creates combinations instead of matching each transaction's customer.

3 questions test this
Lake Formation blueprints generate repeatable data-lake ingestion workflows

When an existing data lake needs relational database ingestion with minimal custom development, use an AWS Lake Formation database blueprint. The blueprint generates AWS Glue crawlers, jobs, and triggers to load and catalog the data. Choose a database snapshot for a full load or an incremental database blueprint for supported incremental ingestion.

Trap Using an Amazon Kinesis Data Streams stream as a relational extraction workflow, although producers must still extract and publish the database records.

3 questions test this
DynamoDB exports extract training data without consuming table read capacity

When extracting a large DynamoDB dataset must not compete with application reads, export the table to Amazon S3 and process the exported data. Export requires point-in-time recovery and does not consume read capacity units. Export and S3 charges still apply, and asynchronous completion should not be treated as a fixed-time guarantee.

Trap Using a parallel table scan to avoid read-capacity consumption, although scan operations consume the table's read capacity.

3 questions test this
An existing DynamoDB export can be reused across Glue processing runs

AWS Glue's DynamoDB export connector can read an existing export from Amazon S3 instead of requesting a fresh table export. Reuse the export when repeated preprocessing experiments should use the same source snapshot. Request a new export when the dataset must reflect later table changes.

Trap Requesting a new table export for every transformation experiment, although the existing S3 export already contains the required snapshot.

3 questions test this
A Glue JDBC connection needs network access as well as database credentials

A Glue connection to a private relational database must use a reachable VPC subnet and appropriate security groups in addition to valid database authentication. Glue attaches network interfaces using the connection's networking configuration. A successful credential check alone does not establish a path to the database endpoint.

Trap Rotating the database password to fix a connection timeout caused by a blocked network path, which does not change routing or security-group rules.

3 questions test this
DataSync transfers file-based corpora into an existing S3 ingestion location

When a dataset resides on an NFS or SMB file server and must be copied into Amazon S3, use AWS DataSync with the appropriate source and destination locations. These file-server transfers require a DataSync agent. This is file movement; the downstream preprocessing job still performs record parsing and feature transformations.

Trap Using a Glue JDBC connection to copy an SMB document collection, although JDBC connects to database records rather than file shares.

3 questions test this
Joins enrich matching entities while unions append compatible records

Use a join when transaction rows need attributes from a customer table matched by a key. Use a union when datasets represent additional rows of the same logical schema. Align column meanings and data types before appending records, rather than interpreting a union as an entity match.

Trap Unioning customer profiles with transactions to enrich each transaction, although appending rows does not match customers to their transactions.

3 questions test this
A left join preserves source examples that lack enrichment matches

When every training example must survive enrichment, make the examples the left side of a left join. An inner join retains only matched keys and can silently change which examples remain. Inspect missing enrichment values and repeated keys because the join type does not itself clean or deduplicate the inputs.

Trap Choosing an inner join solely to add optional profile fields, which removes examples whose profile key has no match.

3 questions test this
Existing EBS dataset files become readable through the volume's mounted file system

Amazon EBS exposes an attached volume as a block device rather than an object-storage location. To extract files from an existing EBS dataset, make its existing file system available on the attached EC2 instance and have the extraction process read the mounted files. A volume restored from a snapshot can already contain the file system and dataset.

Trap Formatting a restored dataset volume as if it were empty, which overwrites its existing file system and data.

3 questions test this
An EFS-to-S3 DataSync transfer can use the managed EFS source without an agent

When an existing Amazon EFS file corpus must be copied to Amazon S3 for preparation, configure an EFS source location and an S3 destination in AWS DataSync. For a transfer within the same AWS account, whether in the same Region or across Regions in the same AWS partition, no DataSync agent is required; DataSync accesses the EFS mount target through VPC network interfaces. Configure the location's subnet, security groups, and file-system access permissions so the source files are readable.

Trap Treating managed EFS as an on-premises NFS source requiring a deployed DataSync agent, which applies the self-managed file-server access path unnecessarily.

3 questions test this
Incremental RDS extraction through Glue depends on suitable JDBC bookmark keys

Extract Amazon RDS relational tables through an AWS Glue JDBC connection compatible with the database engine. Use a full table read when all source rows are required; for repeated incremental reads, enable JDBC bookmarks and select keys that satisfy the bookmark ordering requirements. User-defined bookmark keys must each be strictly monotonically increasing or decreasing, because Glue compares their values with saved progress to identify later rows. An update to an old row whose bookmark key remains unchanged is not newly discoverable through that key alone.

Trap Selecting a revision counter reused across different records as a bookmark key, which violates the required monotonic ordering across the dataset.

3 questions test this
Glue can extract selected OpenSearch index documents into a preparation job

Use an AWS Glue for Spark OpenSearch Service connection when existing indexed documents must become input to dataset preparation. Select the source index and supply an OpenSearch query with pushdown so the service returns the relevant documents to a DynamicFrame. This native connection supports OpenSearch Service domains, not OpenSearch Serverless, so verify the source deployment type before choosing it.

3 questions test this
AWS Glue executes multi-source joins and unions in its managed Spark environment

AWS Glue Spark jobs run Apache Spark as the processing engine for batch dataset merging, including Join and Union transforms configured in the visual ETL editor. The Join transform takes two input datasets and explicit matching keys; the Union transform requires compatible input schemas and offers ALL or DISTINCT behavior. Select DISTINCT when the merged output must remove duplicate rows, rather than assuming that appending sources automatically deduplicates them.

3 questions test this
Parquet and ORC suit repeated analytical reads of selected columns

When feature preparation repeatedly reads a subset of a wide dataset's columns, store the analytical copy in Parquet or ORC. Columnar layout and compression can reduce the data read by compatible query engines. CSV remains useful for simple interchange but does not provide the same column-oriented layout.

Trap Choosing CSV because it is human-readable when the controlling requirement is minimizing repeated wide-table column scans.

3 questions test this
JSON represents nested records without flattening them into positional columns

JSON is suitable for semi-structured records that contain named fields, nested objects, or arrays. CSV is a flat row-and-column representation, so nested content requires an agreed serialization or flattening convention. Choose the input format that the consumer actually supports rather than assuming every ML algorithm accepts nested JSON.

Trap Writing nested objects directly into ordinary CSV fields without an encoding convention, which leaves the intended structure ambiguous to the reader.

3 questions test this
Firehose format conversion uses JSON input and a Glue schema

Amazon Data Firehose can convert JSON records to Parquet or ORC before delivery to Amazon S3 by using a schema in the AWS Glue Data Catalog. When the incoming records use another format, transform them into compatible JSON before conversion. Catalog fields govern which data can be represented in the converted output.

Trap Enabling Parquet conversion directly on raw CSV records, although the format-conversion stage expects JSON input.

3 questions test this
S3 archival choices must match the dataset's retrieval requirements

When a dataset must be read immediately, choose a storage class that supports immediate access. S3 Glacier Flexible Retrieval and S3 Glacier Deep Archive require restoration before ordinary access, whereas S3 Glacier Instant Retrieval supports millisecond retrieval. A lower storage charge alone does not make a restore-based archive suitable for an immediately scheduled preprocessing run.

Trap Putting the next training run's only dataset copy in S3 Glacier Deep Archive to minimize storage cost while retaining an immediate-read requirement.

3 questions test this
S3 Intelligent-Tiering fits datasets with changing or unknown access patterns

Use S3 Intelligent-Tiering when access frequency is difficult to predict and automatic movement between access tiers is useful. Its monitoring and automation have their own cost considerations, and optional archive tiers introduce retrieval considerations. A fixed infrequent-access class is a different choice when the access pattern is already known.

Trap Treating S3 Standard-IA as an automatic access-pattern optimizer, although it is a selected storage class rather than an automatic tiering mechanism.

3 questions test this
S3 Object Lock compliance mode prevents early deletion of protected versions

When a dataset version must remain immutable for its retention period even against privileged users, use S3 Object Lock compliance mode. Governance mode permits authorized bypass, so it serves a different control requirement. Object Lock protects object versions rather than preventing the creation of a new version with the same key.

Trap Choosing governance mode for retention that administrators must not bypass, although specially authorized users can bypass governance retention.

3 questions test this

Use an S3 Object Lock legal hold when preservation must continue without a predetermined expiration date. A fixed retention period instead protects a version until a specified date. Legal holds and retention periods are independent, so expiration of retention does not remove an active legal hold.

Trap Using only a fixed retention date for an investigation with an unknown end date, which allows the time-based protection to expire.

3 questions test this
S3 dataset partitions should match the filters used by downstream queries

Partition an S3 analytical dataset by fields commonly used to restrict queries, such as event date or customer identifier. A partition-aware query engine can then prune irrelevant partitions and read only the relevant portion of the dataset. This optimization selects which groups of files to scan, complementing columnar formats that reduce which columns must be read within those files.

3 questions test this
A reproducible prepared corpus needs a versioned artifact and its source lineage

Version prepared datasets and record the source identities, source versions or extraction points, and transformations that produced each version. Retain the relevant source and output versions under the dataset's retention policy so a particular corpus can be reproduced and audited. Source metadata identifies where data came from, while transformation lineage explains how it became the prepared artifact.

Trap Keeping only the preparation code while overwriting the input and output datasets, which preserves transformation logic but loses the specific data used by an earlier run.

Kinesis Data Streams supports replay within the retained stream history

When independent applications must consume and replay the same incoming records, use Amazon Kinesis Data Streams and keep the required history within its retention window. Each consumer maintains its own progress through the stream. Amazon Data Firehose focuses on managed delivery to destinations rather than exposing an equivalent general-purpose replay log.

Trap Choosing a Firehose delivery stream as the independent replay log, although its delivery interface is not the Kinesis Data Streams consumer model.

3 questions test this
Firehose buffering affects when records reach their destination

Amazon Data Firehose buffers incoming records before delivery according to the destination and configured buffering settings. Select settings that fit the required freshness rather than equating ingestion acceptance with destination availability. Larger delivery batches can improve write efficiency but can delay visibility of low-volume data.

Trap Increasing Firehose buffer intervals to solve a low-volume delivery-freshness problem, which extends the period before a buffer is delivered.

3 questions test this
A hot Kinesis partition key can bottleneck one shard

With partition-key-based record distribution, Kinesis Data Streams maps partition keys to shards, so a heavily reused key can concentrate writes on one shard. When throttling is concentrated rather than evenly distributed, review the key distribution as well as total capacity. In this mode, adding shards does not split a single partition key's records across multiple shards.

Trap Adding aggregate shard capacity while keeping all high-volume events under one partition key in a stream using partition-key-based record distribution, which leaves that key concentrated on one shard.

3 questions test this
Enhanced fan-out gives registered consumers dedicated shard read throughput

When multiple Kinesis consumers contend for shared read throughput, use enhanced fan-out for consumers that need dedicated delivery capacity. Shared-throughput consumers compete within the shard's shared read allowance. Enhanced fan-out addresses consumer contention, not a producer-side hot-key write bottleneck. Shards belong to the stream, not to producers (a Kinesis data stream is a set of shards[1]): adding shards still leaves shared-throughput consumers splitting each shard's read throughput[2].

Trap Adding shards solely to isolate competing readers without considering enhanced fan-out's per-consumer read capacity.

3 questions test this
Kinesis ordering is scoped to shards rather than the whole stream

Kinesis Data Streams assigns sequence numbers to records within a shard. Use partitioning that keeps related events together when their relative order matters, and account for producer sequencing and retries. A multi-shard stream does not provide a single total order across unrelated partition keys.

Trap Sorting all stream records by sequence number as though sequence numbers form a globally ordered stream-wide counter.

3 questions test this

Use event time in Amazon Managed Service for Apache Flink when features such as windowed transaction counts must reflect source-event timestamps despite delivery delays. Processing time instead follows the clock of the machine executing the operation, and ingestion time follows entry into the service. Select the time basis that matches the feature's business meaning.

Trap Using processing-time windows for event-occurrence statistics when network delays can move records into later processing windows.

3 questions test this
Kafka topics organize streams into partition-level ordered logs

Apache Kafka organizes records into named topics, with each topic divided into partitions that act as ordered logs. Producers append records to a partition and consumers read from positions within that log. Use partition-aware ingestion when related records need ordered processing; parallel partitions do not form one globally ordered topic log.

3 questions test this
Kafka consumer groups distribute partitions among workers rather than broadcast every record

Use the same Apache Kafka consumer group for workers that should share one ingestion workload. Within a group, a partition is assigned to only one consumer at a time, so partition count bounds useful consumer parallelism. Use separate consumer groups when independent applications each need to consume the stream for their own purpose.

Trap Increasing topic replication to give more workers partition assignments, which adds redundant record copies rather than additional partitions for the group to share.

3 questions test this
Kafka committed offsets record where a consumer group should resume

Apache Kafka offsets identify positions within topic partitions, and committed consumer-group offsets preserve consumption progress for resumption. Keep the intended group identity and its saved offsets when restarting an ingestion consumer. Replay also requires the source records to remain within the topic's retained history; saving a position does not retain the underlying records indefinitely.

Trap Relying on topic replication alone to resume a restarted consumer: replication adds copies of each partition for durability, while a consumer that rejoins its group resumes from the consumer group's committed offset.

3 questions test this
Firehose dynamic partitioning can route records by their content and event date

When S3 delivery must group records by customer or the date the source event occurred, use Amazon Data Firehose dynamic partitioning with keys extracted from each record. Firehose evaluates the configured S3 prefix expression and groups records with the same result for delivery. Deriving date components from the record's event timestamp also places delayed events with their event-date data rather than merely with records that arrived together.

2 questions test this
Firehose dynamic partition cardinality can exhaust capacity despite modest total traffic

Amazon Data Firehose creates a separate buffer for every active dynamically evaluated S3 prefix, and each buffer is delivered independently when its size or time condition is met. Many low-volume prefixes can therefore produce small objects and a high active-partition count even when aggregate ingestion throughput is modest. Check partition cardinality and stalled deliveries when diagnosing active-partition errors: a partition remains active until its buffered data is delivered, and exceeding the active-partition quota routes excess records to the S3 error prefix.

Trap Increasing the buffering interval to address small files when active-partition capacity is already exhausted, which can keep more partition buffers active for longer.

2 questions test this
Firehose can insert newline separators between records delivered to S3

Enable Firehose's new line delimiter option when downstream readers need newline-separated records within delivered S3 objects. This setting adds separators between output records, whereas multi-record deaggregation splits logical events bundled inside an input record. Choose the setting for the boundary that needs to change: output record separation or input event separation.

Trap Using Firehose's JSON-to-Parquet conversion to meet a newline-delimited text requirement, which produces a columnar format instead of the expected text records.

Firehose partition-key failures can be diagnosed from the S3 error prefix

A missing or differently named field can prevent Firehose from extracting the configured dynamic partition key and evaluating the destination prefix. Firehose delivers records that fail parsing, key extraction, or prefix evaluation to the required S3 error prefix, organized by error type and accompanied by error details. Inspect those details and compare the failed record's field names and structure with the extraction expression before correcting the producer or routing configuration.

Trap Requesting a higher active-partition quota for missing-key errors, which changes partition capacity rather than repairing the record fields used for routing.

2 questions test this
Firehose loads Redshift through S3 staging and a COPY command

For an Amazon Redshift destination, Amazon Data Firehose first delivers streaming records to an S3 bucket and then issues a Redshift COPY command to load them into the cluster. Include that staging bucket in the delivery configuration and distinguish successful S3 delivery from completion of the Redshift load. If source-record backup is also enabled for transformed data, that optional backup serves a separate purpose from the S3 staging step.

2 questions test this
RDS for PostgreSQL with pgvector adds vector retrieval to relational data

When an existing PostgreSQL application must combine SQL data with embedding similarity search, use the pgvector extension on a supported Amazon RDS for PostgreSQL version. It supplies vector storage and similarity operations within the database. Keep this choice distinct from moving the dataset into a separate search service when the stated requirement is to retain relational integration.

Trap Moving relational records into an OpenSearch index solely to obtain vectors when the requirement specifically calls for SQL integration inside the existing database.

2 questions test this
OpenSearch Service supports text search alongside vector similarity

Use Amazon OpenSearch Service when an existing retrieval workload needs both full-text search and vector similarity. Store embeddings in a vector field and retain searchable text or structured fields for the other query requirements. Embedding generation remains a separate preparation step unless an explicitly configured model integration performs it.

Trap Selecting a vector-only similarity operation as a replacement for exact keyword matching when both retrieval behaviors are required.

2 questions test this
S3 Vectors uses vector buckets and indexes rather than ordinary object listings

Amazon S3 Vectors stores embeddings in vector indexes within vector buckets and exposes similarity-query operations. Use these resources when the specified workload needs S3-native vector storage and retrieval. Uploading arrays into ordinary S3 objects preserves the bytes but does not itself create a similarity-search index.

Trap Storing embeddings as JSON objects in a general-purpose S3 bucket and expecting object-list operations to perform nearest-neighbor search.

2 questions test this
Every vector in an S3 vector index must match its configured dimension

Configure an S3 vector index with the embedding model's selected output dimension. Every inserted vector must have exactly that number of values. Changing to a different output dimension requires a new index because the dimension of an existing index cannot be updated.

Trap Padding a newly generated shorter embedding with arbitrary values to reuse an incompatible index, which changes the intended vector representation.

2 questions test this
The vector distance metric should follow the embedding model's recommendation

Choose the index distance metric that the embedding model recommends. In S3 Vectors, cosine distance emphasizes vector direction, while Euclidean distance incorporates straight-line separation and therefore magnitude. Changing the metric of an existing S3 vector index requires a new index rather than an in-place setting change.

Trap Choosing cosine distance for a representation whose required similarity depends on vector magnitude as well as direction, although cosine comparison discards that magnitude distinction.

2 questions test this
Only filterable vector metadata can restrict S3 similarity queries

Keep attributes such as document category filterable when retrieval must restrict results by those attributes. S3 Vectors metadata is filterable unless configured as non-filterable; non-filterable fields can accompany returned vectors but cannot be used as query filters. Long source text that is returned for context is a suitable candidate for non-filterable metadata.

Trap Marking a required category-filter field as non-filterable to save filterable metadata space, which removes that field from filtering operations.

2 questions test this
Approximate nearest-neighbor search trades exactness for retrieval efficiency

When an OpenSearch vector workload needs scalable similarity retrieval, an approximate nearest-neighbor index can avoid exhaustively comparing every stored vector. Approximation can miss neighbors that exact search would return, so evaluate recall as well as query latency. Use exact search when the required result guarantees and dataset size justify exhaustive comparison.

Trap Treating approximate nearest-neighbor results as guaranteed identical to exhaustive search merely because both return a requested number of neighbors.

2 questions test this
Knowledge-base synchronization incrementally processes source changes

After adding, modifying, or removing documents in a connected knowledge-base source, synchronize the source so the indexed content reflects those changes. Synchronization processes documents changed since the preceding sync rather than requiring every unchanged document to be processed again. Updating the source files alone does not complete the indexing step.

Trap Recreating the entire knowledge base after every document edit to refresh retrieval, although incremental synchronization processes the source changes.

2 questions test this
Scanned documents need OCR before ordinary text preprocessing

When source PDFs contain page images rather than an extractable text layer, use OCR such as Amazon Textract to obtain text. Ordinary PDF text extraction is appropriate for digitally authored documents with embedded text. Inspect the extracted output because document layout can affect reading order and field interpretation.

Trap Using a text-only PDF parser on scanned page images, which have no embedded text for that parser to extract.

2 questions test this
HTML ingestion should separate page content from navigation boilerplate

When preparing web pages as a text corpus, extract the passages that bear on each page's subject rather than keeping a raw HTML dump, so less of the model's input goes to boilerplate and navigation, and keep the headings, which help RAG models understand document structure. When menus repeat across pages, a dump of every visible string can overrepresent those menus rather than each page's subject.

Trap Using a dump of every visible string as clean article content, which includes repeated navigation and unrelated page elements.

2 questions test this
Transcribe batch and streaming transcription have different input requirements

Use Amazon Transcribe batch transcription for media files in Amazon S3 and streaming transcription for live media streams. Supported audio formats differ between these modes, so a format accepted by a batch job is not automatically a valid streaming encoding. Validate the actual encoding before choosing the ingestion mode.

Trap Sending a WAV file unchanged as streaming PCM because batch transcription accepts WAV, although a WAV container is not raw PCM stream encoding.

2 questions test this
Speaker partitioning and channel identification solve different audio layouts

Use Transcribe speaker partitioning when multiple speakers share one audio channel and their speech must be distinguished. Use channel identification when speakers are already separated into different audio channels. Both can produce a single transcript file, so the number of output files is not the selection criterion.

Trap Selecting channel identification to separate speakers mixed into one channel, which provides no separate channels for that feature to identify.

2 questions test this
A declared audio sample rate must match the actual recording

Amazon Transcribe streaming requests require the audio sample rate, while batch requests can omit it. When supplied, the rate must describe the actual audio; changing the declared number does not resample the recording. A mismatch can make a transcription request fail.

Trap Declaring a higher sample rate to improve low-fidelity audio, which changes request metadata rather than the samples themselves.

2 questions test this
Long-lived transcription datasets should be saved to controlled storage

For batch transcripts that must remain available as training data, specify an Amazon S3 output bucket you control and grant Transcribe permission to write there. Service-managed output provides temporary download access and is removed when the transcription job expires. A temporary download link is not a durable dataset location.

Trap Saving only the service-managed transcript download URL as the permanent dataset reference, although that URL expires.

2 questions test this
Image ingestion must validate usable image assets rather than just file locations

An image corpus needs decodable files in formats and dimensions supported by the consuming workflow. During ingestion, identify corrupted images and create resized working copies where required, while retaining the original assets and a source reference linking each prepared image to its origin. Data Wrangler supports image import, corrupted-image removal, and resizing; a Ground Truth input manifest's source-ref entries can preserve the association between an S3 image location and its dataset record.

Trap Replacing the image corpus with OCR text, which preserves extracted characters but not the visual assets required by an image workflow.

2 questions test this
Feature Store online and offline stores serve different access patterns

Use the Feature Store online store for low-latency access to current feature values and the offline store for historical training datasets and batch analysis. A feature group can use either store or both. The offline store preserves history in Amazon S3 rather than acting as the low-latency current-value lookup.

Trap Querying the offline store for every latency-sensitive inference request because it contains the complete history, which substitutes analytical access for the online lookup path.

3 questions test this
Feature group ingestion requires a defined record schema and event time

Before ingesting features, define the feature names and types, the record identifier, and the event-time feature. The record identifier identifies the entity, while event time identifies when the feature record applies. Validate incoming values against this contract rather than treating a feature group as an arbitrary schemaless document collection.

Trap Using the ingestion job's run identifier as every entity's record identifier, which collapses unrelated entities under the same lookup key.

3 questions test this
Feature Store uses event time to distinguish current values from history

When an ingested record has a later event time than the existing record for that entity, it can replace the current online value. Older historical records are written to the configured offline history instead of replacing newer online state. This allows historical backfills without making current features stale.

Trap Assuming the last-arriving historical record becomes the online value solely because it was ingested last, which ignores event-time ordering.

3 questions test this
Feature Store can target offline ingestion without changing online features

When a historical dataset should populate only the offline store, explicitly target that store during ingestion. Otherwise, Feature Store targets the stores configured for the feature group, subject to event-time rules. Store targeting controls where records are ingested; it does not create a store that was never configured.

3 questions test this
A Feature Store PutRecord write replaces a record rather than patching one field

Feature Store PutRecord performs a full-record overwrite, so provide the feature values that the resulting record must contain. Use UpdateRecord with the Standard_V2 online store tier when the requirement is to change individual feature values without replacing the rest. Selecting the write semantics prevents an ingestion update from unintentionally dropping unrelated values.

Trap Sending only one changed feature in a full-record replacement and expecting omitted features to be merged automatically.

3 questions test this
Feature Store accepts both incremental updates and batch feature loads

Use streaming record writes when updated features must become available as individual source updates arrive. Use a batch processing workflow, such as a Data Wrangler export executed as a SageMaker AI Processing job, for scheduled bulk feature preparation and ingestion. Both approaches populate feature groups rather than requiring separate feature definitions for each arrival mode.

Trap Building a separate feature repository solely because source updates arrive in batches, although Feature Store supports batch ingestion.

3 questions test this
Offline feature history needs explicit snapshot selection for training

Feature Store's offline store is append-only historical storage in Parquet, so a raw query can return several versions of the same entity. Select the required time horizon and handle deleted or duplicate records when constructing a training dataset. The dataset-building helpers can perform this filtering; a raw table scan does not inherently represent one current row per entity.

Trap Treating every offline history row as an independent current entity, which mixes multiple feature versions into the training population.

3 questions test this

Also tested in

References

  1. https://docs.aws.amazon.com/streams/latest/dev/key-concepts.html
  2. https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html
  3. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html
  4. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/S3DataExport.HowItWorks.html
  5. https://docs.aws.amazon.com/aws-certification/latest/machine-learning-engineer-associate-02/machine-learning-engineer-associate-02-domain1.html
  6. https://docs.aws.amazon.com/ebs/latest/userguide/ebs-using-volumes.html
  7. https://docs.aws.amazon.com/datasync/latest/userguide/working-with-locations.html
  8. https://docs.aws.amazon.com/glue/latest/dg/start-connecting.html
  9. https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-dynamodb-home.html
  10. https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-opensearch-home.html
  11. https://docs.aws.amazon.com/firehose/latest/dev/create-name.html
  12. https://docs.aws.amazon.com/firehose/latest/dev/writing-with-msk.html
  13. https://docs.aws.amazon.com/athena/latest/ug/columnar-storage.html
  14. https://docs.aws.amazon.com/glue/latest/dg/aws-glue-programming-etl-connect-s3-home.html
  15. https://docs.aws.amazon.com/datasync/latest/userguide/how-datasync-transfer-works.html
  16. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference-arns.html
  17. https://docs.aws.amazon.com/datasync/latest/userguide/create-efs-location.html
  18. https://docs.aws.amazon.com/glue/latest/dg/programming-etl-connect-bookmarks.html
  19. https://docs.aws.amazon.com/lake-formation/latest/dg/workflows-about.html
  20. https://docs.aws.amazon.com/glue/latest/dg/transforms-configure-union.html
  21. https://docs.aws.amazon.com/redshift/latest/dg/r_FROM_clause30.html
  22. https://docs.aws.amazon.com/glue/latest/dg/what-is-glue.html
  23. https://docs.aws.amazon.com/glue/latest/dg/transforms-configure-join.html
  24. https://docs.aws.amazon.com/sagemaker/latest/dg/cdf-inference.html
  25. https://docs.aws.amazon.com/firehose/latest/dev/record-format-conversion.html
  26. https://docs.aws.amazon.com/athena/latest/ug/partitions.html
  27. https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html
  28. https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html
  29. https://docs.aws.amazon.com/wellarchitected/latest/machine-learning-lens/mlrel02-bp03.html
  30. https://docs.aws.amazon.com/streams/latest/dev/service-managed-pk-considerations.html
  31. https://docs.aws.amazon.com/streams/latest/dev/service-managed-pk-consuming-considerations.html
  32. https://docs.aws.amazon.com/streams/latest/dev/large-records.html
  33. https://docs.aws.amazon.com/streams/latest/dev/troubleshooting-producers.html
  34. https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html
  35. https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes-msk.html
  36. https://docs.aws.amazon.com/msk/latest/developerguide/bestpractices.html
  37. https://docs.aws.amazon.com/managed-flink/latest/java/what-is.html
  38. https://docs.aws.amazon.com/managed-flink/latest/java/how-time.html
  39. https://docs.aws.amazon.com/managed-flink/latest/java/best-practices.html
  40. https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html
  41. https://docs.aws.amazon.com/firehose/latest/dev/create-configure-backup.html
  42. https://docs.aws.amazon.com/firehose/latest/dev/buffering.html
  43. https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning-partitioning-keys.html
  44. https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning-s3bucketprefix.html
  45. https://docs.aws.amazon.com/firehose/latest/APIReference/API_CreateDeliveryStream.html
  46. https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning-error-handling.html
  47. https://docs.aws.amazon.com/firehose/latest/dev/create-destination.html
  48. https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning-multirecord-deaggergation.html
  49. https://docs.aws.amazon.com/prescriptive-guidance/latest/migration-solr-opensearch/overview.html
  50. https://docs.aws.amazon.com/prescriptive-guidance/latest/choosing-an-aws-vector-database-for-rag-use-cases/vector-db-options.html
  51. https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors.html
  52. https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-setup.html
  53. https://docs.aws.amazon.com/opensearch-service/latest/developerguide/knn.html
  54. https://docs.aws.amazon.com/opensearch-service/latest/developerguide/vector-search.html
  55. https://docs.aws.amazon.com/opensearch-service/latest/developerguide/s3-vector-opensearch-integration-engine.html
  56. https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-vectors-indexes.html
  57. https://docs.aws.amazon.com/textract/latest/dg/what-is.html
  58. https://docs.aws.amazon.com/textract/latest/dg/how-it-works-detecting.html
  59. https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/gateway-target-connector-web-search-tool.html
  60. https://docs.aws.amazon.com/prescriptive-guidance/latest/writing-best-practices-rag/best-practices.html
  61. https://docs.aws.amazon.com/bedrock/latest/userguide/kb-data-source-sync-ingest.html
  62. https://docs.aws.amazon.com/sagemaker/latest/dg/data-wrangler-transform.html
  63. https://docs.aws.amazon.com/sagemaker/latest/dg/canvas-data-prep.html
  64. https://docs.aws.amazon.com/sagemaker/latest/dg/sms-input-data-input-manifest.html
  65. https://docs.aws.amazon.com/transcribe/latest/dg/how-input.html
  66. https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store.html
  67. https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-concepts.html
  68. https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_feature_store_PutRecord.html
  69. https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-storage-configurations-online-store.html
  70. https://docs.aws.amazon.com/sagemaker/latest/dg/feature-store-create-a-dataset.html