aequasi / memcached-bundle
Memcached Bundle
Requires
- php: >=5.3.0
- ext-memcached: *
- doctrine/common: >=2.1.0
- doctrine/dbal: >=2.1.0
- symfony/symfony: >=2.1.0
README
此套餐已弃用
今后,请使用 php-cache
库
如果您坚持...
Symfony 2 的 Memcached Bundle
在 Symfony 2 中创建一个服务,该服务也可以与 doctrines 的 result_cache_driver
和 query_cache_driver
一起使用。
还有将键映射存储在 mysql 中的功能。基本上,它存储键、值的长度、生存时间和何时过期。
应在所有版本的 symfony 和 php 5.3 上正常工作
需要 php5-memcached 扩展(也可以与亚马逊的 elasticache 扩展一起使用)
要求
- PHP 5.3.x 或 5.4.x
- php5-memcached 1.x 或 2.x(这是使用 "libmemcached" 的 PHP "memcached" 扩展)
- (也可以与亚马逊的 elasticache 扩展一起使用)
安装
composer.phar require aequasi/memcached-bundle dev-master // Replace dev master with what ever version you want
将套餐添加到 app/AppKernerl.php
$bundles( ... new Aequasi\Bundle\MemcachedBundle\AequasiMemcachedBundle(), ... );
然后添加您的服务器和选项的参数(可能在 config.yml 中)
aequasi_memcached: clusters: default: prefix: 'result_' # Optional persistent_id: cluser_1 hosts: - { host: localhost, port: 11211, weight: 100 } options: compression: true libketama_compatible: true connect_timeout: 50 recv_timeout: 500000 send_timeout: 500000 poll_timeout: 50 retry_timeout: 5 no_block: true server_failure_limit: 7 tcp_no_delay: true keyMap: enabled: %memcached.keymap.enabled% connection: default
还有您可以在上面指定的选项。您可以通过运行以下命令获取选项列表:
php app/console config:dump aequasi_memcached
Doctrine
此套餐允许您使用其服务进行 Doctrine 的元数据、结果和查询的缓存方法。
如果您希望 doctrine 使用此作为结果和查询缓存,请添加以下内容:
aequasi_memcached: doctrine: metadata: cluster: default entity_manager: default # the name of your entity_manager connection document_manager: default # the name of your document_manager connection result: cluster: default entity_manager: [default, read] # you may specify multiple entity_managers query: cluster: default entity_manager: default
会话
此套餐甚至允许您将您的会话数据存储在您的 memcache 集群之一中。要启用...
aequasi_memcached: session: cluster: default prefix: "session_" ttl: 7200
防止踩踏
来自 Lws\MemcacheBundle
让我们分析一个高流量网站案例,看看 Memcache 的行为
您的缓存存储时间为 90 分钟。计算缓存值大约需要 3 秒,从缓存读取缓存值大约需要 1 毫秒。您每秒大约有 5000 个请求,并且值被缓存。您每秒获取大约 5000 个请求,读取缓存值大约需要 5000 毫秒。您可能会认为这是不可能的,因为 5000 > 1000,但这取决于您的 Web 服务器上的工作进程数量。假设大约有 100 个工作进程(在高负载下)每个有 75 个线程。您的 Web 请求每个大约需要 20 毫秒。每当缓存失效(90 分钟后),在 3 秒内,将有 15,000 个请求获得缓存失效。所有获得失效的线程将开始计算缓存值(因为它们不知道其他线程正在做同样的事情)。这意味着在(几乎)3 秒内,服务器将无法响应用户请求,但请求仍在继续。由于每个工作进程有 75 个线程(保持 100 x 75 个连接),因此需要增加工作进程的数量才能处理它们。
大量分支会导致额外的 CPU 使用,并且每个工作进程都会使用额外的 RAM。这种意外的 RAM 和 CPU 增加被称为“狗群效应”或“踩踏”,在 Web 服务的峰值时段非常不受欢迎。
有一个解决方案:在计算新值的同时提供服务旧缓存条目,并通过使用原子读写操作,我们可以确保在内容失效时只有一个线程会收到缓存失效。该算法在 LswMemcacheBundle 中的 AntiDogPileMemcache 类中实现。它提供了 getAdp() 和 setAdp() 函数,可以用作正常 get 和 set 的替代。
请注意
如果您的访问量较低或计算新值相对较快,可能不需要防踩踏功能。如果可以将大计算分解为较小的部分,甚至为每个部分设置不同的超时,则可能不需要防踩踏功能。防踩踏可能会获取比指定的无效化数据更早的数据。特别是在线程/工作进程对“获取”请求返回“false”,但在之后未能“设置”新计算值的情况下。防踩踏的“getAdp”和“setAdp”比正常的“get”和“set”更昂贵,从而降低了所有缓存命中的速度。防踩踏不能保证不会发生狗堆效应。重启Memcache、清除数据或RAM不足也会导致键被清除,您仍然会遇到问题。
使用方法
您可以使用默认的memcached函数、doctrine的useResultCache
和useQueryCache
,或者使用cache
函数。以下是一个示例
use Aequasi\Bundle\MemcachedBundle\Cache\AntiStampedeMemcached as Cache; /** @var $em \Doctrine\ORM\EntityManager */ $data = $this->get( 'memcached.default' )->cache( 'somekey', function( ) use( $em, $color ) { $repo = $em->getRepository( 'AcmeDemoBundle:Fruit' ); return $repo->findBy( array( 'color' => $color ) ); }, Cache::THIRTY_MINUTE );
这将尝试获取somekey
。如果找不到,它将运行闭包,并将结果缓存30分钟,作为somekey
。您可以使用闭包、可调用对象,甚至只是可扩展的类型。
还有三个命令(可能以后还会添加更多),用于获取、设置和删除缓存中的项。
php app/console memcached:get cluster key php app/console memcached:set cluster key value [lifetime=60] php app/console memcached:delete cluster key php app/console memcached:clear [cluster] # If cluster is specified, might not clear all the keys for the cluster. Uses https://php.ac.cn/manual/en/memcached.getallkeys.php php app/console memcached:statistics cluster php app/console memcached:initialize:keymap cluster (required if using the keymap)
需要帮助?
如果发现错误,请创建一个问题
或发送电子邮件至aequasi@gmail.com