php的cache
opcache
opcode级别的缓存,缓存的是zend引擎编译后的代码。PHP是动态脚本语言,执行的时候需要先由zend引擎编译成opcode执行。好处就是任何时候修改php代码,都能马上看到结果。然而实际项目中并不会随时随地地修改程序代码,也就是说很长一段时间里服务器运行的php代码都是一样的,如果没有启用opcache,那么这些代码每次执行都需要重新编译成opcode。理论上代码不发布更新,就可以缓存opcache一直不过期。
apcu
fastcgi进程级别的缓存,缓存指定的用户数据,同一个fastcgi进程内的各个独立请求可以共享。本质上跟Redis,Memcached提供一样的基于键值的缓存服务,但是其直接存在于fastcgi进程的内存中,速度远远超过基于tcp访问的redis这种应用层服务。然而正是由于这一点,导致它的作用范围只存在于fastcgi内存中,无法跨进程,甚至跨机器共享。
redis、memcache
应用级别的缓存,缓存用户数据。通过网络访问,可在集群间共享。
cache策略
- 结合以上各种缓存,应用多级缓存机制
- 合理设置缓存过期策略
cache问题
cache穿透
请求了无效的key,无论是缓存还是数据库都没有找不到有效数据。如果不做处理,那么每次无效key的请求都会访问缓存再访问数据库,同时发起大量无效key的访问可瘫痪服务器。
- 无效的key较少,可以设置缓存为空值(此处联想空对象模式)
- 无效的key比较多,采用布隆过滤器
cache击穿
高并发场景下缓存key刚好到期失效了,导致这些请求同时并发访问数据库。
- 部分数据不需要设置失效时间
- 互斥锁,只允许单个请求访问数据库,其余并发请求持续等待直到缓存重新生效。
cache雪崩
多个key同时到期失效。一般情况下应用初始化时会生成大量不同的缓存,这些缓存可能具有相同的过期时间。因此可能在某一时刻会出现大量缓存同时失效,导致整个服务器雪崩。
- 给缓存设置一个随机过期时间,错开失效时间。
- 软件层面对访问流量进行监控,设置熔断机制。
- 硬件层面增加缓存服务器,数据库服务的容灾能力。