-
-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Does the config example lack line 'content_by_lua' ? #127
Comments
Yes it should! Well spotted. I've just fixed it and updated the syntax to use the newer
They should point to the Thanks for the report. |
thanks 👍 just start playing with it not the most noob friendly docs :) |
Yeah, the docs need a lot of work! It's on the list... ;) Just added lua-ffi-zlib there too... thanks! |
@pintsized sorry for asking questions but its not working maybe something else is missing in the docs? I always get cache miss, I even tried to do: then inserting into redis some html into 'check' key and it's still missing, try to remove Cache-Control header or set it to max-age=6000, public and still missing
|
What do you have in your request headers? If you turn Nginx debug logging on: error_log logs/error.log debug; ...you'll see what the Ledge state machine is deciding to do with the request, which tends to explain most things. Feel free to paste that here. |
|
I can see that cache-control: max-age=0, chrome auto send this header when refreshing the page.. tried to make nginx ignore it |
Ha yes, was just about to say that. Test with curl if you want to be a bit more in control, but yeah I think we drop Chrome's max-age=0 in production. Chrome (I think) is unique in sending max-age=0 for simple location bar navigation, but it doesn't send it for normal browsing. |
You're missing some stuff from the top of the debug log, which tells you if Ledge decides "cache_accepted" or not, so that's quite key. The other thing that's useful (with debug logging off) is understand that an X-Cache: MISS response header means it couldn't serve cache (either because the client didn't allow it or because the cache was expired), but the absence of an X-Cache header means the response itself is not cacheable (i.e. we just proxy transparently). |
Tnx edited my comment missed that part. |
Use https://github.com/openresty/lua-nginx-module#ngxreqclear_header |
Looks like it is caching (just not able to serve it to a max-age=0 request) so, as Hamish says, just clear the stuff in the request headers that you don't want before starting Ledge. If it wasn't caching, the way to override that would be (before ledge:run()): ledge:bind("origin_fetched", function(res)
res.header["Cache-Control"] = "max-age=3600"
end) This will fire whenever it goes upstream, but before saving the response, so it's a window to modify the response however you like basically. |
@hamishforbes @pintsized
I got this log:
somehow no matter what its always saying "esi_scan_disabled" backend:
|
Ah I think you need to inject the surrogate control header, or have your origin send it for pages that need ESI'ing (this would be more efficient if you can do it in your backend app)
You might also need to add |
@pintsized @hamishforbes tnx guys really helped me, got most of it to work I searched a lot and even start thinking about creating a simple node.js proxy server by myself apache traffic server - too hard to support clustering on aws and other cloud providers (due to multicast) this one is perfect 👍 last question I want to purge the cache without making http request directly with redis, is there any problem with doing it? if it ok I see that for each request you put in redis this keys:
if I want to purge some pages directly through redis, do i need to delete all this keys? |
No worries! Yeah, we're getting there... :)
Is there a reason why you don't want to issue a PURGE request? It's not expensive to do or anything, and the advantage is that since the URI itself is the endpoint, any config applying to the URI you're purging (such as cache_key_spec overrides) still applies. So it's the best way to know that the correct keys were purged for a given URI. Also, when we PURGE things, they are actually just invalidated. This allows you to serve stale (invalidated or expired) content on upstream error for example. So it depends what the effect you want is. Issue a PURGE with "X-Purge: delete" to hard remove things. To answer your question though, yes a safe brute force approach is to just to use the Redis
That's an interesting idea. Again, my gut says to avoid messing with the data structure directly. To avoid end users having to put up with expensive cache misses, you could try:
|
Hi I understand your questions but I think that you miss the real use case of proxy cache server. you really focused that library on the "old" http cache things like Cache-control header and Pragma, but do you really want to give any user control over the backend cache? it's should totally be in my control
I don't want to issue a purge request it's a lot more easier and fast to purge the data directly through redis or even just replace the data directly so if a user add a comment he can instantly see is comment when he refresh.
my dream is 100% cache hit with my backends server only updating the cache so like 100% of my request just fetched with redis with 0% stale data. so a simple post request for a comment will look like
I still can have a rare occasion when two comments submitted at same time and one of them will get lost from the cache one thing I still don't understand is why to use redis keys or scan is there any other redis keys you put in the redis that I missed? wouldn't be much easier just to purge that keys without scanning? |
It is in your control, 100%, but by using HTTP semantics. Which are only "old" in so much as they are well considered, thought through and proven. Or, you can reinvent the wheel. Your choice ;)
Demonstrably, it's much easier to purge using the PURGE method than it is to manually run Redis commands. There is absolutely no performance reason why you'd want to do it directly. Consider that you can run the PURGE command locally on the server using curl if you wish. Think of it as a restful web service end-point to your cache, using a custom HTTP method.
What you're talking about is more like an application cache. That is, a system where things don't expire over time (i.e. stale by definition), they are manually invalidated on change, because your application knows when something changes, and fires an invalidation message. You can absolutely achieve this, and yep, using ESI to break things up is a great way to help with that because the impact is more focussed. Set a long TTL on the comment ESI, and ensure it sends cacheable headers in a POST response. People think you can't cache POST request, but you can cache POST responses, and serve them to subsequent GETs. So as long as your POST response contains the newly updated comments template, and sets cacheable headers, it'll update the old version in cache at the same time. Which means you don't have to do anything custom to achieve this. I haven't tried this particular pattern in a while, so give it a try - I'm pretty sure it'll just work.
Well if your backend comments DB is the source of truth, then the latest rendering of the comments HTML will always be correct. Things only get weird if you try to interfere with the process, manually editing cache etc.
I suggest it because it's not hard, and is guaranteed to work. If you write a script to catch all of the current keys, and then upgrade to a new version of Ledge, I might have changed the schema and your script wont know. You should be aware that there can be more than one entity for a cache entry. They are garbage collected, so in theory you only have to delete the "live" entity. If you delete an old one, and not the live one (which you determine by inspecting the "::key" which is a pointer to the live one), you'll leave an orphaned entity around. Seriously, use PURGE, it's what it's there for. If not, use KEYS to make sure you get everything. You'll thank me. |
If I understand you correctly you can do this by remove the http type request from the cache key so POST to /post/1/comments will save the cache for GET /post/1/comments ?
so on data change I will need to send purge request to clear the cache and then sending another dummy request to populate the cache? |
Nope, it should just work. The HTTP method is not included in the cache key by default. That is, the request method has a bearing only on whether the request can be served from cache, but not on whether its response is allowed to save / update the cache. So if the response has cacheable headers, it'll update cache, and the next GET will see the updated version.
Well, in the case above, you don't need to do anything because cache is updated in place. In the case where something changes for other reasons and you need to update the cache as a result, you can either purge and manually send a dummy request to replace the cache, or use the X-Purge header: $> curl -X PURGE -H "Host: example.com" -H "X-Purge: revalidate" http://cache.example.com/path This will invalidate the current version, and immediately start a background revalidation job. So it's not synchronous but should happen pretty immediately. |
really like that revalidate feature, maybe purging process can be better, just think about it for every purge request we actually scanning the whole redis keys, I didn't test it yet but that scan match its not recommended way, I opened a stackoverflow question about it and got answer by redis labs developer who said:
for medium-low site with 500,000 - 1,000,000 keys and 4-6 purging a minute we gonna do million keys scanning 6 times a minutes |
Yeah, it's not ideal. Remember it only happens when wildcard purging though (purges without * in the URI never scan anthing and are practically instant), and it is backgrounded so you can tune the impact with worker concurrency and Some of the data structure refactor I mentioned is going to reduce the number of keys per cache entry, which will help a little, but it's still a lot of keyspace scanning. Personally I like the idea of Cache Tags, discussed here #112 . This would be much more concrete for the "I just changed content x, and so all URIs tagged with x should be purged / revalidated" pattern. This would remove the need to scan the entire keyspace, but obviously it depends on your application knowing how to tag things. Wildcard purging is really best for administrative reasons (remove everything from this path onwards etc). If used as a general part of the application one does have to be careful. |
totaly missed that part, so in normal purge you just delete the keys https://github.com/pintsized/ledge/blob/master/lib/ledge/ledge.lua#L2806 I think I gonna stick to purge the keys directly with redis I will follow the changelog for any keys changes, thanks for your help going to watch this repo closely Cache Tags will be amazing could be achieved using sets no?
than on article-1 tags purging simply go all over the set and purging this urls |
Yep. It's synchronous and basically instant. Like ~1ms end-to-end or something. A wildcard PURGE gets backgrounded, and just returns 200. I'm working on a feature at the moment where PURGE returns a JSON body with some info on what happened. In the case of wildcard purges, you'll have a JID to track the background work in qless.
Honestly, terrible idea, but I've told you that already. PURGE is your API for purging. Modifying the data directly is more work, no faster, and likely to lead to errors with GC and the like (orphaned entities taking up memory). Also consider if you really want to delete them - you may only want to invalidate the keys, so you can still serve them in the event of upstream errors (site stays live, just out of date). Depends on the type of content mostly. We run Redis with the volatile-lru eviction policy (default) so it'll evict the least recently used stuff once out of memory anyway. So there's no real need to delete for memory reasons.
Yep, exactly. |
in the example config you gave this sample code:
in the server directive it should be:
content_by_lua 'ledge:run()';
?The text was updated successfully, but these errors were encountered: