
采用“一致性哈希分片+多级预检查(布隆+缓存+时间窗口)+分布式存储版本控制”架构,通过负载均衡、快速预检查降低延迟,结合版本控制保证数据一致性,支持PB级日志高吞吐去重。
(老师口吻,技术讲解)
| 策略类型 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 一致性哈希分片 | 节点故障时数据自动迁移 | 负载均衡,高可用 | 分布式系统,节点动态变化 | 需维护虚拟节点,避免数据倾斜 |
| 布隆过滤器 | 基于位数组的概率去重 | 极快,空间高效,允许误报 | 海量数据初步去重,降低后续压力 | 误报率需控制,误报导致漏检 |
| 缓存去重 | 分布式缓存存储已处理数据 | 响应快,但内存有限 | 低延迟场景,数据量适中 | 需防缓存雪崩,设置TTL/互斥锁 |
| 时间窗口去重 | 结合时间窗口限制重复 | 适用于周期性重复数据 | 日志中周期性事件(如每5分钟一次) | 窗口大小需合理,避免过宽导致去重失效 |
| 版本控制 | 分布式存储的版本号(时间戳) | 确保数据不丢失,可追溯 | 长期数据存储,保证一致性 | 需考虑存储成本,版本号管理 |
伪代码处理日志条目:
def process_log_entry(log_entry):
# 1. 数据分片:一致性哈希分配节点
shard_id = hash(log_entry.id) % num_shards
node = get_shard_node(shard_id)
# 2. 布隆过滤器检查(预检查)
bf = BloomFilter(node, log_entry.id)
if bf.contains(): # 误报则继续
return "已去重"
# 3. 缓存检查(分布式Redis)
cache_key = f"cache:{log_entry.id}"
if redis.get(cache_key):
return "已去重"
# 4. 时间窗口检查(滑动窗口,5分钟)
window = SlidingWindow(log_entry.timestamp, 5*60)
if window.contains(log_entry.id):
return "已去重"
# 5. 存储去重(HBase,带版本控制)
store_log_entry(log_entry, version=log_entry.timestamp)
# 6. 更新缓存和布隆过滤器
redis.setex(cache_key, 60, log_entry.id) # TTL 60秒
bf.add(log_entry.id)
return "去重成功"
(约90秒,自然表达)
“面试官您好,针对海量日志的分布式去重系统,我设计的方案核心是构建一个‘分片+缓存+布隆+时间窗口’的架构,结合分布式存储的版本控制保证一致性。首先,数据分片采用一致性哈希+虚拟节点,将日志按ID哈希分配到不同节点,节点故障时数据自动迁移,实现负载均衡。处理流程中,先通过布隆过滤器快速判断是否已存在(允许误报,降低后续检查压力),接着检查分布式缓存(如Redis)是否命中,再结合滑动时间窗口(5分钟)限制周期性重复。对于确认的新数据,写入分布式存储(如HBase),并更新缓存和布隆过滤器。关键技术点包括:1. 一致性哈希分片确保节点故障时数据自动迁移;2. 布隆+缓存+时间窗口三重预检查,平衡速度与准确率;3. 滑动时间窗口处理周期性重复数据。数据一致性通过分布式存储的版本控制(时间戳序列)保证,即使节点故障也能恢复。处理数据倾斜问题,通过虚拟节点和负载均衡,结合动态扩容(比如监控分片负载率,超过阈值时增加分片数量或调整虚拟节点位置),确保每个分片负载均匀。”