tqdev / memcache-bundle
Memcache Doctrine 缓存和会话存储在 Web 调试工具栏中
Requires
- php: >=5.3.2
- ext-memcache: >=3.0
- symfony/framework-bundle: >=2.1
Requires (Dev)
- phpunit/phpunit: ~4.0
This package is auto-updated.
Last update: 2024-09-05 18:36:19 UTC
README
TqdMemcacheBundle
如果您想优化您的Web应用以应对高负载和/或低加载时间,Memcache是一个不可或缺的工具。它将管理您的会话数据,而无需在Web服务器或数据库服务器上进行磁盘I/O。您还可以将其运行为您网站的中央对象存储。在这个角色中,它用于通过Doctrine缓存支持缓存数据库查询或通过实现Memcache的“get”和“set”命令来缓存昂贵的API调用。
此Symfony包将为Symfony和Doctrine提供Memcache集成,用于会话存储和缓存。它具有完整的Web调试工具栏集成,允许您分析和调试缓存行为和性能。
阅读TQdev.com博客中的TqdMemcacheBundle文章
要求
- PHP 5.3.10或更高版本(支持PHP 7)
- php-memcache 3.0.6或更高版本
- memcached 1.4或更高版本
安装
要使用Composer安装TqdMemcacheBundle,请运行以下命令
php composer.phar require tqdev/memcache-bundle
最后,将包添加到'app/AppKernel.php'文件中的AppKernel类的registerBundles函数中
public function registerBundles()
{
$bundles = array(
...
new Tqd\MemcacheBundle\TqdMemcacheBundle(),
...
);
通过添加以下内容来配置包'app/config/config.yml'
tqd_memcache: session: pool: default pools: default: servers: - { host: localhost, tcp_port: 11211 }
安装以下依赖项(在基于Ubuntu的系统上使用'apt-get')
apt-get install memcached php-memcache
注意:在PHP5中,此最后一个包称为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'。
配置
以下是一个此包的示例配置。
tqd_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(有效的pool)。您还可以指定key prefix
和ttl
。
tqd_memcache: session: pool: sessions auto_load: true prefix: "session_" ttl: 7200 locking: true spin_lock_wait: 150000 # pools
请注意,会话锁定默认启用,默认的自旋锁定设置为每150毫秒(150000微秒)轮询一次。
Doctrine支持
此包还提供在Memcache服务器上对Doctrine缓存的支撑。要启用Doctrine缓存,您将不得不通过doctrine键启用它。请注意,您可以指定所有三种Doctrine缓存类型:'metadata'、'result'和'query'。这些子键中的必需键是both pool
(有效的pool)和entity_manager
(通常是默认值)。您还可以指定一个prefix
。
tqd_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
(有效的pool)。您还可以指定一个key prefix
和concurrency
(默认为10)。如果您使用一个或多个反向代理,则在reverse_proxies
键中指定它们。
tqd_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增加被称为“狗堆”效应或“ stampeding herd”或“thundering herd”,在Web服务的峰值时段是非常不受欢迎的。
有一个解决方案:我们在计算新值的同时提供旧的缓存条目,并通过使用原子的读写操作,我们可以确保当内容失效时,只有一个线程会收到缓存未命中的通知。该算法在TqdMemcacheBundle中的AntiDogPileMemcache类中实现。它提供了getAdp()、setAdp()和deleteAdp()函数,这些函数可以用作正常get、set和delete的替代。
请注意
- 如果您有少量的点击量或者计算新值相对较快,可能不需要ADP。
- 如果您可以将大计算拆分成更小的部分,甚至为每个部分设置不同的超时时间,可能不需要ADP。
- ADP可能会给您比指定的失效更老的数据。特别是当一个线程/工作者在“get”请求中得到“false”,但在之后未能“set”新计算出的值时。
- ADP的“getAdp”、“setAdp”和“deleteAdp”比正常的“get”、“set”和“delete”更昂贵,这会减慢所有缓存命中。
- ADP不能保证不会发生狗堆效应。重启Memcache、清除数据或RAM不足也会导致键被清除,您仍然会遇到这个问题。
已知问题
触发memcache set操作的会话写入在页面渲染后执行。memcache数据收集器的collect调用在页面渲染完成之前执行,因此也先于会话写入执行。这导致会话写入不会显示在Web调试工具栏中。
鸣谢
Doctrine支持基于SncRedisBundle的实现
https://github.com/snc/SncRedisBundle 由Henrik Westphal提供
- DependencyInjection/TqdMemcacheExtension.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许可。