CML,即缓存元语言¶
警告¶
- mod_cml 已弃用,推荐使用提供类似功能的 mod_magnet。
这是什么¶
CML 旨在将动态网站的缓存命中和缓存未命中决策
从动态应用程序中移出,从而无需启动应用程序或动态
语言。
特别是 PHP,众所周知在脚本开始执行之前会有巨大的开销。
如何安装¶
CML 使用的语言是 LUA,您可以在 https://lua.ac.cn/ 找到它。
要了解如何编写 LUA 代码的背景知识,请查看
优势¶
CML 的主要优势是其性能。
一个非常简单的基准测试显示:
- 静态 'output.html'(由 PHP 脚本生成)约为 1000 请求/秒
- 如果调用 index.cml(缓存命中),约为 600 请求/秒
- 如果调用 index.php(缓存未命中),约为 50 请求/秒
使用 CML 将测试页面的性能提高了 12 倍,使其
几乎达到了静态文件传输的可能最大值。
使用模式¶
https://lighttpd.ac.cn/ 正在使用 CML 来降低负载(即使负载很小)。
首页的布局取决于几个文件:
- content-1
- content-6
- 模板 /main.tmpl
如果任何文件被修改,页面的缓存版本也必须随之改变。
output_contenttype = "text/html" trigger_handler = "index.php" -- this file updated by the trigger output_include = { "output.html" } docroot = request["DOCUMENT_ROOT"] cwd = request["CWD"] -- the dependencies files = { cwd .. "content-1", cwd .. "content-6", docroot .. "main.tmpl" } cached_mtime = file_mtime(cwd .. "output.html") -- if one of the source files is newer than the generated files -- call the trigger for i,v in ipairs(files) do if file_mtime(v) > cached_mtime then return 1 end end return 0
延迟重新检查¶
如果您正在构建一个新闻聚合器,延迟缓存内容的重建一段时间会很有用,因为您可以假设新闻不会随着每次请求而改变。因此,您不需要在每次请求时重新验证,而是延迟验证检查。
-- same as above -- check again in 5 minutes delay_recheck = 3600 if cached_mtime + delay_recheck > os.time() then return 0 end -- we are behind the delayed recheck, check the cache as usual for i,v in ipairs(files) do if file_mtime(v) > cached_mtime then return 1 end end return 0
为了告诉中间的代理在收到此内容后的 5 分钟内不要再次检查,请使用 setenv 模块并添加一些缓存控制或过期头信息。
CML 与数据库¶
CML 不提供对 MySQL 或 PostgreSQL 等数据库的直接访问,而且可能永远不会。
有一种更好/更快的方式来使 CML 与数据库接口:MemCache
您所要做的就是将决定页面是否需要重新生成所需的信息保存在 memcached 存储本身中。假设每当您在数据库中存储一个条目时,您都为其关联一个版本 ID。一旦您对资源进行更改,版本 ID 就会递增。
这个版本 ID 现在同时存储在数据库和 memcache 中。CML 现在可以获取版本 ID,检查是否已为其生成内容,并在必要时生成。
output_contenttype = "text/html" content_key = md5(request["PATH_INFO"]) version = memcache_get_long(content_key) cwd = request["CWD"] trigger_handler = "generate.php" if version >= 0 then output_include = { cwd .. content_key .. "-" .. version .. ".html" } return 0 else return 1 end
generate.php 将需要:
- 获取 PATH_INFO
- 从数据库中获取相关信息
- 为页面生成内容并写入磁盘
- 将其交付给客户端
要使数据库与 memcached 接口,您可以使用 UDF
- 对于 MySQL,可以在 jans mysql page 获取 mysql udf
- 对于 PostgreSQL,Sean Chittenden 编写了 pgmemcache
在 MySQL 和 UDF 中,您只需执行:
#!sql BEGIN; UPDATE content SET @v := (version = version + 1) WHERE id = <id>; SELECT memcache_set("127.0.0.1:11211", <id>, @v); COMMIT;
检查缓存当前正在使用的版本
#!sql SELECT memcache_get("127.0.0.1:11211", <id>);