首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Zend Framework 1 集成 Memcached 缓存:Bootstrap 资源插件化、Registry 全局访问、标签式失效策略

     編輯:PHP 相關知識

架构设计

  • 资源插件化:_initMemcached() 在 Bootstrap 中创建 Zend_Cache 实例,注入 Zend_Registry 全局访问。
  • 双后端支持:Core 前端 + Memcached 后端,配置生命周期、压缩、序列化。
  • 标签清理:利用 Zend_Cache 标签机制实现分组失效(如 clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, ['user_list']))。

Bootstrap.php 集成代码

<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    protected function _initMemcached()
    {
        $frontendOptions = [
            'lifetime' => 1800,              // 30 分钟默认 TTL
            'automatic_serialization' => true, // 自动 serialize/unserialize
            'automatic_cleaning_factor' => 10, // 10% 概率触发清理
            'write_control' => true,         // 校验写入
        ];

        $backendOptions = [
            'servers' => [
                ['host' => '127.0.0.1', 'port' => 11211, 'weight' => 100],
                // 多台从库可添加 weight 实现负载均衡
            ],
            'compression' => false,          // Memcached 自带压缩,关闭避免双重
            'compatibility' => false,        // 关闭兼容模式,启用二进制协议
        ];

        // 创建缓存实例
        $cache = Zend_Cache::factory('Core', 'Memcached', $frontendOptions, $backendOptions);

        // 注册到全局注册表
        Zend_Registry::set('cache', $cache);

        // 可选:设置默认标签前缀
        $cache->setOption('cache_id_prefix', 'myapp_');

        return $cache;
    }
}

Controller/Service 中使用

<?php
class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $cache = Zend_Registry::get('cache');

        // 场景 1:友情链接列表,标签 'link_list'
        if (!$links = $cache->load('link_list')) {
            $model = new Application_Model_Link();
            $links = $model->fetchAll(['status' => 1], 'sort ASC');
            $cache->save($links, 'link_list', ['link_list']); // 绑定标签
        }
        $this->view->links = $links;

        // 场景 2:用户信息,键 'user_1001',标签 'user_1001'
        $userId = 1001;
        $cacheKey = "user_{$userId}";
        if (!$user = $cache->load($cacheKey)) {
            $user = (new Application_Model_User())->find($userId);
            $cache->save($user, $cacheKey, ["user_{$userId}"]);
        }
        $this->view->user = $user;
    }

    // 后台更新链接后,清理标签
    public function adminUpdateLinkAction()
    {
        // ... 更新逻辑 ...
        $cache = Zend_Registry::get('cache');
        $cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, ['link_list']);
        $this->_helper->json(['status' => 'ok']);
    }
}

进阶:缓存键命名规范与防穿透

<?php
class CacheKey
{
    // 统一格式:模块:实体:动作:标识
    public static function user(int $id): string { return "user:info:$id"; }
    public static function userList(array $filters): string {
        ksort($filters);
        return 'user:list:' . md5(http_build_query($filters));
    }
    public static function article(int $id): string { return "article:detail:$id"; }
}

// 使用
$key = CacheKey::user(1001);
if (!$user = $cache->load($key)) {
    // 防缓存穿透:设置空值占位,短 TTL
    $cache->save(null, $key, [], 60); // 60 秒空值缓存
    $user = $model->find(1001);
    if ($user) $cache->save($user, $key, ['user_1001'], 1800);
}

监控与运维

指标获取方式告警阈值
命中率stats get_hits / (get_hits + get_misses)< 80%
内存使用率stats bytes / limit_maxbytes> 85%
驱逐数stats evictions持续增长
连接数stats curr_connections> 80% maxconns
# 监控脚本片段
$mem = new Memcached();
$mem->addServer('127.0.0.1', 11211);
$stats = $mem->getStats();
$hitRate = $stats['get_hits'] / ($stats['get_hits'] + $stats['get_misses']);

常见问题排查

现象原因解决
save/load 返回 falseMemcached 服务未启动/防火墙/主机名解析失败telnet 11211 测试连通性,检查 /etc/hosts
数据不一致(主从不同步)多台 Memcached 无复制机制仅作缓存层,接受短暂不一致;关键数据落 Redis/DB
大 Value 存储失败超过 1MB 限制(默认)调大 -I 启动参数,或拆分/压缩
PHP 扩展版本不匹配pecl/memcached vs pecl/memcache 混淆统一用 Memcached (libmemcached),php -m | grep memcached 验证

从 ZF1 迁移到 Laminas/现代框架的等价实现

<?php
// Laminas / Mezzio / Symfony 等现代框架:ServiceManager 工厂
use Laminas\Cache\StorageFactory;
use Laminas\Cache\Storage\Adapter\Memcached;
use Laminas\Cache\Storage\Plugin\Serializer;

$cache = StorageFactory::factory([
    'adapter' => [
        'name' => Memcached::class,
        'options' => [
            'servers' => [['127.0.0.1', 11211]],
            'liboptions' => [
                Memcached::OPT_BINARY_PROTOCOL => true,
                Memcached::OPT_COMPRESSION => false,
            ],
        ],
    ],
    'plugins' => [
        'serializer' => Serializer::class,
    ],
]);

// 容器注册
$container->setService('cache', $cache);
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved