← 返回博客列表
DoorDash

DoorDash VO:负载均衡 Debug + 一致性哈希(Consistent Hashing)系统设计

2025-11-29

# DoorDash VO:负载均衡 Debug + 一致性哈希(Consistent Hashing)系统设计

oavoservice 原创复盘:DoorDash 很爱用“先 debug 一个坏实现,再让你讲可扩展设计”的组合题。

Part 1:Round Robin 负载均衡器 Debug(改写版)

你拿到一个负载均衡器的伪代码(或不完整实现),单测要求:

常见 bug 画像

一个正确的最小实现(Python)

class Backend:
    def __init__(self, name, state='AVAILABLE'):
        self.name = name
        self.state = state


class TrafficRouter:
    def __init__(self, backends):
        self.backends = list(backends)
        self._idx = 0

    def add_backend(self, backend):
        self.backends.append(backend)

    def get_backend(self):
        n = len(self.backends)
        if n == 0:
            return None

        tried = 0
        while tried < n:
            b = self.backends[self._idx]
            self._idx = (self._idx + 1) % n
            tried += 1
            if b.state == 'AVAILABLE':
                return b
        return None

面试官听什么

Part 2:为什么 Round Robin 不够?(状态/粘性会话)

如果后端是有状态的(session、cache、shopping cart),Round Robin 会导致:

于是引出 一致性哈希

Part 3:一致性哈希设计(核心要点)

目标

基本做法

虚拟节点(Virtual Nodes)

为了更均匀,给每个 backend 放多个 vnode:

参考实现(简化)

import bisect
import hashlib


def h32(s: str) -> int:
    return int(hashlib.md5(s.encode('utf-8')).hexdigest()[:8], 16)


class ConsistentHashRing:
    def __init__(self, replicas=100):
        self.replicas = replicas
        self.ring = []          # sorted hashes
        self.nodes = []         # parallel array of node ids
        self.live = set()

    def add_node(self, node_id: str):
        self.live.add(node_id)
        for i in range(self.replicas):
            key = f"{node_id}#{i}"
            hv = h32(key)
            idx = bisect.bisect_left(self.ring, hv)
            self.ring.insert(idx, hv)
            self.nodes.insert(idx, node_id)

    def remove_node(self, node_id: str):
        if node_id not in self.live:
            return
        self.live.remove(node_id)
        i = 0
        while i < len(self.nodes):
            if self.nodes[i] == node_id:
                self.nodes.pop(i)
                self.ring.pop(i)
            else:
                i += 1

    def route(self, request_key: str) -> str | None:
        if not self.ring:
            return None
        hv = h32(request_key)
        idx = bisect.bisect_left(self.ring, hv)
        if idx == len(self.ring):
            idx = 0
        return self.nodes[idx]

面试扩展点


如果你要准备 DoorDash / Uber / Stripe 这类后端 VO,oavoservice 会用这类“debug + 系统设计升级”的题把你的表达训练成:先修正确性,再谈可扩展与工程权衡。


需要面试真题? 立刻联系微信 Coding0201,获得真题