news 2026/9/28 20:46:50

IEEE 1588 PTP授时:ptp_clock驱动与硬件时间戳同步实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
IEEE 1588 PTP授时:ptp_clock驱动与硬件时间戳同步实战

简介:这份压缩包提供PTP 1588时钟的用户空间接口实现,面向需要在应用中集成高精度时间同步的嵌入式或网络开发者,解决用户态程序与内核PTP时钟交互的问题。包内共2个文件,以C源码与头文件为主:ptp_clock.c包含时钟初始化、报文收发与同步消息处理等函数,ptp_clock.h则声明接口原型与数据结构,便于上层程序直接调用,实现对主从时钟选举、时间校正等流程的精细控制。资源体积仅5KB,结构非常精简,适合快速阅读和移植。目前已有192人学习下载。通过阅读这些代码,开发者可清晰理解PTP 1588在用户空间的实现脉络,掌握如何查询和设置时钟参数、参与同步流程,并可将相关接口复用到分布式系统、网络测量或IoT设备等需要微秒级时间对齐的场景,从而在时间敏感型项目集成中少走弯路。

1. ptp_clock 这套代码到底在干什么:先看 IEEE 1588 授时的价值边界

做网络设备的人迟早会撞上一个问题:NTP 顶天给你毫秒级,等到了需要把多台设备的采集时刻对齐到微秒的场景,就得换成 IEEE 1588 的 PTP 授时。ptp_clock.rar 这类以压缩包分发的工程,核心就是一套 PTP 时钟实现,里面既有内核态的时钟驱动(ptp_clock),也有配套的用户态同步工具。拆开它之前,先想清楚你要的是哪个层面的东西:是驱动级的硬件时钟访问,还是协议级的同步算法,还是配置好现成工具就够了。这篇文章按这个需求顺序往下拆,看完之后你至少能判断这套代码值不值得用、怎么落地。标题里的 ptp_space 我理解为工程里用来组织这套时钟实现的命名空间或目录名,它把内核驱动、报文解析、伺服算法隔离开,下面一步步展开。

2. IEEE 1588 同步模型:ptp_clock 要解决的偏移与延迟计算

2.1 主从时钟的四步交互:Sync、Follow_Up、Delay_Req、Delay_Resp

PTP 的核心思路不是让所有设备各自去对“授时服务器”,而是先在网络里选出一个主时钟(Master),其余设备作为从时钟(Slave),通过一组报文把主钟的时间“搬”到从钟上。这套交互在 IEEE 1588 里被设计成四步:主钟周期性发 Sync,从钟记录到达时刻;如果网络支持硬件时间戳,Sync 真正的发送时刻由主钟在报文离开网卡那一刻打点,并通过 Follow_Up 告诉从钟;从钟再发 Delay_Req,主钟收到后记下接收时刻,丢一个 Delay_Resp 回去。一次完整的往返,从钟拿到 t1、t2、t3、t4 四个时间戳,才能算出自己跟主钟差了多少。

这里面有个容易被忽略的前提:四步交互只解决了“主从之间相差多少”和“路径延迟是多少”这两个未知数,但方程的成立依赖路径延迟对称。也就是说,主到从和从到主的报文走同一条物理链路、延迟相等。实际工程里光纤收发路径不等长、交换机缓存排队,都会让这个假设失真,这也是后面排查章里最常翻车的地方。理解了这一点,你就知道 ptp_clock 这类实现里那些看似繁琐的报文状态机并不是形式主义,每一步都是在为这两个方程采集干净的时间戳。

2.2 偏移和路径延迟的公式推导:offset 与 delay 的两个方程

先把符号定下来:设主钟发出 Sync 的时刻为 t1,从钟收到时本地读到 t2;主从之间的路径单向延迟为 d;从钟相对主钟的时间偏移为 offset,定义是从钟读数减去主钟读数,正值表示从钟走快了。那么在 Sync 这条腿上,从钟收到的本地时刻满足 t2 = t1 + d + offset。再走 Delay_Req/Delay_Resp 这条路:从钟本地 t3 发请求,主钟收到时读数为 t4。由于从钟读数为 t3 时,主钟真实读数其实是 t3 减 offset,所以 t4 = (t3 - offset) + d = t3 + d - offset。

两个方程联立,把 d 消掉就能得到 offset = ((t2 - t1) - (t4 - t3)) / 2;把 offset 消掉则得到 d = ((t2 - t1) + (t4 - t3)) / 2。ptp4l 这类用户态工具拿到 offset 后不会一次掰到位,而是交给一个 PI 伺服器,按比例慢慢把误差压下去,避免从钟时间忽快忽慢把下游应用震坏。这个公式看起来简单,但它对时间戳的“干净程度”极其敏感:只要 t1 到 t4 任何一个来自软件层,抖动就能吃掉你几百纳秒的精度。这也是为什么 IEEE 1588 的落地几乎离不开硬件时间戳,也就是下面要讲的 ptp_clock 存在的根本理由。

2.3 软件时间戳与硬件时间戳:为什么 ptp_clock 必须依赖 PHC

软件时间戳的路径是:报文到达网卡后经过中断、协议栈、套接字,最后才在应用程序里读时间,这里的抖动取决于系统负载,几十微秒到几百微秒都有可能。硬件时间戳则是在报文进出网卡的物理层或 MAC 层那一下就完成打点,jitter 可以压到几十纳秒以内。IEEE 1588 要的就是第二个量级,所以从钟网卡必须支持在 PHY/MAC 打时间戳,内核里负责管理这块硬件时钟(PHC,PTP Hardware Clock)的框架就是 ptp_clock。

对比项软件时间戳硬件时间戳
打点位置应用层/协议栈网卡 PHY/MAC
典型抖动几十到几百微秒几十纳秒以内
对 CPU 负载敏感度高低
内核依赖普通网络栈ptp_clock + PHC 驱动

ptp_clock 在内核里的角色是给用户态提供一组操作硬件时钟的接口:读取当前时间、设置时间、微调频率。它通过字符设备 /dev/ptp0 暴露给上层,ptp4l 用它拿到硬件时间戳和校准硬件时钟,phc2sys 再把硬件时钟“喂”给系统实时时钟。所以说 ptp_clock 不是同步算法本身,而是算法和硬件之间的桥。如果你手头这包代码里只有 ptp_clock.ko 而没带用户态工具,那还得自己把 linuxptp 或等价实现补上,缺了任何一头,链路都闭合不了。

3. ptp_clock.rar 的工程组织:从解包到挂载内核时钟设备

3.1 解包与目录识别:ptp_space 里通常放着什么

拿到一个 ptp_clock.rar,我一般先不急着编译,而是解包之后把文件列表过一遍,确认它到底是内核模块工程、用户态 C++ 工程还是两者都带。从包名看,ptp_space 大概率是组织代码的目录或命名空间,用来放时钟核心逻辑。这类工程最常见的布局是:一个目录放内核驱动源文件(ptp_clock.c、ptp_clock.h),一个目录放用户态同步逻辑(报文解析、状态机、伺服),外加 Makefile 或 CMakeLists.txt 负责构建。

mkdir -p ~/ptp_work && cd ~/ptp_work # unzip 解不了 rar 就用 unrar 或 7z unrar x ptp_clock.rar find . -maxdepth 2 -type f | sort

解压命令本身没什么可说的,关键是看 find 的结果。我会重点确认三样东西:有没有 Makefile 或 CMakeLists.txt,有没有 Kconfig(说明这包里有内核模块要编),以及有没有 README 或 config 示例文件。很多包你拿到手第一步就卡在“不知道从哪编起”,其实看构建文件比看代码更高效。如果顶层只有一个 ptp_space 目录,里面是 .cpp/.h 文件,那这多半是用户态实现,需要 CMake 或手动 g++ 编;如果看到 ptp_clock.c 和 Kconfig,那就是往内核里挂的驱动部分。

3.2 编译并挂载 PTP 时钟驱动:/dev/ptp0 的诞生

内核态的 ptp_clock 驱动,本质是注册一个 ptp_clock 设备,并实现 gettime/settime/adjtime/adjfreq 这几个回调,分别对应读取时间、设置时间、调整单次偏移和调整频率。编译它需要当前内核的头文件,命令很直白,但容易踩两个坑:一是内核头文件版本和运行内核不一致,二是不清楚驱动的 Makefile 期望的源码目录结构。

# 在内核驱动源码目录里执行,假设当前目录就是 ptp_clock 驱动源码 make -C /lib/modules/$(uname -r)/build M=$(pwd) modules sudo insmod ptp_clock.ko dmesg | tail -20 ls -l /dev/ptp*

-C 指定内核构建目录,M=$(pwd) 告诉 kbuild 到当前目录找模块源码,这两项几乎是所有内核模块编译的固定写法。insmod 之后,dmesg 里应该能看到驱动注册成功,/dev/ptp* 节点出现,如果是第一个 PHC 设备就是 /dev/ptp0。如果 dmesg 报 “Unknown symbol” 或者找不到 ptp_clock_class,说明内核没开 CONFIG_PTP_1588_CLOCK,需要重新编译内核或者加载依赖模块。用户态那边要做的第一件事就是用 ls /dev/ptp* 确认设备号,ptp4l 和 phc2sys 后面都要显式绑这个节点。

3.3 用户态协议栈的配合:ptp4l 与 phc2sys 各管哪一段

很多从内核模块入手的新手容易以为 insmod 挂上驱动就等于授时完成了,其实还早得很。ptp_clock 驱动只提供“操作硬件时钟”的能力,协议交互得靠用户态。最常见方案是 linuxptp 套件里的 ptp4l 跑 PTP 协议栈,phc2sys 负责把 /dev/ptp0 的硬件时间和系统时间对齐。ptp4l 的角色是算出 offset 并校准硬件时钟,phc2sys 的角色是把已经准的硬件时钟同步给系统实时时钟,两者一前一后,缺一个都会出现“PTP 域里准了,但应用层 time() 还是飘的”的怪象。

# 终端一:跑协议栈 sudo ptp4l -i eth0 -m -l 6 -f /etc/linuxptp/ptp4l.conf # 终端二:把硬件时钟同步到系统时钟 sudo phc2sys -s eth0 -c CLOCK_REALTIME -m -l 6

ptp4l 的 -i 指定网卡,-m 把日志打到标准输出,-l 6 是日志级别,保证你能在终端直接看到 offset 变化。phc2sys 的 -s 是源时钟,既可以写网络接口名(表示读该网卡的 PHC),也可以写 /dev/ptp0;-c 是目标时钟,CLOCK_REALTIME 就是系统时钟。两个进程一跑,等几十秒就能在 ptp4l 日志里看到 offset 从几千纳秒往下收敛。如果这时系统时间纹丝不动,问题多半出在 phc2sys 没带 -O 参数补偿主钟和系统时间的基准差,具体在第 5 章排查里细说。

4. 跑通最小 PTP 授时链路:配置、启动命令与同步判据

4.1 主从角色的选择:BMC 算法与 clockClass、priority1/2

PTP 网络里谁当主钟不是人肉指定的,而是设备之间跑 BMC(Best Master Clock)算法自己选。决定权在三个参数:clockClass 表示时钟质量等级,数值越小越优先,普通从钟一般配 248,GPS 授时主钟配 6 这类更小的值;priority1 和 priority2 是管理员手动干预的手段,当两个时钟质量相同时,priority1 小的赢,再相同比 priority2。搞不清楚这层关系,最容易出现的问题是你明明把一台设备当主钟配置了,它却因为 clockClass 不够优而退化成从钟。

# /etc/linuxptp/master.conf —— 主钟侧 [global] domainNumber 24 logSyncInterval 0 logAnnounceInterval 1 clockClass 6 clockAccuracy 0x21 priority1 127 priority2 127

domainNumber 是 PTP 域号,不同业务用不同域号可以避免互相干扰。logSyncInterval 是 Sync 报文的发送间隔对数,0 表示每秒一次,想要更高同步率就降到 -1(每秒两次)甚至更低,但会吃掉更多带宽。clockAccuracy 是宣称的时钟精度,配合 clockClass 参与 BMC 选主。主钟侧的配置核心就是让这台设备在 BMC 评比里胜出,如果对端也是同样质量的设备,就用 priority1 强行指定主从。

4.2 最小配置文件与启动命令:主钟和从钟各一条命令

从钟侧配置更简单,核心是把自己声明为 slaveOnly,同时把域号和报文间隔跟主钟对齐。域号不一致是最隐蔽的坑:主钟在域 24 发报文,从钟在默认域 0 里监听,两边日志都正常但就是同步不上,因为从钟根本收不到同域的消息。

# /etc/linuxptp/slave.conf [global] domainNumber 24 logSyncInterval 0 logAnnounceInterval 1 clockClass 248 priority1 128 priority2 128 slaveOnly 1 # 从钟启动 sudo ptp4l -i eth0 -m -l 6 -f /etc/linuxptp/slave.conf

看到日志里出现 “PTP master selected” 或者 “new foreign master” 字样,说明从钟已经认到主钟了。如果日志一直停在 waiting for foreign master,先查域号,再查网卡是否真的在收组播报文。从钟侧还有一个常见错误是漏了 slaveOnly 1,导致它反过来跟主钟抢选主,两个设备反复切换,offset 永远在跳。

4.3 日志里 offset 的读法:从几千纳秒收敛到锁定

ptp4l 的 -m 日志每一条都长这样:ptp4l[1234.567]: master offset -2450 s2 freq +1234 path delay 8521。这里面的 offset 是当前时刻算出来的从钟偏移,单位纳秒,负表示从钟慢了;freq 是伺服器对硬件时钟的频率补偿值,单位 ppb;path delay 是当前测得的平均路径延迟。看一个系统是否同步上,不能只看一眼 offset,要看它的变化趋势。

# 从日志里抓 offset 一列,避免手抄 sudo ptp4l -i eth0 -m -l 6 -f /etc/linuxptp/slave.conf 2>&1 | tee ptp.log # 用 awk 抽 offset 每隔 10 条看一次 awk '/master offset/{offset=$3; if(NR%10==0) print NR, offset}' ptp.log

判定标准我一般卡三条:起步阶段 offset 可以在几千纳秒级别摆动,这是伺服器在拖拽收敛;几十秒后 offset 应该稳定在几百纳秒以内来回震荡;freq 值应该固定在一个小范围内波动,而不是单调往一个方向冲。如果 offset 收敛了但 freq 一直在几百甚至上千 ppb 的位置徘徊,说明主从之间的频率差较大,硬件时钟本身偏了,这时要看 phc2sys 是否在正常工作,或者主钟那头是否接了外部参考源。

5. PTP 授时踩坑排查:5 个让同步翻车的真实问题

5.1 ethtool -T 显示不支持硬件时间戳:从钟全程在走软件路径

现象是 ptp4l 能跑,logSyncInterval 也正常,但 offset 抖动永远在几百微秒量级,再怎么调伺服参数都压不下去。原因大概率是网卡的硬件时间戳能力压根没启用,或者网卡芯片本身不支持。很多服务器板载网卡在驱动里默认不打开 PHC,需要 ethtool 确认。

解决:先查能力再跑协议。

ethtool -T eth0

输出里要看两处:time-stamping 段落是否列出 hardware-transmit 和 hardware-receive,以及 PTP Hardware Clock 段落是否显示一个设备。如果只有 software 相关字段,这卡就吃不了硬件时间戳,要么换网卡,要么死心用软件时间戳接受毫秒级精度。还有个坑是驱动支持但固件没打开,表现为 ethtool -T 显示硬件能力,但 ptp4l 就是拿不到,这时候查网卡驱动参数里有没有 ptp 相关开关,常见于部分多队列网卡驱动默认关闭 PHC。

提示:买网卡或者批量采购服务器时,别只看标称万兆,要确认 PHC 和硬件时间戳能力,这直接决定 PTP 能不能做。

5.2 网络路径不对称:固定偏移 50 微秒查到最后是光纤长度

现象是 offset 收敛得很漂亮,但那是在一个固定偏置附近收敛,比如永远在 +50 微秒附近,而且换个方向测又不一样。原因是公式推导的前提是主从路径延迟对称,一旦光纤收发不是同一根、交换机端口缓存配置不同,路径延迟就是不对称的,这个误差会原封不动变成静态 offset,伺服器无法消除。

解决:先用 ptp4l 日志里的 path delay 值估算不对称量,再用硬件手段核对。最直接的办法是用一根经过测距的光纤,或者用支持 802.1AS 的交换机把延迟修正打开。工程上更省事的替代是把主钟放在距离所有从钟都差不多的拓扑中心,减少路径差异,或者在知道不对称量之后,用 ptp4l 的 配置项里手动补偿静态偏移。

5.3 网卡多队列与节能特性:时间戳乱了套

现象是同步刚跑起来数据很漂亮,一旦业务流量上来,offset 就开始周期性毛刺,毛刺之间还挺规律。原因是网卡的多队列、RSS 会把 PTP 事件报文分散到不同队列处理,或者在报文进队列前被 buffer 和聚合逻辑搅乱,导致硬件时间戳虽然打了点,但那颗点跟实际报文进出时刻对不上。节能特性(比如 ASPM、动态关闭 PHY)更麻烦,它会让时钟在运行中重锁,产生几百纳秒的跳变。

解决:把 PTP 事件报文固定到专用队列,或者从网卡驱动层面关闭可能干扰时间戳的聚合和节能。日志里看到 offset 毛刺跟流量呈正相关时,优先关闭 ethtool 的 coalescing 相关参数,再看驱动是否支持把 PTP 报文 pin 到某个 queue。这个坑排查起来最像玄学,我的血泪经验是别先怀疑代码,先怀疑网卡驱动默认参数。

5.4 主钟切换瞬断:BMC 选钟策略没配好,从钟跳变

现象是网络里有多台号称主钟的设备,某天其中一台维护重启,从钟的 offset 突然跳了几毫秒,然后慢慢爬回来。原因是主钟失效后,从钟要重新跑 BMC 挑选新主钟,在新主钟锁定前,从钟是在没有参考的状态下自由运行的,这段时间的频率误差全部变成相位跳变。

解决:把 network 里所有候选主钟的 clockClass、priority 规划好,保证切换在一两个 Announce 周期内完成,同时从钟的 servo 要配置成 holdover 模式,主钟丢失后在本地保持最后频率而不是回到自由振荡。具体到 ptp4l,可以在配置里加 holdover_timeout 参数,让从钟在失去主钟后不立即大幅调整。切换后的 offset 跳变是正常物理现象,关键是跳变幅度能不能被下游接受,接受不了就得上边界时钟把故障域隔开。

5.5 phc2sys 没配好:/dev/ptp0 准了,系统时间还是飘的

现象是 ptp4l 日志里 offset 已经很漂亮了,但在应用里打 time() 出来跟主钟对不上,甚至每秒都在往一个方向跑。原因是 ptp4l 只校准了网卡的 PHC,也就是 /dev/ptp0,它跟系统实时时钟(CLOCK_REALTIME)之间没有同步关系。phc2sys 没跑、跑错了设备、或者没加基准偏移补偿,都会出现这种“协议层准、系统层飘”的怪象。

解决:确认 phc2sys 的 -s 指向的确实是 ptp4l 在用的网卡,别一个用 eth0 一个用 eth1。如果主钟的 PTP 域跑的是 TAI,而系统时钟是 UTC,必须给 phc2sys 加 -O 参数补偿闰秒差。检查方法是看 phc2sys 日志里 offset,正常应该在正负几百纳秒内,而不是跟着 UTC 差 37 秒。这个坑让人翻车的点在于它不会让 ptp4l 报错,所有同步状态看着都正常,只有到最后输出时间时才发现瞎忙一场。

6. 验证与进阶:用 PPS 对测和长期日志把精度钉在亚微秒

6.1 用 PPS 秒脉冲做外部对测:示波器看相位差

软件日志说得再漂亮,都不如把主钟的 1PPS 和从钟的 1PPS 拉出来对一下。主钟一般能输出秒脉冲,从钟的 ptp_clock 如果驱动实现了辅助 pin 功能,也能把 PHC 的秒脉冲引到板卡接口上。两台设备各引一根线到示波器两个通道,触发在上升沿,直接量两路上升沿的时间差,这个值比任何内部日志都硬。

# 查看 PHC 辅助 pin 功能是否可用,确认设备有没有输出 PPS 的硬件能力 sudo phc_ctl /dev/ptp0 caps sudo phc_ctl /dev/ptp0 get

phc_ctl 的 caps 输出会列出辅助 pin 的数量和功能,get 会读取当前 PHC 时间。示波器上如果两个上升沿的差稳定在小几百纳秒内,说明整条链路是真的通了;如果差的均值和一个固定 offset 重合,回头查路径对称问题。没有示波器的时候,退而求其次用第二个网卡做同样的 PTP 同步,跨网卡比 offset 也能看出个大概,但精度和说服力就差远了。

6.2 长期日志统计:mean、stddev 与 max 的判定阈值

看同步质量不能只看一分钟,要跑至少 24 小时的长期日志,统计 offset 的均值、标准差和最大值。均值反映静态偏置,标准差反映抖动,最大值反映最坏情况。我用 awk 直接从 ptp4l 日志里抽 offset 并计算这三项,比肉眼翻日志可靠得多。

awk '/master offset/{offset=$3; sum+=offset; sumsq+=offset*offset; if(offset>max) max=offset; n++} END{printf "mean: %.1f ns, stddev: %.1f ns, max: %d ns\n", sum/n, sqrt(sumsq/n-(sum/n)^2), max}' ptp.log

这个统计有个细节要看清楚:max 取的是绝对值还是原始值。同一台设备正向跳和负向跳往往不对称,我一般两个都算。判定标准看场景:单纯以太网链路的硬件同步,长期 stddev 在几十纳秒、max 不超过几百纳秒属于正常;如果 stddev 过千,多半是 5.3 那种网卡配置问题还没清干净。

6.3 伺服参数调整:收敛速度与抖动之间的取舍

ptp4l 默认的 PI 伺服器参数通常够用,但碰到特殊场景还是要手动碰。pi_proportional_const 和 pi_integral_const 归零时,伺服器会按协议栈内置的默认尺度算,适合大多数网卡。如果你发现从钟开机后要几分钟才锁定,可以把比例常数调大一点让收敛更快;如果锁定后 offset 高频抖得厉害,则适当减小积分常数,避免伺服器对噪声过度反应。

我自己的习惯是:先用默认参数跑 24 小时拿到一组统计数,确认基线没问题之后再动伺服参数。改参数一次只改一个,每改一次重新统计对比,不要同时动两个变量,否则出了问题根本分不清是谁引起的。IEEE 1588 这套东西,代码层面的坑其实有限,真正花时间的全是物理链路和网卡行为,遇到说不清的现象先记日志、再改一个变量、最后动手拆链路,顺序别反。这是我从几次半夜抓不到问题的经历里学到的教训,希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 20:44:22

Claude Code Tips:用 TaoToken 统一 Key 打通 settings.json 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/28 20:44:16

高通ARM64 ramdump解析:crash工具隐藏参数与KASLR偏移实战

把高通平台的ramdump.bin直接丢给crash工具,回车,然后看着它吐出一堆crash: read error或者WARNING: cannot access vmallocd address——这个场景,过去两年里我在8155、8295、8550这几个大平台上遇到过不下十次。网上很多教程把crash解析ram…

作者头像 李华
网站建设 2026/9/28 20:42:49

基于Android的乡村研学旅行APP的设计与实现

摘 要 随着人们生活水平的提升,教育观念逐渐转变,研学旅行作为寓教于乐的新兴教育方式,愈发受到欢迎。乡村地区拥有独特的自然资源与深厚的文化底蕴,是开展研学旅行的理想场所。然而,乡村研学旅行信息分散&#xff0c…

作者头像 李华
网站建设 2026/9/28 20:42:39

渐变/阴影/滤镜⾼阶⽤法:统⼀项⽬UI、精简冗余组件

一、前言在鸿蒙 ArkUI 项目开发里,很多页面视觉效果,开发者第一反应都是靠多层组件嵌套叠加实现。想要渐变背景就外层套容器 内层色块;卡片阴影单独写一层透明占位组件;图片柔光、暗角效果,直接用多张图片叠加或者引入…

作者头像 李华
网站建设 2026/9/28 20:37:36

redis缓存问题

1.缓存穿透定义:缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到数据库解决方案:缓存空对象:优点: 实现简单,维护方便缺点: 额外的内存消耗;可能造成短期的不一致布隆过滤器:优点 :内存占用较少,没有多余key缺点 : 实现复杂;存…

作者头像 李华