Forum Discussion
David_Farkas_29
Nimbostratus
Feb 01, 2005Cache persistence on domain name
Under 4.x I've used a very simple cache rule to send requests to a set of caches. However, back in 4.2 PTF6, a 'special' feature was added to allow persistence to a cache based on the level of the host name (see below). I was wonder if this 'feature' was carried forward in 9.x or is there a iRule that will accomplish the same thing.
Here is how the feature works:
b internal set cache_uses_host_domain = 0 (default) - makes cache rules use the URI
b internal set cache_uses_host_domain = 1 - makes cache rule use 1st level TLD. (i.e. .com, .net, .org, etc.)
b internal set cache_uses_host_domain = 2 - makes cache rule use 2nd level domain (i.e. merck.com, yahoo.com, hotmail.com, etc.)
b internal set cache_uses_host_domain = 3 - makes cache rule use 3rd level domain (i.e. www.merck.com , ftp.yahoo.com
, www.slashdot.org ,etc.)
21 Replies
- unRuleY_95363Historic F5 AccountWe have not yet implemented the 4.x cache rule command in 9.0. This is currently planned for the release in late spring.
In the meantime, I will look into writing a Tcl equivalent. - David_Farkas_29
Nimbostratus
So is this why I get an error when I attempt to use the cache rule, even the example that is the manual?when HTTP_REQUEST { if { [HTTP::host] starts_with "abc" } { cache { [HTTP::uri] ends_with "html" or [HTTP::uri] ends_with "gif" } { origin_pool origin_server cache_pool cache_servers hot_pool cache_servers hot_threshold 100 cool_threshold 10 hit_period 60 content_hash_size 1024 } else { pool host named_servers } } } - unRuleY_95363Historic F5 AccountYes, I must apologize for that.
This feature was originally scheduled to be implemented in the initial v9.0 release, but do to resource scheduling issues we did not get it completed. Unfortunately, we never got this additional information about it not getting completed communicated to the tech pubs folks and so the command was still documented.
Again, my apologies on this. We are working to get it implemented now and should have it available shortly, however, our next release cycle is not until spring. We will get you an interim version if you go through our support department. I will also look into implementing equivalent functionality using iRules (without the cache command) and post it here if it's feasible.
Thanks for your patience on this. - David_Farkas_29
Nimbostratus
Here is the current cache rule I am using in the 4.x:cache (not (http_host == "xxxx")) { origin_pool Caches cache_pool Caches }
And we are going down to the 2nd level domain (i.e. yahoo.com)
Here is an iRule I came up with. Will it do the same?when HTTP_REQUEST { if { [HTTP::host] != "xxxx"} { pool cache_pool persist universal [domain [HTTP::host] 2] 86400 } else { pool cache_pool persist universal [domain [HTTP::host] 2] 86400 } } - David_Farkas_29
Nimbostratus
Just check ing to see if there was a possibility of getting a TCL equivalent written for this functionality? - unRuleY_95363Historic F5 AccountThe following is an approximation of the logic used by the cache rule command. However, it does not remap uri's to a new cache member when a cache member goes down. In this rule, that is instead handled at the time a request for the uri comes in. I don't foresee this really being an issue though.
Here's the rule:when HTTP_REQUEST { if { } { pool cache_pool set key [crc32 [concat [domain [HTTP::host] 2] [HTTP::uri]]] set cache_mbr [persist lookup hash $key node] if { $cache_mbr ne "" } { Make sure request isn't coming from the cache if { [IP::addr [IP::remote_addr] equals $cache_mbr] } { Yup, send the request from the cache to the origin pool pool origin_pool return } } Make sure persistence record is added for this host/uri persist hash $key } else { pool origin_pool } }
Substitute with whatever expression you would use to determine whether or not you want to send requests to the cache pool. - unRuleY_95363Historic F5 AccountOh, I forgot to mention that the above rule doesn't handle the concept of hot content being spread across the entire cache.
To do that, the rule would have to track the hit rate which we currently can't do efficiently because we have to use the Tcl clock command (which can have a potential performance impact).
You are welcome to try out the following rule which does track the hit rate and disables persistence so that the hot content is load-balance across the entire set of cache servers.
(I also further customized the rule to be closer to your original 4.x example - using the expression and pools, etc):when HTTP_REQUEST { if { [HTTP::host] starts_with "abc" and \ ( [HTTP::uri] ends_with "html" or \ [HTTP::uri] ends_with "gif" ) } { pool cache_servers set key [crc32 [concat [domain [HTTP::host] 2] [HTTP::uri]]] set cache_mbr [persist lookup hash $key node] if { $cache_mbr ne "" } { Make sure request isn't coming from the cache if { [IP::addr [IP::remote_addr] equals $cache_mbr] } { Yup, send the request from the cache to the origin pool pool origin_server } else { set cur_time [clock seconds] set hit_info [session lookup hash $key] if { $hit_info ne "" } { set hit_time [lindex $hit_info 0] set hit_total [lindex $hit_info 1] set hit_list [lindex $hit_info 2] set hot [lindex $hit_info 3] set hit_count [lindex $hit_list 0] Calculate current hit rate set $delta_time [expr $cur_time - $hit_time] If the amount of elapsed time is > hit period if {$delta_time > 60} { Just re-initialize the entire hit period set hit_info "" } else { Shift out the elapsed hits for {} {$delta_time > 0} {incr delta_time -1} { set hit_total [expr $hit_total - [lindex $hit_list 0]] set hit_list [lrange hit_list 1 end] lappend hit_list 0 } } } if { $hit_info eq "" } { Initialize hit period with no hits for {set hot 0} {$hot <= 60} {incr hot} { lappend hit_list 0 } set hit_count 0 set hit_total 0 set hot 0 } Update current hit count lset hit_list end [incr hit_count] incr hit_total if { $hit_total > 100 } { Above hot threshold set hot 1 } elseif { $hot and $hit_total < 10 } { Below cool threshold set hot 0 } if { not $hot } { Use persistence to go to the same cache (with a 3600 secs timeout) persist hash $key 3600 } session add hash $key { $cur_time $hit_total $hit_list $hot } } } else { Make sure persistence record is added for this host/uri persist hash $key 3600 } } else { pool origin_pool } }
Warning: I have not tested this rule. - David_Farkas_29
Nimbostratus
First of all I would like to THANK YOU for getting this iRule together. However, I have a few questions about the hash and the persistence.
Based on the rule, it creates a unique key (using crc32) based on the host/uri and then persists on key. The default persist time is 180 seconds. Don't you think this would create a lot of persist records since the number of unique host/uri combinations are almost endless?
Based on the hash, will the BigIP always send it to the same member? For example, if a client requests and HTTP page and based on the hash the BigIP sends it to member cache-1 and then 10 minutes later another client requests the same page, will the BigIP hash and send the request back to memeber cache-1 even if the persist record is no longer there?
I also see that you can get the pool member that the hash would send the request to (set cache_mbr [persist lookup hash $key node]), is it possible to just send the request directly to the member and not worry about the persistence? - unRuleY_95363Historic F5 AccountYes, the default persist time is 180 seconds, however, if you notice in the second rule I actually set this to an hour. Yes, it does have the potential to create a lot of persist records, but they are fairly small and the system can support millions of them with no effect on performance.
Yes, the drawback to using regular persistence is that when the persist entry times out (due to lack of usage), then the new request will get load balanced to a new member. However, one of the side benefits to HASH persistence is that it even if there is no persist record, it will still persist to the member that is a result of taking the number of active pool member modulo the hash value. So, this should help keep the requests going to the same member even though the persist entry timed out. (I actually forgot about this last night and hence I don't think increasing the persist timeout value is necessary).
Lastly, yes you could just set the request directly to the member and not worry about it, however, persistence already takes care of that so why bother? (I guess if you wanted to simulate the hash persistence behavior above, you could certainly do that). - David_Farkas_29
Nimbostratus
I used the following rule and it works great with HTTP requests. However, it breaks HTTPS requests.
Any idea why??????when HTTP_REQUEST { if { [HTTP::host] != "xxxxx" } { pool Caches set key [crc32 [domain [HTTP::host] 2]] Make sure persistence record is added for this domain persist hash $key } else { pool Caches } }
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
