系统设计与分布式算法实战指南

系统设计与分布式算法实战指南

项目概述

本项目是一个全面的系统设计算法实现库,专注于分布式系统核心组件的实际编码实现。项目包含负载均衡算法、限流算法、一致性哈希等关键分布式系统组件的Java和Python双语言实现,为开发者提供学习和实践系统设计概念的完整资源。

功能特性

:counterclockwise_arrows_button: 负载均衡算法

  • 轮询算法 (Round Robin) - 均匀分配请求到所有服务器
  • 加权轮询 (Weighted Round Robin) - 根据服务器权重分配请求
  • IP哈希算法 (IP Hash) - 基于客户端IP的哈希值分配请求
  • 最少连接数 (Least Connections) - 选择当前连接数最少的服务器
  • 最小响应时间 (Least Response Time) - 基于服务器响应时间选择最优服务器

:bullseye: 一致性哈希

  • 虚拟节点支持,实现更好的负载分布
  • 动态添加/移除服务器节点
  • 最小化数据迁移影响

🚦 限流算法

  • 固定窗口计数器 (Fixed Window Counter) - 基于固定时间窗口的请求限制
  • 滑动窗口日志 (Sliding Window Log) - 精确的滑动窗口限流
  • 滑动窗口计数器 (Sliding Window Counter) - 加权滑动窗口算法
  • 漏桶算法 (Leaky Bucket) - 平滑流量控制
  • 令牌桶算法 (Token Bucket) - 支持突发流量的限流

安装指南

环境要求

  • Java 8+ 或 Python 3.6+
  • 无需额外依赖库

快速开始

直接克隆项目到本地:

git clone <repository-url>
cd system-design-implementations

Java项目可直接编译运行:

javac implementations/java/*.java

Python脚本可直接执行:

python implementations/python/*.py

使用说明

负载均衡示例

轮询负载均衡 (Java):

List<String> servers = List.of("Server1", "Server2", "Server3");
RoundRobin roundRobinLB = new RoundRobin(servers);

for (int i = 0; i < 6; i++) {
    System.out.println(roundRobinLB.getNextServer());
}

一致性哈希 (Python):

servers = ["S0", "S1", "S2", "S3", "S4", "S5"]
ch = ConsistentHashing(servers)

print(ch.get_server("UserA"))  # 映射UserA到服务器
print(ch.get_server("UserB"))  # 映射UserB到服务器

# 动态添加服务器
ch.add_server("S6")
print(ch.get_server("UserA"))  # 可能重新分配

限流算法示例

令牌桶限流 (Java):

TokenBucket limiter = new TokenBucket(10, 1.0); // 容量10,填充率1令牌/秒

for (int i = 0; i < 15; i++) {
    if (limiter.allowRequest(1)) {
        System.out.println("请求允许");
    } else {
        System.out.println("请求被限流");
    }
    Thread.sleep(100);
}

滑动窗口限流 (Python):

limiter = SlidingWindowLog(window_size=60, max_requests=5)  # 每分钟5个请求

for i in range(10):
    if limiter.allow_request():
        print(f"请求 {i+1}: 允许")
    else:
        print(f"请求 {i+1}: 被限流")

核心代码

一致性哈希算法 (Java完整实现)

package implementations.java.consistent_hashing;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

public class ConsistentHashing {
    private final int numReplicas; // 每个服务器的虚拟节点数量
    private final TreeMap<Long, String> ring; // 哈希环,存储虚拟节点
    private final Set<String> servers; // 物理服务器集合

    public ConsistentHashing(List<String> servers, int numReplicas) {
        this.numReplicas = numReplicas;
        this.ring = new TreeMap<>();
        this.servers = new HashSet<>();

        // 将每个服务器添加到哈希环
        for (String server : servers) {
            addServer(server);
        }
    }

    private long hash(String key) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(key.getBytes());
            byte[] digest = md.digest();
            return ((long) (digest[0] & 0xFF) << 24) |
                   ((long) (digest[1] & 0xFF) << 16) |
                   ((long) (digest[2] & 0xFF) << 8) |
                   ((long) (digest[3] & 0xFF));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法未找到", e);
        }
    }

    public void addServer(String server) {
        servers.add(server);
        for (int i = 0; i < numReplicas; i++) {
            long hash = hash(server + "-" + i); // 每个虚拟节点的唯一哈希
            ring.put(hash, server);
        }
    }

    public void removeServer(String server) {
        if (servers.remove(server)) {
            for (int i = 0; i < numReplicas; i++) {
                long hash = hash(server + "-" + i);
                ring.remove(hash);
            }
        }
    }

    public String getServer(String key) {
        if (ring.isEmpty()) {
            return null; // 没有可用服务器
        }

        long hash = hash(key);
        // 顺时针方向查找最近的服务器
        Map.Entry<Long, String> entry = ring.ceilingEntry(hash);
        if (entry == null) {
            // 如果超过最高节点,回绕到第一个节点
            entry = ring.firstEntry();
        }
        return entry.getValue();
    }
}

令牌桶限流算法 (Java完整实现)

package implementations.java.rate_limiting;

import java.time.Instant;

public class TokenBucket {
    private final long capacity;        // 桶能容纳的最大令牌数
    private final double fillRate;      // 令牌添加速率(令牌/秒)
    private double tokens;              // 当前桶中的令牌数
    private Instant lastRefillTimestamp; // 上次补充令牌的时间戳

    public TokenBucket(long capacity, double fillRate) {
        this.capacity = capacity;
        this.fillRate = fillRate;
        this.tokens = capacity;  // 开始时桶是满的
        this.lastRefillTimestamp = Instant.now();
    }

    public synchronized boolean allowRequest(int tokens) {
        refill();  // 首先根据经过的时间添加新令牌

        if (this.tokens < tokens) {
            return false;  // 令牌不足,拒绝请求
        }

        this.tokens -= tokens;  // 消耗令牌
        return true;  // 允许请求
    }

    private void refill() {
        Instant now = Instant.now();
        // 根据经过的时间计算要添加的令牌数
        double tokensToAdd = (now.toEpochMilli() - lastRefillTimestamp.toEpochMilli()) * fillRate / 1000.0;
        this.tokens = Math.min(capacity, this.tokens + tokensToAdd);  // 添加令牌,但不超过容量
        this.lastRefillTimestamp = now;
    }
}

最少连接数负载均衡 (Python完整实现)

import random

class LeastConnections:
    def __init__(self, servers):
        self.servers = {server: 0 for server in servers}

    def get_next_server(self):
        # 查找最小连接数
        min_connections = min(self.servers.values())
        # 获取所有具有最小连接数的服务器
        least_loaded_servers = [server for server, connections in self.servers.items() if connections == min_connections]
        # 从最小负载服务器中随机选择一个
        selected_server = random.choice(least_loaded_servers)
        self.servers[selected_server] += 1
        return selected_server

    def release_connection(self, server):
        if self.servers[server] > 0:
            self.servers[server] -= 1

# 使用示例
servers = ["Server1", "Server2", "Server3"]
load_balancer = LeastConnections(servers)

for i in range(6):
    server = load_balancer.get_next_server()
    print(f"请求 {i + 1} -> {server}")
    load_balancer.release_connection(server)

滑动窗口日志限流 (Python完整实现)

import time
from collections import deque

class SlidingWindowLog:
    def __init__(self, window_size, max_requests):
        self.window_size = window_size  # 滑动窗口大小(秒)
        self.max_requests = max_requests  # 窗口内最大请求数
        self.request_log = deque()  # 记录请求时间戳的日志

    def allow_request(self):
        now = time.time()
        
        # 移除当前窗口之外的时间戳
        while self.request_log and now - self.request_log[0] >= self.window_size:
            self.request_log.popleft()

        # 检查是否仍在限制内
        if len(self.request_log) < self.max_requests:
            self.request_log.append(now)
            return True
        return False

# 使用示例
limiter = SlidingWindowLog(window_size=60, max_requests=5)  # 每分钟5个请求

for i in range(10):
    if limiter.allow_request():
        print(f"请求 {i+1}: 允许")
    else:
        print(f"请求 {i+1}: 被限流")
    time.sleep(0.1)

这些核心算法实现展示了分布式系统中关键组件的设计原理,每个实现都包含了完整的错误处理和实际应用场景,可以直接在生产环境或学习项目中使用。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

公众号二维码

公众号二维码

posted @ 2025-11-07 18:07  qife  阅读(3)  评论(0)    收藏  举报