THE AWS CERTIFIED DEVELOPER – ASSOCIATE EXAM TOPICS COVERED IN THIS CHAPTER MAY INCLUDE, BUT ARE NOT LIMITED TO, THE FOLLOWING:
Content may include the following:
Content may include the following:
As applications grow, they become harder to manage and maintain. Application components are tightly coupled with each other, and the failure of one component can cause the failure of the whole application.
Microservices architecture is a method to design and build software applications as a suite of modular services, each performing a specific functional task, which deploy and access application components via well-defined standard application programming interfaces (APIs). Where possible, you automate the provisioning, termination, and configuration of resources. A best-practice scenario is shown in Figure 11.1. In this case, if an application fails, Amazon CloudWatch automatically detects the unhealthy instance and alerts AWS Auto Scaling to launch and configure an identical server, notifies the administrator, and logs the action to your change management solution.
Containers are software-defined execution environments that you can rapidly provision and independently deploy in server and serverless environments. Microservices that run in containers take portability and interoperability to a new level because the services function the same on-premises as they do in any cloud that supports containers. Independence and modularity also provide opportunities to design for elastic scalability and operational resilience.
To refactor to microservices is to separate the application components into separate microservices so that each microservice has its own data store, scales independently, and deploys on its own infrastructure. Refactoring includes rewriting and decoupling applications, re-architecting a solution, and determining whether you will perform a complete refactor (lift and shift—all in) or only a partial refactor (lift and shift—hybrid).
To refactor to microservices requires a message infrastructure so that the microservices can communicate with each other. Message queues communicate between applications. AWS provides the message infrastructure that enables you to build microservice architectures without the need to spend the time and effort for a connective infrastructure.
A serverless solution is provisioned at the time of need. You can store static web assets externally, such as in an Amazon S3 bucket, and user authentication and user state storage are handled by managed AWS offerings and services.
You can further safeguard your application against latency because of failure if you avoid a single point of failure, as shown in Figure 11.2.
This section describes the different services AWS provides to enable the building of microservice architectures. The certification exam objectives for refactoring to microservices include the following:
Message-oriented middleware (MoM) supports messaging types in which the messages that are produced (producers) can broadcast and publish to multiple message consumers, also known as message subscribers.
Amazon Simple Queue Service (Amazon SQS) is a fully managed message queuing service that makes it easy to decouple and scale microservices, distributed systems, and serverless applications to assist in event-driven solutions. Amazon SQS both moves data between distributed application components and helps you to decouple these components. Amazon SQS is the best option for cloud-designed applications that need unlimited scalability, capacity, throughput, and high availability. Amazon SQS temporarily stores messages from a message producer while they wait for a message consumer to process the message.
With the use of Amazon SQS, application components send messages to each other and do not have to wait for a response, as shown in Figure 11.3.
The producer is the component that sends the message. The consumer is the component that pulls the message off the queue. The queue passively stores messages and does not notify you of new messages. When you poll the Amazon SQS queue, the queue responds with messages that it includes, as shown in Figure 11.4.
With Amazon SQS, multiple producers can write messages, and multiple consumers can process the messages. One of the consumers processes each message, and when a consumer processes a message, they remove it from the queue. That message is no longer available for other consumers. If the amount of work on the queue exceeds the capacity for a single consumer, you can add more consumers to help the process.
Figure 11.5 illustrates the way that the Amazon SQS queue interacts with both Amazon EC2 and the process servers.
As shown in Figure 11.6, a sign-in service run on a single log server is dependent on the reliability of the log server to send and receive messages. If the log server experiences any issues, the sign-in service can go offline.
If you replace the log server with an Amazon SQS queue with multiple log servers, you can remove this point of failure.
As the other servers in your application send their sign-in messages to the queue, the sign-in server can pull messages off the queue and process them, as shown in Figure 11.7.
There are several benefits to using the Amazon SQS queue:
The Amazon SQS is a distributed cluster of servers. There is no limit on the number of producers that can write to the queue, and there is no limit on the number of messages that the queue can store.
Amazon SQS is a Payment Card Industry Data Security Standard (PCI DSS) service.
An Amazon SQS message has three basic states:
A message is stored after it is sent to a queue by a producer but not yet received from the queue by a consumer (that is, between states 1 and 2). There is no limit to the number of stored messages. A message is considered to be in-flight after it is received from a queue by a consumer but not yet deleted from the queue (that is, between states 2 and 3). There is a limit to the number of in-flight messages.
Limits that apply to in-flight messages are unrelated to the unlimited number of stored messages.
For most standard queues (depending on queue traffic and message backlog), there can be a maximum of approximately 120,000 in-flight messages (received from a queue by a consumer but not yet deleted from the queue). If you reach this limit, Amazon SQS returns the OverLimit error message. To avoid reaching the limit, delete messages from the queue after they are processed. You can also increase the number of queues if you file an AWS Support request.
For first-in, first-out (FIFO) queues, there can be a maximum of 20,000 in-flight messages (received from a queue by a consumer but not yet deleted from the queue). If you reach this limit, Amazon SQS returns no error messages.
The ReceiveMessage action waits for a message to arrive. Valid values are integers from 0 to 20 seconds, with the default value of 0.
Long polling helps reduce the cost of Amazon SQS by eliminating the number of empty responses (when there are no messages available for a ReceiveMessage request) and false empty responses (when messages are available but are not included in a response).
To ensure optimal message processing, do the following:
The VisibilityTimeout action is the duration (in seconds) that the received messages are hidden from subsequent retrieve requests after being retrieved by a ReceiveMessage request. The default VisibilityTimeout for a message is 30 seconds. The minimum is 0 seconds. The maximum is 12 hours.
How you set the VisibilityTimeout depends on how long it takes your application to process and delete a message. To ensure that there is sufficient time to process messages, use one of the following strategies:
To extend the VisibilityTimeout action for longer than 12 hours, consider using AWS Step Functions.
For example, if your application requires 10 seconds to process a message and you set VisibilityTimeout to 15 minutes, you must wait for a relatively long time to attempt to process the message again if the previous processing attempt fails. Alternatively, if your application requires 10 seconds to process a message but you set VisibilityTimeout to only 2 seconds, a duplicate message is received by another consumer while the original consumer is still working on the original message.
WaitTimeSeconds is the duration (in seconds) for which the call waits for a message to arrive in the queue before returning. If a message is available, the call returns sooner than WaitTimeSeconds. If no messages are available and the wait time expires, the call returns successfully with an empty list of messages.
ReceiveMessageWaitTimeSeconds is the length of time, in seconds, for which a ReceiveMessage action waits for a message to arrive. Valid values are integers from 0 to 20 (seconds), with the default value equal to 0.
ChangeMessageVisibility changes the visibility timeout of a message in a queue to a new value. The default VisibilityTimeout setting for a message is 30 seconds. The minimum is 0 seconds. The maximum is 12 hours.
If you attempt to set VisibilityTimeout to a value greater than the maximum time left, Amazon SQS returns an error. Amazon SQS doesn’t automatically recalculate and increase the timeout to the maximum remaining time.
Unlike with a queue, when you change the VisibilityTimeout value for a specific message, the TimeoutValue action applies immediately but is not saved in memory for that message. If you do not delete a message after it is received, the next time the message is received, the VisibilityTimeout setting for the message reverts to the original TimeoutValue setting and not to the value of the ChangeMessageVisibility action.
For example, suppose that you have a message with a VisibilityTimeout setting of 5 minutes. After 3 minutes, you call ChangeMessageVisibility with a timeout of 10 minutes. You can continue to call ChangeMessageVisibility to extend the VisibilityTimeout to the maximum allowed time. If you try to extend the VisibilityTimeout beyond the maximum, your request is rejected.
DelaySeconds is the length of time, in seconds, that a specific message will be delayed. Valid values are 0–900, with a maximum of 15 minutes. Messages with a positive DelaySeconds value become available for processing after the delay period is finished. If you do not specify a value, the default value for the queue applies.
When you set FifoQueue, you cannot set DelaySeconds per message. You can set this parameter only on a queue level.
MessageRetentionPeriod is the length of time, in seconds, that Amazon SQS retains a message. It is an integer representing seconds, from 60 (1 minute) to 1,209,600 (14 days). Changes made to the MessageRetentionPeriod attribute can take up to 15 minutes to take effect.
DeleteMessage deletes the specified message from the specified queue. To select the message to delete, use the ReceiptHandle value of the message (not the MessageId that you receive when you send the message). Amazon SQS can delete a message from a queue even if a VisibilityTimeout setting causes the message to be locked by another consumer. Amazon SQS automatically deletes messages kept in a queue longer than the retention period configured for the queue.
Refer to Table 11.5 to view the differences between the Amazon Simple Notification Service (Amazon SNS) and Amazon SQS event-driven solutions.
Amazon SQS supports dead-letter queues, which other queues (source queues) can target for messages that cannot process (be consumed) successfully. Dead-letter queues are useful when you debug your application or message system because the queues let you isolate problematic messages to determine why their process did not succeed.
Sometimes messages do not process because of a variety of possible issues, such as erroneous conditions within the producer or consumer application or an unexpected state change that causes an issue with your application code. For example, if a user places a web order with a particular product ID but the product ID is deleted, the web store’s code fails and displays an error, and the message with the order request is sent to a dead-letter queue.
Occasionally, producers and consumers might fail to interpret aspects of the protocol that they use to communicate, causing message corruption or loss. Also, the consumer’s hardware errors might corrupt message payload.
If the consumer of the source queue fails to process a message in the number of times you specify, the redrive policy (RedrivePolicy) specifies the source queue, the dead-letter queue, and the conditions under which Amazon SQS moves messages from the former to the latter. When the ReceiveCount value for a message exceeds the maxReceiveCount value for a queue, Amazon SQS moves the message to a dead-letter queue. For example, if the source queue has a redrive policy with maxReceiveCount set to 5 and the consumer of the source queue receives a message five times and it does not delete, Amazon SQS moves the message to the dead-letter queue.
To specify a dead-letter queue, you can use the AWS Management Console or the AWS SDK for Java for each queue that sends messages to a dead-letter queue. Multiple queues can target a single dead-letter queue. The dead-letter queue uses the CreateQueue or SetQueueAttributes action.
Use the same AWS account to create the dead-letter queue and the other queues that send messages to the dead-letter queue. Also, dead-letter queues must reside in the same region as the other queues that use the dead-letter queue. For example, if you create a queue in the US East (Ohio) Region, and you want to use a dead-letter queue with that queue, the second queue must also be in the US East (Ohio) Region.
The expiration of a message is based on its original enqueue timestamp. When a message moves to a dead-letter queue, the enqueue timestamp does not change. For example, if a message spends one day in the original queue before it moves to a dead-letter queue and the retention period of the dead-letter queue is set to 5 days, the message is deleted from the dead-letter queue after 3 days. Thus, AWS recommends that you set the retention period of a dead-letter queue to be longer than the retention period of the original queue.
The main task of a dead-letter queue is to handle message failure. Use a dead-letter queue to set aside and isolate messages that cannot be processed correctly to determine why their processes failed. The dead-letter queue enables you to do the following:
Standard queues continue to process messages until the expiration of the retention period. This ensures continuous processing of messages, which minimizes the chances of your queue being blocked by messages that cannot process. It also ensures fast recovery for your queue.
Amazon SQS standard queues work by using scalability and throughput. To achieve this, they trade off two qualities:
In a system that processes thousands of messages and in which you have a large number of messages that the consumer repeatedly fails to acknowledge and delete, standard queues may increase costs and place an extra load on the hardware. Instead of trying to process messages that fail until they expire, move them to a dead-letter queue after a few process attempts.
Standard queues support a high number of in-flight messages. If the majority of your messages cannot be consumed and are not sent to a dead-letter queue, your rate of processing valid messages can slow down. Thus, to maintain the efficiency of your queue, you must ensure that your application handles message processing correctly.
Amazon SQS uses FIFO message queues that place the messages in the queue in the order that you receive them. The first messages that you receive display first in the queue. Message groups also follow this order so that when you publish messages to different message groups, each message group preserves the messages’ internal order.
FIFO queues support 3,000 operations (read, write, and delete) per second with batching and support 300 operations per second without batching.
Amazon SQS standard queues use scalability and throughput, unlike Amazon SQS FIFO queues. To achieve this, they trade off two qualities:
If the removal of either or both of these two constraints is important, use Amazon SQS FIFO queues. Amazon SQS FIFO queues provide order within message groups, and they delete any duplicate messages that occur within 5-minute intervals.
FIFO queues ensure single processing by consuming messages in sequence from a message group. Thus, although the consumer can continue to retrieve ordered messages from another message group, the first message group remains unavailable until the message that is blocking the queue processes successfully.
FIFO queues support a lower number of in-flight messages. To ensure that your FIFO queue does not get blocked by a message, you must make sure that your application handles message processing correctly.
Use dead-letter queues with Amazon SQS standard queues when your application does not depend on the order of messages. Dead-letter queues help you troubleshoot incorrect message transmission operations.
The dead-letter queue of a FIFO queue must also be a FIFO queue. Similarly, the dead-letter queue of a standard queue must also be a standard queue.
Even when you use dead-letter queues, continue to monitor your queues, and retry to send messages that fail for transient reasons.
Do use dead-letter queues to decrease the number of messages and to reduce the possibility that you expose your system to messages that you can receive but cannot process.
Do not use a dead-letter queue with standard queues when you want to retry the transmission of a message indefinitely. For example, do not use a dead-letter queue if your program must wait for a dependent process to become active or available.
Do not use a dead-letter queue with a FIFO queue if you do not want to break the exact order of messages or operations.
In some cases, Amazon SQS dead-letter queues might not behave as you expect. This section gives an overview of common issues and shows how to resolve them.
Amazon SQS counts a message you view in the AWS Management Console against the queue’s redrive policy. As a result, if you view a message in the console the number of times you specify in the queue’s redrive policy, the message moves to the queue’s dead-letter queue.
To adjust this behavior, do the following:
If you send a message to a dead-letter queue manually, the NumberOfMessagesSent metric counts it. However, if a message is sent to a dead-letter queue because of a failed process attempt, the metric does not count it. Thus, the values of NumberOfMessagesSent and NumberOfMessagesReceived can be different.
Table 11.1, Table 11.2, and Table 11.3 provide all the details of the Amazon SQS message attributes, DLQ settings, and server-side encryption (SSE) settings.
Table 11.1 Amazon SQS Message Attributes
Attribute | Default | Meaning |
Default Visibility Timeout | 30 seconds | How long a message is hidden while it is processed. Maximum limit is 12 hours. |
Message Retention Period | 4 days | How long a queue retains a message before deleting it. |
Maximum Message Size | 256-KB text | Maximum size of a message with 10 items maximum. |
Delivery Delay | 0 seconds | How long to delay before publishing the message to the queue. |
Receive Message Wait Time | 0 seconds | Maximum time consumer receives call waits for new messages. |
To send a message larger than 256 KB, use Amazon SQS to save the file in Amazon Simple Storage Service (Amazon S3) and then send a link to the file on Amazon SQS. Large Messages
Table 11.2 Dead-Letter Queue Settings
Setting
Meaning
Use Redrive Policy
Send messages to the dead-letter queue if consumers keep failing to process it.
Dead-Letter Queue
Name of dead-letter queue.
Maximum Receives
Maximum number of times a message is received before it is sent to the dead-letter queue.
Table 11.3 Server-Side Encryption (SSE) Settings
Setting | Meaning |
Use SSE | Amazon SQS encrypts all messages sent to this queue. |
AWS Key Management Service (AWS KMS) Customer Master Key | The AWS KMS master key that generates the data keys. |
Data Key Reuse Period | Length of time to reuse a data key before a new one regenerates. |
Amazon CloudWatch monitors your AWS resources and the applications you run on AWS in real time. You can use CloudWatch to collect and track metrics, which are variables that you can measure for your resources and applications.
CloudWatch alarms send notifications or automatically make changes to the resources you monitor based on rules that you define, for example, when a message is sent to the dead-letter queue.
If you must pass messages to other users, create an Amazon SQS queue, subscribe all the administrators to this queue, and then configure Amazon CloudWatch Events to send a message on a daily cron schedule into the Amazon SQS queue.
CloudWatch provides a reliable, scalable, and flexible monitoring solution with no need to set up, manage, and scale your own monitoring systems and infrastructure. You may also use Amazon CloudWatch Logs to monitor, store, and access your log files from Amazon EC2 instances, AWS CloudTrail, or other sources.
The AWS/Events namespace includes the DeadLetterInvocations metric, as shown in Table 11.4. The DeadLetterInvocations metric uses Count as the unit, so Sum and SampleCount are the most useful statistics.
Table 11.4 Amazon CloudWatch Dead-Letter Queue
Metric | Description |
DeadLetterInvocations | Measures the number of times a rule’s target is not invoked in response to an event. This includes invocations that would result in triggering the same rule again, causing an infinite loop. Valid Dimensions: RuleName Units: Count |
Amazon Simple Notification Service (Amazon SNS) is a flexible, fully managed producer/consumer (publisher/subscriber) messaging and mobile notifications web service that coordinates the delivery of messages to subscribing endpoints and clients. Amazon SNS coordinates and manages the delivery or sending of messages to subscriber endpoints or clients to assist in event-driven solutions.
Amazon SNS is based on the publish-subscribe model, and it allows the message producer to send a message to a topic that has multiple subscribers that choose to receive the same message. The message is delivered to multiple subscribers, which can then consume the message to trigger subsequent processes. A topic allows multiple receivers of the message to subscribe dynamically for identical copies of the same notification.
With Amazon SNS, you can easily set up, operate, and reliably send notifications to all your endpoints at any scale. You can also send messages to a large number of subscribers, including distributed systems and services and mobile devices. By default, Amazon SNS offers 10 million subscriptions per topic and 100,000 topics per account. To request a higher limit, contact AWS Support.
Amazon SNS enables you to send notifications from the cloud, and it allows applications to publish messages that are immediately delivered to a subscriber, as shown in Figure 11.8.
There are two types of clients in Amazon SNS: producers (publishers) and consumers (subscribers).
Producers communicate asynchronously with subscribers by producing and sending a message to a topic, which, in the context of Amazon SNS, is a logical access point and communication channel. Subscribers, such as web servers, email addresses, Amazon SQS queues, and AWS Lambda functions, consume or receive the message or notification over one of the supported protocols, such as Amazon SQS, HTTPS, email, Short Message Service (SMS), and AWS Lambda, when the consumer subscribes to the topic.
The sequence of operations in Amazon SNS includes the following:
If a user subscribes to the topic after a message was published, the user will not receive the message. A subscriber receives messages that are published only after they have subscribed to the topic. The topics do not buffer messages.
You can use Amazon SNS to produce a single message to multiple subscribers, as shown in Figure 11.9.
For example, when a cryptocurrency price fluctuates, you must update the dashboard to indicate the new price and update the value of the portfolio to reflect the new price. All users who subscribed to your cryptocurrency topic then receive a notification on the new prices.
Amazon SNS supports the following endpoints:
Amazon SNS retries sending messages for HTTPS endpoints as a REST call to these endpoints. You can configure the number of retries and the delay between them.
Amazon SNS topic names have a limit of 256 characters. Topic names must be unique within an AWS account and can include alphanumeric characters plus hyphens (-) and underscores (_). After you delete a topic, you can reuse the topic name. When a topic is created, Amazon SNS assigns a unique Amazon Resource Name (ARN) to the topic, which includes the service name (SNS), AWS Region, AWS ID of the user, and topic name. The ARN returns as part of the API call to create the topic. Whenever a producer or consumer needs to perform any action on the topic, you reference the unique topic ARN.
For example, Amazon SNS clients use the ARN address to identify the right topic.
aws sns publish --topic-arn topic-arn --message "message" --message-attributes '{"store":{"DataType":"String","StringValue":"example_corp"}}'
This is the ARN for a topic named mytopic that you create with the account ID 123456789012 and host in the US East Region:
arn:aws:sns:us-east-1:1234567890123456:mytopic
Do not attempt to build the topic ARN from its separate components—topics should use the name the API calls to create the topic returns.
Amazon SNS provides a set of simple APIs to enable event notifications for topic owners, consumers, and producers.
These are the owner operations:
These are the subscriber operations:
After you create a topic, subscribe to it, and publish a message to the topic. You unsubscribe from the topics and delete them to clean up your environment from the Amazon SNS console.
The subscription is deleted unless it is a pending subscription, meaning that it has not yet been confirmed. You cannot delete a pending subscription, but if it remains pending for 3 days, Amazon SNS automatically deletes it.
Amazon SNS supports notifications over multiple transport protocols. You can select transports as part of the subscription requests.
With Amazon SNS, you can send push notification messages directly to apps on mobile devices. Push notification messages sent to a mobile endpoint can appear in the mobile app as message alerts, badge updates, or even sound alerts.
You send push notification messages to both mobile devices and desktops with the following push notification services:
Push notification services, such as APNS and GCM, maintain a connection with each app and mobile device registered to use their service. When an app and mobile device are registered, the push notification service returns a device token. Amazon SNS uses the device token to create a mobile endpoint to which it can send direct push notification messages. For Amazon SNS to communicate with the different push notification services, you submit your push notification service credentials to Amazon SNS.
You can also use Amazon SNS to send messages to mobile endpoints subscribed to a topic. The concept is the same as subscribing other endpoint types. The difference is that Amazon SNS communicates with the push notification services for the subscribed mobile endpoints to receive push notification messages sent to the topic. Figure 11.10 shows a mobile endpoint as a subscriber to an Amazon SNS topic. The mobile endpoint communicates with push notification services, whereas the other endpoints do not.
When you first register an app and mobile device with a notification service, such as Apple Push Notification Service (APNS) and Google Cloud Messaging for Android (GCM), device tokens or registration IDs return from the notification service. When you add the device tokens or registration IDs to Amazon SNS, they use the PlatformApplicationArn API to create an endpoint for the app and device. When Amazon SNS creates the endpoint, an EndpointArn returns, and this is how Amazon SNS knows to which app and mobile device to send the notification message.
You can add device tokens and registration IDs to Amazon SNS by using these methods:
You can use one of two options to create Amazon SNS endpoints for device tokens or registration IDs.
Amazon Cognito Your mobile app requires credentials to create and associate endpoints with your Amazon SNS platform application. AWS recommends that you use temporary security credentials that expire after a period of time. You can use Amazon SNS to receive an event with the new endpoint ARN, or you can use the ListEndpointByPlatformApplication API to view the full list of endpoints registered with Amazon SNS.
Proxy Server If your application infrastructure is already set up for your mobile apps to call in and register on each installation, you can use your server to act as a proxy and pass the device token to Amazon SNS mobile push notifications. This includes any user data that you would like to store. The proxy server connects to Amazon SNS with your AWS credentials and uses the CreatePlatformEndpoint API call to upload the token information. The newly created endpoint ARN is returned, which your server can store to make subsequent publish calls to Amazon SNS.
Amazon SNS includes a Free Tier, which allows you to use Amazon SNS free of charge for the first 1 million Amazon SNS requests, and with no charges for the first 100,000 notifications over HTTP, no charges for the first 100 notifications over SMS, and no charges for the first 1,000 notifications over email.
With Amazon SNS, there is no minimum fee, and you pay only for what you use. You pay $0.50 per 1 million Amazon SNS requests, $0.06 per 100,000 notification deliveries over HTTP, and $2 per 100,000 notification deliveries over email. For SMS messaging, users can send 100 free notification deliveries, and for subsequent messages, charges vary by destination country.
By default, Amazon SNS offers 10 million subscriptions per topic and 100,000 topics per account. To request a higher limit, contact AWS Support.
Amazon SNS supports the same attributes and parameters as Amazon SQS. For more information, refer to Table 11.2, Table 11.3 and Table 11.4.
When compared with Amazon SQS, which is a queue with a pull mechanism, Amazon SNS is a fanout with a push mechanism to send messages to subscribers. This means that the Amazon SNS message is sent to a topic and then replicated and pushed to multiple Amazon SQS queues, HTTP endpoints, or email addresses. This operation eliminates the need for the message consumers to poll for any new messages. There several differences between the Amazon SNS and Amazon SQS event-driven solutions, as listed in Table 11.5.
Table 11.5 Amazon SNS and Amazon SQS Feature Comparison
Features | Amazon SNS | Amazon SQS |
Message persistence | Not persisted | Persisted |
Delivery mechanism | Push (passive) | Pull (active) |
Producer/consumer | Publish/subscribe (1 to N) | Send/receive (1 to 1) |
Amazon Kinesis Data Streams is a service that ingests large amounts of data in real time and performs real-time analytics on the data. Producers write data into Amazon Kinesis Data Streams, and consumers read data from it.
Figure 11.11 illustrates the high-level architecture of Amazon Kinesis Data Streams. The producers continually push (PushRecords) data to Amazon Kinesis Data Streams, and the consumers process the data in real time. Consumers (such as a custom application running on Amazon EC2, or an Amazon Kinesis Data Firehose delivery stream) can store their results by using an AWS service, such as Amazon DynamoDB, Amazon Redshift, or Amazon Simple Storage Service (Amazon S3).
Multiple types of consumers can consume from the same Amazon Kinesis Data stream. The messages are not deleted when they are consumed. The consumers save a reference to the last message they view, and messages iterate based on sequence IDs to fetch the latest messages.
To place (PutRecords) data into the stream, specify the name of the stream, a partition key, and the data blob to add to the stream. The partition key determines the shard in the stream to which to add the data record.
All data in the shard is sent to the same worker that processes the shard. The partition key determines how to map a data record to a particular shard, so which partition key you use depends on your application logic. The number of partition keys should typically be much greater than the number of shards, and if you have enough partition keys, the data can be evenly distributed across the shards in a stream.
For example, you use the two-letter abbreviation of the state for each partition key, such as WA for Washington and WY for Wyoming. In this example, all records with a partition key of WA reside in the Washington stream, and all records with a partition key of WY reside in the Wyoming stream.
There are several differences between Amazon Kinesis Data Streams and Amazon SQS.
In Amazon SQS, when a consumer receives a message off the queue and then processes and deletes it, the message is no longer available for any other consumer.
In Amazon Kinesis Data Streams, you can process the same message by multiple applications. Each application tracks which records it last processed. Then it requests the records that came after it. It is the application’s responsibility to track its checkpoint within the data stream.
Amazon Kinesis Data Streams do not delete records after they process them, as it is possible that another application will request the message. Records automatically delete after their retention interval expires, which you configure. The default retention interval is 1 day, but you can extend it up to 7 days. Before the record’s interval expires, multiple applications can consume the message.
Amazon Kinesis uses shards to configure and support high throughput. When you create an Amazon Kinesis data stream, specify the number of shards in your stream. You can increase or decrease the number of shards through the API.
On the producer side, the shard supports 1 MB per second of ingest, or 1,000 transactions per second. Producers can write up to 1 MB per second of data, or 1000 writes.
On the consumer side, each shard supports 2 MB per second of reads, or five transactions per second. Amazon Kinesis Data Streams support twice as much data for reads as they do for writes (2 MB per second of read versus 1 MB per second of write) per shard. This allows multiple applications to read from a stream to enable more reads. Because the same records might be read by multiple applications, you require more throughput on the read side.
Amazon Kinesis Data Streams support 5,000 transactions per second for writes, but only five transactions per second for reads per shard. Reads frequently acquire many records at once. When a read request asks for all the records that came in after the last read, it acquires a large number of records. Because of this, five transactions per second per shard is sufficient to handle reads.
To increase your throughput capacity, reshard the stream to adjust the number of shards.
Unlike Amazon SQS, Amazon Kinesis Data Streams enable real-time analytics, which produces metrics from incoming data as it arrives. The alternative is batch analytics in which the data accumulates for a period, such as 24 hours, and then is analyzed as a batch job. Real-time analytics allow you to detect patterns in the data immediately as it arrives, with a delay of only a few seconds to a few minutes.
After you define your monitoring goals and create your monitoring plan, the next step is to establish a baseline for normal Kinesis Video Streams performance in your environment. Measure Kinesis Video Streams performance at various times and under different load conditions. As you monitor Kinesis Video Streams, you should store a history of the monitored data that you collect. You can compare current Kinesis Video Streams performance to this historical data to help you identify normal performance patterns and performance anomalies and devise methods to address issues that may arise.
Open source tools, such as Fluentd and Flume, support Amazon Kinesis Data Streams as a destination, and you can use them to publish messages into an Amazon Kinesis data stream.
Your custom applications, real-time or batch-oriented, can run on Amazon EC2 instances. These applications might process data with open source deep-learning algorithms or use third-party applications that integrate with Kinesis Video Streams.
After you create the stream in Amazon Kinesis data stream, you need two applications to build your pipeline: a collection of producers that write data into the stream and consumers to read the data from the stream.
Here are options for you to build producers that can write into Amazon Kinesis Data Streams:
Amazon Kinesis Agent This is an application that reads data, appends to a log file, and writes to the stream. The benefit of the Amazon Kinesis Agent is that it does not require you to write application code.
Amazon Kinesis Data Steams API You write an application to use the Amazon Kinesis Data Streams API to put data on the stream.
Amazon Kinesis Producer Library (KPL) The KPL gives you a higher-level interface over the low-level Amazon Kinesis Data Streams API. It has the logic to retry failures and to buffer and batch-send multiple messages together. The KPL makes it easier to write messages into a stream than if you use the low-level API.
Consumers have the following options for the Amazon Kinesis Data Streams:
Amazon Kinesis Data Streams API You can write an application with the Amazon Kinesis Data Streams API to read data from a stream. To scale this to process large volumes of data, create a shard for each consumer. With multiple consumers that run independently, there is a risk that one of them might fail. To handle failure, coordinate between the consumers. Use the Amazon Kinesis Client Library (KCL) to track your consumers and shards.
Amazon Kinesis Client Library The Amazon Kinesis Client Library handles the complexity of coordinating between different consumers that read from different shards in a stream. It ensures that no shard is ignored, and no shard is processed by two consumers. The library creates a table in Amazon DynamoDB with the same name as the application name and uses this table to coordinate between the different consumers.
AWS Lambda AWS Lambda is another option that you can use to build Amazon Kinesis Data Streams for consumers. AWS Lambda can scale and handle fault tolerance automatically. It does not require the use of the KCL.
Amazon Kinesis Data Firehose can replace the CoDA service to ingest data. In many business applications, you require a real-time pipeline, but you do not require latency of a few seconds. You can afford to have latency that can run anywhere from 1–15 minutes.
Amazon Kinesis Data Firehose is easier to use than Amazon Kinesis Data Streams, as it does not require you to write a consumer application. Data that arrives at the Amazon Kinesis Data Firehose is automatically delivered to both Amazon S3 and the other destinations. From Amazon S3, you can deliver the data to Amazon Redshift, Amazon Elasticsearch Service, and Splunk.
Amazon Kinesis Data Firehose also handles dynamically scaling the underlying shards of the stream based on the amount of traffic.
Amazon Kinesis Data Firehose buffers the data before it writes it to Amazon S3, with a delayed reaction to real-time data based on the length of the buffer, as detailed in Table 11.6.
Table 11.6 Amazon Kinesis Data Firehose Buffers
Parameter | Min | Max | Description |
Buffer size | 1 MB | 128 MB | How much data Kinesis Data Firehose buffers |
Buffer interval | 60 seconds | 900 seconds | How long to buffer data |
With Amazon Kinesis Data Firehose, you do not need to write consumer applications or manage resources. Configure data producers to send data to Amazon Kinesis Data Firehose, and it will automatically deliver the data to the destination you specify. You can also configure Amazon Kinesis Data Firehose to transform your data before you deliver it. For example, you run a news site, and you analyze the stream of clicks from users who read the articles on your site. You want to use this analysis to move the most popular articles to the top of the page to capture news stories that are going viral. It is simple to verify that a story acquires a large number of hits, with a lag of only a few minutes.
Amazon Kinesis Data Analytics enables you to process and analyze streaming data with standard structured query language (SQL). It also enables you to run SQL code against streaming sources to perform time-series analytics, feed real-time dashboards, and create real-time metrics. Amazon Kinesis Data Analytics supports ingesting from either Amazon Kinesis Data Streams or Amazon Kinesis Data Firehose, and it continuously reads and processes streaming data. You can configure destinations where Amazon Kinesis Data Analytics sends the results, as shown in Figure 11.12. Amazon Kinesis Data Analytics supports the following destinations:
Use cases for Amazon Kinesis Data Analytics include the following:
Generate time series analytics You can calculate metrics over time windows and stream values to Amazon S3 or Amazon Redshift through a Firehose delivery stream.
Feed real-time dashboards You can send aggregated and processed streaming data results downstream to feed real-time dashboards.
Create real-time metrics You can create custom metrics and triggers for use in real-time monitoring, notifications, and alarms.
Use the Amazon Kinesis Video Streams service to push device video content into AWS and then onto the cloud to process that content and detect patterns in it.
You can use Amazon Kinesis Video Streams to build computer vision and machine learning applications.
A single stream can support one producer connection and three consumer connections at a time.
Amazon DynamoDB Streams integrates with Amazon DynamoDB to publish a message every time a change is made in a table. When you insert, delete, or update an item, Amazon DynamoDB produces an event, which publishes it to the Amazon DynamoDB Streams, as shown in Figure 11.13. To use this table-level feature, enable Amazon DynamoDB Streams on the table.
Amazon DynamoDB Streams is a database trigger for Amazon DynamoDB tables that you can use in any situation in which you continuously poll the database to indicate if a variable changes. An example would be a customer who publishes a vote in an Amazon DynamDB table called votes in an online application. With Amazon DynamoDB Streams, you can automatically track that change in both the votes table and in the consumer table to update the aggregate votes counted.
Amazon DynamoDB integrates with AWS Lambda so that you can create triggers, which are pieces of code that automatically respond to events in DynamoDB Streams. With triggers, you can build applications that react to data modifications in DynamoDB tables.
An AWS Lambda function or application that accesses the Amazon DynamoDB Streams API consumes the event when it publishes in the stream.
If you enable DynamoDB Streams on a table, you can associate the stream ARN with a Lambda function that you write. Immediately after you modify an item in the table, a new record appears in the table’s stream. AWS Lambda polls the stream and invokes your AWS Lambda function synchronously when it detects new stream records.
The AWS Lambda function can perform any actions you specify, such as to send a notification or initiate a workflow. For example, you can write a Lambda function simply to copy each stream record to persistent storage, such as Amazon S3, to create a permanent audit trail of write activity in your table. Or, suppose that you have a mobile gaming app that writes to a GameScores table. Whenever the TopScore attribute of the GameScores table updates, a stream record writes to the table’s stream. This event could then trigger an AWS Lambda function that posts a congratulatory message on a social media network. The function would ignore any stream records that are not updates to GameScores or that do not modify the TopScore attribute.
When you run an Amazon DynamoDB as a database backend, a large number of changes can occur at the same time. Amazon DynamoDB Streams publishes the changes in your table into multiple shards.
If you create a consumer application using AWS Lambda, each AWS Lambda instance processes the messages in a particular shard. This enables concurrent processing and allows Amazon DynamoDB Streams to scale to handle a high volume of concurrent changes. At any given time, each partition in an Amazon DynamoDB table maps to a single shard. The single shard captures all updates to that partition.
AWS IoT Device Management is a cloud-based service that makes it easy for customers to manage IoT devices securely throughout their lifecycle. Customers can use AWS IoT Device Management to onboard device information and configuration, organize their device inventory, monitor their fleet of devices, and remotely manage devices deployed across many locations. This remote management includes over-the-air (OTA) updates to device software.
AWS IoT is a service that manages devices associated with the Internet of Things, collects data from them, and sends out commands with updates to their state. The devices can communicate to the service with Message Queuing Telemetry Transport (MQTT) or HTTP. MQTT is a fire-and-forget asynchronous communication protocol that uses binary encoding. To view the AWS flow for IoT, refer to Figure 11.14.
When messages enter the AWS IoT Device Management service, the service dispatches them to different AWS endpoints. AWS IoT rule actions specify what to do when a rule is triggered. AWS IoT can dispatch the messages to AWS Lambda, an Amazon Kinesis data stream, a DynamoDB database, and other services. This dispatch is done through the AWS IoT rules engine. Rules give your devices the ability to interact with AWS products and services. Rules are analyzed, and actions occur based on the MQTT topic stream.
The IoT rules engine supports the following actions:
CloudWatch alarm action Use this to change the Amazon CloudWatch alarm state. Specify the state change reason and value in this call.
Amazon CloudWatch metric action The CloudWatch metric action allows you to capture an Amazon CloudWatch metric. Specify the metric namespace, name, value, unit, and timestamp.
DynamoDB action The dynamoDB action allows you to write all or part of an MQTT message to an Amazon DynamoDB table.
DynamoDBv2 action The dynamoDBv2 action allows you to write all or part of an MQTT message to an Amazon DynamoDB table. Each attribute in the payload is written to a separate column in the Amazon DynamoDB database.
Elasticsearch action The elasticsearch action allows you to write data from MQTT messages to an Amazon ES domain. You can query and visualize data in Amazon ES with tools such as Kibana.
Firehose action A firehose action sends data from an MQTT message that triggers the rule to a Kinesis Data Firehose stream.
IoT Analytics action An iotAnalytics action sends data from the MQTT message that triggers the rule to an AWS IoT Analytics channel.
Kinesis action The kinesis action allows you to write data from MQTT messages into a Kinesis stream.
Lambda action A lambda action calls an AWS Lambda function to pass it to a MQTT message that triggers the rule.
Republish action The republish action allows you to republish the message that triggers the role to another MQTT topic.
S3 action An s3 action writes the data from the MQTT message that triggers the rule to an Amazon S3 bucket.
Salesforce action A salesforce action sends data from the MQTT message that triggers the rule to a Salesforce IoT Input Stream.
SNS action An sns action sends the data from the MQTT message that triggers the rule as an Amazon SNS push notification.
Amazon SQS action An sqs action sends data from the MQTT message that triggers the rule to an Amazon SQS queue.
Step Functions action A stepFunctions action starts execution of an AWS Step Functions state machine.
The AWS IoT rules engine does not currently retry delivery for messages that fail to publish to another service.
The AWS IoT message broker is a publish/subscribe broker service that enables you to send messages to and receive messages from IoT. When you communicate with AWS IoT, a client sends a message to a topic address such as Sensor/temp/room1. The message broker then sends the message to all clients that have registered to receive messages for that topic. The act of sending the message is referred to as publishing. The act of registering to receive messages for a topic filter is referred to as subscribing.
The topic namespace is isolated for each account and region pair. For example, the Sensor/temp/room1 topic for an account is independent from the Sensor/temp/room1 topic for another account. This is true of regions, too. The Sensor/temp/room1 topic in the same account in us-east-1 is independent from the same topic in us-east-2.
AWS IoT does not send and receive messages across AWS accounts and regions.
The message broker maintains a list of all client sessions and the subscriptions for each session. When a message publishes on a topic, the broker checks for sessions with subscriptions that map to the topic. The broker then forwards the message to all sessions that have a currently connected client.
The AWS IoT device shadow is an always-available representation of the device, which allows communications back from cloud applications to the IoT devices. Cloud applications can update the device shadow even when the underlying IoT device is offline. Then when the device is brought back online, it synchronizes its final state with a query to the AWS IoT service for the current state of the instances.
A device’s shadow is a JavaScript Object Notation (JSON) document that stores and retrieves current state information for a device. The device shadow service maintains a shadow for each device that you connect to AWS IoT. You can use the shadow to get and set the state of a device over MQTT or HTTP, regardless of whether the device is connected to the internet. Each device’s shadow is uniquely identified by the name of the corresponding thing. The device shadow service acts as an intermediary that allows devices and applications to retrieve and update a device’s shadow.
Amazon MQ is a managed message broker service for Apache ActiveMQ that makes it easy to migrate to a message broker on the cloud. Amazon MQ is a managed Apache Active MQ that runs on Amazon EC2 instances that you select. AWS manages the instances, the operating system, and the Apache Active MQ software stack. You place these instances in your Amazon Virtual Private Cloud (Amazon VPC) and control access to them through security groups.
Amazon MQ makes it easy to migrate to a message broker on the cloud. A message broker allows software applications and components to communicate with the use of various programming languages, operating systems, and formal messaging protocols.
A broker is a message broker environment that runs on Amazon MQ. It is the basic building block of Amazon MQ. The combined description of the broker instance class (m5, t2) and size (large, micro) is a broker instance type (for example, mq.m5.large).
A single-instance broker is composed of one broker in one Availability Zone. The broker communicates with your application and with an AWS storage location.
An active/standby broker for high availability consists of two brokers in two different Availability Zones, which you configure in a redundant pair. These brokers communicate synchronously with your application and with a shared storage location.
You can enable automatic minor version upgrades to new versions of the broker engine, as Apache releases new versions. Automatic upgrades occur during the 2-hour maintenance window that you define by the day of the week, the time of day (in the 24-hour format), and the time zone (UTC, by default).
Amazon MQ works with your existing applications and services without the need to manage, operate, or maintain your own messaging system.
Amazon MQ is a managed message broker service that provides compatibility with many popular message brokers. AWS recommends Amazon MQ to migrate applications from current message brokers that rely on compatibility with APIs, such as JMS, or protocols like Advanced Message Queuing Protocol (AMQP), MQTT, OpenWire, and STOMP.
Amazon SQS and Amazon SNS are queue and topic services that are highly scalable, simple to use, and do not require you to set up message brokers. AWS recommends these services for new applications that can benefit from nearly unlimited scalability and simple APIs.
The AWS Step Functions service enables you to launch and develop workflows that can run for up to several months, and it allows you to monitor the progress of these workflows. You can coordinate the components of distributed applications and microservices by using visual workflows to build applications quickly, scale and recover reliably, and evolve application easily. Figure 11.15 displays the AWS Step Functions service.
The state machine is the workflow template that is made up of a collection of states. Each time you launch a workflow, you provide it with an input. Each state that is part of the state machine receives the input, modifies it, and passes it to the next state.
These workflow templates are called state machines. You can use AWS Step Functions as event sources to trigger AWS Lambda. Figure 11.16 is an example of using the AWS Step Functions service.
Use AWS Step Functions to build visual workflows that enable fast translation of business requirements into technical requirements. You can build applications in a matter of minutes. When your needs change, you can swap or reorganize components without customizing any code.
AWS Step Functions manages state, checkpoints, and restarts for you to make sure that your application executes in order and as you would expect. Built-in try/catch, retry, and rollback capabilities deal with errors and exceptions automatically.
AWS Step Functions manages the logic of your application for you, and it implements basic primitives such as branching, parallel execution, and timeouts. This removes extra code that may be repeated in your microservices and functions.
A finite state machine can express an algorithm as a number of states, their relationships, and their input and output. AWS Step Functions allows you to coordinate individual tasks by expressing your workflow as a finite state machine, written in the Amazon States Language. Individual states can decide based on their input, perform actions, and pass output to other states. In Step Functions, you can express your workflows in the Amazon States Language, and the Step Functions console provides a graphical representation of that state machine to help visualize your application logic.
Names identify states, which can be any string, but must be unique within the state machine specification. Otherwise, it can be any valid string in JSON text format.
An instance of a state exists until the end of its execution.
States can perform the following functions in your state machine:
Here is an example state named HelloWorld, which performs an AWS Lambda function:
"HelloWorld": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloFunction",
"Next": "AfterHelloWorldState",
"Comment": "Run the HelloWorld Lambda function"
}
States share the following common features:
These fields are common within each state:
To see the Amazon Function State Language, refer to Figure 11.17.
A task state involves a form of compute. A task executes on an AWS Lambda function or on an Amazon EC2 instance. An activity is a task that executes on an Amazon EC2 instance.
A task state ("Type": "Task") represents a single unit of work that a state machine performs.
In addition to the common state fields, task state fields include the following:
A Task state either must set the End field to true if the state ends the execution or must provide a state in the Next field that runs upon completion of the Task state. Here’s an example:
"ActivityState": {
"Type": "Task",
"Resource": "arn:aws:states:us-east-1:123456789012:activity:HelloWorld",
"TimeoutSeconds": 300,
"HeartbeatSeconds": 60,
"Next": "NextState"
}
The ActivityState schedules the HelloWorld activity for execution in the us-east-1 region on the caller’s account. When HelloWorld completes, the Next state (NextState) runs.
If this task fails to complete within 300 seconds or it does not send heartbeat notifications in intervals of 60 seconds, then the task is marked as failed. Set a Timeout value and a HeartbeatSeconds interval for long-running activities.
To specify the Resource field’s Amazon Resource Name (ARN), use the syntax:
arn:partition:service:region:account:task_type:name
where:
You cannot reference ARNs across partitions with Step Functions. For example, aws-cn cannot invoke tasks in the aws partition, and vice versa.
Task types support activity and AWS Lambda functions.
Activity Activities represent workers (processes or threads) that you implement and host, which perform a specific task.
Activity resource ARNs use the following syntax:
arn:partition:states:region:account:activity:name
Create activities with Step Functions (using a CreateActivity API action or the Step Functions console) before their first use.
AWS Lambda Functions Lambda tasks execute a function using AWS Lambda. To specify an AWS Lambda function, use the ARN of the AWS Lambda function in the Resource field. AWS Lambda function Resource ARNs use the following syntax:
arn:partition:lambda:region:account:function:function_name
Here's an example:
"LambdaState": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:HelloWorld",
"Next": "NextState"
}
When the AWS Lambda function you specify in the Resource field completes, its output is sent to the state you identify in the Next field (NextState).
The Choice state enables control flow between several different paths based on the input you select. In a choice state, you place a condition on the input. The state machine evaluates the condition, and it follows the path of the first condition that is true about the input.
A Choice state may have more than one Next, but only one within each Choice Rule. A Choice state cannot use End.
A Choice state ("Type": "Choice") adds branch logic to a state machine.
Other Choice state fields include the following:
Choices (Required) An array of Choice Rules that determines which state the state machine transitions to next
Default (Optional, Recommended) The name of the state to transition to if none of the transitions in Choices is taken
Choice states do not support the End field. They also use Next only inside their Choices field.
You must specify the $.type field. If the state input does not contain the $.type field, the execution fails, and an error displays in the execution history.
This is an example of a Choice state and other states to which it transitions:
"ChoiceStateX": {
"Type": "Choice",
"Choices": [
{
"Not": {
"Variable": "$.type",
"StringEquals": "Private"
},
"Next": "Public"
},
{
"Variable": "$.value",
"NumericEquals": 0,
"Next": "ValueIsZero"
},
{
"And": [
{
"Variable": "$.value",
"NumericGreaterThanEquals": 20
},
{
"Variable": "$.value",
"NumericLessThan": 30
}
],
"Next": "ValueInTwenties"
}
],
"Default": "DefaultState"
},
"Public": {
"Type" : "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:Foo",
"Next": "NextState"
},
"ValueIsZero": {
"Type" : "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:Zero",
"Next": "NextState"
},
"ValueInTwenties": {
"Type" : "Task",
"Resource": "arn:aws:lambda:us-east-1:123456789012:function:Bar",
"Next": "NextState"
},
"DefaultState": {
"Type": "Fail",
"Cause": "No Matches!"
}
In this example, the state machine starts with the input value:
{
"type": "Private",
"value": 22
}
Step Functions transitions to the ValueInTwenties state, based on the value field.
If there are no matches for the Choice state’s Choices, the state in the Default field runs instead. If there is no value in the Default state, the execution fails with an error.
A Choice state must have a Choices field whose value is a nonempty array and whose every element is an object called a Choice Rule. A Choice Rule contains the following:
Comparison Two fields that specify an input variable to compare, the type of comparison, and the value to which to compare the variable.
Next field The value of this field must match a state name in the state machine.
This example checks whether the numerical value is equal to 1:
{
"Variable": "$.foo",
"NumericEquals": 1,
"Next": "FirstMatchState"
}
This example checks whether the string is equal to MyString:
{
"Variable": "$.foo",
"StringEquals": "MyString",
"Next": "FirstMatchState"
}
This example checks whether the string is greater than MyStringABC:
{
"Variable": "$.foo",
"StringGreaterThan": "MyStringABC",
"Next": "FirstMatchState"
}
This example checks whether the timestamp is equal to 2018-01-01T12:00:00Z:
{
"Variable": "$.foo",
"TimestampEquals": "2018-01-01T12:00:00Z",
"Next": "FirstMatchState"
}
Step Functions examines each of the Choice Rules in the order that they appear in the Choices field and transitions to the state you specify in the Next field of the first Choice Rule in which the variable matches the value equal to the comparison operator.
The comparison supports the following operators:
For each of these operators, the value corresponds to the appropriate type: string, number, Boolean, or timestamp. Step Functions do not attempt to match a numeric field to a string value. However, because timestamp fields are logically strings, you can match a timestamp field by a StringEquals comparator.
For interoperability, do not assume that numeric comparisons work with values outside the magnitude or precision that the IEEE 754-2008 binary64 data type represents. In particular, integers outside of the range [-253+1, 253-1] might fail to compare in the way that you would expect.
Timestamps (for example, 2016-08-18T17:33:00Z) must conform to RFC3339 profile ISO 8601, with the following further restrictions:
To understand the behavior of string comparisons, see the Java compareTo documentation here:
https://docs.oracle.com/javase/8/docs/api/java/lang/ String.html#compareTo-java.lang.String-
The values of the And and Or operators must be nonempty arrays of Choice Rules that do not themselves contain Next fields. Likewise, the value of a Not operator must be a single Choice Rule with no Next fields.
You can create complex, nested Choice Rules using And, Not, and Or. However, the Next field can appear only in a top-level Choice Rule.
The Parallel state enables control flow to execute several different execution paths at the same time in parallel. This is useful if you have activities or tasks that do not depend on each other, can execute in parallel, and can help your workflow complete faster.
You can use the Parallel state ("Type": "Parallel") to create parallel branches of execution in your state machine.
In addition to the common state fields, Parallel states introduce these additional fields:
Branches (Required) An array of objects that specify state machines to execute in parallel. Each such state machine object must have the fields States and StartAt and mean the same as those in the top level of a state machine.
ResultPath (Optional) Specifies where in the input to place the output of the branches. The OutputPath field (if present) filters the input before it becomes the state’s output.
Retry (Optional) An array of objects, called Retriers, which define a retry policy in case the state encounters runtime errors.
Catch (Optional) An array of objects, called Catchers, which define a fallback state that executes in case the state encounters runtime errors and you do not define the retry policy or it has been exhausted.
A Parallel state causes AWS Step Functions to execute each branch. The state starts with the name of the state in that branch’s StartAt field, as concurrently as possible, and waits until all branches terminate (reach a terminal state) before it processes the Parallel state’s Next field. Here’s an example:
{
"Comment": "Parallel Example.",
"StartAt": "LookupCustomerInfo",
"States": {
"LookupCustomerInfo": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "LookupAddress",
"States": {
"LookupAddress": {
"Type": "Task",
"Resource":
"arn:aws:lambda:us-east-1:123456789012:function:AddressFinder",
"End": true
}
}
},
{
"StartAt": "LookupPhone",
"States": {
"LookupPhone": {
"Type": "Task",
"Resource":
"arn:aws:lambda:us-east-1:123456789012:function:PhoneFinder",
"End": true
}
}
}
]
}
}
}
In this example, the LookupAddress and LookupPhone branches execute in parallel. Figure 11.18 displays the workflow in the Step Functions console.
Each branch must be self-contained. A state in one branch of a Parallel state must not have a Next field that targets a field outside of that branch, nor can any other state outside the branch transition into that branch.
A Parallel state provides each branch with a copy of its own input data (InputPath). It generates output, which is an array with one element for each branch that contains the output from that branch. There is no requirement that all elements be of the same type. You can insert the output array into the input data (and the whole sent as the Parallel state’s output) with a ResultPath field. Here’s an example:
{
"Comment": "Parallel Example.",
"StartAt": "FunWithMath",
"States": {
"FunWithMath": {
"Type": "Parallel",
"End": true,
"Branches": [
{
"StartAt": "Add",
"States": {
"Add": {
"Type": "Task",
"Resource": "arn:aws:swf:us-east-1:123456789012:task:Add",
"End": true
}
}
},
{
"StartAt": "Subtract",
"States": {
"Subtract": {
"Type": "Task",
"Resource": "arn:aws:swf:us-east-1:123456789012:task:Subtract",
"End": true
}
}
}
]
}
}
}
If the FunWithMath state was given the array [3, 2] as input, then both the Add and Subtract states receive that array as input. The output of Add would be 5, that of Subtract would be 1, and the output of the Parallel state would be an array.
[ 5, 1 ]
If any branch fails, because of an unhandled error or by a transition to a Fail state, the entire Parallel state fails, and all of its branches stop. If the error is not handled by the Parallel state itself, Step Functions stops the execution with an error.
When a Parallel state fails, invoked AWS Lambda functions continue to run, and activity workers that process a task token do not stop.
To stop long-running activities, use heartbeats to detect whether Step Functions has stopped its branch, and stop workers that are processing tasks. If the state has failed, calling SendTaskHeartbeat, SendTaskSuccess, or SendTaskFailure generates an error.
You cannot stop AWS Lambda functions that are running. If you have implemented a fallback, use a Wait state so that cleanup work happens after the AWS Lambda function finishes.
A state machine completes its execution when it reaches an end state. Each state defines either a next state or an end state, and the end state terminates the execution of the step function.
Each execution of the state machine requires an input as a JSON object and passes that input to the first state in the workflow. The state machine receives the initial input by the process initiating the execution. Each state modifies the input JSON object that it receives and injects its output into this object. The final state produces the output of the state machine.
Individual states receive JSON as the input and usually pass JSON as the output to the next state. Understand how this information flows from state to state and learn how to filter and manipulate this data to design and implement workflows in AWS Step Functions effectively.
In the Amazon States Language, three components filter and control the flow of JSON from state to state: InputPath, OutputPath, and ResultPath.
Figure 11.19 shows how JSON information moves through a task state. InputPath selects which components from the input to pass to the task of the Task state, for example, an AWS Lambda function. ResultPath then selects what combination of the state input and the task result to pass to the output. OutputPath can filter the JSON output to limit further the information that passes to the output.
InputPath, OutputPath, and ResultPath each use paths to manipulate JSON as it moves through each state in your workflow.
ResultPath uses reference paths, which limit scope so that it can identify only a single node in JSON.
In this section, you will learn how to use paths and reference paths to process inputs and outputs.
Paths In Amazon States Language, a path is a string that begins with $ that you can use to identify components within JSON text. Paths follow the JsonPath syntax.
Reference paths A reference path is a path whose syntax can identify only a single node in a JSON structure.
You can access object fields with only a dot (.) and square brackets ([ ]) notation.
Paths and reference paths do not support the operators @ .. , : ? * and functions such as length().
For example, state input data contains the following values:
{
"foo": 123,
"bar": ["a", "b", "c"],
"car": {
"cdr": true
}
}
In this case, the reference paths return the following:
$.foo => 123
$.bar => ["a", "b", "c"]
$.car.cdr => true
Certain states use paths and reference paths to control the flow of a state machine or configure a state’s options.
To specify how to use part of the state’s input and what to send as output to the next state, you can use InputPath, OutputPath, and ResultPath.
For InputPath and OutputPath, you must use a path that follows the JsonPath syntax.
For ResultPath, you must use a reference path.
InputPath The InputPath field selects a portion of the state’s input to pass to the state’s task to process. If you omit the field, it receives the $ value, which represents the entire input. If you use null, the input is not sent to the state’s task, and the task receives JSON text representing an empty object {}.
A path can yield a selection of values. Here’s an example:
{ "a": [1, 2, 3, 4] }
If you apply the path $.a[0:2], the result is as follows:
[ 1, 2 ]
ResultPath If a state executes a task, the task results are sent along as the state’s output, which becomes the input for the next task.
If a state does not execute a task, the state’s own input is sent, unmodified, as its output. However, when you specify a path in the value of a state’s ResultPath and OutputPath fields, different scenarios become possible.
The ResultPath field takes the results of the state’s task that executes and places them in the input. Next, the OutputPath field selects a portion of the input to send as the state’s output. The ResultPath field might add the results of the state’s task that executes to the input, overwrites an existing part, or overwrites the entire input.
ResultPath field values must be reference paths.
OutputPath If the OutputPath matches an item in the state’s input, only that input item is selected. This input item becomes the state’s output.
The following example demonstrates how InputPath, ResultPath, and OutputPath fields work in practice. Consider this input for the current state:
{
"title": "Numbers to add",
"numbers": { "val1": 3, "val2": 4 }
}
In addition, the state has the following InputPath, ResultPath, and OutputPath fields:
"InputPath": "$.numbers",
"ResultPath": "$.sum",
"OutputPath": "$"
The state’s task receives only the numbers object from the input. In turn, if this task returns 7, the output of this state equals the following:
{
"title": "Numbers to add",
"numbers": { "val1": 3, "val2": 4 }
"sum": 7
}
You can modify the OutputPath as follows:
"InputPath": "$.numbers",
"ResultPath": "$.sum",
"OutputPath": "$.sum"
As before, you use the following state input data:
{
"numbers": { "val1": 3, "val2": 4 }
}
However, now the state output data is 7.
You can use state machines to process long-running workflows. For example, if a customer orders a book and it requires several different events, use the state machine to run all the events. When the customer orders the book, the state machine creates a credit card transaction, generates a tracking number for the book, notifies the warehouse to ship the order, and then emails the tracking number to the customer. The AWS Step Functions service runs all these steps.
The benefit of AWS Step Functions is that it enables the compute to be stateless. The AWS Lambda functions and the Amazon EC2 instances provide compute to the state machine to execute in a stateless way. AWS Lambda functions and Amazon EC2 do not have to remember the information about the state of the current execution. The AWS Step Functions service remembers the information about the state of the current execution.
This chapter covered the different services to refactor larger systems into smaller components that can communicate with each other through infrastructure services. To be successful, the refactoring infrastructure must exist, which enables the different components to communicate with each other. You also now know about the different infrastructure communication services that AWS provides for different use cases.
Know how refactoring to microservices is beneficial and what services it includes. This includes the use of the Amazon Simple Queue Service (Amazon SQS), Amazon Simple Notification Service (Amazon SNS), Amazon Kinesis Data Streams, Amazon Kinesis services, Amazon DynamoDB Streams, AWS Internet of Things (IoT), Amazon Message Query (Amazon MQ), and AWS Step Functions.
Know about the Amazon Simple Queue Service. Know that the Amazon Simple Queue Service (Amazon SQS) is a fully managed message queuing service that makes it easy to decouple and scale microservices, distributed systems, and serverless applications. There will be questions about the dead-letter queue and how to pass messages with Amazon CloudWatch.
Know about the Amazon Simple Notification Service. Familiarize yourself with the Amazon Simple Notification Service (Amazon SNS) and how it is a flexible, fully managed producer/consumer (publisher/subscriber) messaging and mobile notifications web service for coordinating the delivery of messages to subscribing to endpoints and clients. Amazon SNS coordinates and manages the delivery or sending of messages to subscriber endpoints or clients.
Know about Amazon Kinesis Data Streams. Study how Amazon Kinesis Data Streams is a service for ingesting large amounts of data in real time and for performing real-time analytics on the data. Producers write data into Amazon Kinesis Data Streams, and consumers read data from it. Be familiar with the use of multiple applications, high throughput, real-time analytics, and open source tools that Kinesis supports. There will be questions about producer and consumer options on the exam.
Know about Amazon Kinesis Data Firehose. Familiarize yourself with Amazon Kinesis Data Firehose latency. Amazon Kinesis Data Firehose also handles automatic scaling of the underlying shards of the stream based on the amount of traffic.
Know about Amazon Kinesis Data Analytics. There will also be questions about how Amazon Kinesis Data Analytics enables you to process and analyze streaming data with standard SQL. Make sure that you know which destinations it supports.
Know about Amazon Kinesis Video Streams. Know that the Amazon Kinesis Video Streams service allows you to push device video content into AWS and then onto the cloud to process that content and detect patterns in it. You can also use Amazon Kinesis Video Streams to build computer vision and machine learning applications.
Know about Amazon DynamoDB Streams. Remember that Amazon DynamoDB Streams allows Amazon DynamoDB to publish a message every time a change is made in a table. When you insert, update, or delete an item, Amazon DynamoDB produces an event that publishes it to the Amazon DynamoDB Streams. Familiarize yourself with tables, consumers, concurrency, and streams.
Know about AWS Internet of Things (AWS IoT). Make sure that you know that AWS IoT Device Management is a cloud-based device management service that makes it easy for customers to manage IoT devices securely throughout their lifecycle. Memorize information on the rules engine, message, broker, and device shadow.
Know about Amazon MQ. Know that the primary use for Amazon MQ is to enable customers who use Apache Active MQ to migrate to the cloud. A message broker allows software applications and components to communicate with various programming languages, operating systems, and formal messaging protocols. Know how the Amazon SQS and Amazon SNS differ from Amazon MQ.
Know about AWS Step Functions. The exam includes questions that require a thorough understanding of AWS Step Functions. Ensure that you know each step in the state machine, task state, Choice state, Parallel state, and end state. Remember the inputs and outputs in the step functions.
Know how state information flows and how to filter it. Understand how this information flows from state to state and learn how to filter and manipulate this data to design and implement workflows effectively in AWS Step Functions.
In this exercise, you will use the AWS SDK for Python (Boto) to create an Amazon SQS queue, and then you will put messages in the queue. Finally, you will receive messages from this queue and delete them.
This is the code that you downloaded at the beginning of the exercises.
# Test SQS.
import boto3
# Pretty print.
import pprint
pp = pprint.PrettyPrinter(indent=2)
# Create queue.
sqs = boto3.resource('sqs')
queue = sqs.create_queue(QueueName='test1')
print(queue.url)
# Get existing queue.
queue = sqs.get_queue_by_name(QueueName='test1')
print(queue.url)
# Get all queues.
for queue in sqs.queues.all(): print queue
# Send message.
response = queue.send_message(MessageBody='world')
pp.pprint(response)
# Send batch.
response = queue.send_messages(Entries=[
{ 'Id': '1', 'MessageBody': 'world' },
{ 'Id': '2', 'MessageBody': 'hello' } ])
pp.pprint(response)
# Receive and delete all messages.
for message in queue.receive_messages():
pp.pprint(message)
message.delete()
# Delete queue.
queue.delete()
This creates a queue, sends messages to it, receives messages from it, deletes the messages, and then deletes the queue.
In this exercise, you will use Amazon SNS to publish an SMS message to your mobile phone. This solution can be useful when you run a job that will take several hours to complete, and you do not want to wait for it to finish. Instead, you can have your app send you an SMS text message when it is done.
This is the code that you downloaded at the beginning of the exercises.
import boto3
# Create SNS client.
sns_client = boto3.client('sns')
# Send message to your mobile number.
# (Replace dummy mobile number with your number.)
sns_client.publish(
PhoneNumber='1-222-333-3333',
Message='Hello from your app')
The 1 at the beginning is the U.S. country code, 222 is the area code, and 333-3333 is the mobile phone number.
Check your phone to view the message.
In this exercise, you will create an Amazon Kinesis data stream, put records on it (write to the stream), and then get those records back (read from the stream). At the end, you will delete the stream.
This is the code that you downloaded at the beginning of the exercises.
import boto3
import random
import json
# Create the client.
kinesis_client = boto3.client('kinesis')
# Create the stream.
kinesis_client.create_stream(
StreamName='donut-sales',
ShardCount=2)
# Wait for stream to be created.
waiter = kinesis_client.get_waiter('stream_exists')
waiter.wait(StreamName='donut-sales')
# Store each donut sale using location as partition key.
location = 'california'
data = b'{"flavor":"chocolate","quantity":12}'
kinesis_client.put_record(
StreamName='donut-sales',
PartitionKey=location, Data=data)
print("put_record: " + location + " -> " + data)
# Next lets put some random records.
# List of location, flavors, quantities.
locations = ['california', 'oregon', 'washington', 'alaska']
flavors = ['chocolate', 'glazed', 'apple', 'birthday']
quantities = [1, 6, 12, 20, 40]
# Generate some random records.
for i in xrange(20):
# Generate random record.
flavor = random.choice(flavors)
location = random.choice(locations)
quantity = random.choice(quantities)
data = json.dumps({"flavor": flavor, "quantity": quantity})
# Put record onto the stream.
kinesis_client.put_record(
StreamName='donut-sales',
PartitionKey=location, Data=data)
print("put_record: " + location + " -> " + data)
# Get the records.
# Get shard_ids.
response = kinesis_client.list_shards(StreamName='donut-sales')
shard_ids = [shard['ShardId'] for shard in response['Shards']]
print("list_shards: " + str(shard_ids))
# For each shard_id print out the records.
for shard_id in shard_ids:
# Print current shard_id.
print("shard_id=" + shard_id)
# Get a shard iterator from this shard.
# TRIM_HORIZON means start from earliest record.
response = kinesis_client.get_shard_iterator(
StreamName='donut-sales',
ShardId=shard_id,
ShardIteratorType='TRIM_HORIZON')
shard_iterator = response['ShardIterator']
# Get records on shard and print them out.
response = kinesis_client.get_records(ShardIterator=shard_iterator)
records = response['Records']
for record in records:
location = record['PartitionKey']
data = record['Data']
print("get_records: " + location + " -> " + data)
# Delete the stream.
kinesis_client.delete_stream(
StreamName='donut-sales')
# Wait for stream to be deleted.
waiter = kinesis_client.get_waiter('stream_not_exists')
waiter.wait(StreamName='donut-sales')
Observe the output and how all the records for a specific location occur in the same shard. This is because they have the same partition keys. All records with the same partition key are sent to the same shard.
In this exercise, you will create an AWS Step Functions state machine. The state machine will extract price and quantity from the input and inject the billing amount into the output.
This state machine will calculate how much to bill a customer based on the price and quantity of an item they purchased.
This is the code that you downloaded at the beginning of the exercises.
{
"StartAt": "CreateOrder",
"States": {
"CreateOrder": {
"Type": "Pass",
"Result": {
"Order" : {
"Customer" : "Alice",
"Product" : "Coffee",
"Billing" : { "Price": 10.0, "Quantity": 4.0 }
}
},
"Next": "CalculateAmount"
},
"CalculateAmount": {
"Type": "Pass",
"Result": 40.0,
"ResultPath": "$.Order.Billing.Amount",
"OutputPath": "$.Order.Billing",
"End": true
}
}
}
{
"Price": 10,
"Quantity": 4,
"Amount": 40
}
In CalculateAmount, "ResultPath": "$.Order.Billing.Amount" injected Amount under Billing under Order. Then in the same element, "OutputPath": "$.Order.Billing" threw away the rest of the input and passed only the contents of the Billing element forward. This is why the output contains only Price, Quantity, and Amount.
In this exercise, you will create an AWS Step Functions state machine. The state machine will contain a conditional branch. It will use the Choice state to choose which state to transition to next.
The state machine inspects the input and based on it decides whether the user ordered green tea, ordered black tea, or entered invalid input.
This is the code that you downloaded at the beginning of the exercises.
{
"Comment" :
"Input should look like {'tea':'green'} with double quotes instead of single.",
"StartAt": "MakeTea",
"States" : {
"MakeTea": {
"Type": "Choice",
"Choices": [
{"Variable":"$.tea","StringEquals":"green","Next":"Green"},
{"Variable":"$.tea","StringEquals":"black","Next":"Black"}
],
"Default": "Error"
},
"Green": { "Type": "Pass", "End": true, "Result": "Green tea" },
"Black": { "Type": "Pass", "End": true, "Result": "Black tea" },
"Error": { "Type": "Pass", "End": true, "Result": "Bad input" }
}
}
This updates the visual representation of the state machine. The MakeTea state is a Choice state. Based on the input it receives, it will branch out to Green, Black, or Error.
{ "tea" : "green" }
"Green tea"
For example, try the following inputs:
For Input type, enter black tea. This input works.
{ "tea" : "black" }
For Input type, enter orange tea. This produces an error.
{ "tea" : "orange" }
When a user submits a build into the build system, you want to send an email to the user, acknowledging that you have received the build request, and start the build. To perform these actions at the same time, what type of a state should you use?
Suppose that a queue has no consumers. The queue has a maximum message retention period of 14 days. After 14 days, what happens?
What is size of an Amazon Simple Queue Service (Amazon SQS) message?
You want to send a 1 GB file through Amazon Simple Queue Service (Amazon SQS). How can you do this?
You want to design an application that sends a status email every morning to the system administrators. Which option will work?
What is the size of an Amazon Simple Notification Service (Amazon SNS) message?
You have an Amazon Kinesis data stream with one shard and one producer. How many consumer applications can you consume from the stream?
A company has a website that sells books. It wants to find out which book is selling the most in real time. Every time a book is purchased, it produces an event. What service can you use to provide real-time analytics on the sales with a latency of 30 seconds?
A company sells books in the 50 states of the United States. It publishes each sale into an Amazon Kinesis data stream with two shards. For the partition key, it uses the two-letter abbreviation of the state, such as WA for Washington, WY for Wyoming, and so on. Which of the following statements is true?
What are the options for Amazon Kinesis Data Streams producers?