Cloud Service and Deployment Models Questions
The foundational service models (IaaS, PaaS, SaaS, FaaS) and deployment models (public, private, hybrid, community cloud) and when each is appropriate. Covers the shared-responsibility boundary, on-demand elasticity, the core value proposition of cloud versus on-premises, and how service-model choice shifts operational ownership. The conceptual entry point before any provider-specific or architectural depth.
Explain how you would run Apache Spark jobs on Kubernetes. Describe the role of the driver and executors, resource requests/limits, dynamic allocation, and strategies to prevent executor OOM or long GC pauses when reading large Parquet datasets from object storage.
Sample Answer
Run Spark on Kubernetes by deploying the Spark driver as a Kubernetes pod (or as a client-submitted pod) and executors as worker pods launched by the driver. The driver coordinates the application (DAG scheduling, task assignment, shuffle map status); executors run tasks, hold cached RDD/DataFrame partitions, and perform shuffles.
Resource requests/limits
- Set CPU/memory requests to reflect expected steady usage and limits to cap pods: requests for scheduler placement, limits to prevent noisy neighbors.
- Configure spark.kubernetes.executor.request.cores and spark.executor.memory for requests; set spark.kubernetes.executor.limit.cores and spark.kubernetes.memoryOverhead/spark.kubernetes.executor.memoryOverhead for headroom (JVM off-heap, native libraries, shuffle).
- Ensure limit > request to avoid OOMKilled and to provide overhead.
Dynamic allocation
- Use spark.dynamicAllocation.enabled with shuffle tracking (spark.dynamicAllocation.shuffleTracking.enabled=true) or an external shuffle service. Configure min/max executors (spark.dynamicAllocation.minExecutors/maxExecutors) to control scale. Dynamic allocation helps right-size executors for variable input sizes and avoids long-running idle executors.
Preventing executor OOM / long GC when reading large Parquet from object storage
- Control partition sizing: set spark.sql.files.maxPartitionBytes and spark.sql.shuffle.partitions so each task processes a manageable amount of data (avoid tasks reading huge files).
- Use predicate pushdown and column pruning to minimize data read from Parquet.
- Tune memory regions: adjust spark.memory.fraction and spark.memory.storageFraction if cache vs execution contention occurs.
- Provide sufficient memoryOverhead (e.g., 10-20%) to accommodate native buffers and avoid container OOM.
- Enable efficient GC: use G1GC (-XX:+UseG1GC) and set pause targets (-XX:MaxGCPauseMillis) or use ZGC on modern JVMs for very large heaps.
- Avoid packing too many cores per executor: more cores -> more concurrent tasks -> more GC pressure. Prefer moderate cores (2-5) and larger memory per executor.
- Enable spill to disk (shuffle/spill thresholds) and increase shuffle and broadcast compression to reduce memory footprint.
- Use adaptive execution (AQE) to optimize shuffle partitions at runtime.
- Reduce small-file overhead: compact Parquet files and use larger files (but keep per-task read size reasonable).
- Local temp storage: use fast ephemeral storage (emptyDir SSD) for spill and shuffle files.
Monitoring and safety nets
- Add pod-level liveness/oom metrics, Spark metrics, and JVM GC logs; set alerts for GC pause time and OOMKilled.
- Test with production-like sample sizes, adjust executor size/cores, and use load tests to find the best balance between parallelism and memory headroom.
Design a lakehouse architecture using object storage and a metadata/transaction layer (e.g., Delta Lake/Hudi/Iceberg). Explain how you would enforce ACID semantics, handle schema evolution, and support time-travel queries for analytics at petabyte scale.
Sample Answer
Requirements & constraints:
- Ingest diverse, high-throughput streams/batches into object storage (S3/GCS/Blob).
- Provide ACID transactions, schema evolution, and time-travel for petabyte-scale analytics with low-latency reads for OLAP.
- Support Spark/Flink/Presto/Trino and BI tools.
High-level architecture:
- Object Storage (cold/warm): raw/parquet/ORC files partitioned by date/partition-key.
- Metadata & transaction layer: Iceberg/Delta/Hudi running on top of object store (catalog backed by Hive Metastore / Glue / HMS + dedicated catalog DB).
- Compute: Spark/Flink for ETL, Trino/Presto and Spark SQL for analytics.
- Async ingestion & compaction services: writers, compaction/upgrade jobs, and GC/expire service.
- Catalog DB + Write-conflict coordinator (leader/election via ZK/consensus).
Enforcing ACID:
- Use a table format with transaction semantics (e.g., Delta/Iceberg snapshot isolation).
- Writes produce new immutable data files and atomically update metadata (manifest/manifest lists / Delta transaction log). Use optimistic concurrency: writers append new snapshot metadata via atomic compare-and-swap on the catalog (object store conditional write + catalog DB).
- For multi-writer safety, coordinate via commit protocol: writer stages files, writes transaction record, runs commit which creates new manifest and updates snapshot pointer. Catalog stores lineage and commit checksum; conflicting commits detected and retried.
- Use snapshot isolation for readers — queries point to a snapshot id/timestamp; concurrent writers don't break readers.
Schema evolution:
- Support additive/nullable changes and controlled column changes:
- Store explicit schema in metadata (Avro/JSON/Protobuf schema in table metadata).
- For additive columns: update metadata to include new column with default/null; reading engines handle missing columns.
- For type promotion/rename: use explicit schema evolution APIs (Iceberg’s field IDs or Delta’s column mapping) to map old-to-new fields without rewriting data.
- Backfill strategy: lazy backfill on read or background jobs to physically rewrite files when needed.
- Validation rules in commit: enforce compatibility (reject breaking changes unless forced).
Time-travel & retention:
- Metadata maintains ordered snapshots with timestamps and manifest lists. Time-travel query resolves snapshot by timestamp or snapshot-id.
- Implement retention & GC: keep N snapshots or time window; compaction job rewrites small files and produces new snapshot; vacuum/expire removes unreachable files after safe retention window to avoid breaking time-travel.
Scalability & performance:
- Partitioning + data clustering to prune reads (partition by date + secondary clustering by high-cardinality keys).
- File sizing: target optimal parquet file sizes (256MB-1GB) controlled by writer/compression for scan efficiency.
- Use manifest pruning (Iceberg manifest stats) and partition/row-group statistics for pushdown filters to avoid listing large directories.
- Metadata scaling: store manifest and snapshot metadata as small JSON/Parquet artifacts; use a scalable catalog (Glue/BigQuery/Custom DB) and cache frequent metadata in a metadata service or catalog cache (per-query).
- Concurrency: scale writers by sharding writes by partition keys and using per-partition commit coordination.
Operational considerations:
- Schema-change policy & CI checks to prevent accidental breaking changes.
- Testing: replay replays and snapshot restores.
- Monitoring: commit latency, failed transactions, orphan files, vacuum backlog.
- Disaster recovery: periodic metadata backups; cross-region replication of object storage plus rehydrate metadata catalog.
Trade-offs:
- Delta vs Iceberg: Delta has strong transactional log semantics; Iceberg has better manifest pruning and table-split design at massive scale. Choose based on ecosystem and catalog choices.
- Stronger consistency (serializable) requires heavier coordination and impacts write throughput; snapshot isolation is pragmatic for analytics.
Example flow (append write + time-travel read):
- Writer writes parquet files to staging path → creates manifest → performs atomic commit updating snapshot metadata (JSON) in object store → catalog pointer updated.
- Analyst queries table AS OF timestamp t → engine resolves snapshot with matching timestamp, reads manifests and data files referenced by that snapshot only.
This design provides ACID-like semantics, robust schema evolution, and time-travel while scaling to petabytes through careful metadata design, partitioning, manifest pruning, and background maintenance.
Define the core components of cloud networking for data platforms: VPC/Virtual Network, subnet, route table, security group/firewall, NAT, and Internet Gateway. Explain their role when provisioning a data-processing cluster that must access both public storage and private database endpoints.
Sample Answer
VPC / Virtual Network: the isolated virtual network that contains your data platform. It provides IP addressing, tenancy, and boundary for routing and security. For a cluster, the VPC is where you place all compute and storage endpoints (public and private).
Subnet: a CIDR-scoped segment inside the VPC. Use public subnets for resources that need direct Internet access (e.g., bastion hosts, NAT gateways) and private subnets for cluster nodes and private DB endpoints to reduce exposure.
Route table: defines how traffic leaves a subnet. Attach route tables so private-subnet traffic to the Internet goes via a NAT gateway, while public-subnet traffic can route to an Internet Gateway (IGW).
Security group / Firewall: stateful instance-level firewall that allows/denies ports and protocols. Tighten cluster SGs to allow only required ingress (e.g., SSH from bastion, Spark ports from other cluster nodes) and egress to the private DB port and to public storage endpoints (e.g., S3 endpoints).
NAT (Network Address Translation) / NAT Gateway: enables instances in private subnets to initiate outbound Internet connections (for fetches, package installs) without exposing their private IPs. Used so cluster nodes can reach public storage or updates while remaining unreachable from the Internet.
Internet Gateway (IGW): a VPC-level gateway that enables resources in public subnets to have direct Internet connectivity. Only attach to subnets that need inbound/outbound Internet communication.
Putting it together for a data-processing cluster:
- Place cluster nodes in private subnets with a route table pointing default traffic to a NAT gateway in a public subnet.
- Deploy NAT gateway in a public subnet that has an IGW route.
- Use VPC endpoints (S3 / Blob) where possible to access public object storage privately (improves performance and security).
- Configure security groups: allow cluster egress to storage endpoints and DB IP/port; allow DB to accept connections only from cluster SG. Use least privilege and deny wide-open rules.
This design keeps compute private, allows controlled outbound access, and secures private DB access while enabling access to public storage.
Discuss trade-offs between managed streaming (e.g., MSK/Kinesis) and self-managed Kafka on Kubernetes for a low-latency, high-throughput event backbone with strict ordering requirements. Focus on latency, operational complexity, control over configuration, and failure modes.
Sample Answer
Context: We need a low-latency, high-throughput event backbone with strict ordering. I'll compare managed streaming (MSK / Kinesis) versus self-managed Kafka on Kubernetes across latency, operational complexity, control, and failure modes, then give recommendations.
Latency:
- Managed: Providers optimize networking, offer tuned instances and regional endpoints. Predictable low median latency, but some knobs (e.g., JVM tuning, kernel settings) may be limited. Multi-tenant control plane can add tail latency.
- Self-managed on K8s: You can tune at host, OS, JVM, and NIC level, colocate producers/consumers, and use dedicated network fabric—potentially lower tail latency. Achieving stable low latency requires careful configuration and resource isolation.
Operational complexity:
- Managed: Much lower ops burden—provisioning, patching, scaling, and Zookeeper/Kafka upgrades handled. Faster time-to-value and easier monitoring integrations. Limited deep-debugging pathways.
- Self-managed: High complexity: Zookeeper/KRaft management, broker scaling, storage provisioning, partition reassignment, rolling upgrades, and cluster autoscaling on noisy neighbors. Requires SRE skillset and runbooks.
Control over configuration:
- Managed: Exposes many broker and topic configs but may block risky settings (e.g., certain JVM flags, kernel tuning). Limits physical placement and storage class choices.
- Self-managed: Full control—custom JVM, kernel, io schedulers, PCIe NVMe access, CRI-socket tuning, and strict pod/node affinity to enforce ordering guarantees.
Failure modes and ordering:
- Managed: Failures are often at AZ/instance level or transient control-plane events. Providers offer SLAs and automated failover; however opaque failure recovery can cause temporary rebalances that impact ordering (consumer group rebalances, leader changes).
- Self-managed: More failure types—disk, pod eviction, node upgrades, misconfigured resource limits causing GC pauses. With full control you can design for minimal leader movement (partition leaders pinned, Rack Awareness), but misops increase risk of ordering breaks.
Recommendation:
- If team prefers low ops, needs fast delivery, and can accept some black-box behavior: start with managed (MSK/Kinesis) and use single-partition flows or sticky partitioning for strict ordering; tune client retries and idempotence.
- If ultra-low tail latency and absolute control over ordering/placement are business-critical and you have strong SRE capability: self-manage Kafka on Kubernetes with dedicated nodes, I/O-optimized instances, rack-awareness, strict resource reservations, and comprehensive chaos testing.
Also consider hybrid: managed for general streams, self-managed for critical strict-order topics.
List the primary cloud cost drivers for a data platform (compute, storage, network egress, managed service license/instance costs, I/O, API calls). For each, describe one levers you would use to reduce cost while minimizing impact to performance.
Sample Answer
Compute (VMs/containers, EMR/Dataproc, serverless function time)
- Lever: Right-size and use autoscaling + spot/preemptible instances for non-critical batch jobs.
- Why: Autoscaling matches capacity to workload; spot reduces cost by 60–90% for retryable jobs. Keep critical low-latency jobs on on-demand.
Storage (object/columnar/warehouse storage)
- Lever: Tiering + lifecycle policies (hot → warm → cold/Glacier) and compacting small files / columnar compression.
- Why: Move infrequently accessed data to cheaper tiers and reduce storage/IO overhead; compacting reduces metadata and query scanning cost with minimal performance hit for reads.
Network egress (data transfer out)
- Lever: Co-locate compute and storage in same region/account, use VPC peering/private endpoints, and compress/aggregate transfers.
- Why: Eliminates cross-region egress fees and reduces bytes transferred; compression adds negligible CPU cost compared to saving network bill.
Managed service license/instance costs (DB/warehouse clusters)
- Lever: Use serverless/auto-pausing offerings or scale down non-peak; negotiate reserved capacity or committed use discounts.
- Why: Pausing dev/test and off-peak reduces billed hours; reservations lower unit price with predictable workloads.
I/O (random/sequential disk ops, read/write amplification)
- Lever: Use caching (in-memory or SSD), partitioning/pruning, and read-optimized formats (Parquet/ORC) with predicate pushdown.
- Why: Reduces physical I/O and speeds queries; careful partitioning avoids unnecessary scans with little upstream change.
API calls (requests to services, metadata operations)
- Lever: Batch/multiplex operations, use pagination and exponential backoff, and cache responses where safe.
- Why: Lowers per-request costs and throttling risk; batching trades minimal latency for significant cost reduction.
For each lever, measure baseline metrics (cost, latency, error rates), apply changes in stages, and monitor SLA impact to ensure cost savings don't degrade critical performance.
Unlock Full Question Bank
Get access to all Cloud Service and Deployment Models interview questions and detailed answers.
Sign in to ContinueJoin thousands of developers preparing for their dream job.