2011-07-27 52 views
4

我的Zend應用程序使用3個ini配置文件,總共需要解析200多行,包含100多條指令。這些文件是否每個請求都被解析?有人說他們是(如herehere)。如果是這樣,這不是一個效率問題嗎?Zend Config Ini緩存

這些鏈接中的註釋有不同的看法 - 有人說你應該避免使用ini配置文件並在PHP中進行配置,有人說你可以使用Zend_Cache_Frontend_File,有人說這不是問題。但是,如果您預計會有相當多的流量,那麼爲每個請求分析200行文本肯定會很快成爲問題。

如果您確實推薦使用緩存技術,請您準確解釋您將如何實現它?

回答

10

是的,他們每次都被解析,除非你緩存它們。這確實節省了時間(我在自己的項目中檢查過)。

那麼你如何使用Zend_Cache_Frontend_File緩存一個ini文件呢?那麼我可以爲你提供一個例子。在項目中,我有一個包含了許多定製路線route.ini文件:

routes.ini

routes.showacc.route = "/@show/:city/:id/:type" 
routes.showacc.type = "Zend_Controller_Router_Route" 
routes.showacc.defaults.module = default 
routes.showacc.defaults.controller = accommodation 
routes.showacc.defaults.action = show 
routes.showacc.defaults.city = 
routes.showacc.defaults.type = 
routes.showacc.defaults.id = 
routes.showacc.defaults.title = 
routes.showacc.reqs.id = "\d+" 

;and more 

在我bootstrap.php中我使用高速緩存(如果可能的話)加載它們:

protected function _initMyRoutes() { 
    $this->bootstrap('frontcontroller'); 
    $front = Zend_Controller_Front::getInstance(); 
    $router = $front->getRouter(); 

    // get cache for config files 
    $cacheManager = $this->bootstrap('cachemanager')->getResource('cachemanager'); 
    $cache = $cacheManager->getCache('configFiles'); 
    $cacheId = 'routesini'; 

    // $t1 = microtime(true); 
    $myRoutes = $cache->load($cacheId); 

    if (!$myRoutes) { 
     // not in cache or route.ini was modified. 
     $myRoutes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/routes.ini'); 
     $cache->save($myRoutes, $cacheId); 
    } 
    // $t2 = microtime(true); 
    // echo ($t2-$t1); // just to check what is time for cache vs no-cache scenerio 

    $router->addConfig($myRoutes, 'routes'); 
} 

緩存是建立在我的的application.ini如下

resources.cachemanager.configFiles.frontend.name = File 
resources.cachemanager.configFiles.frontend.customFrontendNaming = false 
resources.cachemanager.configFiles.frontend.options.lifetime = false 
resources.cachemanager.configFiles.frontend.options.automatic_serialization = true 
resources.cachemanager.configFiles.frontend.options.master_files[] = APPLICATION_PATH "/configs/routes.ini"  
resources.cachemanager.configFiles.backend.name = File 
resources.cachemanager.configFiles.backend.customBackendNaming = false 
resources.cachemanager.configFiles.backend.options.cache_dir = APPLICATION_PATH "/../cache" 
resources.cachemanager.configFiles.frontendBackendAutoload = false 

希望這會有所幫助。

+1

馬辛,您的文章幫了我,現在我已經用它更好的性能。但是怎麼樣,而不是試圖加載緩存對象: $ cache = $ cacheManager-> getCache('configFiles'); ($ cacheManager-> hasCache($ routeCache)){ $ cache = $ cacheManager-> getCache($ routeCache);如果它首先存在,則執行額外檢查: if // ... } –

+0

爲我工作。謝謝。 –

4

如果你加載一個像ZF這樣的框架,你可以加載數十個包含數千行代碼的文件。必須爲每個用戶和請求讀取文件。服務器端你有一些磁盤控制器的緩存,不需要每次都從磁盤實際讀取文件。同樣,操作系統中的內存管理器也會跟蹤內存併爲內存提供一些緩存,所以不必每次都將內存讀取到內存中 - 僅限於此。接下來你通常會有一個數據庫,或多或少發生同樣的事情,因爲數據庫最終存儲在硬盤上的文件中。數據庫服務器或多或少地讀取文件和相同的故事。

那麼,我會擔心配置文件中的幾行?當然不是因爲我需要我的應用程序的數據才能工作。它來自哪裏是次要的。

關於使用Zend_Cache進行緩存。如果您的數據非常緊湊,並且不需要像Zend_Config中的文件那樣進行大量處理,您將可以節省很少的微秒。您基本上是將緊湊格式存儲爲另一種緊湊格式;序列化的字符串必須再次解除序列化。如果您可以緩存數據以避免數據庫訪問或渲染整個視圖,包括所有模型支持的數據請求,那麼我們正在討論完全不同的故事。

+1

一般來說,這個答案是正確的,你不想微觀優化。但是,Zend在幕後進行了大量的操作。在最近的分析中,我做了一箇舊版本的框架(1.11.4),Zend_Config類有一些糟糕的表現。有使用中的自定義數組遞歸函數,在加載/解析配置文件時被稱爲數千次,導致數百毫秒的加載時間。在這種情況下緩存配置對象絕對是值得的。 – zombat

+0

@zombat夠了。你提到的遞歸我認爲是對於不同部分的合併/級聯,坦率地說,我不會主張在生產系統的生產部分之外和生產部分之外需要許多信息。我想這是從ZF2中刪除它的主要原因。 –

2

如果您認爲PHP文件被緩存在內存中,而解析後的ini文件也在內存中,您可以在跳過Zend_Config_Ini類和解析過程的情況下將ini文件轉換爲php文件。

# public/index.php 
$cachedConfigFile = APPLICATION_PATH.'/../cache/application.ini.'.APPLICATION_ENV.'.php'; 

if(!file_exists($cachedConfigFile) || filemtime($cachedConfigFile) < filemtime(APPLICATION_PATH . '/configs/application.ini')) 
{ 
    require_once 'Zend/Config/Ini.php'; 
    $config = new Zend_Config_Ini(APPLICATION_PATH . '/configs/application.ini', APPLICATION_ENV); 
    file_put_contents($cachedConfigFile, '<?php '.PHP_EOL.'return '.var_export($config->toArray(),true).';'); 
} 

$application = new Zend_Application(
    APPLICATION_ENV, 
    $cachedConfigFile // originally was APPLICATION_PATH . '/configs/application.ini' 
); 

$application->bootstrap() 
     ->run(); 

我測試過ab。非緩存配置:

ab -n 100 -c 100 -t 10 http://localhost/ 
Requests per second: 45.57 [#/sec] (mean) 
Time per request:  2194.574 [ms] (mean) 
Time per request:  21.946 [ms] (mean, across all concurrent requests) 
Transfer rate:   3374.08 [Kbytes/sec] received 

VS緩存配置:

Requests per second: 55.24 [#/sec] (mean) 
time per request:  1810.245 [ms] (mean) 
Time per request:  18.102 [ms] (mean, across all concurrent requests) 
Transfer rate:   4036.00 [Kbytes/sec] received 

即高出18%的性能。

0

按照我們的朋友,誰創建的文件:

https://github.com/QualityCase/Mini-Case/blob/master/modules/admin/Bootstrap.php

我發現這非常有用:

protected function _initConfig() 
{ 
    if(!$config = $this->_cache->load('config')) { 

     $config = new Zend_Config_Ini(BASE_PATH . '/configs/application.ini'); 
     $config = $config->toArray(); 

     $this->_cache->save($config, 'config'); 
    } 

    Zend_Registry::set('config', $config); 
}