惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

www.infosecurity-magazine.com
www.infosecurity-magazine.com
Vercel News
Vercel News
G
Google Developers Blog
MyScale Blog
MyScale Blog
The Register - Security
The Register - Security
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security Blog
V
Visual Studio Blog
V2EX - 技术
V2EX - 技术
F
Fortinet All Blogs
博客园_首页
S
Secure Thoughts
GbyAI
GbyAI
S
Security Affairs
N
News | PayPal Newsroom
Forbes - Security
Forbes - Security
Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Archives - TechRepublic
Security Archives - TechRepublic
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Heimdal Security Blog
A
About on SuperTechFans
P
Proofpoint News Feed
H
Help Net Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Y
Y Combinator Blog
L
LINUX DO - 最新话题
Apple Machine Learning Research
Apple Machine Learning Research
L
LangChain Blog
博客园 - 叶小钗
A
Arctic Wolf
Cisco Talos Blog
Cisco Talos Blog
T
The Exploit Database - CXSecurity.com
人人都是产品经理
人人都是产品经理
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Security Latest
Security Latest
The Hacker News
The Hacker News
T
Tor Project blog
O
OpenAI News
博客园 - 三生石上(FineUI控件)
PCI Perspectives
PCI Perspectives
量子位
大猫的无限游戏
大猫的无限游戏
Stack Overflow Blog
Stack Overflow Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Implementing Multicloud Data Sharding with Hexagonal Storage Adapters
Cláudio Fili · 2026-05-13 · via DEV Community

Data residency requirements and regional compliance laws such as GDPR or LGPD often force architectures to fragment data across multiple cloud providers and geographic boundaries. When a centralized database becomes a legal or performance bottleneck, engineering teams frequently resort to manual data duplication or brittle synchronization scripts. This fragmentation leads to inconsistent state, increased latency for cross-border users, and a massive expansion of the security attack surface. The definitive solution to this complexity is a Multicloud Data Sharding layer orchestrated through Hexagonal Architecture. By decoupling the domain entity from the underlying storage mechanism, we allow the application to route queries to specific cloud-native databases based on tenant metadata. This approach ensures that a Brazilian housing cooperative's data remains within Azure's South Brazil region while a European counterpart resides in AWS Frankfurt, all while maintaining a single, unified codebase and strictly adhering to data sovereignty mandates.

Prerequisites

Building this sharding plane requires Terraform version 1.8.0 or higher to manage cross-cloud provider states effectively. You must have the AWS provider (version 5.45+) and AzureRM provider (version 3.95+) initialized. The application logic requires Python 3.12 using the SQLAlchemy 2.0 library for database abstraction and pydantic for strict data validation. Advanced knowledge of Domain-Driven Design (DDD) is essential to identify the correct sharding keys within your bounded contexts. You will also need active Service Principals for Azure and IAM Roles for AWS with permissions to manage RDS and Azure SQL instances.

Step-by-Step

Defining Geographic Sharding Boundaries

The first step in a multicloud sharding strategy involves the physical provisioning of isolated database clusters that serve as regional shards. We use Terraform to define these resources, ensuring that each database is configured with provider-specific best practices such as AWS Aurora for high-performance clusters and Azure SQL Database for serverless flexibility. Architectural integrity is maintained by ensuring that no shard shares a common network or credentials. Each shard must be tagged with a unique identifier that corresponds to a geographic region or a regulatory jurisdiction. This physical isolation prevents "noisy neighbor" effects and ensures that a regional outage in one cloud provider does not cascade into a global failure. We utilize a standardized naming convention to facilitate dynamic discovery during the application runtime.

# database_shards/main.tf
variable "shard_configs" {
  type = map(object({
    provider = string
    region   = string
    tier     = string
  }))
}

resource "aws_db_instance" "shard_aws" {
  for_each               = { for k, v in var.shard_configs : k => v if v.provider == "aws" }
  identifier             = "db-shard-${each.key}"
  engine                 = "postgres"
  instance_class         = each.value.tier
  allocated_storage      = 20
  db_name                = "tenant_data"
  publicly_accessible    = false
  skip_final_snapshot    = true
  vpc_security_group_ids = [aws_security_group.db_access.id]

  tags = {
    ShardID    = each.key
    Regulatory = "GDPR_Compliant"
  }
}

resource "azurerm_mssql_database" "shard_azure" {
  for_each       = { for k, v in var.shard_configs : k => v if v.provider == "azure" }
  name           = "db-shard-${each.key}"
  server_id      = azurerm_mssql_server.primary.id
  collation      = "SQL_Latin1_General_CP1_CI_AS"
  max_size_gb    = 10
  read_scale     = false
  sku_name       = "S0"

  tags = {
    ShardID    = each.key
    Regulatory = "LGPD_Compliant"
  }
}

Enter fullscreen mode Exit fullscreen mode

This infrastructure provides the storage backbone for our distributed data. How does the application decide which cloud to query for a specific tenant without hardcoding environment-specific logic into the core domain?

Constructing Hexagonal Storage Adapters

We maintain architectural purity by implementing the Hexagonal Architecture pattern, where the domain logic interacts only with a storage port (an abstract interface). We define a StoragePort protocol in Python that specifies the required data operations, such as saving or retrieving a housing cooperative's records. We then develop specific adapters for AWS and Azure that implement this protocol using cloud-native drivers. The application uses a factory pattern to inject the correct adapter at runtime based on the tenant's regional metadata. This decoupling ensures that the core business logic remains agnostic of the underlying database engine or cloud provider. If a specific region requires a migration from AWS to Azure, only the adapter configuration changes while the core domain remains untouched, preserving the stability of the business rules.

# domain/ports.py
from typing import Protocol, Dict, Any
from abc import abstractmethod

class CooperativeRepositoryPort(Protocol):
    @abstractmethod
    def save(self, data: Dict[str, Any]) -> bool:
        pass

    @abstractmethod
    def get_by_id(self, cooperative_id: str) -> Dict[str, Any]:
        pass

# infrastructure/adapters.py
import sqlalchemy
from sqlalchemy.orm import sessionmaker

class PostgresShardAdapter:
    def __init__(self, connection_string: str):
        self.engine = sqlalchemy.create_engine(connection_string)
        self.Session = sessionmaker(bind=self.engine)

    def save(self, data: Dict[str, Any]) -> bool:
        with self.Session() as session:
            # Operational logic for PostgreSQL in AWS
            session.execute(sqlalchemy.text(
                "INSERT INTO cooperatives (id, name, region) VALUES (:id, :name, :region)"
            ), data)
            session.commit()
            return True

class AzureSqlShardAdapter:
    def __init__(self, connection_string: str):
        self.engine = sqlalchemy.create_engine(connection_string)
        self.Session = sessionmaker(bind=self.engine)

    def save(self, data: Dict[str, Any]) -> bool:
        with self.Session() as session:
            # Operational logic for MS SQL in Azure
            session.execute(sqlalchemy.text(
                "INSERT INTO cooperatives (id, name, region) VALUES (:id, :name, :region)"
            ), data)
            session.commit()
            return True

Enter fullscreen mode Exit fullscreen mode

The use of ports and adapters ensures that the domain logic is protected from infrastructure churn. If a shard becomes unavailable due to a provider-wide outage, how does the system maintain partial availability for other regions while attempting a recovery?

Implementing Resilient Shard Resolution

Resilience in a sharded multicloud environment depends on a robust shard resolution mechanism that utilizes a globally distributed metadata store. We implement a ShardResolver that queries a lightweight mapping table, often stored in a highly available global service such as AWS DynamoDB Global Tables or Azure Cosmos DB. This resolver identifies the target cloud, the specific region, and the connection credentials for a given cooperative ID. To ensure high performance, these mappings are cached in memory using a TTL-based strategy. When a request enters the system, the resolver determines the correct shard and provides the corresponding adapter to the domain service. This architecture supports partial failure; if the AWS Frankfurt shard is offline, only the European tenants are affected while Brazilian tenants on Azure continue to operate without degradation. This granular isolation is the primary benefit of the cellular sharding pattern.

# application/services.py
from typing import Dict, Optional

class ShardResolver:
    def __init__(self, metadata_store: Dict[str, str]):
        # In production, this would be a DynamoDB or CosmosDB call
        self.metadata_store = metadata_store

    def resolve_adapter(self, cooperative_id: str) -> Optional[CooperativeRepositoryPort]:
        shard_info = self.metadata_store.get(cooperative_id)
        if not shard_info:
            return None

        # Logic to return PostgresShardAdapter or AzureSqlShardAdapter
        # based on shard_info['provider']
        if shard_info['provider'] == 'aws':
            return PostgresShardAdapter(shard_info['dsn'])
        return AzureSqlShardAdapter(shard_info['dsn'])

class CooperativeService:
    def __init__(self, resolver: ShardResolver):
        self.resolver = resolver

    def create_cooperative(self, cooperative_id: str, payload: Dict[str, Any]):
        adapter = self.resolver.resolve_adapter(cooperative_id)
        if adapter:
            return adapter.save(payload)
        raise ConnectionError(f"No shard found for ID {cooperative_id}")

Enter fullscreen mode Exit fullscreen mode

Diagram

This resolution logic ensures that traffic is always directed to the legally and geographically correct shard. How can we optimize the cross-shard reporting process when executives require a global view of data that is physically segregated across two different cloud providers?

Common Troubleshooting

A frequent issue in multicloud sharding is the exhaustion of connection pools in the application layer. Since each shard requires a distinct connection pool, an application pod connecting to fifty shards may consume an excessive amount of memory and file descriptors. To solve this, implement a dynamic pool recycler that closes idle connections to infrequently accessed shards or utilize a database proxy such as AWS RDS Proxy or Azure SQL Database Proxy to multiplex connections efficiently.

Another critical failure point is the inconsistency between the global shard metadata and the actual state of the database shards. If a shard is migrated from AWS to Azure but the metadata store is not updated atomically, the application will experience "dead-end" routing errors. We mitigate this by using a two-phase commit or a saga pattern for shard migrations, ensuring that the metadata is updated only after the target database is fully synchronized and validated.

Lastly, latency spikes can occur if the application is running in AWS but the metadata store is only in Azure. Always implement local caching of shard metadata within the application process and utilize a globally replicated database for the shard map to ensure the resolver always reads from the nearest regional endpoint.

Conclusion

Multicloud data sharding through Hexagonal Architecture provides a sophisticated framework for managing data sovereignty and architectural resilience. By isolating storage concerns into specific adapters and utilizing a global resolver, you ensure that your platform can scale across providers without sacrificing domain clarity or compliance. The next advanced step is to implement cross-shard distributed queries using a federated engine like Presto or Trino. This allows for analytical reporting across AWS and Azure shards without moving large volumes of sensitive data, providing a unified view of a geographically dispersed system.

References

Fowler, M. (2002). Patterns of enterprise application architecture. Addison-Wesley Professional.

Kleppmann, M. (2017). Designing data-intensive applications: The big ideas behind reliable, scalable, and maintainable systems. O'Reilly Media.

Microsoft. (2024). Data sharding pattern. Azure Architecture Center. https://learn.microsoft.com/en-us/azure/architecture/patterns/sharding

Post, G. (2023). Global data residency: Architectural strategies for multicloud compliance. Journal of Cloud Computing Research.