webgrin
V2EX  ›  PHP

如何实现维持一个在 PHP 程序运行期间一直存在的常量数组?

  •  
  •   webgrin · Nov 14, 2018 · 6647 views
    This topic created in 2914 days ago, the information mentioned may be changed or developed.
    出于减少数据库查询优化程序性能的考虑,打算把一个程序运行期间高频使用的数据集保存到一个常量多维数组里面,即需要访问此数据集不再查询数据库,直接访问此数组即可,此数组在多个不同 php 程序文件里面都需要使用。

    由于这个数组里面的数据随着网站运行,会增加新数据,故无法硬编码到 php 程序文件里面。

    我初步想法是把数据更新的时候,自动将此数组写入一个 JSON 文件存储到网站本地目录下面,然后在每个 php 文件开头读取此文件然后解析后生成数组供后续函数使用。我的粗浅理解是查询数据库的性能会低于直接读取一个本地文件,不知道是否正确?

    水平比较渣,感觉此方法不精致。请教高手,有什么更高效的实现思路?
    45 replies  •  2018-11-19 17:19:47 +08:00
    jessynt
    jessynt
    Nov 14, 2018 via iPhone❤️1
    1
    yac?
    eggshell
    eggshell
    Nov 14, 2018
    2
    “打算把一个程序运行期间高频使用的数据集保存到一个常量多维数组” , redis 不符合要求吗?
    webgrin
    webgrin
    OP
    Nov 14, 2018
    3
    @eggshell 惭愧,只会简单编程,暂时只考虑不借助外在工具,完全使用 php 实现。谢谢回复,有时间再学下 redis
    zjsxwc
    zjsxwc
    Nov 14, 2018 via Android
    4
    文件缓存,实现方式千变万化
    0ZXYDDu796nVCFxq
    0ZXYDDu796nVCFxq
    Nov 14, 2018 via Android
    5
    是什么让你产生读数据库比读文件快的错觉……

    另外,文件需要更新,你怎么保证线程安全的同时性能不明显下降?每更新一次需要写入整个数组
    随便一个数据库都比你这个方案强
    dobelee
    dobelee
    Nov 14, 2018 via Android
    6
    php 常驻进程。这种情况 redis 最简单。
    Lax
    Lax
    Nov 14, 2018
    7
    正确的写个文件缓存系统,可真不如直接用成熟的方案,除非是条件不允许。
    zjsxwc
    zjsxwc
    Nov 14, 2018 via Android
    8
    搜索了下,除了$_SESSION 变量,php 居然有个神奇的变量应该可以满足楼主需求 $_ENV['foobar']
    zjsxwc
    zjsxwc
    Nov 14, 2018 via Android
    9
    $_ENV 改 linux 全局环境变量来共享数据
    chinvo
    chinvo
    Nov 14, 2018 via iPhone
    10
    PHP-FPM/Apache Mod 正常情况下执行是一次访问一个实例的,执行完即销毁,除了 session env 之外就只能用 文件 /memcached/redis 等了
    visonme
    visonme
    Nov 14, 2018❤️1
    11
    不依赖第三方,比较常用的应该就是文件方式存储(数据存储结构以那种方式优,自己评估),全局共享内存,SESSION,当然如果可以还是最推荐通过 redis 来存储
    webgrin
    webgrin
    OP
    Nov 14, 2018
    12
    @visonme 谢谢回复了解决思路,现在只是想用最简单的方法实现,所以才想出了这个笨办法。
    webgrin
    webgrin
    OP
    Nov 14, 2018
    13
    @zjsxwc 使用全局变量好像不解决问题,全局变量也无法跨文件使用。如果所有文件都引用一个共同的文件,就又回到了起点,相当于每个文件都需要查询一次数据库然后再转换数据得到目标数组。
    loginv2
    loginv2
    Nov 14, 2018 via Android
    14
    php 可以用共享内存的,和读写文件一样的操作
    loginv2
    loginv2
    Nov 14, 2018 via Android
    15
    其他语言也可以读写
    webgrin
    webgrin
    OP
    Nov 14, 2018
    16
    @loginv2 共享内存有待进一步学习。谢谢回复。
    Event
    Event
    Nov 14, 2018
    17
    redis/memcached
    0xff0x77
    0xff0x77
    Nov 14, 2018❤️1
    18
    楼主想法很好,但是你考虑过 IO 性能吗?

    没有什么方案可选的,其实楼主就是在纠结这么几点。
    1、文件缓存
    2、redis 缓存
    3、shm 缓存
    4、数据库读取

    到底用哪个?

    这四个中,shm 最快,其他都差不多,数据库最慢。
    但是 shm 和文件不支持分布式

    shm 可以使用余庆大佬的 https://github.com/happyfish100/libshmcache
    也可以考虑鸟哥之前的 APCU,当然两者有区别,本质上性能比 redis 和数据库等需要 io 操作的东西快 100 倍
    xiaoz
    xiaoz
    Nov 14, 2018 via Android
    19
    redis 进行缓存比较符合要求,而且效率很高。
    ywisax
    ywisax
    Nov 14, 2018
    20
    直接存放 redis 比较好
    Actrace
    Actrace
    Nov 14, 2018
    21
    一般 /tmp 似乎是挂内存的,直接在 /tmp 读写文件共享数据就好了,如果要求保持一致性的话,写的时候记得加个锁。
    akira
    akira
    Nov 14, 2018
    22
    这就是典型的内存缓存的作用啊,memcache 和 redis 都可以满足你的需求
    t6attack
    t6attack
    Nov 15, 2018
    23
    用文件当缓存,有个最简单方式,很多人使用过 ramdisk 类软件,弄出的内存虚拟盘,接近内存的读写效率。
    而 centos 下,/dev/shm 目录就是系统自带的 ramdisk。把文件存在这里,就是内存的读写效率,重启后自动消失。
    rebill
    rebill
    Nov 15, 2018
    24
    APCu 了解一下。`apcu_fetch` `apcu_store` 应该就能满足你的需求了。
    msg7086
    msg7086
    Nov 15, 2018❤️2
    25
    "只会简单编程,暂时只考虑不借助外在工具,完全使用 php 实现"

    有点意思,放着简单好用的外部工具不用,自己去用 PHP 实现?

    "打算弄辆车。只会做简单的手工,所以暂时只考虑不买车,完全手工制作一辆车出来"

    我只能说,加油吧兄弟,希望你早日用 PHP 写一个 Redis 的雏形出来。
    chinvo
    chinvo
    Nov 15, 2018 via iPhone
    26
    @Actrace #21 tmp 不是内存,只是每次开机都会清理罢了,shm 才是内存
    lihongming
    lihongming
    Nov 15, 2018 via iPhone
    27
    为什么都推荐 redis 而不是 memcache ?
    Canon1014
    Canon1014
    Nov 15, 2018
    28
    楼主意思应该是不想用其他技术 只靠简单 php 语法实现这个功能.
    sagaxu
    sagaxu
    Nov 15, 2018 via Android
    29
    swoole 了解一下
    encro
    encro
    Nov 15, 2018
    30
    if file_exist("config.php")
    $config = file_get_contents("config.php");
    else
    file_put_contents ("config.php",var_export($config));

    假如你的 php 安装了 opcache 扩展的话,那么性能是非常高的
    用 redis 是正确的选择
    encro
    encro
    Nov 15, 2018
    31
    另外 eacc,apcu,opcache 都有对象缓存了解下。
    encro
    encro
    Nov 15, 2018
    32
    假如你存文件,JSON 的性能可能还不如 mysql 的 memcache 表
    xavier007
    xavier007
    Nov 15, 2018
    33
    采用缓存,缓存加上过期时间,过期了重新查询更新缓存;
    或者刚数据更新时触发更新缓存,前提数据更新不频繁
    markgor
    markgor
    Nov 15, 2018
    34
    数据量不大的情况下,直接利用 serialize\unserialize 存进个文件就可以啦
    数据量大就考虑下 redis
    freewind
    freewind
    Nov 15, 2018
    35
    将数组生成一个 php 文件 file_put_contents ("config.php", "<?php $config =数组字符串; ?>");
    修改的重新生成一下

    其他文件 include
    ferock
    ferock
    Nov 15, 2018
    36
    提了那么多建议,看到的还是楼主想用文件。
    est
    est
    Nov 15, 2018
    37
    一个 redis 可能不够。用 rrrrreeeeeddddddiiiiiiissssssss 就够了。
    gouchaoer2
    gouchaoer2
    Nov 15, 2018
    38
    用 apcu 方案最好
    NEETLEE
    NEETLEE
    Nov 15, 2018
    39
    写文件!
    duzhenlin
    duzhenlin
    Nov 15, 2018
    40
    写入文件,当量上来的是你会发现文件读取的 io 就跟不上了。可以考虑内存型缓存方式
    webgrin
    webgrin
    OP
    Nov 15, 2018
    41
    @Canon1014 是这个意思,运用其他的知识都需要一个学习的过程。
    ysw
    ysw
    Nov 16, 2018
    42
    单例模式
    qsbaq
    qsbaq
    Nov 16, 2018
    43
    你需要 redis 或者 memcache
    flyingghost
    flyingghost
    Nov 16, 2018❤️1
    44
    方案各位大佬提了很多了。我只提醒一个事情:
    自己暂时不会 -> 学习成本高->时间久 千万不要推导出 ->复杂方案不用。
    自己熟悉的技术 -> 无学习成本 -> 千万不要推导出 -> 这就是简单方案。

    这两件事,不等同。
    哪怕是再简单的系统,用 PHP 实现文件缓存、共享内存等思路为啥大家都不用?
    那是因为千万人都认为 redis/memcache 才是真·简单啊。
    webgrin
    webgrin
    OP
    Nov 19, 2018
    45
    @flyingghost 逻辑明确。谢谢。目前不想采用需要进一步学习的方案主要是希望尽快做出一个“最小可用品”上线,后续会在技术方案上做进一步优化。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1701 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 10:30 · PVG 18:30 · LAX 02:30 · JFK 05:30
    ♥ Do have faith in what you're doing.