mirror of
https://github.com/harivansh-afk/system-design.git
synced 2026-04-15 03:00:48 +00:00
ui
This commit is contained in:
parent
1ab3058cca
commit
89ce6a9542
13 changed files with 392 additions and 394 deletions
24
src/app.css
24
src/app.css
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-surface-700;
|
||||
@apply border-surface-800;
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
@ -16,15 +16,15 @@
|
|||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
@apply bg-surface-900;
|
||||
@apply bg-surface-950;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
@apply bg-surface-700 rounded-full;
|
||||
@apply bg-surface-800 rounded-full;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
@apply bg-surface-600;
|
||||
@apply bg-surface-700;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
}
|
||||
|
||||
.card-hover {
|
||||
@apply card hover:border-surface-600 hover:bg-surface-800/50 transition-all duration-200 cursor-pointer;
|
||||
@apply card hover:border-surface-700 hover:bg-surface-800/40 transition-colors duration-200 cursor-pointer;
|
||||
}
|
||||
|
||||
.btn {
|
||||
|
|
@ -42,11 +42,11 @@
|
|||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply btn bg-blue-600 hover:bg-blue-500 text-white;
|
||||
@apply btn bg-surface-100 hover:bg-surface-200 text-surface-950;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply btn bg-surface-800 hover:bg-surface-700 text-surface-200;
|
||||
@apply btn bg-surface-900 hover:bg-surface-800 text-surface-200 border border-surface-800;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
}
|
||||
|
||||
.tag-concept {
|
||||
@apply tag bg-purple-500/20 text-purple-400;
|
||||
@apply tag bg-surface-800 text-surface-200 border border-surface-700;
|
||||
}
|
||||
|
||||
/* Animated flow lines for diagrams */
|
||||
|
|
@ -87,8 +87,8 @@
|
|||
|
||||
/* Node styles for diagrams */
|
||||
.diagram-node {
|
||||
@apply bg-surface-800 border-2 border-surface-600 rounded-xl p-4 shadow-lg;
|
||||
@apply hover:border-blue-500 hover:shadow-blue-500/20 transition-all duration-200;
|
||||
@apply bg-surface-900 border border-surface-800 rounded-xl p-4;
|
||||
@apply hover:border-surface-700 transition-colors duration-200;
|
||||
}
|
||||
|
||||
.diagram-node-aws {
|
||||
|
|
@ -102,10 +102,10 @@
|
|||
|
||||
@layer utilities {
|
||||
.text-gradient {
|
||||
@apply bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-400;
|
||||
@apply text-surface-100;
|
||||
}
|
||||
|
||||
.glass {
|
||||
@apply bg-surface-900/80 backdrop-blur-lg;
|
||||
@apply bg-surface-900/90;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,8 +85,8 @@
|
|||
{/if}
|
||||
<span
|
||||
class="px-3 py-1 rounded-full text-sm transition-colors"
|
||||
class:bg-blue-600={isLast}
|
||||
class:text-white={isLast}
|
||||
class:bg-surface-100={isLast}
|
||||
class:text-surface-950={isLast}
|
||||
class:bg-surface-800={!isLast}
|
||||
class:text-surface-400={!isLast}
|
||||
>
|
||||
|
|
@ -110,8 +110,8 @@
|
|||
{#if currentNode.type === 'question'}
|
||||
<!-- Question Node -->
|
||||
<div class="text-center space-y-6">
|
||||
<div class="w-16 h-16 mx-auto rounded-full bg-blue-500/20 flex items-center justify-center">
|
||||
<Icons.HelpCircle class="w-8 h-8 text-blue-400" />
|
||||
<div class="w-16 h-16 mx-auto rounded-full bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<Icons.HelpCircle class="w-8 h-8 text-surface-300" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
@ -143,8 +143,8 @@
|
|||
<!-- Answer Node -->
|
||||
{@const Icon = getIcon(currentNode.icon)}
|
||||
<div class="text-center space-y-6">
|
||||
<div class="w-20 h-20 mx-auto rounded-full bg-green-500/20 flex items-center justify-center">
|
||||
<Icon class="w-10 h-10 text-green-400" />
|
||||
<div class="w-20 h-20 mx-auto rounded-full bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<Icon class="w-10 h-10 text-surface-200" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
@ -165,8 +165,8 @@
|
|||
{#if currentNode.alternatives && currentNode.alternatives.length > 0}
|
||||
<div class="text-left bg-surface-800 rounded-lg p-4 border border-surface-700">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<Icons.GitBranch class="w-5 h-5 text-purple-400" />
|
||||
<span class="font-medium text-purple-400">Alternatives to consider</span>
|
||||
<Icons.GitBranch class="w-5 h-5 text-surface-300" />
|
||||
<span class="font-medium text-surface-300">Alternatives to consider</span>
|
||||
</div>
|
||||
<ul class="space-y-1">
|
||||
{#each currentNode.alternatives as alt}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@
|
|||
<div class="relative">
|
||||
<div class="h-1 bg-surface-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
class="h-full bg-gradient-to-r from-blue-500 to-purple-500 transition-all duration-300"
|
||||
class="h-full bg-surface-100 transition-all duration-300"
|
||||
style="width: {progress}%"
|
||||
></div>
|
||||
</div>
|
||||
|
|
@ -122,12 +122,15 @@
|
|||
{@const Icon = getIcon(s.icon)}
|
||||
<button
|
||||
onclick={() => goToStep(i)}
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg transition-all duration-200"
|
||||
class:bg-blue-600={i === currentStep}
|
||||
class:text-white={i === currentStep}
|
||||
class:bg-surface-800={i !== currentStep && i <= currentStep}
|
||||
class:text-surface-300={i !== currentStep && i <= currentStep}
|
||||
class:bg-surface-900={i > currentStep}
|
||||
class="flex items-center gap-2 px-3 py-2 rounded-lg border transition-colors duration-200"
|
||||
class:bg-surface-100={i === currentStep}
|
||||
class:border-surface-200={i === currentStep}
|
||||
class:text-surface-950={i === currentStep}
|
||||
class:bg-surface-900={i !== currentStep && i <= currentStep}
|
||||
class:border-surface-800={i !== currentStep && i <= currentStep}
|
||||
class:text-surface-200={i !== currentStep && i <= currentStep}
|
||||
class:bg-surface-950={i > currentStep}
|
||||
class:border-surface-900={i > currentStep}
|
||||
class:text-surface-600={i > currentStep}
|
||||
>
|
||||
<Icon class="w-4 h-4" />
|
||||
|
|
@ -146,8 +149,8 @@
|
|||
<div class="flex items-start gap-6">
|
||||
<!-- Icon -->
|
||||
<div class="flex-shrink-0">
|
||||
<div class="w-16 h-16 rounded-xl bg-gradient-to-br from-blue-500/20 to-purple-500/20 flex items-center justify-center">
|
||||
<StepIcon class="w-8 h-8 text-blue-400" />
|
||||
<div class="w-16 h-16 rounded-xl bg-surface-900 border border-surface-800 flex items-center justify-center">
|
||||
<StepIcon class="w-8 h-8 text-surface-200" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -163,8 +166,8 @@
|
|||
{#if step.details}
|
||||
<div class="bg-surface-800 rounded-lg p-4 border border-surface-700">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<Icons.Info class="w-4 h-4 text-blue-400" />
|
||||
<span class="text-sm font-medium text-blue-400">Technical Details</span>
|
||||
<Icons.Info class="w-4 h-4 text-surface-300" />
|
||||
<span class="text-sm font-medium text-surface-300">Technical Details</span>
|
||||
</div>
|
||||
<p class="text-sm text-surface-400">{step.details}</p>
|
||||
</div>
|
||||
|
|
@ -200,9 +203,9 @@
|
|||
<button
|
||||
onclick={() => goToStep(i)}
|
||||
class="w-2 h-2 rounded-full transition-all duration-200"
|
||||
class:bg-blue-500={i === currentStep}
|
||||
class:bg-surface-100={i === currentStep}
|
||||
class:w-4={i === currentStep}
|
||||
class:bg-surface-600={i !== currentStep}
|
||||
class:bg-surface-700={i !== currentStep}
|
||||
></button>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -30,22 +30,22 @@
|
|||
const borderColor = $derived({
|
||||
aws: 'border-aws-orange',
|
||||
gcp: 'border-gcp-blue',
|
||||
concept: 'border-purple-500',
|
||||
default: 'border-surface-600'
|
||||
concept: 'border-surface-700',
|
||||
default: 'border-surface-800'
|
||||
}[type]);
|
||||
|
||||
const bgColor = $derived({
|
||||
aws: 'bg-aws-orange/10',
|
||||
gcp: 'bg-gcp-blue/10',
|
||||
concept: 'bg-purple-500/10',
|
||||
default: 'bg-surface-800'
|
||||
concept: 'bg-surface-900',
|
||||
default: 'bg-surface-900'
|
||||
}[type]);
|
||||
|
||||
const iconColor = $derived({
|
||||
aws: 'text-aws-orange',
|
||||
gcp: 'text-gcp-blue',
|
||||
concept: 'text-purple-400',
|
||||
default: 'text-surface-300'
|
||||
concept: 'text-surface-200',
|
||||
default: 'text-surface-200'
|
||||
}[type]);
|
||||
</script>
|
||||
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
{onclick}
|
||||
class="relative group cursor-pointer transition-all duration-200 transform hover:scale-105"
|
||||
class:ring-2={selected}
|
||||
class:ring-blue-500={selected}
|
||||
class:ring-surface-200={selected}
|
||||
class:ring-offset-2={selected}
|
||||
class:ring-offset-surface-950={selected}
|
||||
>
|
||||
|
|
@ -70,9 +70,9 @@
|
|||
|
||||
<!-- Description (on hover) -->
|
||||
{#if description}
|
||||
<div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-surface-800 rounded-lg text-xs text-surface-300 whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none z-10 border border-surface-700 shadow-lg">
|
||||
<div class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 px-3 py-2 bg-surface-900 rounded-lg text-xs text-surface-300 whitespace-nowrap opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none z-10 border border-surface-800 shadow-lg">
|
||||
{description}
|
||||
<div class="absolute top-full left-1/2 -translate-x-1/2 -mt-1 w-2 h-2 bg-surface-800 border-r border-b border-surface-700 transform rotate-45"></div>
|
||||
<div class="absolute top-full left-1/2 -translate-x-1/2 -mt-1 w-2 h-2 bg-surface-900 border-r border-b border-surface-800 transform rotate-45"></div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
<span class="absolute -top-2 -right-2 px-1.5 py-0.5 text-[10px] font-medium rounded-full uppercase
|
||||
{type === 'aws' ? 'bg-aws-orange text-white' : ''}
|
||||
{type === 'gcp' ? 'bg-gcp-blue text-white' : ''}
|
||||
{type === 'concept' ? 'bg-purple-500 text-white' : ''}
|
||||
{type === 'concept' ? 'bg-surface-200 text-surface-950' : ''}
|
||||
">
|
||||
{type}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -34,14 +34,14 @@
|
|||
<div class="h-16 flex items-center px-4 border-b border-surface-800">
|
||||
{#if $sidebarOpen}
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="w-8 h-8 rounded-lg bg-gradient-to-br from-blue-500 to-purple-500 flex items-center justify-center">
|
||||
<Icons.Layers class="w-5 h-5 text-white" />
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<Icons.Layers class="w-5 h-5 text-surface-200" />
|
||||
</div>
|
||||
<span class="font-bold text-lg text-surface-100">System Design</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="w-8 h-8 rounded-lg bg-gradient-to-br from-blue-500 to-purple-500 flex items-center justify-center mx-auto">
|
||||
<Icons.Layers class="w-5 h-5 text-white" />
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center mx-auto">
|
||||
<Icons.Layers class="w-5 h-5 text-surface-200" />
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -76,9 +76,10 @@
|
|||
{:else}
|
||||
<a
|
||||
href={item.href}
|
||||
class="w-full flex items-center gap-3 px-3 py-2 rounded-lg transition-colors duration-150"
|
||||
class:bg-blue-600={active}
|
||||
class:text-white={active}
|
||||
class="w-full flex items-center gap-3 px-3 py-2 rounded-lg border border-transparent transition-colors duration-150"
|
||||
class:bg-surface-800={active}
|
||||
class:border-surface-700={active}
|
||||
class:text-surface-100={active}
|
||||
class:text-surface-400={!active}
|
||||
class:hover:bg-surface-800={!active}
|
||||
class:hover:text-surface-200={!active}
|
||||
|
|
@ -97,7 +98,7 @@
|
|||
{@const childActive = isActive(child.href)}
|
||||
<a
|
||||
href={child.href}
|
||||
class="flex items-center gap-3 px-3 py-1.5 rounded-lg text-sm transition-colors duration-150 {childActive ? 'bg-blue-600/20 text-blue-400' : 'text-surface-500 hover:bg-surface-800 hover:text-surface-300'}"
|
||||
class="flex items-center gap-3 px-3 py-1.5 rounded-lg border border-transparent text-sm transition-colors duration-150 {childActive ? 'bg-surface-800 text-surface-200 border-surface-700' : 'text-surface-500 hover:bg-surface-800 hover:text-surface-300'}"
|
||||
>
|
||||
<ChildIcon class="w-4 h-4 flex-shrink-0" />
|
||||
<span>{child.label}</span>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
title: 'Fundamentals',
|
||||
description: 'Core distributed systems concepts: CAP theorem, consistency, scaling',
|
||||
icon: 'BookOpen',
|
||||
color: 'from-blue-500 to-cyan-500',
|
||||
href: '/fundamentals/cap-theorem'
|
||||
},
|
||||
{
|
||||
|
|
@ -16,7 +15,6 @@
|
|||
title: 'Compute',
|
||||
description: 'VMs, serverless, containers, and Kubernetes',
|
||||
icon: 'Cpu',
|
||||
color: 'from-purple-500 to-pink-500',
|
||||
href: '/compute/virtual-machines'
|
||||
},
|
||||
{
|
||||
|
|
@ -24,7 +22,6 @@
|
|||
title: 'Databases',
|
||||
description: 'SQL, NoSQL, caching, replication patterns',
|
||||
icon: 'Database',
|
||||
color: 'from-green-500 to-emerald-500',
|
||||
href: '/databases/sql'
|
||||
},
|
||||
{
|
||||
|
|
@ -32,7 +29,6 @@
|
|||
title: 'Networking',
|
||||
description: 'VPC, DNS, load balancing, CDN',
|
||||
icon: 'Network',
|
||||
color: 'from-orange-500 to-red-500',
|
||||
href: '/networking/vpc'
|
||||
},
|
||||
{
|
||||
|
|
@ -40,7 +36,6 @@
|
|||
title: 'Messaging',
|
||||
description: 'Message queues, pub/sub, event-driven architecture',
|
||||
icon: 'MessageSquare',
|
||||
color: 'from-yellow-500 to-orange-500',
|
||||
href: '/messaging/queues'
|
||||
},
|
||||
{
|
||||
|
|
@ -48,7 +43,6 @@
|
|||
title: 'Decision Trees',
|
||||
description: 'Interactive guides: which database? serverless or not?',
|
||||
icon: 'GitBranch',
|
||||
color: 'from-indigo-500 to-purple-500',
|
||||
href: '/decisions/which-database'
|
||||
}
|
||||
];
|
||||
|
|
@ -72,13 +66,13 @@
|
|||
<div class="max-w-6xl mx-auto space-y-12">
|
||||
<!-- Hero Section -->
|
||||
<div class="text-center space-y-6 py-8">
|
||||
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-blue-500/10 border border-blue-500/20 text-blue-400 text-sm">
|
||||
<div class="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-surface-900 border border-surface-800 text-surface-300 text-sm">
|
||||
<Icons.Sparkles class="w-4 h-4" />
|
||||
Interactive Visual Learning
|
||||
</div>
|
||||
|
||||
<h1 class="text-4xl md:text-5xl font-bold text-surface-100">
|
||||
Master <span class="text-gradient">System Design</span>
|
||||
Master System Design
|
||||
</h1>
|
||||
|
||||
<p class="text-lg text-surface-400 max-w-2xl mx-auto">
|
||||
|
|
@ -107,8 +101,8 @@
|
|||
class="card-hover group"
|
||||
>
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-12 h-12 rounded-xl bg-gradient-to-br {category.color} flex items-center justify-center flex-shrink-0 group-hover:scale-110 transition-transform duration-200">
|
||||
<Icon class="w-6 h-6 text-white" />
|
||||
<div class="w-12 h-12 rounded-xl bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0 group-hover:border-surface-600 transition-colors duration-200">
|
||||
<Icon class="w-6 h-6 text-surface-200" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-surface-100 group-hover:text-white transition-colors">
|
||||
|
|
@ -117,7 +111,7 @@
|
|||
<p class="text-sm text-surface-400 mt-1">{category.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex items-center text-sm text-blue-400 group-hover:text-blue-300">
|
||||
<div class="mt-4 flex items-center text-sm text-surface-400 group-hover:text-surface-200">
|
||||
<span>Explore</span>
|
||||
<Icons.ArrowRight class="w-4 h-4 ml-1 group-hover:translate-x-1 transition-transform" />
|
||||
</div>
|
||||
|
|
@ -128,8 +122,8 @@
|
|||
<!-- Quick Comparisons -->
|
||||
<div class="card">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-10 h-10 rounded-lg bg-purple-500/20 flex items-center justify-center">
|
||||
<Icons.Scale class="w-5 h-5 text-purple-400" />
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<Icons.Scale class="w-5 h-5 text-surface-300" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold text-surface-100">Quick Comparisons</h2>
|
||||
|
|
@ -197,8 +191,8 @@
|
|||
<!-- Key Concepts Preview -->
|
||||
<div class="card">
|
||||
<div class="flex items-center gap-3 mb-6">
|
||||
<div class="w-10 h-10 rounded-lg bg-green-500/20 flex items-center justify-center">
|
||||
<Icons.Lightbulb class="w-5 h-5 text-green-400" />
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<Icons.Lightbulb class="w-5 h-5 text-surface-300" />
|
||||
</div>
|
||||
<div>
|
||||
<h2 class="font-semibold text-surface-100">Key Concepts You'll Learn</h2>
|
||||
|
|
|
|||
|
|
@ -93,26 +93,26 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h1 class="text-3xl font-bold text-white mb-2">Kafka vs RabbitMQ</h1>
|
||||
<p class="text-gray-400 mb-8">Event streaming platform vs traditional message broker - understanding the fundamental differences</p>
|
||||
<h1 class="text-3xl font-bold text-surface-100 mb-2">Kafka vs RabbitMQ</h1>
|
||||
<p class="text-surface-400 mb-8">Event streaming platform vs traditional message broker - understanding the fundamental differences</p>
|
||||
|
||||
<!-- TL;DR -->
|
||||
<section class="mb-12">
|
||||
<div class="bg-gradient-to-r from-orange-500/10 to-green-500/10 rounded-xl p-6 border border-gray-700">
|
||||
<h2 class="text-lg font-semibold text-white mb-4">TL;DR</h2>
|
||||
<div class="card">
|
||||
<h2 class="text-lg font-semibold text-surface-100 mb-4">TL;DR</h2>
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="w-3 h-3 rounded-full bg-orange-500 mt-1.5"></div>
|
||||
<div>
|
||||
<span class="text-orange-400 font-medium">Kafka</span>
|
||||
<span class="text-gray-300"> = Event streaming. High throughput, message replay, data pipelines.</span>
|
||||
<span class="text-surface-300"> = Event streaming. High throughput, message replay, data pipelines.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="w-3 h-3 rounded-full bg-green-500 mt-1.5"></div>
|
||||
<div>
|
||||
<span class="text-green-400 font-medium">RabbitMQ</span>
|
||||
<span class="text-gray-300"> = Message broker. Complex routing, guaranteed delivery, task queues.</span>
|
||||
<span class="text-surface-300"> = Message broker. Complex routing, guaranteed delivery, task queues.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -121,14 +121,14 @@
|
|||
|
||||
<!-- Architecture Comparison -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Architecture Difference</h2>
|
||||
<p class="text-gray-400 mb-6">The fundamental architectural difference explains most of their behavior differences.</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Architecture Difference</h2>
|
||||
<p class="text-surface-400 mb-6">The fundamental architectural difference explains most of their behavior differences.</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<!-- Kafka -->
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-orange-500/30">
|
||||
<div class="card border-orange-500/30">
|
||||
<h3 class="text-lg font-semibold text-orange-400 mb-2">{architectureDiff.kafka.title}</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">{architectureDiff.kafka.description}</p>
|
||||
<p class="text-surface-400 text-sm mb-4">{architectureDiff.kafka.description}</p>
|
||||
|
||||
<div class="space-y-3 mb-4">
|
||||
{#each architectureDiff.kafka.flow as step, i}
|
||||
|
|
@ -137,8 +137,8 @@
|
|||
{i + 1}
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-white font-medium text-sm">{step.label}</div>
|
||||
<div class="text-gray-500 text-xs">{step.desc}</div>
|
||||
<div class="text-surface-100 font-medium text-sm">{step.label}</div>
|
||||
<div class="text-surface-500 text-xs">{step.desc}</div>
|
||||
</div>
|
||||
{#if i < architectureDiff.kafka.flow.length - 1}
|
||||
<div class="flex-1 border-t border-dashed border-orange-500/30"></div>
|
||||
|
|
@ -153,9 +153,9 @@
|
|||
</div>
|
||||
|
||||
<!-- RabbitMQ -->
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-green-500/30">
|
||||
<div class="card border-green-500/30">
|
||||
<h3 class="text-lg font-semibold text-green-400 mb-2">{architectureDiff.rabbitmq.title}</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">{architectureDiff.rabbitmq.description}</p>
|
||||
<p class="text-surface-400 text-sm mb-4">{architectureDiff.rabbitmq.description}</p>
|
||||
|
||||
<div class="space-y-3 mb-4">
|
||||
{#each architectureDiff.rabbitmq.flow as step, i}
|
||||
|
|
@ -164,8 +164,8 @@
|
|||
{i + 1}
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-white font-medium text-sm">{step.label}</div>
|
||||
<div class="text-gray-500 text-xs">{step.desc}</div>
|
||||
<div class="text-surface-100 font-medium text-sm">{step.label}</div>
|
||||
<div class="text-surface-500 text-xs">{step.desc}</div>
|
||||
</div>
|
||||
{#if i < architectureDiff.rabbitmq.flow.length - 1}
|
||||
<div class="flex-1 border-t border-dashed border-green-500/30"></div>
|
||||
|
|
@ -183,58 +183,58 @@
|
|||
|
||||
<!-- Message Lifecycle -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Message Lifecycle</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Message Lifecycle</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="card">
|
||||
<h3 class="text-lg font-semibold text-orange-400 mb-4">Kafka: Log-Based</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-3 p-3 bg-orange-500/10 rounded-lg">
|
||||
<span class="text-2xl">1.</span>
|
||||
<div>
|
||||
<div class="text-white">Message written to partition</div>
|
||||
<div class="text-gray-500 text-sm">Appended to end of log with offset</div>
|
||||
<div class="text-surface-100">Message written to partition</div>
|
||||
<div class="text-surface-500 text-sm">Appended to end of log with offset</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-orange-500/10 rounded-lg">
|
||||
<span class="text-2xl">2.</span>
|
||||
<div>
|
||||
<div class="text-white">Consumers read at their offset</div>
|
||||
<div class="text-gray-500 text-sm">Multiple consumers can read same message</div>
|
||||
<div class="text-surface-100">Consumers read at their offset</div>
|
||||
<div class="text-surface-500 text-sm">Multiple consumers can read same message</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-orange-500/10 rounded-lg">
|
||||
<span class="text-2xl">3.</span>
|
||||
<div>
|
||||
<div class="text-white">Retention policy deletes old messages</div>
|
||||
<div class="text-gray-500 text-sm">After 7 days or 1GB (configurable)</div>
|
||||
<div class="text-surface-100">Retention policy deletes old messages</div>
|
||||
<div class="text-surface-500 text-sm">After 7 days or 1GB (configurable)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="card">
|
||||
<h3 class="text-lg font-semibold text-green-400 mb-4">RabbitMQ: Queue-Based</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-3 p-3 bg-green-500/10 rounded-lg">
|
||||
<span class="text-2xl">1.</span>
|
||||
<div>
|
||||
<div class="text-white">Message routed to queue(s)</div>
|
||||
<div class="text-gray-500 text-sm">Exchange determines destination</div>
|
||||
<div class="text-surface-100">Message routed to queue(s)</div>
|
||||
<div class="text-surface-500 text-sm">Exchange determines destination</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-green-500/10 rounded-lg">
|
||||
<span class="text-2xl">2.</span>
|
||||
<div>
|
||||
<div class="text-white">Broker pushes to consumer</div>
|
||||
<div class="text-gray-500 text-sm">One consumer receives each message</div>
|
||||
<div class="text-surface-100">Broker pushes to consumer</div>
|
||||
<div class="text-surface-500 text-sm">One consumer receives each message</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-green-500/10 rounded-lg">
|
||||
<span class="text-2xl">3.</span>
|
||||
<div>
|
||||
<div class="text-white">Consumer acknowledges</div>
|
||||
<div class="text-gray-500 text-sm">Message deleted from queue</div>
|
||||
<div class="text-surface-100">Consumer acknowledges</div>
|
||||
<div class="text-surface-500 text-sm">Message deleted from queue</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -244,23 +244,23 @@
|
|||
|
||||
<!-- Feature Comparison -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Feature Comparison</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Feature Comparison</h2>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="bg-surface-900 rounded-xl border border-surface-800 overflow-hidden">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left p-4 text-gray-400 font-medium">Feature</th>
|
||||
<tr class="border-b border-surface-800">
|
||||
<th class="text-left p-4 text-surface-400 font-medium">Feature</th>
|
||||
<th class="text-left p-4 text-orange-400 font-medium">Kafka</th>
|
||||
<th class="text-left p-4 text-green-400 font-medium">RabbitMQ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each features as feature, i}
|
||||
<tr class="border-b border-gray-700/50 {i % 2 === 0 ? 'bg-gray-800/30' : ''}">
|
||||
<td class="p-4 text-white font-medium">{feature.name}</td>
|
||||
<td class="p-4 text-gray-300">{feature.kafka}</td>
|
||||
<td class="p-4 text-gray-300">{feature.rabbitmq}</td>
|
||||
<tr class="border-b border-surface-800 {i % 2 === 0 ? 'bg-surface-950/40' : ''}">
|
||||
<td class="p-4 text-surface-100 font-medium">{feature.name}</td>
|
||||
<td class="p-4 text-surface-300">{feature.kafka}</td>
|
||||
<td class="p-4 text-surface-300">{feature.rabbitmq}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
|
@ -270,45 +270,45 @@
|
|||
|
||||
<!-- When to Use -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">When to Use Each</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">When to Use Each</h2>
|
||||
<ComparisonTable options={comparisonOptions} />
|
||||
</section>
|
||||
|
||||
<!-- Exchange Types (RabbitMQ) -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">RabbitMQ Routing Patterns</h2>
|
||||
<p class="text-gray-400 mb-4">RabbitMQ's flexible exchange types enable complex routing scenarios that Kafka cannot do natively.</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">RabbitMQ Routing Patterns</h2>
|
||||
<p class="text-surface-400 mb-4">RabbitMQ's flexible exchange types enable complex routing scenarios that Kafka cannot do natively.</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-green-400 font-semibold mb-2">Direct</div>
|
||||
<div class="text-gray-400 text-sm">Route by exact routing key match</div>
|
||||
<div class="mt-2 text-xs text-gray-500">order.created to orders queue</div>
|
||||
<div class="text-surface-400 text-sm">Route by exact routing key match</div>
|
||||
<div class="mt-2 text-xs text-surface-500">order.created to orders queue</div>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-green-400 font-semibold mb-2">Topic</div>
|
||||
<div class="text-gray-400 text-sm">Route by pattern matching (*.error)</div>
|
||||
<div class="mt-2 text-xs text-gray-500">app.*.error to error-handler</div>
|
||||
<div class="text-surface-400 text-sm">Route by pattern matching (*.error)</div>
|
||||
<div class="mt-2 text-xs text-surface-500">app.*.error to error-handler</div>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-green-400 font-semibold mb-2">Fanout</div>
|
||||
<div class="text-gray-400 text-sm">Broadcast to all bound queues</div>
|
||||
<div class="mt-2 text-xs text-gray-500">notification to all subscribers</div>
|
||||
<div class="text-surface-400 text-sm">Broadcast to all bound queues</div>
|
||||
<div class="mt-2 text-xs text-surface-500">notification to all subscribers</div>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-green-400 font-semibold mb-2">Headers</div>
|
||||
<div class="text-gray-400 text-sm">Route by message headers</div>
|
||||
<div class="mt-2 text-xs text-gray-500">x-priority: high to fast queue</div>
|
||||
<div class="text-surface-400 text-sm">Route by message headers</div>
|
||||
<div class="mt-2 text-xs text-surface-500">x-priority: high to fast queue</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Kafka Partitions -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Kafka Partitioning</h2>
|
||||
<p class="text-gray-400 mb-4">Kafka achieves scalability through partitions - each partition is an ordered, immutable log.</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Kafka Partitioning</h2>
|
||||
<p class="text-surface-400 mb-4">Kafka achieves scalability through partitions - each partition is an ordered, immutable log.</p>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-6 border border-surface-800">
|
||||
<div class="grid md:grid-cols-3 gap-4 mb-6">
|
||||
<div class="p-4 bg-orange-500/10 rounded-lg border border-orange-500/30">
|
||||
<div class="text-orange-400 font-semibold mb-1">Partition 0</div>
|
||||
|
|
@ -338,16 +338,16 @@
|
|||
|
||||
<div class="grid md:grid-cols-3 gap-4 text-sm">
|
||||
<div>
|
||||
<div class="text-white font-medium">Ordering</div>
|
||||
<div class="text-gray-400">Guaranteed within partition only</div>
|
||||
<div class="text-surface-100 font-medium">Ordering</div>
|
||||
<div class="text-surface-400">Guaranteed within partition only</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-white font-medium">Parallelism</div>
|
||||
<div class="text-gray-400">Max consumers = number of partitions</div>
|
||||
<div class="text-surface-100 font-medium">Parallelism</div>
|
||||
<div class="text-surface-400">Max consumers = number of partitions</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-white font-medium">Key-based routing</div>
|
||||
<div class="text-gray-400">Same key always goes to same partition</div>
|
||||
<div class="text-surface-100 font-medium">Key-based routing</div>
|
||||
<div class="text-surface-400">Same key always goes to same partition</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -355,49 +355,49 @@
|
|||
|
||||
<!-- Use Case Examples -->
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Real World Examples</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Real World Examples</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-orange-500/30">
|
||||
<div class="card border-orange-500/30">
|
||||
<h3 class="text-lg font-semibold text-orange-400 mb-4">Kafka Use Cases</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Real-time Analytics</div>
|
||||
<div class="text-gray-400 text-sm">Stream clickstream data to analytics pipeline</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Real-time Analytics</div>
|
||||
<div class="text-surface-400 text-sm">Stream clickstream data to analytics pipeline</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Event Sourcing</div>
|
||||
<div class="text-gray-400 text-sm">Store all state changes as immutable events</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Event Sourcing</div>
|
||||
<div class="text-surface-400 text-sm">Store all state changes as immutable events</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Log Aggregation</div>
|
||||
<div class="text-gray-400 text-sm">Centralize logs from thousands of services</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Log Aggregation</div>
|
||||
<div class="text-surface-400 text-sm">Centralize logs from thousands of services</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">CDC Pipelines</div>
|
||||
<div class="text-gray-400 text-sm">Stream database changes to data warehouse</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">CDC Pipelines</div>
|
||||
<div class="text-surface-400 text-sm">Stream database changes to data warehouse</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-green-500/30">
|
||||
<div class="card border-green-500/30">
|
||||
<h3 class="text-lg font-semibold text-green-400 mb-4">RabbitMQ Use Cases</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Task Queues</div>
|
||||
<div class="text-gray-400 text-sm">Background job processing with retries</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Task Queues</div>
|
||||
<div class="text-surface-400 text-sm">Background job processing with retries</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Microservices</div>
|
||||
<div class="text-gray-400 text-sm">Async communication between services</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Microservices</div>
|
||||
<div class="text-surface-400 text-sm">Async communication between services</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">IoT Messaging</div>
|
||||
<div class="text-gray-400 text-sm">MQTT protocol for device communication</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">IoT Messaging</div>
|
||||
<div class="text-surface-400 text-sm">MQTT protocol for device communication</div>
|
||||
</div>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="text-white font-medium">Request/Reply</div>
|
||||
<div class="text-gray-400 text-sm">RPC-style communication patterns</div>
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-surface-100 font-medium">Request/Reply</div>
|
||||
<div class="text-surface-400 text-sm">RPC-style communication patterns</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -248,10 +248,10 @@
|
|||
/>
|
||||
|
||||
<!-- The Real Question -->
|
||||
<div class="card bg-gradient-to-br from-purple-500/10 to-pink-500/10 border-purple-500/30">
|
||||
<div class="card">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-lg bg-purple-500/20 flex items-center justify-center flex-shrink-0">
|
||||
<Icons.Lightbulb class="w-5 h-5 text-purple-400" />
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0">
|
||||
<Icons.Lightbulb class="w-5 h-5 text-surface-300" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-surface-100 mb-2">The Real Question to Ask</h3>
|
||||
|
|
|
|||
|
|
@ -97,33 +97,33 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h1 class="text-3xl font-bold text-white mb-2">Serverless Computing</h1>
|
||||
<p class="text-gray-400 mb-8">Understanding cold starts, warm starts, and optimization strategies</p>
|
||||
<h1 class="text-3xl font-bold text-surface-100 mb-2">Serverless Computing</h1>
|
||||
<p class="text-surface-400 mb-8">Understanding cold starts, warm starts, and optimization strategies</p>
|
||||
|
||||
<!-- Cold vs Warm Visual -->
|
||||
<section class="mb-12">
|
||||
<div class="flex gap-4 mb-6">
|
||||
<button
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all
|
||||
{showColdStart ? 'bg-blue-500 text-white' : 'bg-gray-700 text-gray-300 hover:bg-gray-600'}"
|
||||
{showColdStart ? 'bg-surface-100 text-surface-950' : 'bg-surface-900 border border-surface-800 text-surface-300 hover:bg-surface-800'}"
|
||||
on:click={() => showColdStart = true}
|
||||
>
|
||||
Cold Start
|
||||
</button>
|
||||
<button
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all
|
||||
{!showColdStart ? 'bg-green-500 text-white' : 'bg-gray-700 text-gray-300 hover:bg-gray-600'}"
|
||||
{!showColdStart ? 'bg-surface-100 text-surface-950' : 'bg-surface-900 border border-surface-800 text-surface-300 hover:bg-surface-800'}"
|
||||
on:click={() => showColdStart = false}
|
||||
>
|
||||
Warm Start
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="card">
|
||||
{#if showColdStart}
|
||||
<div class="mb-4">
|
||||
<h3 class="text-xl font-semibold text-blue-400 mb-2">Cold Start</h3>
|
||||
<p class="text-gray-400">No existing execution environment - must provision new container</p>
|
||||
<p class="text-surface-400">No existing execution environment - must provision new container</p>
|
||||
</div>
|
||||
|
||||
<!-- Cold Start Timeline -->
|
||||
|
|
@ -132,24 +132,24 @@
|
|||
<div class="space-y-4 pl-8">
|
||||
{#each coldStartPhases as phase, i}
|
||||
<div class="relative">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-blue-500 border-4 border-gray-800"></div>
|
||||
<div class="bg-gray-700/50 rounded-lg p-4">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-blue-500 border-4 border-surface-900"></div>
|
||||
<div class="bg-surface-800/60 border border-surface-800 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-white font-medium">{phase.name}</span>
|
||||
<span class="text-surface-100 font-medium">{phase.name}</span>
|
||||
<span class="text-blue-400 text-sm font-mono">{phase.duration}</span>
|
||||
</div>
|
||||
<p class="text-gray-400 text-sm">{phase.desc}</p>
|
||||
<p class="text-surface-400 text-sm">{phase.desc}</p>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="relative">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-green-500 border-4 border-gray-800"></div>
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-green-500 border-4 border-surface-900"></div>
|
||||
<div class="bg-green-500/20 rounded-lg p-4 border border-green-500/30">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-white font-medium">Handler Execution</span>
|
||||
<span class="text-surface-100 font-medium">Handler Execution</span>
|
||||
<span class="text-green-400 text-sm font-mono">Your code</span>
|
||||
</div>
|
||||
<p class="text-gray-400 text-sm">Finally, your function handler runs</p>
|
||||
<p class="text-surface-400 text-sm">Finally, your function handler runs</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -157,36 +157,36 @@
|
|||
|
||||
<div class="mt-6 p-4 bg-blue-500/10 rounded-lg border border-blue-500/30">
|
||||
<div class="text-blue-300 font-medium">Total Cold Start: 200ms - 3s+</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Depends on runtime, package size, and dependencies</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Depends on runtime, package size, and dependencies</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="mb-4">
|
||||
<h3 class="text-xl font-semibold text-green-400 mb-2">Warm Start</h3>
|
||||
<p class="text-gray-400">Reuses existing execution environment - skips initialization</p>
|
||||
<p class="text-surface-400">Reuses existing execution environment - skips initialization</p>
|
||||
</div>
|
||||
|
||||
<div class="relative">
|
||||
<div class="absolute left-0 top-0 bottom-0 w-1 bg-gray-600 rounded"></div>
|
||||
<div class="absolute left-0 top-0 bottom-0 w-1 bg-surface-700 rounded"></div>
|
||||
<div class="space-y-4 pl-8">
|
||||
{#each coldStartPhases as phase}
|
||||
<div class="relative opacity-40">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-gray-600 border-4 border-gray-800"></div>
|
||||
<div class="bg-gray-700/30 rounded-lg p-4">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-surface-700 border-4 border-surface-900"></div>
|
||||
<div class="bg-surface-800/40 border border-surface-800 rounded-lg p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="text-gray-500 font-medium line-through">{phase.name}</span>
|
||||
<span class="text-gray-600 text-sm">SKIPPED</span>
|
||||
<span class="text-surface-500 font-medium line-through">{phase.name}</span>
|
||||
<span class="text-surface-600 text-sm">SKIPPED</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="relative">
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-green-500 border-4 border-gray-800"></div>
|
||||
<div class="absolute -left-8 w-4 h-4 rounded-full bg-green-500 border-4 border-surface-900"></div>
|
||||
<div class="bg-green-500/20 rounded-lg p-4 border border-green-500/30">
|
||||
<div class="flex items-center justify-between mb-1">
|
||||
<span class="text-white font-medium">Handler Execution</span>
|
||||
<span class="text-surface-100 font-medium">Handler Execution</span>
|
||||
<span class="text-green-400 text-sm font-mono">~1-5ms</span>
|
||||
</div>
|
||||
<p class="text-gray-400 text-sm">Jump straight to your code!</p>
|
||||
<p class="text-surface-400 text-sm">Jump straight to your code!</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -194,7 +194,7 @@
|
|||
|
||||
<div class="mt-6 p-4 bg-green-500/10 rounded-lg border border-green-500/30">
|
||||
<div class="text-green-300 font-medium">Total Warm Start: 1-5ms</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Container reused for ~5-15 minutes of inactivity</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Container reused for ~5-15 minutes of inactivity</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
|
@ -202,32 +202,32 @@
|
|||
|
||||
<!-- Cold Start Walkthrough -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Cold Start Deep Dive</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Cold Start Deep Dive</h2>
|
||||
<GuidedWalkthrough {...coldStartWalkthrough} />
|
||||
</section>
|
||||
|
||||
<!-- Runtime Comparison -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Runtime Comparison</h2>
|
||||
<p class="text-gray-400 mb-6">Cold start times vary significantly by language runtime</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Runtime Comparison</h2>
|
||||
<p class="text-surface-400 mb-6">Cold start times vary significantly by language runtime</p>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="bg-surface-900 rounded-xl border border-surface-800 overflow-hidden">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left p-4 text-gray-400 font-medium">Runtime</th>
|
||||
<tr class="border-b border-surface-800">
|
||||
<th class="text-left p-4 text-surface-400 font-medium">Runtime</th>
|
||||
<th class="text-left p-4 text-blue-400 font-medium">Cold Start</th>
|
||||
<th class="text-left p-4 text-green-400 font-medium">Warm Start</th>
|
||||
<th class="text-left p-4 text-gray-400 font-medium">Notes</th>
|
||||
<th class="text-left p-4 text-surface-400 font-medium">Notes</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each runtimeComparison as rt, i}
|
||||
<tr class="border-b border-gray-700/50 {i % 2 === 0 ? 'bg-gray-800/30' : ''}">
|
||||
<td class="p-4 text-white font-medium">{rt.runtime}</td>
|
||||
<tr class="border-b border-surface-800 {i % 2 === 0 ? 'bg-surface-950/40' : ''}">
|
||||
<td class="p-4 text-surface-100 font-medium">{rt.runtime}</td>
|
||||
<td class="p-4 text-blue-300 font-mono">{rt.coldStart}</td>
|
||||
<td class="p-4 text-green-300 font-mono">{rt.warmStart}</td>
|
||||
<td class="p-4 text-gray-400 text-sm">{rt.notes}</td>
|
||||
<td class="p-4 text-surface-400 text-sm">{rt.notes}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
|
|
@ -237,26 +237,26 @@
|
|||
|
||||
<!-- Optimization Strategies -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Optimization Strategies</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Optimization Strategies</h2>
|
||||
|
||||
<div class="space-y-6">
|
||||
{#each optimizations as category}
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<h3 class="text-lg font-semibold text-white mb-4">{category.category}</h3>
|
||||
<div class="card">
|
||||
<h3 class="text-lg font-semibold text-surface-100 mb-4">{category.category}</h3>
|
||||
<div class="grid md:grid-cols-2 gap-4">
|
||||
{#each category.items as item}
|
||||
<div class="p-4 bg-gray-700/30 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/40 border border-surface-800 rounded-lg">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-white font-medium">{item.name}</span>
|
||||
<span class="text-surface-100 font-medium">{item.name}</span>
|
||||
<span class="px-2 py-0.5 rounded text-xs font-medium
|
||||
{item.impact === 'Eliminates' ? 'bg-green-500/20 text-green-400' : ''}
|
||||
{item.impact === 'High' ? 'bg-blue-500/20 text-blue-400' : ''}
|
||||
{item.impact === 'Medium' ? 'bg-yellow-500/20 text-yellow-400' : ''}
|
||||
{item.impact === 'Low' ? 'bg-gray-500/20 text-gray-400' : ''}">
|
||||
{item.impact === 'Low' ? 'bg-surface-700/40 text-surface-300' : ''}">
|
||||
{item.impact} impact
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-gray-400 text-sm">{item.desc}</p>
|
||||
<p class="text-surface-400 text-sm">{item.desc}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
@ -267,30 +267,30 @@
|
|||
|
||||
<!-- Provisioned Concurrency vs SnapStart -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Provisioned Concurrency vs SnapStart</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Provisioned Concurrency vs SnapStart</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-purple-500/30">
|
||||
<div class="card border-purple-500/30">
|
||||
<h3 class="text-lg font-semibold text-purple-400 mb-4">Provisioned Concurrency</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Pre-initialize a specified number of execution environments that are always ready.
|
||||
</p>
|
||||
<div class="space-y-2 mb-4">
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-green-400">+</span>
|
||||
<span class="text-gray-300">Eliminates cold starts completely</span>
|
||||
<span class="text-surface-300">Eliminates cold starts completely</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-green-400">+</span>
|
||||
<span class="text-gray-300">Works with any runtime</span>
|
||||
<span class="text-surface-300">Works with any runtime</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-red-400">-</span>
|
||||
<span class="text-gray-300">Costs money even when idle</span>
|
||||
<span class="text-surface-300">Costs money even when idle</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-red-400">-</span>
|
||||
<span class="text-gray-300">Must estimate concurrency needs</span>
|
||||
<span class="text-surface-300">Must estimate concurrency needs</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 bg-purple-500/10 rounded-lg">
|
||||
|
|
@ -298,27 +298,27 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-orange-500/30">
|
||||
<div class="card border-orange-500/30">
|
||||
<h3 class="text-lg font-semibold text-orange-400 mb-4">SnapStart</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Snapshot initialized state and restore from cache instead of re-initializing.
|
||||
</p>
|
||||
<div class="space-y-2 mb-4">
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-green-400">+</span>
|
||||
<span class="text-gray-300">Up to 10x faster cold starts</span>
|
||||
<span class="text-surface-300">Up to 10x faster cold starts</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-green-400">+</span>
|
||||
<span class="text-gray-300">No additional cost</span>
|
||||
<span class="text-surface-300">No additional cost</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-red-400">-</span>
|
||||
<span class="text-gray-300">Only Java, Python, .NET</span>
|
||||
<span class="text-surface-300">Only Java, Python, .NET</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm">
|
||||
<span class="text-red-400">-</span>
|
||||
<span class="text-gray-300">May need code changes for uniqueness</span>
|
||||
<span class="text-surface-300">May need code changes for uniqueness</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-3 bg-orange-500/10 rounded-lg">
|
||||
|
|
@ -330,30 +330,30 @@
|
|||
|
||||
<!-- Best Practices -->
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Best Practices</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Best Practices</h2>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="card">
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div>
|
||||
<h4 class="text-green-400 font-medium mb-3">DO</h4>
|
||||
<ul class="space-y-2">
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-green-400 mt-0.5">+</span>
|
||||
Initialize SDK clients outside the handler (global scope)
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-green-400 mt-0.5">+</span>
|
||||
Reuse database connections across invocations
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-green-400 mt-0.5">+</span>
|
||||
Use Lambda Layers for shared dependencies
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-green-400 mt-0.5">+</span>
|
||||
Monitor INIT duration in CloudWatch
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-green-400 mt-0.5">+</span>
|
||||
Use ARM architecture for cost savings
|
||||
</li>
|
||||
|
|
@ -362,23 +362,23 @@
|
|||
<div>
|
||||
<h4 class="text-red-400 font-medium mb-3">DON'T</h4>
|
||||
<ul class="space-y-2">
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-red-400 mt-0.5">-</span>
|
||||
Create new connections on every invocation
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-red-400 mt-0.5">-</span>
|
||||
Bundle unnecessary dependencies
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-red-400 mt-0.5">-</span>
|
||||
Use VPC unless you need private resources
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-red-400 mt-0.5">-</span>
|
||||
Ignore cold start metrics in production
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300 text-sm">
|
||||
<li class="flex items-start gap-2 text-surface-300 text-sm">
|
||||
<span class="text-red-400 mt-0.5">-</span>
|
||||
Use Java without SnapStart for user-facing APIs
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -203,29 +203,29 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h1 class="text-3xl font-bold text-white mb-2">Caching Patterns</h1>
|
||||
<p class="text-gray-400 mb-8">Understanding different caching strategies and when to use each</p>
|
||||
<h1 class="text-3xl font-bold text-surface-100 mb-2">Caching Patterns</h1>
|
||||
<p class="text-surface-400 mb-8">Understanding different caching strategies and when to use each</p>
|
||||
|
||||
<!-- Overview -->
|
||||
<section class="mb-12">
|
||||
<div class="bg-gradient-to-r from-blue-500/10 to-purple-500/10 rounded-xl p-6 border border-gray-700">
|
||||
<h2 class="text-lg font-semibold text-white mb-4">Why Caching Matters</h2>
|
||||
<div class="card">
|
||||
<h2 class="text-lg font-semibold text-surface-100 mb-4">Why Caching Matters</h2>
|
||||
<div class="grid md:grid-cols-4 gap-4 text-center">
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-3xl font-bold text-blue-400">10-100x</div>
|
||||
<div class="text-gray-400 text-sm">Faster than database</div>
|
||||
<div class="text-surface-400 text-sm">Faster than database</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-3xl font-bold text-green-400"><1ms</div>
|
||||
<div class="text-gray-400 text-sm">Cache read latency</div>
|
||||
<div class="text-surface-400 text-sm">Cache read latency</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-3xl font-bold text-purple-400">90%+</div>
|
||||
<div class="text-gray-400 text-sm">Target hit rate</div>
|
||||
<div class="text-surface-400 text-sm">Target hit rate</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-3xl font-bold text-orange-400">$$$</div>
|
||||
<div class="text-gray-400 text-sm">Reduced DB costs</div>
|
||||
<div class="text-surface-400 text-sm">Reduced DB costs</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -233,12 +233,12 @@
|
|||
|
||||
<!-- Pattern Cards -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Caching Patterns</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Caching Patterns</h2>
|
||||
|
||||
<div class="grid gap-6">
|
||||
{#each patterns as pattern}
|
||||
<div
|
||||
class="bg-gray-800/50 rounded-xl border border-gray-700 overflow-hidden cursor-pointer transition-all hover:border-gray-500"
|
||||
class="bg-surface-900 rounded-xl border border-surface-800 overflow-hidden cursor-pointer transition-colors hover:border-surface-700"
|
||||
class:border-blue-500={selectedPattern === pattern.id && pattern.color === 'blue'}
|
||||
class:border-green-500={selectedPattern === pattern.id && pattern.color === 'green'}
|
||||
class:border-purple-500={selectedPattern === pattern.id && pattern.color === 'purple'}
|
||||
|
|
@ -252,8 +252,8 @@
|
|||
<div class="p-6">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-white">{pattern.name}</h3>
|
||||
<p class="text-gray-400 text-sm">{pattern.description}</p>
|
||||
<h3 class="text-lg font-semibold text-surface-100">{pattern.name}</h3>
|
||||
<p class="text-surface-400 text-sm">{pattern.description}</p>
|
||||
</div>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-medium
|
||||
{pattern.color === 'blue' ? 'bg-blue-500/20 text-blue-400' : ''}
|
||||
|
|
@ -269,23 +269,23 @@
|
|||
<div class="flex items-center gap-2 mb-4 overflow-x-auto pb-2">
|
||||
{#each pattern.steps as step, i}
|
||||
<div class="flex items-center">
|
||||
<div class="px-3 py-2 bg-gray-700/50 rounded-lg text-sm text-gray-300 whitespace-nowrap">
|
||||
<div class="px-3 py-2 bg-surface-800/60 border border-surface-800 rounded-lg text-sm text-surface-300 whitespace-nowrap">
|
||||
{step}
|
||||
</div>
|
||||
{#if i < pattern.steps.length - 1}
|
||||
<span class="mx-2 text-gray-500">-></span>
|
||||
<span class="mx-2 text-surface-600">-></span>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
{#if selectedPattern === pattern.id}
|
||||
<div class="grid md:grid-cols-2 gap-4 pt-4 border-t border-gray-700">
|
||||
<div class="grid md:grid-cols-2 gap-4 pt-4 border-t border-surface-800">
|
||||
<div>
|
||||
<h4 class="text-green-400 font-medium mb-2">Pros</h4>
|
||||
<ul class="space-y-1">
|
||||
{#each pattern.pros as pro}
|
||||
<li class="text-gray-300 text-sm flex items-start gap-2">
|
||||
<li class="text-surface-300 text-sm flex items-start gap-2">
|
||||
<span class="text-green-400">+</span>
|
||||
{pro}
|
||||
</li>
|
||||
|
|
@ -296,7 +296,7 @@
|
|||
<h4 class="text-red-400 font-medium mb-2">Cons</h4>
|
||||
<ul class="space-y-1">
|
||||
{#each pattern.cons as con}
|
||||
<li class="text-gray-300 text-sm flex items-start gap-2">
|
||||
<li class="text-surface-300 text-sm flex items-start gap-2">
|
||||
<span class="text-red-400">-</span>
|
||||
{con}
|
||||
</li>
|
||||
|
|
@ -313,21 +313,21 @@
|
|||
|
||||
<!-- Cache-Aside Walkthrough -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Cache-Aside in Detail</h2>
|
||||
<p class="text-gray-400 mb-6">The most common caching pattern - walk through each step.</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Cache-Aside in Detail</h2>
|
||||
<p class="text-surface-400 mb-6">The most common caching pattern - walk through each step.</p>
|
||||
<GuidedWalkthrough {...cacheAsideWalkthrough} />
|
||||
</section>
|
||||
|
||||
<!-- Eviction Strategies -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Eviction Strategies</h2>
|
||||
<p class="text-gray-400 mb-6">When cache is full, which items should be removed?</p>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Eviction Strategies</h2>
|
||||
<p class="text-surface-400 mb-6">When cache is full, which items should be removed?</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{#each evictionStrategies as strategy}
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<h3 class="text-white font-semibold mb-2">{strategy.name}</h3>
|
||||
<p class="text-gray-400 text-sm mb-3">{strategy.description}</p>
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<h3 class="text-surface-100 font-semibold mb-2">{strategy.name}</h3>
|
||||
<p class="text-surface-400 text-sm mb-3">{strategy.description}</p>
|
||||
<div class="text-xs text-blue-400">Best for: {strategy.best}</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
|
@ -336,17 +336,17 @@
|
|||
|
||||
<!-- Common Issues -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Common Caching Problems</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Common Caching Problems</h2>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-6">
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-red-500/30">
|
||||
<div class="card border-red-500/30">
|
||||
<h3 class="text-red-400 font-semibold mb-3">Cache Stampede</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Many requests hit an expired cache key simultaneously, all querying the database at once.
|
||||
</p>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-green-400 text-sm font-medium mb-1">Solutions:</div>
|
||||
<ul class="text-gray-300 text-sm space-y-1">
|
||||
<ul class="text-surface-300 text-sm space-y-1">
|
||||
<li>- Lock/mutex on cache refresh</li>
|
||||
<li>- Staggered TTLs</li>
|
||||
<li>- Background refresh</li>
|
||||
|
|
@ -354,14 +354,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-yellow-500/30">
|
||||
<div class="card border-yellow-500/30">
|
||||
<h3 class="text-yellow-400 font-semibold mb-3">Stale Data</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Cache contains outdated data that does not reflect current database state.
|
||||
</p>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-green-400 text-sm font-medium mb-1">Solutions:</div>
|
||||
<ul class="text-gray-300 text-sm space-y-1">
|
||||
<ul class="text-surface-300 text-sm space-y-1">
|
||||
<li>- Appropriate TTL values</li>
|
||||
<li>- Cache invalidation on writes</li>
|
||||
<li>- Write-through pattern</li>
|
||||
|
|
@ -369,14 +369,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-orange-500/30">
|
||||
<div class="card border-orange-500/30">
|
||||
<h3 class="text-orange-400 font-semibold mb-3">Cache Penetration</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Requests for non-existent data bypass cache and always hit the database.
|
||||
</p>
|
||||
<div class="p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="text-green-400 text-sm font-medium mb-1">Solutions:</div>
|
||||
<ul class="text-gray-300 text-sm space-y-1">
|
||||
<ul class="text-surface-300 text-sm space-y-1">
|
||||
<li>- Cache negative results</li>
|
||||
<li>- Bloom filter for existence check</li>
|
||||
<li>- Input validation</li>
|
||||
|
|
@ -388,52 +388,52 @@
|
|||
|
||||
<!-- Redis vs Memcached -->
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Redis vs Memcached</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Redis vs Memcached</h2>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl border border-gray-700 overflow-hidden">
|
||||
<div class="bg-surface-900 rounded-xl border border-surface-800 overflow-hidden">
|
||||
<table class="w-full">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-700">
|
||||
<th class="text-left p-4 text-gray-400 font-medium">Feature</th>
|
||||
<tr class="border-b border-surface-800">
|
||||
<th class="text-left p-4 text-surface-400 font-medium">Feature</th>
|
||||
<th class="text-left p-4 text-red-400 font-medium">Redis</th>
|
||||
<th class="text-left p-4 text-green-400 font-medium">Memcached</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b border-gray-700/50">
|
||||
<td class="p-4 text-white">Data Structures</td>
|
||||
<td class="p-4 text-gray-300">Strings, Lists, Sets, Hashes, Sorted Sets</td>
|
||||
<td class="p-4 text-gray-300">Strings only</td>
|
||||
<tr class="border-b border-surface-800">
|
||||
<td class="p-4 text-surface-100">Data Structures</td>
|
||||
<td class="p-4 text-surface-300">Strings, Lists, Sets, Hashes, Sorted Sets</td>
|
||||
<td class="p-4 text-surface-300">Strings only</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-700/50 bg-gray-800/30">
|
||||
<td class="p-4 text-white">Persistence</td>
|
||||
<td class="p-4 text-gray-300">Yes (RDB, AOF)</td>
|
||||
<td class="p-4 text-gray-300">No</td>
|
||||
<tr class="border-b border-surface-800 bg-surface-950/40">
|
||||
<td class="p-4 text-surface-100">Persistence</td>
|
||||
<td class="p-4 text-surface-300">Yes (RDB, AOF)</td>
|
||||
<td class="p-4 text-surface-300">No</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-700/50">
|
||||
<td class="p-4 text-white">Replication</td>
|
||||
<td class="p-4 text-gray-300">Built-in</td>
|
||||
<td class="p-4 text-gray-300">No</td>
|
||||
<tr class="border-b border-surface-800">
|
||||
<td class="p-4 text-surface-100">Replication</td>
|
||||
<td class="p-4 text-surface-300">Built-in</td>
|
||||
<td class="p-4 text-surface-300">No</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-700/50 bg-gray-800/30">
|
||||
<td class="p-4 text-white">Pub/Sub</td>
|
||||
<td class="p-4 text-gray-300">Yes</td>
|
||||
<td class="p-4 text-gray-300">No</td>
|
||||
<tr class="border-b border-surface-800 bg-surface-950/40">
|
||||
<td class="p-4 text-surface-100">Pub/Sub</td>
|
||||
<td class="p-4 text-surface-300">Yes</td>
|
||||
<td class="p-4 text-surface-300">No</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-700/50">
|
||||
<td class="p-4 text-white">Lua Scripting</td>
|
||||
<td class="p-4 text-gray-300">Yes</td>
|
||||
<td class="p-4 text-gray-300">No</td>
|
||||
<tr class="border-b border-surface-800">
|
||||
<td class="p-4 text-surface-100">Lua Scripting</td>
|
||||
<td class="p-4 text-surface-300">Yes</td>
|
||||
<td class="p-4 text-surface-300">No</td>
|
||||
</tr>
|
||||
<tr class="border-b border-gray-700/50 bg-gray-800/30">
|
||||
<td class="p-4 text-white">Memory Efficiency</td>
|
||||
<td class="p-4 text-gray-300">Good</td>
|
||||
<td class="p-4 text-gray-300">Better (simpler)</td>
|
||||
<tr class="border-b border-surface-800 bg-surface-950/40">
|
||||
<td class="p-4 text-surface-100">Memory Efficiency</td>
|
||||
<td class="p-4 text-surface-300">Good</td>
|
||||
<td class="p-4 text-surface-300">Better (simpler)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="p-4 text-white">Best For</td>
|
||||
<td class="p-4 text-gray-300">Feature-rich caching, sessions, queues</td>
|
||||
<td class="p-4 text-gray-300">Simple, high-throughput key-value cache</td>
|
||||
<td class="p-4 text-surface-100">Best For</td>
|
||||
<td class="p-4 text-surface-300">Feature-rich caching, sessions, queues</td>
|
||||
<td class="p-4 text-surface-300">Simple, high-throughput key-value cache</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -106,33 +106,33 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<h1 class="text-3xl font-bold text-white mb-2">Database Replication</h1>
|
||||
<p class="text-gray-400 mb-8">Understanding replication topologies, sync vs async, and consistency trade-offs</p>
|
||||
<h1 class="text-3xl font-bold text-surface-100 mb-2">Database Replication</h1>
|
||||
<p class="text-surface-400 mb-8">Understanding replication topologies, sync vs async, and consistency trade-offs</p>
|
||||
|
||||
<!-- Why Replication -->
|
||||
<section class="mb-12">
|
||||
<div class="bg-gradient-to-r from-blue-500/10 to-purple-500/10 rounded-xl p-6 border border-gray-700">
|
||||
<h2 class="text-lg font-semibold text-white mb-4">Why Replicate?</h2>
|
||||
<div class="card">
|
||||
<h2 class="text-lg font-semibold text-surface-100 mb-4">Why Replicate?</h2>
|
||||
<div class="grid md:grid-cols-4 gap-4">
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg text-center">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg text-center">
|
||||
<div class="text-2xl mb-2">HA</div>
|
||||
<div class="text-white font-medium">High Availability</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Survive node failures</div>
|
||||
<div class="text-surface-100 font-medium">High Availability</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Survive node failures</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg text-center">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg text-center">
|
||||
<div class="text-2xl mb-2">R</div>
|
||||
<div class="text-white font-medium">Read Scaling</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Distribute read load</div>
|
||||
<div class="text-surface-100 font-medium">Read Scaling</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Distribute read load</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg text-center">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg text-center">
|
||||
<div class="text-2xl mb-2">GEO</div>
|
||||
<div class="text-white font-medium">Geographic</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Data closer to users</div>
|
||||
<div class="text-surface-100 font-medium">Geographic</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Data closer to users</div>
|
||||
</div>
|
||||
<div class="p-4 bg-gray-800/50 rounded-lg text-center">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg text-center">
|
||||
<div class="text-2xl mb-2">DR</div>
|
||||
<div class="text-white font-medium">Disaster Recovery</div>
|
||||
<div class="text-gray-400 text-sm mt-1">Backup in another region</div>
|
||||
<div class="text-surface-100 font-medium">Disaster Recovery</div>
|
||||
<div class="text-surface-400 text-sm mt-1">Backup in another region</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -140,19 +140,19 @@
|
|||
|
||||
<!-- Sync vs Async Toggle -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Synchronous vs Asynchronous</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Synchronous vs Asynchronous</h2>
|
||||
|
||||
<div class="flex gap-4 mb-6">
|
||||
<button
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all
|
||||
{selectedType === 'sync' ? 'bg-blue-500 text-white' : 'bg-gray-700 text-gray-300 hover:bg-gray-600'}"
|
||||
{selectedType === 'sync' ? 'bg-surface-100 text-surface-950' : 'bg-surface-900 border border-surface-800 text-surface-300 hover:bg-surface-800'}"
|
||||
on:click={() => selectedType = selectedType === 'sync' ? null : 'sync'}
|
||||
>
|
||||
Synchronous
|
||||
</button>
|
||||
<button
|
||||
class="px-4 py-2 rounded-lg font-medium transition-all
|
||||
{selectedType === 'async' ? 'bg-green-500 text-white' : 'bg-gray-700 text-gray-300 hover:bg-gray-600'}"
|
||||
{selectedType === 'async' ? 'bg-surface-100 text-surface-950' : 'bg-surface-900 border border-surface-800 text-surface-300 hover:bg-surface-800'}"
|
||||
on:click={() => selectedType = selectedType === 'async' ? null : 'async'}
|
||||
>
|
||||
Asynchronous
|
||||
|
|
@ -161,32 +161,32 @@
|
|||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<!-- Sync -->
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border {selectedType === 'sync' ? 'border-blue-500' : 'border-gray-700'}">
|
||||
<div class="card {selectedType === 'sync' ? 'border-blue-500/40' : 'border-surface-800'}">
|
||||
<h3 class="text-lg font-semibold text-blue-400 mb-4">Synchronous Replication</h3>
|
||||
|
||||
<div class="space-y-3 mb-6">
|
||||
<div class="flex items-center gap-3 p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="flex items-center gap-3 p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="w-10 h-10 rounded-full bg-blue-500/20 flex items-center justify-center text-blue-400 font-bold">1</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm">Client writes to leader</div>
|
||||
<div class="text-surface-100 text-sm">Client writes to leader</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="flex items-center gap-3 p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="w-10 h-10 rounded-full bg-blue-500/20 flex items-center justify-center text-blue-400 font-bold">2</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm">Leader sends to replica</div>
|
||||
<div class="text-surface-100 text-sm">Leader sends to replica</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-blue-500/20 rounded-lg border border-blue-500/30">
|
||||
<div class="w-10 h-10 rounded-full bg-blue-500/30 flex items-center justify-center text-blue-400 font-bold">3</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm font-medium">WAIT for replica confirmation</div>
|
||||
<div class="text-surface-100 text-sm font-medium">WAIT for replica confirmation</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="flex items-center gap-3 p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="w-10 h-10 rounded-full bg-blue-500/20 flex items-center justify-center text-blue-400 font-bold">4</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm">Acknowledge to client</div>
|
||||
<div class="text-surface-100 text-sm">Acknowledge to client</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -197,27 +197,27 @@
|
|||
</div>
|
||||
|
||||
<!-- Async -->
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border {selectedType === 'async' ? 'border-green-500' : 'border-gray-700'}">
|
||||
<div class="card {selectedType === 'async' ? 'border-green-500/40' : 'border-surface-800'}">
|
||||
<h3 class="text-lg font-semibold text-green-400 mb-4">Asynchronous Replication</h3>
|
||||
|
||||
<div class="space-y-3 mb-6">
|
||||
<div class="flex items-center gap-3 p-3 bg-gray-700/50 rounded-lg">
|
||||
<div class="flex items-center gap-3 p-3 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="w-10 h-10 rounded-full bg-green-500/20 flex items-center justify-center text-green-400 font-bold">1</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm">Client writes to leader</div>
|
||||
<div class="text-surface-100 text-sm">Client writes to leader</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-green-500/20 rounded-lg border border-green-500/30">
|
||||
<div class="w-10 h-10 rounded-full bg-green-500/30 flex items-center justify-center text-green-400 font-bold">2</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm font-medium">Acknowledge immediately</div>
|
||||
<div class="text-surface-100 text-sm font-medium">Acknowledge immediately</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 p-3 bg-gray-700/50 rounded-lg opacity-60">
|
||||
<div class="flex items-center gap-3 p-3 bg-surface-800/60 border border-surface-800 rounded-lg opacity-60">
|
||||
<div class="w-10 h-10 rounded-full bg-green-500/20 flex items-center justify-center text-green-400 font-bold">3</div>
|
||||
<div class="flex-1">
|
||||
<div class="text-white text-sm">Replicate in background</div>
|
||||
<div class="text-gray-500 text-xs">May lag behind leader</div>
|
||||
<div class="text-surface-100 text-sm">Replicate in background</div>
|
||||
<div class="text-surface-500 text-xs">May lag behind leader</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -231,23 +231,23 @@
|
|||
|
||||
<!-- When to Use Each -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">When to Use Each</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">When to Use Each</h2>
|
||||
<ComparisonTable options={comparisonOptions} />
|
||||
</section>
|
||||
|
||||
<!-- Replication Topologies -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Replication Topologies</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Replication Topologies</h2>
|
||||
|
||||
<div class="space-y-6">
|
||||
{#each replicationTypes as type}
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<div class="card">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold text-white">{type.name}</h3>
|
||||
<p class="text-gray-400 text-sm">{type.description}</p>
|
||||
<h3 class="text-lg font-semibold text-surface-100">{type.name}</h3>
|
||||
<p class="text-surface-400 text-sm">{type.description}</p>
|
||||
</div>
|
||||
<span class="px-3 py-1 rounded-full text-xs font-medium bg-purple-500/20 text-purple-400">
|
||||
<span class="px-3 py-1 rounded-full text-xs font-medium bg-surface-800 text-surface-300 border border-surface-700">
|
||||
{type.useCase}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -257,7 +257,7 @@
|
|||
<h4 class="text-green-400 font-medium mb-2 text-sm">Pros</h4>
|
||||
<ul class="space-y-1">
|
||||
{#each type.pros as pro}
|
||||
<li class="text-gray-300 text-sm flex items-start gap-2">
|
||||
<li class="text-surface-300 text-sm flex items-start gap-2">
|
||||
<span class="text-green-400">+</span>
|
||||
{pro}
|
||||
</li>
|
||||
|
|
@ -268,7 +268,7 @@
|
|||
<h4 class="text-red-400 font-medium mb-2 text-sm">Cons</h4>
|
||||
<ul class="space-y-1">
|
||||
{#each type.cons as con}
|
||||
<li class="text-gray-300 text-sm flex items-start gap-2">
|
||||
<li class="text-surface-300 text-sm flex items-start gap-2">
|
||||
<span class="text-red-400">-</span>
|
||||
{con}
|
||||
</li>
|
||||
|
|
@ -283,29 +283,29 @@
|
|||
|
||||
<!-- Replication Lag -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Understanding Replication Lag</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Understanding Replication Lag</h2>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-gray-700">
|
||||
<p class="text-gray-400 mb-6">
|
||||
<div class="card">
|
||||
<p class="text-surface-400 mb-6">
|
||||
Replication lag is the delay between when data is written to the leader and when it appears on replicas.
|
||||
Multiple metrics help pinpoint where the lag is occurring.
|
||||
</p>
|
||||
|
||||
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
||||
{#each lagMetrics as metric, i}
|
||||
<div class="p-4 bg-gray-700/50 rounded-lg">
|
||||
<div class="p-4 bg-surface-800/60 border border-surface-800 rounded-lg">
|
||||
<div class="flex items-center gap-2 mb-2">
|
||||
<div class="w-6 h-6 rounded-full bg-blue-500/20 flex items-center justify-center text-blue-400 text-xs font-bold">{i + 1}</div>
|
||||
<span class="text-white font-medium text-sm">{metric.name}</span>
|
||||
<span class="text-surface-100 font-medium text-sm">{metric.name}</span>
|
||||
</div>
|
||||
<p class="text-gray-400 text-xs">{metric.desc}</p>
|
||||
<p class="text-surface-400 text-xs">{metric.desc}</p>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-700/50 rounded-lg p-4">
|
||||
<h4 class="text-white font-medium mb-2">PostgreSQL: Check Replication Lag</h4>
|
||||
<pre class="text-sm text-gray-300 overflow-x-auto"><code>SELECT client_addr, state,
|
||||
<div class="bg-surface-950 rounded-lg border border-surface-800 p-4">
|
||||
<h4 class="text-surface-100 font-medium mb-2">PostgreSQL: Check Replication Lag</h4>
|
||||
<pre class="text-sm text-surface-300 overflow-x-auto"><code>SELECT client_addr, state,
|
||||
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
|
||||
replay_lag
|
||||
FROM pg_stat_replication;</code></pre>
|
||||
|
|
@ -315,45 +315,45 @@ FROM pg_stat_replication;</code></pre>
|
|||
|
||||
<!-- Failover -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Failover Considerations</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Failover Considerations</h2>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-yellow-500/30">
|
||||
<div class="card border-yellow-500/30">
|
||||
<h3 class="text-yellow-400 font-semibold mb-4">Automatic Failover</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
System automatically promotes replica when leader fails. Fast recovery but risks split-brain.
|
||||
</p>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-yellow-400">!</span>
|
||||
Requires proper fencing to prevent split-brain
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-yellow-400">!</span>
|
||||
May lose uncommitted transactions (async)
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-yellow-400">!</span>
|
||||
Applications may need reconnection logic
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="bg-gray-800/50 rounded-xl p-6 border border-blue-500/30">
|
||||
<div class="card border-blue-500/30">
|
||||
<h3 class="text-blue-400 font-semibold mb-4">Manual Failover</h3>
|
||||
<p class="text-gray-400 text-sm mb-4">
|
||||
<p class="text-surface-400 text-sm mb-4">
|
||||
Operator manually promotes replica after verifying state. Slower but safer.
|
||||
</p>
|
||||
<ul class="space-y-2 text-sm">
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-blue-400">-</span>
|
||||
Verify replica is fully caught up
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-blue-400">-</span>
|
||||
Stop writes to old leader first
|
||||
</li>
|
||||
<li class="flex items-start gap-2 text-gray-300">
|
||||
<li class="flex items-start gap-2 text-surface-300">
|
||||
<span class="text-blue-400">-</span>
|
||||
Update DNS/connection strings
|
||||
</li>
|
||||
|
|
@ -364,32 +364,32 @@ FROM pg_stat_replication;</code></pre>
|
|||
|
||||
<!-- Common Patterns -->
|
||||
<section>
|
||||
<h2 class="text-xl font-semibold text-white mb-4">Common Patterns</h2>
|
||||
<h2 class="text-xl font-semibold text-surface-100 mb-4">Common Patterns</h2>
|
||||
|
||||
<div class="grid md:grid-cols-3 gap-4">
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-blue-400 font-semibold mb-2">Read Replicas</div>
|
||||
<p class="text-gray-400 text-sm">Route reads to replicas, writes to leader. Scale read capacity horizontally.</p>
|
||||
<p class="text-surface-400 text-sm">Route reads to replicas, writes to leader. Scale read capacity horizontally.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-green-400 font-semibold mb-2">Hot Standby</div>
|
||||
<p class="text-gray-400 text-sm">Sync replica ready for instant failover. Zero data loss guarantee.</p>
|
||||
<p class="text-surface-400 text-sm">Sync replica ready for instant failover. Zero data loss guarantee.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-purple-400 font-semibold mb-2">Delayed Replica</div>
|
||||
<p class="text-gray-400 text-sm">Intentionally lag behind. Protection against accidental deletes.</p>
|
||||
<p class="text-surface-400 text-sm">Intentionally lag behind. Protection against accidental deletes.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-orange-400 font-semibold mb-2">Cascading Replication</div>
|
||||
<p class="text-gray-400 text-sm">Replicas replicate to other replicas. Reduce load on leader.</p>
|
||||
<p class="text-surface-400 text-sm">Replicas replicate to other replicas. Reduce load on leader.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-red-400 font-semibold mb-2">Cross-Region Replica</div>
|
||||
<p class="text-gray-400 text-sm">Async replica in another region. Disaster recovery and local reads.</p>
|
||||
<p class="text-surface-400 text-sm">Async replica in another region. Disaster recovery and local reads.</p>
|
||||
</div>
|
||||
<div class="bg-gray-800/50 rounded-xl p-4 border border-gray-700">
|
||||
<div class="bg-surface-900 rounded-xl p-4 border border-surface-800">
|
||||
<div class="text-cyan-400 font-semibold mb-2">Logical Replication</div>
|
||||
<p class="text-gray-400 text-sm">Replicate specific tables/databases. Schema changes, version upgrades.</p>
|
||||
<p class="text-surface-400 text-sm">Replicate specific tables/databases. Schema changes, version upgrades.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
|||
|
|
@ -295,18 +295,18 @@
|
|||
{/if}
|
||||
|
||||
<!-- Key Insight -->
|
||||
<div class="card bg-gradient-to-br from-blue-500/10 to-purple-500/10 border-blue-500/30">
|
||||
<div class="card">
|
||||
<div class="flex items-start gap-4">
|
||||
<div class="w-10 h-10 rounded-lg bg-blue-500/20 flex items-center justify-center flex-shrink-0">
|
||||
<Icons.Sparkles class="w-5 h-5 text-blue-400" />
|
||||
<div class="w-10 h-10 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center flex-shrink-0">
|
||||
<Icons.Sparkles class="w-5 h-5 text-surface-300" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="font-semibold text-surface-100 mb-2">The Key Insight</h3>
|
||||
<p class="text-surface-300 text-sm">
|
||||
In practice, <strong class="text-yellow-400">Partition Tolerance (P) is mandatory</strong> for any
|
||||
distributed system - network failures are a reality. This means your real choice is between
|
||||
<strong class="text-purple-400">CP</strong> (consistency over availability) and
|
||||
<strong class="text-pink-400">AP</strong> (availability over consistency).
|
||||
<strong class="text-surface-200">CP</strong> (consistency over availability) and
|
||||
<strong class="text-surface-200">AP</strong> (availability over consistency).
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -318,8 +318,8 @@
|
|||
<div class="grid md:grid-cols-2 gap-6">
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-lg bg-purple-500/20 flex items-center justify-center">
|
||||
<span class="text-sm font-bold text-purple-400">CP</span>
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<span class="text-sm font-bold text-surface-200">CP</span>
|
||||
</div>
|
||||
<span class="font-medium text-surface-200">Choose CP when...</span>
|
||||
</div>
|
||||
|
|
@ -331,7 +331,7 @@
|
|||
'Data conflicts are hard to resolve'
|
||||
] as item}
|
||||
<li class="text-sm text-surface-400 flex items-start gap-2">
|
||||
<Icons.Check class="w-4 h-4 text-purple-400 mt-0.5 flex-shrink-0" />
|
||||
<Icons.Check class="w-4 h-4 text-surface-300 mt-0.5 flex-shrink-0" />
|
||||
{item}
|
||||
</li>
|
||||
{/each}
|
||||
|
|
@ -340,8 +340,8 @@
|
|||
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="w-8 h-8 rounded-lg bg-pink-500/20 flex items-center justify-center">
|
||||
<span class="text-sm font-bold text-pink-400">AP</span>
|
||||
<div class="w-8 h-8 rounded-lg bg-surface-800 border border-surface-700 flex items-center justify-center">
|
||||
<span class="text-sm font-bold text-surface-200">AP</span>
|
||||
</div>
|
||||
<span class="font-medium text-surface-200">Choose AP when...</span>
|
||||
</div>
|
||||
|
|
@ -353,7 +353,7 @@
|
|||
'Stale data is better than no data'
|
||||
] as item}
|
||||
<li class="text-sm text-surface-400 flex items-start gap-2">
|
||||
<Icons.Check class="w-4 h-4 text-pink-400 mt-0.5 flex-shrink-0" />
|
||||
<Icons.Check class="w-4 h-4 text-surface-300 mt-0.5 flex-shrink-0" />
|
||||
{item}
|
||||
</li>
|
||||
{/each}
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ export default {
|
|||
},
|
||||
// Custom theme colors
|
||||
surface: {
|
||||
50: '#f8fafc',
|
||||
100: '#f1f5f9',
|
||||
200: '#e2e8f0',
|
||||
300: '#cbd5e1',
|
||||
400: '#94a3b8',
|
||||
500: '#64748b',
|
||||
600: '#475569',
|
||||
700: '#334155',
|
||||
800: '#1e293b',
|
||||
900: '#0f172a',
|
||||
950: '#020617'
|
||||
50: '#fafafa',
|
||||
100: '#f5f5f5',
|
||||
200: '#e5e5e5',
|
||||
300: '#d4d4d4',
|
||||
400: '#a3a3a3',
|
||||
500: '#737373',
|
||||
600: '#525252',
|
||||
700: '#262626',
|
||||
800: '#141414',
|
||||
900: '#0a0a0a',
|
||||
950: '#000000'
|
||||
}
|
||||
},
|
||||
fontFamily: {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue