乐于分享
好东西不私藏

kafka 源码与OS底层

kafka 源码与OS底层

🏠 README · ⬅ 03 设计与编码 · ➡ 05 分布式理论与大厂设计

  • 包含章节:Ch16 源码与 OS 底层深度

  • 难度:⭐⭐⭐ 大厂二面 / 交叉面 / P7+ 拉差距

  • 建议:内容密度最高,先看模块一打底再来

    • 字节交叉面、阿里 P7+、腾讯 T9+ 必备

    • 时间紧可只挑:16.1(时间轮)+ 16.2(Sender)+ 16.6/16.7(PageCache + 零拷贝)


📑 本模块目录(详细子节)

  • 16. 源码与 OS 底层深度(大厂二面/交叉面) ⭐⭐⭐

    • 16.1 Purgatory 与分层时间轮(Hierarchical Timing Wheel)

    • 16.2 Sender / RecordAccumulator 源码剖析

    • 16.3 SocketServer Reactor 模型

    • 16.4 NetworkClient + InFlightRequests + KafkaChannel

    • 16.5 LogManager / Log 并发控制

    • 16.6 PageCache 工作机制

    • 16.7 零拷贝(sendfile)与 SSL 失效

    • 16.8 mmap vs FileChannel 取舍

    • 16.9 文件系统、O_DIRECT、JBOD vs RAID


模块导引

目标:进入"懂 Kafka 是怎么实现的"层次。大厂二面 / 交叉面 / P7+ 拉差距的关键。

检验标准

  • 能徒手画分层时间轮,并解释"1ms 精度 + 1 小时延迟为什么只需要 80 个桶"
  • 能讲清 Sender / RecordAccumulator 的 DCL 锁、drain 起点轮转、mute/unmute 与幂等的关联
  • 能讲清 Reactor 模型的 Acceptor / Processor / Handler 三层职责
  • 能讲为什么 Kafka 索引用 mmap 而日志用 FileChannel
  • 能讲清 sendfile 在 SSL 模式下失效的具体路径

共 1 章(Ch16)但内容密度最高,建议先看模块一打底再来。


16. 源码与 OS 底层深度(大厂二面/交叉面)

这一章的题目,初中级根本答不出来;如果你能讲清楚一两个,已经超过 80% 候选人。

16.1 Purgatory 与分层时间轮(Hierarchical Timing Wheel)

16.1.1 Purgatory 解决什么问题?

Kafka 内部有大量"挂起等待"的请求:

  • DelayedProduce
    acks=all 时挂起,等 HW 推进。
  • DelayedFetch
    :Consumer 拉到不够 fetch.min.bytes 时挂起,等数据攒够。
  • DelayedJoin
    :Consumer Group rebalance 时等所有成员加入。
  • DelayedHeartbeat
    :Coordinator 等心跳。
  • DelayedDeleteRecords / DelayedRemoteFetch / DelayedAlterPartition
     等。

这些都需要"带超时的等待 + 提前唤醒"语义。直接用 ScheduledThreadPoolExecutor 行不行?

不行,因为 Kafka 的需求是:

  • 单 broker 同时挂起百万级延迟任务;
  • 大多数任务不会真的超时(被 HW 推进 / Fetch 数据到达提前唤醒);
  • 添加和删除任务要 O(1)
  • 超时检查要几乎零开销

ScheduledThreadPoolExecutor 内部是 DelayQueue(堆),插入 O(log n),对百万级任务不够。

16.1.2 分层时间轮算法

单层时间轮

            ┌─────────────────────────────────────────┐            │  bucket[0] bucket[1] ... bucket[n-1]    │  ← 每个 bucket 是一个 TimerTaskList(双向链表)            └─────────────────────────────────────────┘                ▲                │ currentTime(每 tickMs 转一格)tickMs = 1ms, wheelSize = 20任务 expirationMs = currentTime + delay桶位 = (expirationMs / tickMs) % wheelSize

问题:要支持 1ms 精度 + 1 小时延迟 → 需要 360 万个桶,浪费内存。

分层时间轮(Kafka 实现,借鉴 Linux 内核):

Level 0: tickMs=1ms,    wheelSize=20  → 覆盖 0~20msLevel 1: tickMs=20ms,   wheelSize=20  → 覆盖 0~400msLevel 2: tickMs=400ms,  wheelSize=20  → 覆盖 0~8sLevel 3: tickMs=8s,     wheelSize=20  → 覆盖 0~160s... 按需向上溢出,新建更高层

插入算法

def add(task: TimerTask): Boolean = {  val expiration = task.expirationMs  if (expiration < currentTime + tickMs) {    // 已经到期,直接执行    return false  } else if (expiration < currentTime + tickMs * wheelSize) {    // 当前层能容纳,放对应 bucket    val bucket = buckets((expiration / tickMs) % wheelSize)    bucket.add(task)    return true  } else {    // 溢出到上层    overflowWheel.add(task)  }}

降级(cascade):当上层时间轮的 currentTime 推进,导致某个 bucket 内任务变得"足够近" → 把这些任务降到下层时间轮重新插入

这就是为什么 1ms 精度 + 1 小时延迟只需要 4 层 × 20 = 80 个桶。

16.1.3 Kafka 的具体实现

源码位置:kafka.utils.timer.*

  • TimingWheel
    :分层时间轮主类。
  • TimerTaskList
    :桶(双向链表 + 自旋锁)。
  • TimerTaskEntry
    :链表节点,包含 task + expirationMs。
  • SystemTimer
    :上层封装;包含一个 DelayQueue<TimerTaskList>只放"非空 bucket"
  • Reaper 线程
    :从 DelayQueue.poll() 拿到到期 bucket → 执行所有任务(或降级)。

精妙之处

DelayQueue 不放 task 本身,只放 bucket。bucket 是 O(wheelSize × levels) = O(80) 数量级 → DelayQueue 操作几乎零成本。

┌─ Producer 收到 acks=all 请求 ────────────────────────────────────┐│                                                                  ││  ReplicaManager.appendRecords                                    ││      ↓                                                           ││  写本地 → 构造 DelayedProduce(timeout=requestTimeoutMs)           ││      ↓                                                           ││  producePurgatory.tryCompleteElseWatch(DelayedProduce, keys)     ││      │                                                           ││      ├─ tryComplete():检查 HW 是否已推进过该 offset               ││      │     ├─ 是 → 立即响应                                       ││      │     └─ 否 → 加入对应 TopicPartition 的 watch list          ││      │                                                           ││      └─ 同时把任务塞进 SystemTimer 的时间轮                        ││            (超时兜底,避免 watch 永远不触发)                      ││                                                                  ││  当 Follower Fetch 上报 LEO,Leader 推 HW                         ││      ↓                                                           ││  partition.tryCompleteDelayedRequests()                          ││      ↓                                                           ││  从 watch list 取出 DelayedProduce.tryComplete() → 完成响应       │└──────────────────────────────────────────────────────────────────┘

双触发机制(非常巧妙):

  1. 正向
    :HW 推进 / 数据到达 → 主动调用 tryCompleteDelayedRequests → 立即唤醒。
  2. 反向
    :超时兜底,Reaper 线程从时间轮拿到到期 task → 强制完成(返回 timeout 错误)。

16.1.4 高频面试题

Q:Kafka 为什么不用 ScheduledExecutorService?

A:插入/删除 O(log n),百万级任务下抖动严重;不支持"主动提前完成"语义;不支持百万级 watch list。

Q:分层时间轮的时间复杂度?

A:插入/删除 O(1)(桶定位 + 链表操作);任务到期 O(1)(直接执行 bucket 链表)。

Q:精度 1ms + 延迟 1 小时,Kafka 用了几层?

A:层数 = ⌈log₂₀(3,600,000)⌉ ≈ 5 层,每层 20 个桶,共 100 个桶。比单层方案少 4 个数量级内存。


16.2 Sender / RecordAccumulator 源码剖析

16.2.1 整体数据结构

RecordAccumulator├── ConcurrentMap<TopicPartitionDeque<ProducerBatch>>   // 每个 TP 一个队列├── BufferPool                                             // 内存池(buffer.memory)└── IncompleteBatches                                      // 跟踪未完成 batch(abort 时用)ProducerBatch├── MemoryRecordsBuilder      // 累积消息的可变 buffer├── List<Thunk>               // 每个 send 注册的回调├── createdMs / drainedMs     // 时间统计├── retryCount                // 重试次数└── producerId / sequence     // 幂等性元数据

16.2.2 send() 调用链路(精简)

// org.apache.kafka.clients.producer.KafkaProducerpublic Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback cb) {    // 1. 拦截器 → onSend    // 2. 序列化 key/value    // 3. 分区器选 partition    // 4. accumulator.append(...)  ← 关键    RecordAccumulator.RecordAppendResult result = accumulator.append(        topicPartition, timestamp, serializedKey, serializedValue,        headers, callback, maxTimeToBlock /* max.block.ms */, ...);    if (result.batchIsFull || result.newBatchCreated) {        sender.wakeup();   // 唤醒 Sender 线程    }    return result.future;}

append 内部的关键设计

public RecordAppendResult append(TopicPartition tp, ...) {    Deque<ProducerBatch> dq = getOrCreateDeque(tp);    synchronized (dq) {           // 单 TP 队列粒度的锁        // 尝试追加到队尾 batch        RecordAppendResult result = tryAppend(...);        if (result != nullreturn result;    }    // 队尾 batch 装不下 → 申请新 buffer(可能阻塞 max.block.ms)    ByteBuffer buffer = bufferPool.allocate(size, maxTimeToBlock);    synchronized (dq) {        // 双重检查(DCL 模式):可能其他线程已经创建了新 batch        result = tryAppend(...);        if (result != null) {            bufferPool.deallocate(buffer);            return result;        }        // 创建新 batch        ProducerBatch batch = new ProducerBatch(tp, recordsBuilder, now);        batch.tryAppend(...);        dq.addLast(batch);        return new RecordAppendResult(future, /*batchIsFull*/ false/*newBatchCreated*/ true);    }}

精妙点

  1. 每个 TP 独立 Deque + 独立锁
    :跨 TP 完全无锁竞争。
  2. DCL 模式
    :先无锁尝试追加,失败后申请 buffer,再加锁创建新 batch。
  3. BufferPool 复用
    :避免频繁 GC(用过的 ByteBuffer 归还池子,下次复用)。

16.2.3 Sender 线程的 drain 逻辑

// Sender 单线程循环void run() {    while (running) {        // 1. 检查哪些 broker 准备好了        ReadyCheckResult ready = accumulator.ready(metadata, now);        // ready 条件:batch 满 / linger 到 / metadata 可用 / 重试时间到        // 2. 按 broker 维度 drain(关键)        Map<IntegerList<ProducerBatch>> batches =             accumulator.drain(metadata, ready.readyNodes, maxRequestSize, now);        // 3. 处理过期 batch(delivery.timeout.ms 到了)        List<ProducerBatch> expired = accumulator.expiredBatches(now);        expired.forEach(b -> b.done(ERROR));        // 4. 构造 ProduceRequest 并发送        for (Map.Entry<IntegerList<ProducerBatch>> e : batches.entrySet()) {            sendProduceRequest(e.getKey(), e.getValue());        }        // 5. 处理 NetworkClient 的回调        client.poll(timeout, now);    }}

drain 的精妙

public Map<Integer, List<ProducerBatch>> drain(...) {    Map<Integer, List<ProducerBatch>> batches = new HashMap<>();    for (Node node : readyNodes) {        List<ProducerBatch> ready = drainBatchesForOneNode(node, ...);        batches.put(node.id(), ready);    }    return batches;}private List<ProducerBatch> drainBatchesForOneNode(Node node, int maxSize, long now) {    int size = 0;    List<ProducerBatch> ready = new ArrayList<>();    List<PartitionInfo> parts = metadata.partitionsForNode(node.id());    // 关键:从随机 offset 开始遍历,避免每次都从同一个 TP 抢资源(饿死后面的 TP)    int start = drainIndex.getAndIncrement() % parts.size();    int i = start;    do {        TopicPartition tp = ...;        Deque<ProducerBatch> dq = getDeque(tp);        synchronized (dq) {            ProducerBatch first = dq.peekFirst();            if (first == null || isMuted(tp)) continue;            if (size + first.estimatedSize() > maxSize && !ready.isEmpty()) break;            ProducerBatch batch = dq.pollFirst();            batch.close();   // 关闭 builder,禁止再追加            size += batch.estimatedSize();            ready.add(batch);        }        i = (i + 1) % parts.size();    } while (i != start);    return ready;}

为什么要 mute / unmute?

  • 启用幂等性 + 单分区有 in-flight 请求时,该 TP 被 mute(不再 drain),等响应回来才 unmute。
  • 防止:req1 失败时 req2 已发出,req1 重试后顺序错乱。

16.2.4 高频追问

Q:Producer 内存满了会怎样?

A:bufferPool.allocate 阻塞 max.block.ms;超时抛 TimeoutException这个异常如果业务没捕获就是丢消息

Q:linger.ms=0 真的零延迟吗?

A:不是。accumulator.ready() 在 linger.ms=0 时只要 batch 非空就 ready;但 Sender 线程是单线程循环,要等本轮 client.poll() 返回才能进入下一轮 drain。所以实际仍有调度抖动(μs 级)。

Q:batch.size 和 linger.ms 哪个先满足就发?

A:先满足者发。两个互相短路 → 这是设计点。


16.3 SocketServer Reactor 模型

                ┌──────────── Acceptor (1 个线程) ─────────────┐                │ ServerSocketChannel.accept() 接受新连接       │                │ 轮询分配给 Processor                          │                └───────────────────┬───────────────────────────┘                                    │                ┌───────────────────┼───────────────────┐                ▼                   ▼                   ▼         Processor[0]        Processor[1]        ...  Processor[N-1]         (num.network.threads 个 = 默认 3)         │ 每个有自己的 Selector         │ 处理 read / write 事件         └─→ RequestChannel.requestQueue (有界阻塞队列)                                    │                ┌───────────────────┼───────────────────┐                ▼                   ▼                   ▼         KafkaRequestHandler[0]  ...  KafkaRequestHandler[M-1]         (num.io.threads 个 = 默认 8)         │ poll requestQueue,调用 KafkaApis.handle(request)         │ 处理完写到 Processor 的 responseQueue         ▼         Processor 在下一轮 Selector 循环把 response 写回

关键设计

  1. Acceptor 不处理 IO
    ,只 accept;
  2. Processor 不处理业务
    ,只读 byte → 反序列化为 Request → 入队;
  3. 业务线程池(KafkaRequestHandler)专注 CPU/磁盘工作
    ,避免阻塞 IO 线程;
  4. 每个 Processor 有独立的 Selector
    ,避免单 Selector 的伪共享;
  5. RequestChannel 是单一全局队列
    ,所有 Processor 共享 Handler Pool,简单粗暴有效。

为什么 num.network.threads 推荐 = CPU 核数 / 2?

Processor 是 IO 密集,但反序列化 + SSL/SASL 解密是 CPU 密集。通常 3~6 已经够,再多反而锁竞争。

为什么 num.io.threads 推荐 = 磁盘数 × 8?

Handler 主要瓶颈在磁盘 IO 和 PageCache 拷贝。多盘多 Handler 才能压满 IO。


16.4 NetworkClient + InFlightRequests + KafkaChannel

KafkaProducer (Sender 线程)   NetworkClient (单 Selector,多 broker)   ├── Map<NodeIdKafkaChannel>           每个 broker 一个长连接   ├── InFlightRequests                     Map<NodeIdDeque<NetworkSend>>        - 每个 broker 一个 deque        - 上限 = max.in.flight.requests.per.connection   └── Selector (NIO)         ├── send queue         └── completed receives

InFlightRequests 的作用

  1. 维护"已发送未响应"的请求列表;
  2. 响应回来时按顺序匹配(FIFO 顺序);
  3. 检查是否可以再发请求(canSendMore(node))。

幂等场景的特殊处理

  • 启用幂等时,每个 TP 的 batch 携带递增 sequence。
  • OutOfOrderSequenceException
     时,Producer 把该 TP 的所有 in-flight + accumulator 中的 batch 重排再发。

KafkaChannel 内部:

  • 包装 SocketChannel + TransportLayer(PlainText / SSL / SASL);
  • SSL 模式下走 SslTransportLayer完全不能 sendfile / mmap zerocopy,因为加密必须经过用户态。

16.5 LogManager / Log 并发控制

LogManager├── Map<TopicPartition, UnifiedLog> currentLogs├── 后台线程:│   ├── log-cleaner-* (compact)│   ├── kafka-log-retention (delete by time/size)│   └── kafka-log-flusher (定期 fsync,默认 Long.MAX_VALUE 即不主动 fsync)└── 加载/卸载 Log 时的 lock

UnifiedLog(单 Partition 的日志)

class UnifiedLog {    private val lock = new Object()                           // 大锁,写入串行    @volatile var nextOffsetMetadata: LogOffsetMetadata = ... // LEO,volatile 保证读不需要锁    var activeSegment: LogSegment = ...    val segments: ConcurrentNavigableMap[Long, LogSegment]    // 跳表,快速二分定位    def append(records: MemoryRecords): LogAppendInfo = {        lock.synchronized {            // 1. 校验消息(CRC、size、producer state)            // 2. 决定是否 roll segment            // 3. activeSegment.append(...)            // 4. 更新 LEO        }    }    def read(startOffset: Long, maxLength: Int): FetchDataInfo = {        // 读路径不加锁(segments 是 ConcurrentNavigableMap,LEO 是 volatile)        val segment = segments.floorEntry(startOffset).getValue        segment.read(...)    }}

精妙点

  1. 写路径加锁
    (保证 offset 严格递增),读路径无锁(依赖 volatile + ConcurrentMap)。
  2. ConcurrentNavigableMap(跳表)按 baseOffset 索引 segments
    :定位 segment 是 O(log n),并发安全。
  3. Segment 内部的 .index / .timeindex 是 mmap
    ,FileChannel 是数据日志。

16.6 PageCache 工作机制(必背)

16.6.1 写路径

应用 write(fd, buf, len)   ↓内核:把数据 copy 到 PageCache(脏页)   ↓write() 返回(此时数据还没落盘)   ↓内核后台 flush (kworker / pdflush)   ↓ 受以下参数控制   │ vm.dirty_background_ratio  → 后台开始刷盘的脏页占比(默认 10%)   │ vm.dirty_ratio              → 强制同步刷盘的脏页占比(默认 20% 后阻塞 write   │ vm.dirty_expire_centisecs   → 脏页最大停留时间(默认 30s)   │ vm.dirty_writeback_centisecs → 后台 flush 周期(默认 5s)   ↓真正写到磁盘

16.6.2 读路径

应用 read(fd, buf, len)   ↓内核检查 PageCache   ├── HIT  → 从 PageCache 直接 copy 到用户 buf   └── MISS → 从磁盘读到 PageCache → 再 copy 到用户 buf              (会预读 readahead 后续 page)

16.6.3 Kafka 与 PageCache 的关系

操作
经过 PageCache?
备注
Producer 写入
✅ 经过
Broker FileChannel.write() 写入 PageCache
Consumer 读取(热数据)
✅ 命中
直接从 PageCache → sendfile → 网卡
Consumer 读取(冷数据)
✅ MISS 后填充
触发磁盘读 + 预读
Index 文件
✅ mmap
整个文件映射到进程地址空间
Follower 同步
✅ 经过
与 Consumer 走相同路径

所以

  • Producer 写、Consumer 读、Follower 同步全在 PageCache
  • 机器内存越多 → PageCache 越大 → 命中率越高 → 吞吐越高
  • Broker 进程崩溃
    :PageCache 数据由内核管理,不丢;
  • 机器掉电
    :PageCache 数据丢失 → 依赖副本恢复。

16.6.4 经典面试题

Q:为什么 Kafka 不用 Direct I/O 绕过 PageCache?

A:

  1. Direct I/O 要求严格对齐(4KB),Kafka 消息变长不友好;
  2. Direct I/O 跳过 PageCache → 失去预读、热数据缓存优势;
  3. Consumer 的 sendfile 必须经过 PageCache;
  4. 唯一的好处(避免双倍内存占用)对 Kafka 不重要,因为它本来就不在堆里 cache 数据。

Q:什么时候需要调 vm.dirty_*?

A:写入抖动场景。默认 dirty_background_ratio=10% 在大内存机器上意味着 6.4GB 脏页才开始刷 → 一次集中刷盘几秒钟。生产建议 dirty_background_ratio=5, dirty_ratio=60,让后台尽早开刷,避免阈值触发的 stop-the-world 写阻塞。


16.7 零拷贝(sendfile)与 SSL 失效

16.7.1 传统 read + write 的拷贝路径

磁盘 ──DMA──► PageCache (内核空间)            │            └─► copy ──► 应用 buffer (用户空间)                                  │                                  └─► copy ──► Socket buffer (内核空间)                                                       │                                                       └─DMA──► 网卡4 次拷贝 + 4 次上下文切换(user/kernel 来回)

16.7.2 sendfile(Linux 2.1+)

sendfile(out_fd, in_fd, offset, count)磁盘 ──DMA──► PageCache (内核空间) ──► Socket buffer ──DMA──► 网卡                       │                       └─ 仅"描述符 + 长度"传递,数据不拷贝(DMA scatter-gather, 2.4+2 次 DMA + 0 次 CPU 拷贝 + 2 次上下文切换

Java 中通过 FileChannel.transferTo(position, count, socketChannel) 调用 sendfile。

16.7.3 为什么 SSL/TLS 时 sendfile 失效?

必考题。

SSL 加密必须在用户态完成(OpenSSL/JSSE 都是用户态库):

SSL 启用时:磁盘 ──DMA──► PageCache ──copy──► 用户 buffer                                       │                                       └─ SSL.encrypt() 加密                                       │                                       └──copy──► Socket buffer ──DMA──► 网卡退化成 4 次拷贝。

实测数据:开启 SSL 后 Kafka 吞吐下降 30%~50%(不仅是因为加密 CPU 开销,主要是丢失了零拷贝)。

优化方案

  • 关键内网链路用 PLAINTEXT;
  • 对外暴露用 SSL,但加多 broker / 用 kTLS(内核 TLS,将加密下沉到内核,恢复零拷贝,Linux 4.13+ 支持)。

16.8 mmap vs FileChannel 的取舍

场景
Kafka 选择
原因
.log 数据文件
FileChannel + sendfile
文件大(GB 级),mmap 整个文件占地址空间太大;Consumer 需要 sendfile 零拷贝直送网卡,mmap 反而要 CPU 拷贝
.index / .timeindex 索引
mmap
文件小(10MB 级),整个映射到内存;查找通过指针运算,O(log n) 二分

mmap 优点

  • 一次 system call → 后续访问像访问内存;
  • 文件被多次读时复用 PageCache。

mmap 陷阱

  • 32 位 JVM 地址空间有限(不是 Kafka 关心的);
  • mmap 文件写时仍需 msync 才能强制刷盘;
  • mmap 的 page fault 可能阻塞应用线程(如果文件不在 PageCache)。

16.9 文件系统、O_DIRECT、JBOD vs RAID

文件系统

  • XFS
    (推荐):extent-based,大文件性能最好,并发写优秀;
  • ext4
    :通用,性能也行,但小文件多时碎片;
  • 不要用 NFS / GlusterFS
     等网络文件系统,延迟和一致性都不可控。

挂载选项

/dev/nvme0n1   /data/kafka   xfs   defaults,noatime,nodiratime,nobarrier   0 0
  • noatime
     / nodiratime:避免每次读更新 access time(每次更新都要写一次磁盘元数据)。
  • nobarrier
    :跳过 write barrier(依赖电池写缓存);高端 RAID 卡或 NVMe + 电池才安全。

JBOD vs RAID

  • Kafka 推荐 JBOD(Just a Bunch of Disks)
    :让 Kafka 自己在 broker 间均衡分配 partition;
  • RAID 0:性能好但一盘坏全坏;
  • RAID 10:可用但浪费一半容量;
  • 实际生产
    :3 副本已经提供冗余,JBOD 是首选。
  • KIP-112+ 支持单盘故障 broker 不下线(log.dir.failure.timeout.ms)。

16.10 真实面试现场题(5 道带公司风格标记)


🟦 字节风格 Q1:徒手画分层时间轮,并解释为什么 1ms 精度 + 1 小时延迟只需要 80 个桶?

字节"源码 + 数据结构"经典题。考点:能否手写时间轮 + 分层概念。

参考答案

单层时间轮:  tickMs=1ms, wheelSize=20 → 覆盖 0~20ms分层时间轮(Kafka 实现):  Level 0: tickMs=1ms,    wheelSize=20  → 0~20ms  Level 1: tickMs=20ms,   wheelSize=20  → 0~400ms  Level 2: tickMs=400ms,  wheelSize=20  → 0~8s  Level 3: tickMs=8s,     wheelSize=20  → 0~160s  Level 4: tickMs=160s,   wheelSize=20  → 0~3200s ≈ 53分钟每加一层,覆盖范围 ×20。1 小时(3600s)需要 5 层 → 5 × 20 = 100 个桶。若优化到 4 层(最高 tickMs=320s),共 80 个桶。对比 1 小时 1ms 精度的单层方案:3600,000 个桶 → 节省 4500x 内存。每个 task 添加:O(1)任务过期降级:上层 cascade 到下层 O(levels) ≈ O(1)配合 DelayQueue(只放 bucket 不放 task)→ DelayQueue 操作 O(log levels)

追问:Reaper 线程怎么工作?为什么 DelayQueue 只放 bucket?

  • Reaper 单线程从 DelayQueue.poll() 取到期 bucket → 调用 bucket.flush() 执行所有 task。
  • DelayQueue 只放 bucket(80 个量级)而不是 task(百万量级),DelayQueue 操作几乎零成本。

🟧 阿里风格 Q2:你们 Broker JVM 配置 G1 + 8G 堆,频繁 GC 导致 ISR 抖动。怎么解决?

阿里"中间件稳定性"经典题

参考答案

1) 先确认是 GC 抖还是其他   - jstat -gcutil <pid> 1000 看 GC 暂停 > 50ms   - JMX IsrShrinksPerSec / IsrExpandsPerSec 飙升2JVM 调优   -Xms8g -Xmx8g                       (固定不动态扩缩)   -XX:+UseG1GC   -XX:MaxGCPauseMillis=20   -XX:G1HeapRegionSize=16m   -XX:InitiatingHeapOccupancyPercent=35   -XX:+ParallelRefProcEnabled   -XX:+AlwaysPreTouch                  (启动期预触摸内存)3) 不要用 ZGC(除非堆 ≥ 16GB)   - Kafka 大量数据走堆外(NIO/DirectBuffer + mmap)   - 堆里都是短命对象,G1 年轻代复制就够   - ZGC 读屏障开销让吞吐降 10%+4) 关闭 -XX:+DisableExplicitGC   - Kafka 内部依赖 System.gc() 触发 DirectBuffer 回收   - 关闭会导致堆外 OOM5GC 抖根因   - 大消息 / 大 batch 进入老年代 → 调小消息上限   - DirectBuffer 累积 → 检查 Producer / Consumer SDK 是否泄漏   - 同时压测验证调优效果

追问:为什么不用更高级的 ZGC?

  • 详见 Ch9.4:Kafka 堆里没有"长寿大对象",PageCache 才是性能关键。ZGC 适合堆 ≥ 16GB 的业务 Consumer,不适合 Broker 本身。

🟪 蚂蚁风格 Q3:sendfile 零拷贝在 SSL 下失效,金融场景全链路加密怎么权衡?

蚂蚁"金融合规 vs 性能"经典题

参考答案

现状:  传统 sendfile:磁盘 → PageCache → 网卡(2 次 DMA + 0 次 CPU 拷贝)  SSL 启用后:磁盘 → PageCache → 用户 buffer(CPU 加密)→ Socket buffer → 网卡            (4 次拷贝 + CPU 加密开销,吞吐降 30~50%)权衡方案:  1) 内网 PLAINTEXT,南北向 SSL     - Broker 间副本同步用 PLAINTEXT(机房内可控)     - 公网入口 SSL,加 broker 数量 / 网卡补吞吐  2) kTLS(Linux 4.13+,Kafka 3.0+)     - 加密下沉到内核,恢复零拷贝路径     - CPU 仍有加密开销,但少了一次内核-用户态拷贝  3) 应用层加密(端到端)     - Producer 加密 payload,Consumer 解密     - SSL 关闭,sendfile 恢复     - 业务复杂度高,Schema Registry 兼容差  4) 硬件加速(QAT / AES-NI)     - Intel QAT 卡专门做 SSL 卸载,CPU 占用下降 50%+     - 蚂蚁、阿里云已经在用实际选择:  - 金融场景:方案 1 + 方案 2 组合(内网明文 + kTLS 公网)  - 资损零容忍:方案 3(业务层加密)

🟢 腾讯风格 Q4:百亿级 QPS 集群,PageCache 命中率怎么保?

参考答案

1) 内存配比   机器 256GB → 堆 8GB → PageCache 248GB   单 Broker 数据热点 < 248GB → 几乎全命中2) Topic 数量控制   单 Broker partition 数 < 4000,避免文件描述符 / 内存映射开销   过多 Topic → segment 文件多 → PageCache 碎片化 → 命中率下降3) 消费节奏   Consumer Lag < 1 分钟(核心 Topic)→ 几乎只读最新数据 → PageCache 全命中   Lag > 1 小时 → 读冷数据 → PageCache miss + 磁盘 IO 突增4) Tiered Storage(KIP-405)   冷数据下沉 S3,本地只保留热数据 → PageCache 命中率提升5) 监控   sar -B 1 看 majflt/s(major page fault 次数)   命中率 = 1 - major_fault / total_read实际数据:   我们集群命中率从 92% 提到 98%,吞吐提升 30%,磁盘 IOPS 下降 60%。

🟡 美团/快手风格 Q5:mmap 索引文件大 + 内存吃紧场景下,怎么优化?

美团/快手"实战调优"经典题

参考答案

mmap 的作用:  Kafka 把 .index / .timeindex 用 mmap 映射到内存  → 二分查找走指针运算,O(log n) 但在内存里mmap 的代价:  整个文件占进程虚拟地址空间  读时实际占物理内存(PageCache)  Topic 多 → 索引文件多 → mmap 数量爆炸优化方案:  1) 限制每分区 segment 数量     log.segment.bytes 调大(512MB → 1GB)→ segment 少 → 索引少  2) 加快 segment 回收     log.retention.hours 不要设过大 → 老 segment 早删 mmap 释放  3) 控制 Topic 数量     单 Broker partition 总数 < 4000  4) 监控 mmap 数量     ls /proc/<broker_pid>/maps | wc -l     超过 10000 警惕  5) 极端场景换 Pulsar     Pulsar 用 BookKeeper Ledger,索引在 BookKeeper 中     mmap 不会随 Topic 数量爆炸


🧭 章节导航

🏠 返回 README

⬅️ 上一模块:03-设计与编码.md | ➡️ 下一模块:05-分布式理论与大厂设计.md

模块
文件
🔵 模块一·基础原理
01-基础与原理.md
🟢 模块二·调优运维
02-调优与运维.md
🟡 模块三·设计编码
03-设计与编码.md
🔴 模块四·源码 OS(当前)
04-源码与OS底层.md
🟣 模块五·分布式理论
05-分布式理论与大厂设计.md
📎 附录
99-附录.md
基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-05-12 12:05:48 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/611134.html
  2. 运行时间 : 0.160514s [ 吞吐率:6.23req/s ] 内存消耗:4,803.34kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=228269f831c4e474d4541110799cf2b3
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000566s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000744s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000353s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000283s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000508s ]
  6. SELECT * FROM `set` [ RunTime:0.000192s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000560s ]
  8. SELECT * FROM `article` WHERE `id` = 611134 LIMIT 1 [ RunTime:0.001765s ]
  9. UPDATE `article` SET `lasttime` = 1778558748 WHERE `id` = 611134 [ RunTime:0.001421s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.000254s ]
  11. SELECT * FROM `article` WHERE `id` < 611134 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000488s ]
  12. SELECT * FROM `article` WHERE `id` > 611134 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.001799s ]
  13. SELECT * FROM `article` WHERE `id` < 611134 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.009897s ]
  14. SELECT * FROM `article` WHERE `id` < 611134 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.011261s ]
  15. SELECT * FROM `article` WHERE `id` < 611134 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.048810s ]
0.162202s