Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Smarty 3 and Memcache
Goto page 1, 2  Next
 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
bzvarik
Smarty n00b


Joined: 01 Mar 2011
Posts: 4

PostPosted: Tue Mar 01, 2011 9:21 pm    Post subject: Smarty 3 and Memcache Reply with quote

Anyone out there have successfully implemented memcache with Smarty 3?

To use memcached or any custom caching solution, I have to specify something like:
Code:

$smarty->caching_type = 'memcache';


Rather than
Code:

$smarty->cache_handler_func = 'memcache_cache_handler'; 

as it was with smarty 2

Than, under plugins there has to be custom class which handles it.

What I have found is class cacheresource.memcache.php:
http://code.google.com/p/smarty-php/source/browse/branches/rodneyrehm/distribution/demo/plugins/cacheresource.memcache.php?spec=svn4015&r=4015

Which actually expects class smarty_cacheresource_keyvaluestore.php:
http://code.google.com/p/smarty-php/source/browse/branches/rodneyrehm/distribution/libs/sysplugins/smarty_cacheresource_keyvaluestore.php?r=3964

And that one is expecting class smarty_cacheresource.php:
http://code.google.com/p/smarty-php/source/browse/branches/rodneyrehm/distribution/libs/sysplugins/smarty_cacheresource.php?r=3960

I have placed cacheresource.memcache.php under plugins.
smarty_cacheresource_keyvaluestore.php and smarty_cacheresource.php are located under sysplugins (I assume that what I suppose to do , plus I correctly included second class in a first one, and third one in a second one).

Now I'm getting PHP Fatal error: Class Smarty_CacheResource_Memcache contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Smarty_CacheResource::getCachedContents) /libs/plugins/cacheresource.memcache.php on line 6


Am I missing something or is there a bug in a classes above? Don't really want to rewrote them so that's why I'm asking... Or how do you guys use memcache with smarty 3? With Smarty 2 I just had to write my own
memcache_cache_handler function and it was working just fine...

Thanks for help!

Brano
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Tue Mar 01, 2011 10:02 pm    Post subject: Re: Smarty 3 and Memcache Reply with quote

bzvarik wrote:
Anyone out there have successfully implemented memcache with Smarty 3?


Yes. in fact I've implemented a generic interface for key/values stores (such as memcache, APC, …). The solution will be released as part of Smarty 3.1. So you're getting a memcache compatible interface from smarty itself. merry christmas… Smile

bzvarik wrote:
What I have found is class cacheresource.memcache.php:
http://code.google.com/p/smarty-php/source/browse/branches/rodneyrehm/distribution/demo/plugins/cacheresource.memcache.php?spec=svn4015&r=4015


Ok, I see you've found it already…

bzvarik wrote:
Now I'm getting PHP Fatal error: Class Smarty_CacheResource_Memcache contains 1 abstract method and must therefore be declared abstract or implement the remaining methods


Looks to me like you should get the latest revisions of those classes. We've changed the API (again and again) since I wrote them originally…
Back to top
View user's profile Send private message Visit poster's website
bzvarik
Smarty n00b


Joined: 01 Mar 2011
Posts: 4

PostPosted: Wed Mar 02, 2011 12:04 am    Post subject: Reply with quote

Thanks, i overlooked that there are newer revisions of these sysplugin classes.
So now I have :

smarty_cacheresource.php - rev 4024
smarty_cacheresource_keyvaluestore.php - rev 4011
cacheresource.memcache.php - rev 4015

I believe that these are the most recent versions.

Smarty itself - we are using Smarty 3.0.6 (3.0.7 is most recent stable version now). Should I get Smarty 3.0.7 as well?

Now it seems to be almost working, BUT cacheresource.memcache.php is missing these methods (maybe more, not sure yet)
getCachedTimestamp
getCachedContents

Any idea where I can get complete up-to-date class with these methods a well?

Regarding Smarty 3.1 - will it have implemented also memcache caching itself (kind of out of the box sollution) or what exactly will be available?
Also, do you know when Smarty 3.1 will be released?

And thanks again for your help!
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Wed Mar 02, 2011 1:01 am    Post subject: Reply with quote

bzvarik wrote:
Now it seems to be almost working, BUT cacheresource.memcache.php is missing these methods (maybe more, not sure yet)
getCachedTimestamp
getCachedContents

Any idea where I can get complete up-to-date class with these methods a well?


yeah, these methods have been dropped. As I said, the API changed again. Which is exactly why we didn't propagate the branch. Check back some revisions on smarty_cacheresource_keyvaluestore.php. Somewhere those methods should pop up.

bzvarik wrote:
Regarding Smarty 3.1 - will it have implemented also memcache caching itself (kind of out of the box sollution) or what exactly will be available?


yes and no. all the fancy business will be provided by the core. The actual memcache access is something everyone should implement themselves. Some use Memcache, others Memcached, others can't use a PECL at all, … But you'd get there in minutes by looking at the provided examples.

[quote="bzvarik"]Also, do you know when Smarty 3.1 will be released?

no. we're getting closer, though.
Back to top
View user's profile Send private message Visit poster's website
bzvarik
Smarty n00b


Joined: 01 Mar 2011
Posts: 4

PostPosted: Wed May 04, 2011 8:36 pm    Post subject: Reply with quote

Hi,

Two months past – do you guys already know something new about release date of Smarty 3.1 which would make memcache caching easier?

Also, I have been able to utilize memcache, everything seems to be working fine now, except getCachedContents.

Here is Smarty_Internal_CacheResource_File::getCachedContents and it works fine with file-based caching:

Code:

    public function getCachedContents($_template, $no_render = false)
    {
       if (!$no_render) {
           ob_start();
       }
        $_smarty_tpl = $_template;
        include $_template->getCachedFilepath();
        if ($no_render) {
           return null;
        } else {
          return ob_get_clean();
        }
    }


Mine ''memcache' version of the function which looks pretty much same, except I’m getting data from memcache rather then including file from a filesystem:
Code:

    public function getCachedContents($_template, $no_render = false)
    {
        if (!$no_render) {
            ob_start();
        }
       
        $content= $memcache->get( $this->$this->getCacheId($_template));       
        echo $content;
       
        if ($no_render) {
            return null;
        } else {
          return ob_get_clean();
        }
    }




I’m getting content without any problem, but probably because of the buffering, I’m getting at the very top of the template also PHP code like this (just an example):

Code:
<?php /*%%SmartyHeaderCode:5844581574dc1af22021fa4-12208418%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_smarty_tpl->decodeProperties(array (
  'file_dependency' =>
  array (
    '4a6ffbb0594876d710d847f8952e956660bcd955' =>
    array (
      0 => 'store:store_index.tpl',
      1 => 1304538660,
      2 => 'store',
    ),
  ),
  'nocache_hash' => '5844581574dc1af22021fa4-12208418',
  'has_nocache_code' => true,
  'cache_lifetime' => '60',
)); /*/%%SmartyHeaderCode%%*/?>
<?php if (!$no_render) {?>


How should I be outputting content from memcache to make sure buffering will be working fine and this PHP code will not be included on the top of every cached version of the template output? I assume it has something to do with ob_start().

Code:

include $_template->getCachedFilepath();

outputs content immediately, but

Code:

$content= $memcache->get( $this->$this->getCacheId($_template));

just assigns it to variable which has to be outputted later somehow. Not sure if echoing it is the best thing to do.

Thanks for help!
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Wed May 04, 2011 8:50 pm    Post subject: Reply with quote

bzvarik wrote:
Two months past – do you guys already know something new about release date of Smarty 3.1 which would make memcache caching easier?


without making any promises: looks like this month. at least we're packing it up…

Code:

        $content= $memcache->get( $this->$this->getCacheId($_template));       
        echo $content;


should be

Code:

        $content= $memcache->get( $this->$this->getCacheId($_template));       
        eval($content);
Back to top
View user's profile Send private message Visit poster's website
bzvarik
Smarty n00b


Joined: 01 Mar 2011
Posts: 4

PostPosted: Wed May 04, 2011 11:12 pm    Post subject: Reply with quote

Hm, doesn't really work. Content of $content is actually combination of PHP and HTML.
So it is something like

Code:

<?php /*%%SmartyHeaderCode:5844581574dc1af22021fa4-12208418%%*/if(!defined('SMARTY_DIR')) exit('no direct access allowed');
$_smarty_tpl->decodeProperties(array (
  'file_dependency' =>
  array (
    '4a6ffbb0594876d710d847f8952e956660bcd955' =>
    array (
      0 => 'store:store_index.tpl',
      1 => 1304538660,
      2 => 'store',
    ),
  ),
  'nocache_hash' => '5844581574dc1af22021fa4-12208418',
  'has_nocache_code' => true,
  'cache_lifetime' => '60',
)); /*/%%SmartyHeaderCode%%*/?>
<?php if (!$no_render) {?>
<html>
<head>
</head>
<body>
<div>some content here</div>
</body>
</html>


Thing is that eval will evaluate string what is passed to function as a PHP code.
eg this works fine:
Code:

$content = "echo 'test';";
eval($content);


But this will cause error:

Code:

$content = "<?php echo 'test';?><html>some html here</html>";
eval($content);


Thanks for helping me with this!
Back to top
View user's profile Send private message
rippergun
Smarty n00b


Joined: 06 May 2011
Posts: 2

PostPosted: Fri May 06, 2011 7:59 am    Post subject: Working solution Reply with quote

Hi, we currently use this solution. It's working fine. However performance are bad with the "eval".

Code:

/**
     * Returns the cached template output
     *
     * @param object $_template current template
     * @return string |booelan the template content or false if the file does not exist
     */
    public function getCachedContents($_template, $no_render = false)
    {
       if (!$no_render) {
           ob_start();
       }

       $_smarty_tpl = $_template;
      eval("?>" . $this->memcache->get($_template->getCachedFilepath()));

      if ($no_render) {
           return null;
        } else {
          return ob_get_clean();
        }
       return false;
    }


Note the eval("?>" .

You should close the PHP tag before evaluating the code.

FYI : we trying to find another solution without the eval()
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Fri May 06, 2011 8:03 am    Post subject: Re: Working solution Reply with quote

rippergun wrote:
FYI : we trying to find another solution without the eval()


evaluating the cached template is necessary if you're dealing with dynamic (non-caching) sections/functions. Since such a non-caching element can behave whatever way it likes, there is no real way around eval().
Back to top
View user's profile Send private message Visit poster's website
emt
Smarty Regular


Joined: 10 Dec 2009
Posts: 43

PostPosted: Wed May 25, 2011 10:07 am    Post subject: Reply with quote

Just wondered, couldn't we get around 'eval' (and get the benefits of the APC OpCode Cache) by combining a file cache and Memcache?

Here's my idea:

* Retrieve cache details from Memcache
* If cache not expired, use file from file cache
* If cache is expired, remove file from file cache and store cached file from Memcache instead.
* If cached file doesn't exist, retrieve it from Memcache or recompile/create new cache version

So:
- We get the benefit of APC OpCode cache on cached files
- If the server recompiles the template, it's immediately distributed through Memcache

Any thoughts/comments/feedback?
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Wed May 25, 2011 11:01 am    Post subject: Reply with quote

There are two separate considerations to this issue. One being "generate once, use on any machine" (distribution) and "avoid slow HDD".

You could use an NFS mount to store your cache on disk. You'd then have them just as accessible to every machine in your cluster, as if you were using memcache or a database.

Distributing files to multiple machines is not (always) the primary goal though. Reducing the disk I/O is a much bigger issue for load-heavy environments. Disks are slow. They're the slowest storage option you've got.

If you compare RAM / Disk / CPU utilization on your hardware, you'll probably notice your CPU being the least utilized component. This may either be because of the machine having nothing to do, or the machine having to wait on something. If your CPU utilization is rather low compared to the system's load, you probably shouldn't worry about eval() (being a computing thing), but worry about I/O issues regarding disk and network.

The problem with APC's OpCode-Cache is that it can only process scripts from disk. And, unless you specified apc.stat = 0, it will re-check mtime of the source to automatically update the cache if necessary. Very much like Smarty's compile_check option.

BTW:
The only accelerator I could find babbling something about caching eval()ed code was eAccelerator. I'm not sure if it actually caches OpCodes of eval()ed strings or the results of their execution, though.
Back to top
View user's profile Send private message Visit poster's website
emt
Smarty Regular


Joined: 10 Dec 2009
Posts: 43

PostPosted: Wed May 25, 2011 11:32 am    Post subject: Reply with quote

You are making some good points.

Let me briefly explain my goals:
- Generate once, having all servers in the cluster using the updated template
- Speed of delivery of the page (whilst still retaining the flexibility & power of Smarty)

The service will be hosted in the Cloud with various different providers (can't afford downtime like Amazon had recently!).

Adding more servers is therefore easy when disk I/O becomes a real issue.

I am loath to use NFS because of past experience with this. I am looking for a solution that is a relatively no-brainer to implement; with NFS things become much more complicated to trouble-shoot when stuff starts going wrong.

I am therefore planning to use Membase as the back-end for Memcache and have various servers in the different data centres.

So my thinking is (correctly or wrongly) that if I have 100 requests per second, that using an APC stored file (yes, with apc.stat = 0) would be faster than having eval executed 100 times per second.

This will of course be properly tested in a cloud environment before we commit to a final solution.

Interesting about eAccelerator, btw, will look into this more although in previous testing I have found eAccelerator to be much slower than APC.
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Wed May 25, 2011 11:41 am    Post subject: Reply with quote

The assumption that reading caches from APC is faster than eval() is not necessarily true. If you have many cache hits (say per generated cache file at least 20 hits [guessed, needs measuring!]), you may outweigh the overhead of pulling stuff from memcache to disk and shoving it into apc before including the file.

You should also note, that there's a small overhead on every reading request as well. You'd want to store the cache-content and cache-mtime seperately in memcache. You'll have to store the cache-mtime of your local copy on disk to APC as well. Otherwise you don't have the ability to fetch mtime from memcache, fetch mtime from apc, compare and decide to include or reload the cache-content.

I would be very interested in some numbers regarding this approach. If the read/write ratio to make up for the overhead is small enough, we might actually consider building this idea into the cache core.
Back to top
View user's profile Send private message Visit poster's website
emt
Smarty Regular


Joined: 10 Dec 2009
Posts: 43

PostPosted: Wed May 25, 2011 12:45 pm    Post subject: Reply with quote

Good points.

I will definitely carry out some tests and report back my findings on this. I'll do it in a cloud environment so we get "real world" figures. Will be using Nginx and PHP-FPM too so a fair bit of the web server overhead will be reduced too.
Back to top
View user's profile Send private message
rodneyrehm
Administrator


Joined: 30 Mar 2007
Posts: 674
Location: Germany, border to Switzerland

PostPosted: Thu May 26, 2011 4:57 pm    Post subject: Reply with quote

Meanwhile I opened I feature request on APC regarding opcode-cached eval().
[PECL-BUG] Req #22727: enable OpCodeCache for eval() / streams
hopefully we'll see some movement there…
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP