系统设计与分布式算法实战指南
系统设计与分布式算法实战指南
项目概述
本项目是一个全面的系统设计算法实现库,专注于分布式系统核心组件的实际编码实现。项目包含负载均衡算法、限流算法、一致性哈希等关键分布式系统组件的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智能小助手)
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)
公众号二维码

公众号二维码


浙公网安备 33010602011771号