• 《深入探究 php-apcu 实现原理》-- 第一回:apcu的简介、优缺点及使用场景


    在业务开发的某些场景中使用了apcu进行整体的性能优化,也取得了不错的效果,所以前两年就一直想写写相关的主题

    市面上写redis的文章或者书籍铺天盖地,但是去谈apcu的却没有多少,有一些也是科普性的如何安装和使用,所以老赵这里总结一下自己所得,做个分享。

    我这篇文章的主要结构大概是这样的:

    1.apcu在缓存中地位及使用场景,与redis、mysql或者其他的一些nosql数据库如何搭配使用

    2.apcu的源代码在哪里,主要涉及哪些技术点

     1.APCU是什么?在什么样的场景使用?

    官方对于apc的解释如下,可选的php缓存技术。apc包含两个方面,一方面对于本身代码级别的缓存,另一方面是提供给编码者使用的类似于redis的set、get这样的接口。在php 某个版本之后,apcu所提供的用户缓存部分被保存下来了

    The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. Its goal is to provide a free, open, and robust framework for caching and optimizing PHP intermediate code

    apcu扩展使用的方法是这样的:

    <?php
    $bar = 'BAR';
    apcu_add('foo', $bar);
    var_dump(apcu_fetch('foo'));
    echo "
    ";
    $bar = 'NEVER GETS SET';
    apcu_add('foo', $bar);
    var_dump(apcu_fetch('foo'));
    echo "
    ";
    ?>

    大体上来说,使用的api侧与memcahe、redis或者其他的基于磁盘的nosql使用的方式似乎没什么差别,我画了一个典型的web架构的示意图,来标识出来他们各自之间的区别

    一般现在的架构模式下,负载均衡机器、服务集群、redis集群、mysql集群式相互独立运维的,也就是我所画出来的clusterA、clusterB、clusterC、clusterD,按照现在比较流行微服务划分(我对微服务的概念不是很熟),服务间使用网络协议调用

    apcu是基于共享内存技术建设的,多个cgi之间访问apcu中的cache可以完全等同于访问自己进程的一块内存一样,不需要发任何的网络请求。

    而不管是redis、mysql或者其他的独立服务的cache都需要发网络请求,即使存储和服务部署在同一机器上也仍然需要采用本地sock进行网络请求,何况在虚拟化的趋势下,这些存储服务一定是独立运行的。

    按照计算机存储器层次结构的理论,访问内存的速度大概在纳秒级别 ,网络请求的速度在毫秒级别,同机架或者同机房的机器可能在1/10ms左右,还不考虑服务稳定性的情况下。

    简单的进行存取测试,速度至少在千倍以上提升,但是apc在实际的使用中还是存在一定的局限性:

    1. 以扩展的方式接入,跟php这门语言有很强的耦合,而redis作为独立服务存在,使用协议接入
    2. apcu受限于单机内存的限制,扩展受阻,而目前的redis集群模式已经可以做到动态扩容,理论上无容量风险
    3. apcu数据存于单机内存,多机器之间的数据无法共享,这是他使用场景有限的最大阻碍

    所以,我再使用场景中一般用apcu来缓存数据量小、但是读取量大或者瞬间读取量大的场景。

    比如:

    1.你是一个开放平台,你需要对客户请求做鉴权,这个token过来的请求可以访问哪些path请求。这个场景下,用户的token及可访问的path信息持久化在mysql中,变更频次小,数据量小,但是可能每秒有10W次请求

    这个场景就比较适合apc,相比于直接请求mysql/redis的架构,可以给服务省掉10w - N 次/s的网络消耗,N为容器数目

    2.抢购的场景下,假设量比较大,那么可以使用apc来做s级别的缓存元信息,以防止对于存储服务的瞬间链接量过大,导致失败的情况。

    几个关键字:数据大小小、读取量大、配置信息、无状态

    而有状态的信息你还是选择mysql/redis,所以这么来看,他的场景的确是有限。但是在有限场景也能发挥他的价值,作为php多进程之间通信的一种方式,也顺利帮我优化了几万/s的mysql、redis请求。


    对于现在的web服务端编程而言,单个api请求带来的io转化次数是影响服务性能、稳定性的最大的因素(前提是没有慢sql),我曾经见到一个api平均转化了80次mysql,如果请求突增,加机器都很难解决
    统一rpc请求的日志,做好access_cps / rpc_cps 指标监控及上线前的准入还是非常重要的,当然两份日志求交也可以天级别分析出哪些api可能需要优化了

    2.APCU源码及涉及的技术点?

    作者深知我们这些phper扑在了创造互联网价值创造的一线,基础相对薄弱,面对C代码可能一头雾水,特地写了一篇英文的Readme,详细的介绍了实现所用到的技术及原理,多贴心

    apcu源码的git地址在: https://github.com/krakjoe/apcu

    实现说明文档在源码目录中的 TECHNOTES.txt文件下,当然看懂这系列文章的背后,你是需要补充一下内存方向的一些基本知识的:

    1. php  SAPI是什么?MINIT、RINIT阶段做了什么?及扩展开发需要做的一些事情
    2. 关于进程中内存的布局、共享内存技术、虚拟内存与物理内存、内存管理与分配

    介绍先到这里,暂时给自己立个flag,后面的连载节奏是:

    1. php生命周期及扩展相关知识,具体结合apcu在每个阶段做了什么,为后续的技术点展开做好知识预告
    2. 从内存共享,引出mmap、shm等技术点,从而再复习一下进程中内存的布局、虚拟内存与mmap等的关系
    3. 进程间可以共享内存了,如何分配内存? 引 出molloc、free等基于堆的内存分配的实现及与apcu的内存分配器
    4. 内存分配之后,上层的数据结构如何构建能够做到基于key的数据检索?过期键如何实现

    如果想和我我交流技术方向的心得及感受,可以扫码关注我的公众号,上面我绑定了微信号。
  • 相关阅读:
    ADF_Tutorials系列17_ADF Faces_使用布局组件
    ADF_Tutorials系列17_ADF Faces_开发下拉和删除
    ADF_Tutorials系列17_ADF Faces_ADF预定义组件的创建和使用
    ADF_ADF Faces系列6_ADF数据可视化组件简介之建立Thematic Map Component
    ADF_ADF Faces系列5_ADF数据可视化组件简介之建立GeographicMap/Pivot Table/Gantt Chart
    ADF_ADF Faces系列4_ADF数据可视化组件简介之建立BarChart/Gauge/ExportExcel
    ADF_ADF Faces系列3_ADF数据可视化组件简介之建立Master-Detail
    ADF_ADF Faces系列2_使用JSF开发基于Ajax的用户界面:ADF Faces富客户端组件简介(Part2)
    ADF_ADF Faces系列1_使用JSF开发基于Ajax的用户界面:ADF Faces 富客户端组件简介(Part1)
    Form_Form Builder国际化多语言开发(案例)
  • 原文地址:https://www.cnblogs.com/zhaoyixing/p/12635269.html
Copyright © 2020-2023  润新知