Nic*_*ick 12 php caching symfony doctrine-orm
在具有中央ElastiCache(redis)集群的多个AWS EC2实例上运行分布式SF3.3应用程序.
每个EC2实例还运行一个本地Redis实例,该实例用于Doctrine元和查询缓存.
该应用程序使用Doctrines二级缓存,从功能的角度来看,它非常有效.但是AWS上的性能很差(900-1200ms页面加载),因为它在我们的许多页面上所需的Country和VatRate实体中加载了400多个缓存调用.
由于这些Country和VatRate实体很少更改,我想通过使用二级缓存中定义的不同区域来利用本地Redis实例和ElastiCache进行结果缓存.这应该可以减少400+缓存调用的延迟问题,因为在单个框页面上运行时,加载次数为100毫秒.阅读文档这一切似乎都是可能的,只是不完全确定如何使用Symfony和PHP-Cache进行配置.
应用程序/配置/ config.yml
doctrine:
dbal:
# .. params
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
auto_mapping: true
second_level_cache:
enabled: true
region_cache_driver:
type: service
id: doctrine.orm.default_result_cache
cache_adapter:
providers:
meta: # Used for version specific
factory: 'cache.factory.redis'
options:
host: 'localhost'
port: '%redis_local.port%'
pool_namespace: "meta_%hash%"
result: # Used for result data
factory: 'cache.factory.redis'
options:
host: '%redis_result.host%'
port: '%redis_result.port%'
pool_namespace: result
cache:
doctrine:
enabled: true
use_tagging: true
metadata:
service_id: 'cache.provider.meta'
entity_managers: [ default ]
query:
service_id: 'cache.provider.meta'
entity_managers: [ default ]
result:
service_id: 'cache.provider.result'
entity_managers: [ default ]
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ Country.php
/**
* @ORM\Table(name = "countries")
* @ORM\Cache(usage = "READ_ONLY")
*/
class Country
{
// ...
/**
* @var VatRate
*
* @ORM\OneToMany(targetEntity = "VatRate", mappedBy = "country")
* @ORM\Cache("NONSTRICT_READ_WRITE")
*/
private $vatRates;
// ...
}
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ VatRate.php
/**
* @ORM\Table(name = "vatRates")
* @ORM\Cache(usage = "READ_ONLY")
*/
class VatRate
{
// ...
/**
* @var Country
*
* @ORM\ManyToOne(targetEntity = "Country", inversedBy = "vatRates")
* @ORM\JoinColumn(name = "countryId", referencedColumnName = "countryId")
*/
private $country;
// ...
}
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ Order.php
/**
* @ORM\Table(name = "orders")
* @ORM\Cache(usage = "NONSTRICT_READ_WRITE")
*/
class Order
{
// ...
/**
* @var Country
*
* @ORM\ManyToOne(targetEntity = "Country")
* @ORM\JoinColumn(name = "countryId", referencedColumnName = "countryId")
*/
private $country;
// ...
}
Run Code Online (Sandbox Code Playgroud)
应用程序/配置/ config.yml
doctrine:
dbal:
# .. params
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
auto_mapping: true
second_level_cache:
enabled: true
region_cache_driver: array
regions:
local:
type: service
service: "doctrine.orm.default_result_cache" # TODO: needs to be local redis
remote:
type: service
service: "doctrine.orm.default_result_cache" # TODO: needs to be remote redis
cache_adapter:
providers:
meta: # Used for version specific
factory: 'cache.factory.redis'
options:
host: 'localhost'
port: '%redis_local.port%'
pool_namespace: "meta_%hash%"
result: # Used for result data
factory: 'cache.factory.redis'
options:
host: '%redis_result.host%'
port: '%redis_result.port%'
pool_namespace: result
cache:
doctrine:
enabled: true
use_tagging: true
metadata:
service_id: 'cache.provider.meta'
entity_managers: [ default ]
query:
service_id: 'cache.provider.meta'
entity_managers: [ default ]
result:
service_id: 'cache.provider.result'
entity_managers: [ default ]
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ Country.php
/**
* @ORM\Table(name = "countries")
* @ORM\Cache(usage = "READ_ONLY", region = "local")
*/
class Country
{
// as above
}
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ VatRate.php
/**
* @ORM\Table(name = "vatRates")
* @ORM\Cache(usage = "READ_ONLY", region = "local")
*/
class VatRate
{
// as above
}
Run Code Online (Sandbox Code Playgroud)
SRC /的appbundle /实体/ Order.php
/**
* @ORM\Table(name = "orders")
* @ORM\Cache(usage = "NONSTRICT_READ_WRITE", region = "remote")
*/
class Order
{
// as above
}
Run Code Online (Sandbox Code Playgroud)
结果如何
Type error: Argument 1 passed to Doctrine\ORM\Cache\DefaultCacheFactory::setRegion() must be an instance of Doctrine\ORM\Cache\Region, instance of Cache\Bridge\Doctrine\DoctrineCacheBridge given,
Run Code Online (Sandbox Code Playgroud)
也不太清楚哪里何去何从,已经从测试工作在这里:https://github.com/doctrine/DoctrineBundle/blob/74b408d0b6b06b9758a4d29116d42f5bfd83daf0/Tests/DependencyInjection/Fixtures/config/yml/orm_second_level_cache.yml但缺乏文档配置这使它更具挑战性!
ori*_*nal -1
您收到的错误消息完全反映了问题的根源。当需要接口实例时,您正在传递DoctrineCacheBridge实例( 的底层类doctrine.orm.default_result_cache)Doctrine\ORM\Cache\Region:
second_level_cache:
#...
regions:
local:
type: service
service: "region_service_not_cache_service" # Here is a Region instance expected
remote:
type: service
service: "region_service_not_cache_service" #Here is a Region instance expected
Run Code Online (Sandbox Code Playgroud)
在之前的配置中,doctrine.orm.default_result_cache缓存服务通过设置设置为默认缓存region_cache_driver。\Doctrine\ORM\Cache\DefaultCacheFactory生成DefaultRegionon Flight 的实例(因为没有预先配置)并向它们提供默认缓存。
后一种配置预计具有预先配置的区域,并且可以通过多种方式进行修复。我建议下一个:
dbal:
# .. params
orm:
#...
second_level_cache:
#...
regions:
local:
type: default
cache_driver:
type: service
id: "doctrine.orm.default_query_cache" # NOTE that this is the service id of your local cache generated by PHP-Cache Bundle
remote:
type: default
cache_driver:
type: service
id: "doctrine.orm.default_result_cache" # NOTE that this is the service id of your remote cache generated by PHP-Cache Bundle
Run Code Online (Sandbox Code Playgroud)
在这里,您告诉 Doctrine 在和键下创建 2 个DefaultRegion区域,并将和相应地传递给它们。localremotelocal_cacheremote_cache
最好返回region_cache_driver到以前的值,否则DefaultRegion飞行中生成的 s 将使用array缓存:
second_level_cache:
enabled: true
region_cache_driver:
type: service
id: doctrine.orm.default_result_cache
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1229 次 |
| 最近记录: |