leaseweb/memcache-bundle

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

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

安装数: 922 219

依赖者: 6

建议者: 6

安全: 0

星标: 203

关注者: 25

分支: 56

开放问题: 29

类型:symfony-bundle

v2.1.12 2017-05-05 09:50 UTC

README

此存储库不再被积极维护。我们鼓励您不要使用此代码。如果您依赖此代码,您可能希望创建存储库的分支,以防止您的系统在未来出现问题。

Build Status Average time to resolve an issue Percentage of issues still open Total Downloads

LswMemcacheBundle

screenshot

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

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

阅读关于LswMemcacheBundle的LeaseWebLabs博客

需求

  • PHP 5.3.10或更高版本
  • php-memcache 3.0.6或更高版本
  • memcached 1.4或更高版本

注意:此包不再使用使用"libmemcached"的PHP "memcached"扩展,请参阅"注意事项"。

PHP7支持目前(实验性)可通过编译和安装:[https://github.com/websupport-sk/pecl-memcache/tree/php7](https://github.com/websupport-sk/pecl-memcache/tree/php7)

安装

要使用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(),
        ...
    );

通过在'app/config/config.yml'中添加以下内容来配置包

lsw_memcache:
    session:
        pool: default
    pools:
        default:
            servers:
              - { host: localhost, tcp_port: 11211 }

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

apt-get install memcached php5-memcache

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

使用

当您想从控制器中使用缓存时,您可以简单地调用

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

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

配置

以下是一个此包的配置示例。

lsw_memcache:
    pools:
        default:
            servers:
                - { host: 10.0.0.1, tcp_port: 11211, weight: 15 }
                - { host: 10.0.0.2, tcp_port: 11211, weight: 30 }
            options:
		        allow_failover: true
		        max_failover_attempts: 20
		        default_port: 11211
		        chunk_size: 32768
		        protocol: ascii
		        hash_strategy: consistent
		        hash_function: crc32
		        redundancy: true
		        session_redundancy: 2
		        compress_threshold: 20000
		        lock_timeout: 15
        sessions:
            servers:
                - { host: localhost, tcp_port: 11212 }

会话支持

此包还提供在Memcache服务器上存储会话数据的功能。要启用会话支持,您需要通过session键启用它(默认情况下auto_load为true)。请注意,会话支持的唯一必需子键是pool(一个有效的池)。您还可以指定一个键prefix和一个ttl

lsw_memcache:
    session:
        pool: sessions
        auto_load: true
        prefix: "session_"
        ttl: 7200
        locking: true
        spin_lock_wait: 150000
    # pools

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

负载均衡器后运行的应用程序会话管理

当您的应用程序在多个服务器上运行时,您必须意识到,您的所有实例都应该与1个缓存服务器进行通信以保持一致性;否则,每个实例都会有自己的会话,这会产生意外的结果。

为了防止上述问题,您必须添加LockingSessionHandler服务。通过这样做,您的所有实例都将使用会话处理程序,会话处理程序将数据存储在配置的Memcache服务器上。

my.memcache.service:
    class: Memcache
    calls:
        - [addServer, ['your_memcache_address', 'your_memcache_port']] 

my.memcached.session.handler:
    class: Lsw\MemcacheBundle\Session\Storage\LockingSessionHandler
   arguments:
       - "@my.memcache.service"
       - prefix: 'your_prefix'
       - expiretime: 'your_expire_time'

Doctrine支持

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

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

防火墙支持

此包还提供了一种防火墙,它可以限制每个IP地址的并发请求数量。它维护每个IP地址的运行请求数量,并在必要时延迟(节流)请求。要启用防火墙支持,您必须通过firewall键启用它。请注意,防火墙支持的唯一必需子键是pool(一个有效的池)。您还可以指定一个键prefix和一个concurrency(默认为10)。如果您使用一个或多个反向代理,则在reverse_proxies键中指定它们。

lsw_memcache:
    firewall:
        pool: firewall
        prefix: "firewall_"
        concurrency: 10
        reverse_proxies: [10.0.0.1]
    # pools

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增加被称为“狗群效应”或“猛冲 herd”或“雷鸣 herd”,在高峰时段的Web服务中非常不受欢迎。

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

请注意

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

考虑事项

LswMemcacheBundle使用的是'memcache' PHP扩展(memcached客户端),而不是基于libmemcache的'memcached' PHP扩展。

此捆绑包的1.0主要版本使用了其他扩展。在捆绑包的2.0主要版本中,由于它的完整功能和良好的设计及支持,选择了PECL "memcache"(不带'd')的3.0.8完整版本。

已知问题

触发memcache set操作的会话写入是在页面渲染之后执行的。memcache数据收集器的collect调用是在页面渲染完成之前执行的,因此也在会话写入之前执行。这导致会话写入不会出现在Web调试工具栏中。

致谢

Doctrine支持基于SncRedisBundle中的实现

https://github.com/snc/SncRedisBundle by Henrik Westphal

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

是基于以下实现的

https://github.com/Emagister/MemcachedBundle by Christian Soronellas

  • Command/StatisticsCommand.php

是基于以下实现的

https://github.com/beryllium/CacheBundle by Kevin Boyd

许可

此捆绑包受MIT许可。