Skip to content

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

  1. Data Warehousing
  2. Enterprise Data Warehouse: Central repository for business data
  3. Reporting and Analytics: Business intelligence and reporting
  4. Historical Analysis: Long-term trend analysis
  5. Compliance Reporting: Regulatory compliance

  6. Business Intelligence

  7. Executive Dashboards: Real-time business metrics
  8. Operational Reports: Departmental reporting
  9. Ad-Hoc Analysis: Exploratory data analysis
  10. Data Visualization: Charts and graphs

  11. Data Lake Analytics

  12. Spectrum: Query data directly in S3
  13. Federated Queries: Query across data sources
  14. ETL Workloads: Data transformation
  15. Data Science: Advanced analytics

  16. Real-Time Analytics

  17. Streaming Ingestion: Real-time data loads
  18. Operational Analytics: Live business monitoring
  19. IoT Analytics: Sensor data analysis
  20. 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

  1. Architecture Decisions
  2. Provisioned vs Serverless selection
  3. Node types and sizing considerations
  4. Distribution and sort key strategies
  5. Spectrum for S3 data queries

  6. Performance Optimization

  7. Table design best practices
  8. Data loading strategies (COPY command)
  9. Query optimization techniques
  10. Workload management (WLM)

  11. Security and Compliance

  12. Encryption at rest and in transit
  13. VPC deployment and network isolation
  14. Row-level and column-level security
  15. Audit logging and compliance

Common Exam Scenarios

  1. Data Warehouse Migration
  2. Migrate from on-premises to Redshift
  3. Choose appropriate node types
  4. Design efficient schema with proper keys
  5. Implement ETL processes for data loading

  6. Analytics Platform

  7. Build enterprise data warehouse
  8. Integrate with S3 data lake using Spectrum
  9. Implement real-time and batch analytics
  10. Configure workload management for different user groups

  11. Cost Optimization

  12. Use Redshift Serverless for variable workloads
  13. Implement data lifecycle management
  14. Optimize storage with compression
  15. 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.