elcweb/memcached-bundle

此包已被放弃,不再维护。未建议替代包。

Memcache Doctrine 缓存和会话存储在 Web Debug Toolbar 中

安装: 677

依赖者: 0

建议者: 0

安全: 0

星标: 0

关注者: 2

分支: 56

类型:symfony-bundle

v2.1.5 2015-12-15 12:47 UTC

README

Latest Stable Version Total Downloads Build Status

screenshot

如果您想优化您的Web应用程序以应对高负载和/或低加载时间,Memcache是一个不可或缺的工具。它将在Web服务器或数据库服务器上管理会话数据,而无需进行磁盘I/O操作。您还可以将其作为网站的中心对象存储运行。在这个角色中,它用于通过Doctrine缓存支持缓存数据库查询或通过实现Memcache的“get”和“set”命令来缓存昂贵的API调用。

此Symfony2包将为Symfony2和Doctrine提供Memcache集成,用于会话存储和缓存。它具有完整的Web Debug Toolbar集成,允许您分析和调试缓存行为和性能。

阅读LeaseWebLabs关于LswMemcacheBundle的博客

要求

  • PHP 5.3.10 或更高版本
  • php-memcached 1.0.2, 2.0.1 或 2.1.0(这是使用“libmemcached”的PHP“memcached”扩展)

注意:php-memcached 2.2.x会在运行时发出警告,应避免使用!

注意:与PHP“memcache”扩展不同,PHP“memcached”扩展尚未包含在PHP Windows二进制文件中。

安装

要使用Composer安装LswMemcacheBundle,只需将以下内容添加到您的'composer.json'文件中

{
    require: {
        "leaseweb/memcache-bundle": "*",
        ...
    }
}

接下来,您应该执行以下命令来安装包

php composer.phar update leaseweb/memcache-bundle

最后,将包添加到'app/AppKernel.php'文件中AppKernel类的registerBundles函数

public function registerBundles()
{
    $bundles = array(
        ...
        new Lsw\MemcacheBundle\LswMemcacheBundle(),
        ...
    );

通过添加以下内容来配置包

lsw_memcache:
    session:
        client: default
    clients:
        default:
            hosts:
              - { dsn: localhost, port: 11211 }

安装以下依赖项(在基于Debian的系统中使用'apt')

apt-get install memcached php5-memcached

不要忘记在添加Memcache模块后重启您的Web服务器。现在,Memcache信息应该在您的调试工具栏中显示一个小双箭头(快进)图标。

使用

当您想从控制器中调用缓存时,您可以直接调用

$this->get('memcache.default')->set('someKey', 'someValue', $timeToLive);
$this->get('memcache.default')->get('someKey');

上面的示例展示了如何将值'someValue'存储在键'someKey'下,最长存活时间为$ timeToLive秒。在第二行中,从Memcache检索值。如果找不到键或已过了指定的秒数,'get'函数将返回值'false'。

配置

以下是可以看到此包的完整配置。

lsw_memcache:
    clients:
        default:
            persistent_id: default  # Do NOT use this, see known issues
            hosts:
                - { dsn: 10.0.0.1, port: 11211, weight: 15 }
                - { dsn: 10.0.0.2, port: 11211, weight: 30 }
            options:
                compression: true
                serializer: json
                prefix_key: ""
                hash: default
                distribution: consistent
                libketama_compatible: true
                buffer_writes: true
                binary_protocol: true
                no_block: true
                tcp_nodelay: false
                socket_send_size: 4096
                socket_recv_size: 4096
                connect_timeout: 1000
                retry_timeout: 0
                send_timeout: 0
                recv_timeout: 0
                poll_timeout: 1000
                cache_lookups: false
                server_failure_limit: 0
        sessions:
            hosts:
                - { dsn: localhost, port: 11212 }

会话支持

此包还提供了将会话数据存储在Memcache服务器上的支持。要启用会话支持,您必须通过session键启用它。请注意,会话支持的唯一必需子键是client(一个有效的客户端)。您还可以指定一个键前缀和TTL。

lsw_memcache:
    session:
        client: sessions
        prefix: "session_"
        ttl: 7200
        locking: true
        spin_lock_wait: 150000
    # clients

请注意,默认情况下启用了会话锁定,默认的自旋锁定设置为每150毫秒(150000微秒)轮询。

Doctrine支持

此包还提供了对Memcache服务器上Doctrine缓存的支持。要启用Doctrine缓存,您必须通过doctrine键来启用它。请注意,您可以指定所有三种Doctrine缓存类型:'metadata'、'result'和'query'。这些子键中所需的关键字是client(有效的客户端)和entity_manager(通常是:默认)。您还可以指定一个前缀。

lsw_memcache:
    doctrine:
        metadata_cache:
            client: default
            entity_manager: default          # the name of your entity_manager connection
            document_manager: default        # the name of your document_manager connection
        result_cache:
            client: default
            entity_manager: [default, read]  # you may specify multiple entity_managers
            prefix: "result_"                # you may specify a prefix for the entries
        query_cache:
            client: default
            entity_manager: default
    # clients

ADP:防狗群

让我们考察一个高流量网站案例,看看Memcache的表现。

您的缓存存储时间为90分钟。计算缓存值大约需要3秒钟,从缓存中读取缓存值需要1毫秒。您每秒大约有5000个请求,并且值被缓存。您每秒得到5000个请求,读取缓存值大约需要5000毫秒。您可能认为这是不可能的,因为5000 > 1000,但这取决于您的Web服务器上的工作进程数量。假设有大约100个工作进程(在高负载下),每个工作进程有75个线程。您的Web请求大约需要20毫秒。每当缓存失效(90分钟后),在3秒钟内,将有15000个请求得到缓存失效。所有得到失效的线程将开始计算缓存值(因为它们不知道其他线程正在做同样的工作)。这意味着在(几乎)3秒钟内,服务器不会回答任何请求,但请求仍在不断进来。由于每个工作进程有75个线程(持有100 x 75个连接),因此必须增加工作进程的数量才能处理这些请求。

大量分叉将导致额外的CPU使用,并且每个工作进程将使用额外的RAM。这种意外的RAM和CPU增加被称为“狗群”效应或“奔马群”,在Web服务的峰值时段非常不受欢迎。

有一个解决方案:在计算新值的同时提供旧缓存条目,并通过使用原子的读写操作,我们可以确保在内容失效时只有一个线程会收到缓存失效。该算法在LswMemcacheBundle的AntiDogPileMemcache类中实现。它提供了getAdp()和setAdp()函数,可以用作正常get和set的替代。

请注意

  • 如果您的访问量很低或者计算新值相对较快,则可能不需要ADP。
  • 如果可以将大计算分解成更小的部分,甚至为每个部分指定不同的超时时间,则可能不需要ADP。
  • ADP可能会得到比指定的失效时间更早的数据。特别是当线程/工作进程在“get”请求中得到“false”但未能“set”随后计算的新值时。
  • ADP的“getAdp”和ADP的“setAdp”比正常的“get”和“set”更昂贵,会减慢所有缓存命中。
  • ADP不能保证狗群不会发生。重启Memcache、清除数据或RAM不足也会导致键被移除,您仍然会遇到这个问题。

注意事项

LswMemcacheBundle使用的是'memcached' PHP扩展(客户端),而不是较旧的'memcache' PHP扩展。有关可用客户端的比较,请参阅:http://code.google.com/p/memcached/wiki/PHPClientComparison

已知问题

在页面渲染后执行调用memcache设置操作的会话写入。在页面渲染完成之前执行memcache数据收集器的收集调用,因此也在会话写入之前执行。这导致会话写入不会显示在Web调试工具栏中。

已知在某些系统上启用持久连接(设置“persistent_id”)会导致php5崩溃(核心转储)。请谨慎使用:强烈建议在配置中省略“persistent_id”。

致谢

Doctrine支持基于SncRedisBundle实现

https://github.com/snc/SncRedisBundle 由Henrik Westphal提供

  • DependencyInjection/LswMemcacheExtension.php
  • DependencyInjection/Configuration.php
  • DependencyInjection/Compiler/EnableSessionSupport.php

基于以下实现

https://github.com/Emagister/MemcachedBundle 由Christian Soronellas提供

  • Command/StatisticsCommand.php

基于以下实现

https://github.com/beryllium/CacheBundle 由Kevin Boyd提供

许可证

此包采用MIT许可证。

Web调试工具栏中的“快进”图标是Picas图标集的一部分(官方网站:http://www.picasicons.com)。该图标已获许可,并且只能用于在Symfony2 Web调试工具栏中标识LswMemcacheBundle。所有图标的所有权和版权均归Rok Benedik所有。