mosdns/Memory-Cache-Implementation-Guide.md

6.4 KiB
Raw Blame History

MikroTik 内存缓存优化实施指南

🎯 优化目标

根据你的需求,我们实现了以下核心优化:

  1. 🚀 完全移除验证功能 - 消除验证带来的额外API调用
  2. 🧠 内存缓存机制 - 程序启动时从MikroTik加载所有现有IP到内存
  3. 智能重复检查 - 在内存中判断IP是否存在避免重复写入
  4. 🌐 /24网段优化 - 使用/24掩码减少地址条目数量

📋 实施步骤

第一步:备份现有配置

# 备份当前配置
cp /opt/mosdns/dns.yaml /opt/mosdns/dns.yaml.backup
cp /opt/mosdns/config.yaml /opt/mosdns/config.yaml.backup

第二步:更新配置文件

我已经为你创建了三个配置版本:

  1. dns.yaml - 你的原配置文件,已优化为/24掩码
  2. dns-memory-optimized.yaml - 完整的内存优化配置
  3. dns-optimized.yaml - 标准性能优化配置

推荐使用 dns-memory-optimized.yaml

# 使用优化配置
cp dns-memory-optimized.yaml /opt/mosdns/dns.yaml

第三步验证MikroTik地址列表

确保MikroTik中存在对应的地址列表

# 连接到MikroTik
ssh admin@10.248.0.1

# 检查现有地址列表
/ip firewall address-list print where list=gfw

# 如果不存在,创建地址列表
/ip firewall address-list add list=gfw comment="Auto-managed by MosDNS"

# 查看当前地址数量
/ip firewall address-list print count-only where list=gfw

🔧 核心优化机制

1. 启动时内存加载

程序启动时会执行以下操作:

// 伪代码流程
func (p *plugin) loadExistingIPs() {
    // 1. 连接MikroTik API
    // 2. 查询 /ip/firewall/address-list/print =list=gfw
    // 3. 将所有现有IP加载到内存map中
    // 4. 构建网段缓存(对于/24掩码)
    // 5. 记录加载统计信息
}

启动日志示例:

INFO loading existing IPs from MikroTik...
INFO loaded address list list=gfw ip_count=1250
INFO finished loading existing IPs total_ips=1250

2. 内存存在性检查

每次DNS解析后的IP处理流程

// 伪代码流程
func (p *plugin) processIP(ip, domain) {
    cidr := buildCIDRAddress(ip, 24) // 例如: 1.2.3.0/24
    
    // 🚀 纯内存检查,极快速度
    if p.isIPInMemoryCache("gfw", cidr) {
        log.Debug("IP already exists, skipping")
        return // 跳过不调用MikroTik API
    }
    
    // 只有不存在的IP才写入MikroTik
    p.addToMikroTik(cidr, "gfw", domain)
    
    // 🚀 成功后立即更新内存缓存
    p.addToMemoryCache("gfw", cidr)
}

3. /24网段优化

使用/24掩码的好处

  • 减少条目数量: 1.2.3.1, 1.2.3.2, 1.2.3.31.2.3.0/24
  • 提高匹配效率: 单个网段条目可以匹配256个IP
  • 降低内存使用: 缓存条目大幅减少

示例对比:

# /32模式 (原来)
1.2.3.1/32
1.2.3.2/32
1.2.3.3/32
...
1.2.3.255/32  # 255个条目

# /24模式 (优化后)
1.2.3.0/24    # 1个条目覆盖整个网段

📊 性能提升预期

优化项目 优化前 优化后 提升效果
启动速度 立即 +5-10秒 一次性成本
重复检查 MikroTik API 内存查找 99%+ 速度提升
网络调用 每IP一次 仅新IP 减少80-90%
内存使用 最小 +10-50MB 可接受增长
地址条目 大量/32 少量/24 减少70-90%

🔍 监控和验证

启动监控

# 查看启动日志
sudo journalctl -u mosdns -f | grep "loading existing IPs"

# 完整启动日志
sudo systemctl restart mosdns
sudo journalctl -u mosdns --since "1 minute ago"

运行时监控

# 查看实时处理日志
sudo journalctl -u mosdns -f | grep -E "(already exists|successfully added)"

# 查看缓存统计
sudo journalctl -u mosdns -f | grep "cache_stats"

MikroTik端验证

# 查看地址列表大小变化
ssh admin@10.248.0.1 "/ip firewall address-list print count-only where list=gfw"

# 查看最近添加的地址
ssh admin@10.248.0.1 "/ip firewall address-list print where list=gfw" | tail -10

# 监控系统资源
ssh admin@10.248.0.1 "/system resource monitor once"

🚨 故障排除

常见问题

1. 启动时加载失败

# 检查连接
ssh admin@10.248.0.1 "/system resource print"

# 检查地址列表是否存在
ssh admin@10.248.0.1 "/ip firewall address-list print where list=gfw"

2. 内存使用过高

# 监控内存使用
top -p $(pgrep mosdns)

# 如果内存过高,可以调整配置
memory_cache_size: 5000  # 减少缓存大小

3. 性能没有提升

# 检查是否正确跳过重复IP
sudo journalctl -u mosdns -f | grep "already exists"

# 应该看到大量 "already exists" 日志

调试模式

临时启用详细日志:

# 在config.yaml中修改
log:
  level: debug  # 临时改为debug
# 重启服务
sudo systemctl restart mosdns

# 查看详细日志
sudo journalctl -u mosdns -f

快速测试

测试重复IP检查

# 测试同一个域名多次解析
for i in {1..5}; do
  dig @127.0.0.1 -p 5300 amazon.com
  sleep 1
done

# 应该只看到第一次写入MikroTik后续都是 "already exists"

压力测试

# 并发测试多个域名
domains=("aws.amazon.com" "s3.amazonaws.com" "ec2.amazonaws.com" "cloudfront.amazonaws.com")

for domain in "${domains[@]}"; do
  for i in {1..3}; do
    dig @127.0.0.1 -p 5300 "$domain" &
  done
done
wait

# 检查MikroTik地址列表增长
ssh admin@10.248.0.1 "/ip firewall address-list print count-only where list=gfw"

📈 预期结果

实施这些优化后,你应该看到:

  1. 启动时间: 增加5-10秒一次性加载现有IP
  2. 重复查询: 几乎无延迟(纯内存检查)
  3. 网络调用: 大幅减少只写入新IP
  4. MikroTik负载: 显著降低减少80-90%的API调用
  5. 地址条目: 大幅减少(/24网段合并

🔄 回滚方案

如果需要回滚到原配置:

# 恢复原配置
cp /opt/mosdns/dns.yaml.backup /opt/mosdns/dns.yaml

# 重启服务
sudo systemctl restart mosdns

# 验证服务正常
sudo systemctl status mosdns

这个优化方案完全符合你的需预期可以将MikroTik的API调用求移除验证功能、启动时加载现有IP到内存、避免重复写入、使用/24掩码。减少80-90%,显著提升整体性能。