Amazon Redshift¶
Service Overview and Purpose¶
Amazon Redshift is a fully managed, petabyte-scale data warehouse service in the cloud. It provides fast query performance using columnar storage, data compression, and zone maps to reduce I/O, and it uses massively parallel processing (MPP) to parallelize and distribute SQL operations.
Key Characteristics¶
- Columnar Storage: Optimized for analytics workloads
- MPP Architecture: Massively parallel processing
- Petabyte Scale: Handle massive datasets
- SQL Compatible: Standard SQL interface
- Fully Managed: Automated maintenance and scaling
Key Features and Capabilities¶
Architecture Types¶
Redshift Provisioned Clusters¶
- Leader Node: Query planning and coordination
- Compute Nodes: Data storage and query execution
- Node Types: Dense compute (DC2) and Dense storage (DS2)
- Scaling: Resize clusters as needed
Redshift Serverless¶
- Automatic Scaling: Scale based on workload
- Pay-per-Use: No idle capacity charges
- Instant Availability: No provisioning required
- Workgroup-Based: Organize resources by workload
Node Types and Sizing¶
Dense Compute (DC2)¶
- dc2.large: 2 vCPUs, 15 GB RAM, 160 GB SSD
- dc2.8xlarge: 32 vCPUs, 244 GB RAM, 2.56 TB SSD
- Use Case: High performance, smaller datasets
Dense Storage (DS2)¶
- ds2.xlarge: 4 vCPUs, 31 GB RAM, 2 TB HDD
- ds2.8xlarge: 36 vCPUs, 244 GB RAM, 16 TB HDD
- Use Case: Large datasets, cost-effective storage
RA3 with Managed Storage¶
- ra3.xlplus: 4 vCPUs, 32 GB RAM, managed storage
- ra3.4xlarge: 12 vCPUs, 96 GB RAM, managed storage
- ra3.16xlarge: 48 vCPUs, 384 GB RAM, managed storage
- Features: Separate compute and storage scaling
Core Features¶
Performance Optimization¶
- Columnar Storage: Efficient compression and I/O
- Zone Maps: Automatic data pruning
- Sort Keys: Optimize query performance
- Distribution Keys: Data distribution strategy
- Materialized Views: Pre-computed query results
Data Management¶
- COPY Command: Efficient data loading
- UNLOAD Command: Export data to S3
- Automatic Table Optimization: Background optimization
- Vacuum: Reclaim space and sort data
- Analyze: Update table statistics
Security and Compliance¶
- Encryption: At rest and in transit
- VPC Isolation: Network security
- IAM Integration: Access control
- Audit Logging: Query and connection logs
- Data Masking: Column-level security
Use Cases and Scenarios¶
Primary Use Cases¶
- Data Warehousing
- Enterprise Data Warehouse: Central repository for business data
- Reporting and Analytics: Business intelligence and reporting
- Historical Analysis: Long-term trend analysis
-
Compliance Reporting: Regulatory compliance
-
Business Intelligence
- Executive Dashboards: Real-time business metrics
- Operational Reports: Departmental reporting
- Ad-Hoc Analysis: Exploratory data analysis
-
Data Visualization: Charts and graphs
-
Data Lake Analytics
- Spectrum: Query data directly in S3
- Federated Queries: Query across data sources
- ETL Workloads: Data transformation
-
Data Science: Advanced analytics
-
Real-Time Analytics
- Streaming Ingestion: Real-time data loads
- Operational Analytics: Live business monitoring
- IoT Analytics: Sensor data analysis
- Clickstream Analysis: Web analytics
Architecture Patterns¶
-- Typical data warehouse schema design
-- Fact table with foreign keys to dimension tables
CREATE TABLE sales_fact (
sale_id BIGINT IDENTITY(1,1),
date_key INTEGER REFERENCES dim_date(date_key),
customer_key INTEGER REFERENCES dim_customer(customer_key),
product_key INTEGER REFERENCES dim_product(product_key),
store_key INTEGER REFERENCES dim_store(store_key),
quantity INTEGER,
amount DECIMAL(10,2),
cost DECIMAL(10,2)
)
DISTSTYLE KEY
DISTKEY(customer_key)
SORTKEY(date_key, customer_key);
-- Dimension table
CREATE TABLE dim_customer (
customer_key INTEGER IDENTITY(1,1),
customer_id VARCHAR(50),
customer_name VARCHAR(255),
customer_segment VARCHAR(50),
customer_region VARCHAR(50)
)
DISTSTYLE ALL
SORTKEY(customer_key);
Configuration and Best Practices¶
Cluster Creation¶
# Create Redshift cluster
aws redshift create-cluster \
--cluster-identifier redshift-prod-cluster \
--cluster-type multi-node \
--node-type ra3.4xlarge \
--number-of-nodes 3 \
--master-username admin \
--master-user-password SecurePassword123! \
--db-name proddb \
--cluster-parameter-group-name redshift-prod-params \
--cluster-security-groups default \
--vpc-security-group-ids sg-12345678 \
--cluster-subnet-group-name redshift-subnet-group \
--preferred-maintenance-window sun:05:00-sun:06:00 \
--automated-snapshot-retention-period 7 \
--manual-snapshot-retention-period 365 \
--encrypted \
--kms-key-id alias/redshift-encryption-key \
--enhanced-vpc-routing \
--tags Key=Environment,Value=Production Key=Application,Value=DataWarehouse
Redshift Serverless¶
# Create Redshift Serverless workgroup
aws redshift-serverless create-workgroup \
--workgroup-name analytics-workgroup \
--namespace-name analytics-namespace \
--base-capacity 32 \
--enhanced-vpc-routing \
--publicly-accessible false \
--subnet-ids subnet-12345678 subnet-87654321 \
--security-group-ids sg-12345678 \
--tags Key=Environment,Value=Production
# Create namespace
aws redshift-serverless create-namespace \
--namespace-name analytics-namespace \
--db-name analytics \
--admin-username admin \
--admin-user-password SecurePassword123! \
--kms-key-id alias/redshift-serverless-key \
--log-exports useractivitylog,userlog,connectionlog \
--tags Key=Environment,Value=Production
Table Design Best Practices¶
-- Optimized table design with distribution and sort keys
CREATE TABLE sales_optimized (
sale_date DATE,
customer_id INTEGER,
product_id INTEGER,
store_id INTEGER,
quantity INTEGER,
amount DECIMAL(10,2),
cost DECIMAL(10,2)
)
-- Choose distribution strategy based on join patterns
DISTSTYLE KEY
DISTKEY(customer_id) -- Distribute by most frequently joined column
-- Sort by date for time-series queries
SORTKEY(sale_date, customer_id)
-- Enable compression
ENCODE AUTO;
-- Best practices for data loading
COPY sales_optimized
FROM 's3://my-data-bucket/sales-data/'
IAM_ROLE 'arn:aws:iam::account:role/RedshiftS3Role'
FORMAT AS PARQUET
COMPUPDATE ON
STATUPDATE ON;
-- Maintenance commands
VACUUM sales_optimized; -- Reclaim space and resort
ANALYZE sales_optimized; -- Update table statistics
-- Query optimization with materialized views
CREATE MATERIALIZED VIEW monthly_sales AS
SELECT
DATE_TRUNC('month', sale_date) as month,
customer_id,
SUM(amount) as total_sales,
COUNT(*) as transaction_count
FROM sales_optimized
GROUP BY 1, 2;
Performance Optimization¶
-- Distribution styles comparison
-- DISTSTYLE EVEN - distribute rows evenly across nodes
CREATE TABLE table_even (id INTEGER, data VARCHAR(255))
DISTSTYLE EVEN;
-- DISTSTYLE KEY - distribute based on column values
CREATE TABLE table_key (id INTEGER, data VARCHAR(255))
DISTSTYLE KEY
DISTKEY(id);
-- DISTSTYLE ALL - replicate entire table on each node
CREATE TABLE table_all (id INTEGER, data VARCHAR(255))
DISTSTYLE ALL;
-- Sort key strategies
-- Single column sort key
CREATE TABLE table_single_sort (date DATE, id INTEGER, data VARCHAR(255))
SORTKEY(date);
-- Compound sort key (columns sorted in order)
CREATE TABLE table_compound_sort (date DATE, region VARCHAR(50), id INTEGER)
SORTKEY(date, region, id);
-- Interleaved sort key (equal weight to all columns)
CREATE TABLE table_interleaved_sort (date DATE, region VARCHAR(50), id INTEGER)
INTERLEAVED SORTKEY(date, region, id);
Integration with AWS Services¶
S3 Integration¶
-- Load data from S3
COPY sales_fact
FROM 's3://data-lake/sales/year=2023/'
IAM_ROLE 'arn:aws:iam::account:role/RedshiftS3Role'
FORMAT AS PARQUET
PARTITION AUTO;
-- Unload data to S3
UNLOAD ('SELECT * FROM sales_fact WHERE sale_date >= \'2023-01-01\'')
TO 's3://data-export/sales-2023/'
IAM_ROLE 'arn:aws:iam::account:role/RedshiftS3Role'
FORMAT AS PARQUET
PARTITION BY (sale_date)
ALLOWOVERWRITE;
-- Query data in S3 using Redshift Spectrum
CREATE EXTERNAL SCHEMA spectrum_schema
FROM DATA CATALOG
DATABASE 'spectrum_db'
IAM_ROLE 'arn:aws:iam::account:role/RedshiftSpectrumRole';
-- Query external table
SELECT COUNT(*)
FROM spectrum_schema.external_sales
WHERE sale_date >= '2023-01-01';
Data Pipeline Integration¶
# Python script for ETL with Redshift
import psycopg2
import pandas as pd
import boto3
class RedshiftETL:
def __init__(self, host, database, user, password, port=5439):
self.connection = psycopg2.connect(
host=host,
database=database,
user=user,
password=password,
port=port
)
def extract_data(self, query):
"""Extract data using SQL query"""
return pd.read_sql(query, self.connection)
def load_from_s3(self, table_name, s3_path, iam_role):
"""Load data from S3 to Redshift table"""
copy_sql = f"""
COPY {table_name}
FROM '{s3_path}'
IAM_ROLE '{iam_role}'
FORMAT AS PARQUET
COMPUPDATE ON
STATUPDATE ON;
"""
cursor = self.connection.cursor()
try:
cursor.execute(copy_sql)
self.connection.commit()
print(f"Data loaded successfully to {table_name}")
except Exception as e:
self.connection.rollback()
print(f"Error loading data: {e}")
finally:
cursor.close()
def execute_sql(self, sql):
"""Execute SQL statement"""
cursor = self.connection.cursor()
try:
cursor.execute(sql)
self.connection.commit()
return cursor.fetchall()
except Exception as e:
self.connection.rollback()
print(f"Error executing SQL: {e}")
return None
finally:
cursor.close()
# Usage example
redshift = RedshiftETL(
host='redshift-cluster.abc123.us-west-2.redshift.amazonaws.com',
database='proddb',
user='admin',
password='password'
)
# ETL pipeline
def daily_etl_pipeline():
# Extract yesterday's data
yesterday_data = redshift.extract_data("""
SELECT * FROM staging.raw_sales
WHERE DATE(created_at) = CURRENT_DATE - 1
""")
# Transform data (example: aggregation)
transformed_data = yesterday_data.groupby(['customer_id', 'product_id']).agg({
'amount': 'sum',
'quantity': 'sum'
}).reset_index()
# Load to S3 first
s3_path = f's3://processed-data/daily-sales/{yesterday_data.iloc[0]["created_at"].date()}/'
transformed_data.to_parquet(s3_path, index=False)
# Load to Redshift
redshift.load_from_s3(
table_name='fact.daily_sales',
s3_path=s3_path,
iam_role='arn:aws:iam::account:role/RedshiftS3Role'
)
Lambda Integration for Serverless ETL¶
import json
import boto3
import psycopg2
def lambda_handler(event, context):
# Redshift Serverless connection
redshift_data = boto3.client('redshift-data')
workgroup_name = 'analytics-workgroup'
database = 'analytics'
# Execute SQL using Data API
response = redshift_data.execute_statement(
WorkgroupName=workgroup_name,
Database=database,
Sql="""
INSERT INTO daily_summary
SELECT
CURRENT_DATE as summary_date,
COUNT(*) as total_sales,
SUM(amount) as total_revenue
FROM sales_fact
WHERE sale_date = CURRENT_DATE - 1
"""
)
query_id = response['Id']
# Check query status
status_response = redshift_data.describe_statement(Id=query_id)
return {
'statusCode': 200,
'body': json.dumps({
'query_id': query_id,
'status': status_response['Status']
})
}
Monitoring and Performance Tuning¶
CloudWatch Metrics¶
# Key Redshift metrics
# - CPUUtilization: Cluster CPU usage
# - DatabaseConnections: Number of connections
# - HealthStatus: Cluster health
# - MaintenanceMode: Maintenance status
# - NetworkReceiveThroughput/NetworkTransmitThroughput: Network I/O
# - PercentageDiskSpaceUsed: Storage utilization
# - ReadLatency/WriteLatency: I/O latency
# - ReadThroughput/WriteThroughput: I/O throughput
# Create CloudWatch alarms
aws cloudwatch put-metric-alarm \
--alarm-name "Redshift-High-CPU" \
--alarm-description "Redshift cluster high CPU utilization" \
--metric-name CPUUtilization \
--namespace AWS/Redshift \
--statistic Average \
--period 300 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=ClusterIdentifier,Value=redshift-prod-cluster \
--alarm-actions arn:aws:sns:region:account:redshift-alerts
aws cloudwatch put-metric-alarm \
--alarm-name "Redshift-High-Disk-Usage" \
--alarm-description "Redshift cluster high disk utilization" \
--metric-name PercentageDiskSpaceUsed \
--namespace AWS/Redshift \
--statistic Average \
--period 300 \
--threshold 85 \
--comparison-operator GreaterThanThreshold \
--dimensions Name=ClusterIdentifier,Value=redshift-prod-cluster
Query Performance Analysis¶
-- Query performance monitoring
-- Check running queries
SELECT
query,
pid,
user_name,
starttime,
duration/1000000 as duration_seconds,
substring(querytxt, 1, 100) as query_text
FROM stv_recents
WHERE status = 'Running'
ORDER BY starttime DESC;
-- Query performance history
SELECT
query,
userid,
starttime,
endtime,
datediff(seconds, starttime, endtime) as duration,
aborted,
substring(querytxt, 1, 100) as query_text
FROM stl_query
WHERE starttime >= DATEADD(hour, -24, GETDATE())
ORDER BY duration DESC
LIMIT 20;
-- Table scan analysis
SELECT
schema_name,
table_name,
size_mb,
pct_used,
unsorted,
stats_off
FROM svv_table_info
ORDER BY size_mb DESC;
-- Disk usage by table
SELECT
"schema",
"table",
size,
pct_of_total
FROM svv_diskusage
ORDER BY size DESC
LIMIT 20;
Performance Tuning¶
-- Workload Management (WLM) queue configuration
-- Check current WLM configuration
SELECT * FROM stv_wlm_service_class_config;
-- Monitor query queue wait times
SELECT
service_class,
slots,
query,
slot_count,
total_queue_time,
total_exec_time
FROM stl_wlm_query
WHERE start_time >= DATEADD(hour, -1, GETDATE())
ORDER BY total_queue_time DESC;
-- Analyze query execution steps
SELECT
query,
step,
rows,
bytes,
workmem,
is_diskbased,
label
FROM stl_query_summary
WHERE query = <query_id>
ORDER BY step;
-- Check for data distribution skew
SELECT
slice,
COUNT(*) as row_count
FROM stv_tbl_perm
WHERE name = 'sales_fact'
GROUP BY slice
ORDER BY slice;
Security and Compliance¶
Encryption Configuration¶
# Enable encryption for existing cluster
aws redshift modify-cluster \
--cluster-identifier redshift-prod-cluster \
--encrypted \
--kms-key-id alias/redshift-encryption-key
# Configure SSL connections
aws redshift modify-cluster-parameter-group \
--parameter-group-name redshift-prod-params \
--parameters ParameterName=require_ssl,ParameterValue=true
Access Control¶
-- User and group management
-- Create groups
CREATE GROUP analysts;
CREATE GROUP developers;
CREATE GROUP admins;
-- Create users
CREATE USER analyst1 PASSWORD 'SecurePassword123!' IN GROUP analysts;
CREATE USER dev1 PASSWORD 'SecurePassword123!' IN GROUP developers;
-- Grant permissions
GRANT SELECT ON ALL TABLES IN SCHEMA public TO GROUP analysts;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA staging TO GROUP developers;
-- Row-level security
CREATE TABLE sales_rls (
sale_id INTEGER,
region VARCHAR(50),
amount DECIMAL(10,2),
sale_date DATE
);
-- Enable RLS
ALTER TABLE sales_rls ENABLE ROW LEVEL SECURITY;
-- Create policy
CREATE RLS POLICY region_policy ON sales_rls
FOR ALL
TO analyst_role
USING (region = current_setting('app.current_region'));
-- Column-level security (data masking)
CREATE TABLE customer_sensitive (
customer_id INTEGER,
name VARCHAR(255),
ssn VARCHAR(11) ENCODE raw,
email VARCHAR(255)
);
-- Apply masking policy
ALTER TABLE customer_sensitive ALTER COLUMN ssn
SET MASKING USING (CASE WHEN current_user IN ('admin', 'dba')
THEN ssn
ELSE 'XXX-XX-' || RIGHT(ssn, 4) END);
Exam-Specific Tips and Common Scenarios¶
Key Exam Topics¶
- Architecture Decisions
- Provisioned vs Serverless selection
- Node types and sizing considerations
- Distribution and sort key strategies
-
Spectrum for S3 data queries
-
Performance Optimization
- Table design best practices
- Data loading strategies (COPY command)
- Query optimization techniques
-
Workload management (WLM)
-
Security and Compliance
- Encryption at rest and in transit
- VPC deployment and network isolation
- Row-level and column-level security
- Audit logging and compliance
Common Exam Scenarios¶
- Data Warehouse Migration
- Migrate from on-premises to Redshift
- Choose appropriate node types
- Design efficient schema with proper keys
-
Implement ETL processes for data loading
-
Analytics Platform
- Build enterprise data warehouse
- Integrate with S3 data lake using Spectrum
- Implement real-time and batch analytics
-
Configure workload management for different user groups
-
Cost Optimization
- Use Redshift Serverless for variable workloads
- Implement data lifecycle management
- Optimize storage with compression
- Use Reserved Instances for predictable workloads
Exam Tips¶
- Know the differences between node types and when to use each
- Understand distribution keys and their impact on performance
- Remember Spectrum enables querying S3 data directly
- Know security features like encryption and row-level security
- Understand when to use Provisioned vs Serverless
This comprehensive Redshift documentation covers all essential aspects needed for AWS certification exams, including practical SQL examples and performance optimization techniques.