diff --git a/reference/yac/book.xml b/reference/yac/book.xml index 4ab1f9498..9d44ef895 100644 --- a/reference/yac/book.xml +++ b/reference/yac/book.xml @@ -1,6 +1,6 @@ - + @@ -10,48 +10,32 @@ &reftitle.intro; - Yac(Yet Another Cache)是一个无锁(lock-free)的共享内存用户数据缓存, - 可以用来替代 APC 或本地 memcached。 + Yac(Yet Another Cache)是一个无锁(lock-free)的共享内存用户数据缓存,可以用来替代 APC 或本地 memcached。 - Yac 将数据存储在共享内存中,同一台机器上的每个 PHP 工作进程 - 都能直接访问,无需任何进程间通信。 - Yac 不加锁,而是依靠原子的槽位更新加上少量的冲突探测, - 因此缓存未命中(cache miss)绝不会阻塞请求; - 并发写入最坏的情况也只是某次存储失败或某次读取落空, - 调用方直接重试即可。 + Yac 将数据存储在共享内存中,同一台机器上的每个 PHP 工作进程都能直接访问,无需任何进程间通信。 + Yac 不加锁,而是依靠原子的槽位更新加上少量的冲突探测,因此缓存未命中(cache miss)绝不会阻塞请求;并发写入最坏的情况也只是某次存储失败或某次读取落空,调用方直接重试即可。 - 访问路径上没有锁,也没有进程间通信,一次读取本质上就是 - 在共享内存中做一次哈希查找。因此,Yac 极其快, - 读取延迟在微秒级;只要写入分散在不同的键上, - 吞吐量还能随着访问缓存的 worker 数量增长。 + 访问路径上没有锁,也没有进程间通信,一次读取本质上就是在共享内存中做一次哈希查找。因此,Yac 极其快,读取延迟在微秒级;只要写入分散在不同的键上,吞吐量还能随着访问缓存的 worker 数量增长;参见 + 基准测试。 - 由于 Yac 用正确性保证换取速度和吞吐量, - 它最适合缓存那些生成代价高但可以轻易重建的数据: - 页面片段、配置快照、小型服务响应等本地缓存。 - 不要把它用作不可替代数据的权威存储。 + 由于 Yac 用正确性保证换取速度和吞吐量,它最适合缓存那些生成代价高但可以轻易重建的数据:页面片段、配置快照、小型服务响应等本地缓存。不要把它用作不可替代数据的权威存储。 - 从 yac 2.4.0 开始,小标量值——NULL、 - 布尔值、整数、最长 7 字节的短字符串和空数组—— - 直接存储在哈希槽(hash slot)里,而不是单独的值块 - (即“嵌入值”,embedded values)。这样每次访问都省去了 - 值内存的分配和块拷贝,显著提升性能的同时减少了内存占用。 - 2.4.0 还把压缩后端从 FastLZ 换成了 LZ4, - 使压缩数据的读取快了好几倍。 + 从 yac 2.4.0 开始,小标量值——NULL、布尔值、大多数整数(在 64 位构建下能装进 60 个有符号位的整数)、最长 7 字节的字符串和空数组——直接存储在哈希槽(hash slot)里,而不是单独的值块(即“嵌入值”,embedded values)。这样每次访问都省去了值内存的分配和块拷贝,显著提升性能的同时减少了内存占用。 + 2.4.0 还把压缩后端从 FastLZ 换成了 LZ4,使压缩数据的读取快了好几倍。 - 共享内存仅在同一台机器内可见。 - 如果需要在多台服务器之间共享缓存, - 请使用 Memcached 或 Redis 等网络缓存。 + 共享内存仅在同一台机器内可见。如果需要在多台服务器之间共享缓存,请使用 Memcached 或 Redis 等网络缓存。 &reference.yac.setup; + &reference.yac.memory; &reference.yac.constants; &reference.yac.yac; diff --git a/reference/yac/constants.xml b/reference/yac/constants.xml index d539b6646..e8527b2b6 100644 --- a/reference/yac/constants.xml +++ b/reference/yac/constants.xml @@ -1,6 +1,6 @@ - + &reftitle.constants; @@ -14,6 +14,7 @@ + 扩展的版本号(字符串形式)。 @@ -24,7 +25,7 @@ - 键允许的最大长度,为 48 字节。 + 键的最大长度,单位为字节:48。实例前缀也计入该限制。 @@ -35,6 +36,8 @@ + 值在序列化前的最大长度,单位为字节: + 67,108,863((1 << 26) - 1)。更大的值会被拒绝。 @@ -45,6 +48,7 @@ + 存储条目的最大尺寸,单位为字节:1,048,576(1M)。压缩后仍放不下的值会被拒绝。 @@ -55,7 +59,7 @@ - 使用 PHP serialize 作为序列化器。 + 使用 PHP serialize 作为序列化器(默认)。 @@ -66,7 +70,8 @@ - 使用 JSON 作为序列化器(需要 --enable-json)。 + 使用 JSON 作为序列化器。需要扩展以 + 支持编译。 @@ -77,7 +82,8 @@ - 使用 igbinary 作为序列化器(需要 --enable-igbinary)。 + 使用 igbinary 作为序列化器。需要扩展以 + 支持编译。 @@ -88,7 +94,8 @@ - 使用 msgpack 作为序列化器(需要 --enable-msgpack)。 + 使用 msgpack 作为序列化器。需要扩展以 + 支持编译。 @@ -99,7 +106,7 @@ - Yac 当前使用的序列化器。 + 扩展当前使用的序列化器。 diff --git a/reference/yac/ini.xml b/reference/yac/ini.xml index 48176d655..fafe12982 100644 --- a/reference/yac/ini.xml +++ b/reference/yac/ini.xml @@ -1,6 +1,6 @@ - +
&reftitle.runtime; @@ -20,7 +20,7 @@ yac.compress_threshold - -1 + 4K INI_SYSTEM @@ -44,7 +44,7 @@ yac.keys_memory_size - 4M + 8M INI_SYSTEM @@ -76,9 +76,10 @@ - 序列化后大于该字节数的值会在存储前被压缩(当前使用 LZ4)。 - 设为 -1(默认值)则完全禁用压缩。 - 压缩大值可以节省共享内存,代价是存取时多消耗一些 CPU。 + 序列化后大于该字节数的值会在存储前被压缩(自 Yac 2.4.0 起使用 LZ4)。超过 + 1M 存储条目上限(YAC_MAX_RAW_COMPRESSED_LEN)的值无论本设置如何都会被压缩,因为它们无法以未压缩形式存储。默认值 4K 表示开启压缩; + -1 对低于存储条目上限的值禁用压缩;其他正值会被钳制到 1024..1M + 区间内。压缩大值可以节省共享内存,代价是存取时多消耗一些 CPU。 @@ -112,9 +113,7 @@ - 在 CLI SAPI 下运行时是否启用 Yac。 - 默认禁用,因为命令行脚本通常启动后立即结束, - 创建共享内存段毫无意义。 + 在 CLI SAPI 下运行时是否启用 Yac。默认禁用,因为命令行脚本通常启动后立即结束,创建共享内存段毫无意义。 @@ -125,11 +124,7 @@ - 用于存放键和元信息的哈希槽位所占用的共享内存大小。 - 每个槽位是固定大小的结构,因此这个值决定了能同时跟踪多少条目。 - 默认为 4M。 - Yac 将这块区域切分成若干段,每段大小为 4M, - 因此该值必须是 4M 的倍数。 + 用于存放键表的共享内存大小。它限制了能同时存在的条目数量——默认的 8M 大约能容纳 65,536 个条目。如果命中率下降且 kicks 攀升,请调大该值;关于键表写满后的行为以及何时才真正构成问题,参见 @@ -140,13 +135,10 @@ - 存储前把任意 PHP 值转换成字节序列所用的序列化器。 - 可选值为 php(默认)、json、 - igbinarymsgpack。 - 后三者需要扩展以相应支持编译。 + 存储前把任意 PHP 值转换成字节序列所用的序列化器。可选值为 php(默认)、json、 + igbinarymsgpack。后三者需要扩展以相应支持编译。 igbinarymsgpack - 等二进制序列化器通常比 php 更快, - 产生的数据也更小。 + 等二进制序列化器通常比 php 更快,产生的数据也更小。 @@ -157,10 +149,10 @@ - 用于存放实际值的共享内存大小,默认为 64M。 - Yac 以每段 4M 的方式分配这块区域, - 因此该值必须是 4M 的倍数。 - 当区域写满时,最久未使用的条目会被踢出,为新条目腾出空间。 + 用于存放值的共享内存大小。值在一个个 4M 的段上,由一个只进不退的分配器(bump allocator)分配;当没有任何段装得下新值时,分配器游标会绕回起点,最旧的值会被悄悄覆盖(即一次回收, + recycle)。此后对它们的读取会退化为未命中,由一个完整性校验机制检出。如果在槽位尚有余量时 recycles 仍在攀升,请调大该值;或者启用 + yac.compress_threshold + 来压缩大载荷。参见 @@ -168,7 +160,6 @@
- + + + + 内存管理 + + + Yac 把数据存放在两个相互独立的共享内存池里,分别由 + yac.keys_memory_size + 和 + yac.values_memory_size + 配置。两个池写满和释放的方式各不相同,因此在调整任何一个参数之前,先弄清楚症状属于哪个池会很有帮助。 + + +
+ 每个池各存放什么 + + 两个池分别存放一个条目的两半。键池存放键:每个被缓存的键占一个槽位,槽位里带着键本身(最长 48 字节)、哈希值、TTL、命中次数和最后访问时间;值只通过一个指向值池的指针被引用。值池存放值:每个存储的值占用一块序列化后的字节——如果条目经过了 + yac.compress_threshold,则是压缩后的形式。 + + + 唯一的例外是嵌入值(embedded values):极小的标量——&null;、 + &true;、&false;、大多数整数(在 64 位构建下能装进 60 个有符号位的整数)、最长 7 字节的字符串和空数组——直接存放在槽位内部,用的正是本来要引用值块的那个指针。这样的值在值池中完全不占空间,只有它们的键占位。 + + + 粗略的容量规划方法: + + + + 键池每 MB 大约能容纳 8,000 个键,因此 + yac.keys_memory_size + 可以按不同键的数量除以每 MB 8,000 个、再向上取整来估算——默认的 8M 大约能容纳 64,000 个键; + + + + + 值池必须容纳所有仍可能被读取的值,因此 + yac.values_memory_size + 可以按存活值的数量乘以平均序列化(压缩后)大小来估算,并预留大约两倍的空间:这个池是一个环,只有当分配器的游标绕回来覆盖某个值时,它才算消亡。 + + + + 嵌入值和其他条目一样占用槽位,但在值池中不占空间,因此计算第二项时不必把它们算进去。 + +
+ +
+ 键池(槽位) + + yac.keys_memory_size + 维护着一张固定大小的槽位表——默认的 8M + 大约有 65,536 个槽位。每个存储的键恰好占用一个槽位,因此这个池限制了同时能存在的条目数量;与值池不同,槽位永远不会被单独释放。过期的槽位——TTL 已过的,或者 Yac::delete 留下的墓碑——在新键需要时会被免费回收。只有当某条探测路径上的四个候选槽位全部被存活条目占据时,才会驱逐其中一个来腾出空间——这记一次 kick(对应 + Yac::info 的 + kicks 计数器)。 + + + 驱逐只在发生碰撞的探测路径上的四个存活候选者中挑选: + + + + 最近最少使用的那个(atime 最旧)会被驱逐; + + + + + 打平时选命中次数最少的,再打平选探测位置最靠前的。 + + + + + + 一个常见的误解:slots_used 达到 + slots_size 并不是错误状态。一个键的工作集大于槽位表的缓存,此后只是以 100% 的占用率运行,按需驱逐和重新插入而已。判断键池大小是否合适的唯一指标是命中率(hits / (hits + miss),按两次 + Yac::info 快照之间的增量计算,而不是全生命周期的平均值)。单看 kicks 计数很高并不能说明有问题——只是键的分布不均匀,某些探测路径碰撞更多而已。只有当命中率和 kicks 同时很糟时,才说明槽位表对这个键集合来说太小了,解决办法是调大 + yac.keys_memory_size。 + + + 槽位永不释放还有一个后果:没有 TTL(ttl = 0)又再也没被读取过的条目会一直占着槽位,直到某次驱逐恰好选中它。如果应用要存放大量这类一次性数据,请给这些条目设置 TTL,让它们过期后被回收,而不是挤掉存活的条目;或者干脆按全部键集合的大小来规划键池。 + +
+ +
+ 值池(段) + + yac.values_memory_size + 被切分成每段 4M,按环形管理:写入推进各段的游标,空间从不按条目释放。当一次分配放不下时,游标绕回某段的起点——这记一次 recycle(对应 + Yac::info 的 + recycles 计数器)。一次回收并不会立即使整段失效:被覆盖的值在绕回的游标真正覆盖到它们之前仍然可读,一旦被覆盖,对它们的读取就会通不过完整性校验而退化为未命中。 + + + 这个池有两个大小值得关注:总的 + yac.values_memory_size + 必须装得下存活值的工作集,而单个条目存储后最多占 1 MB + (YAC_MAX_RAW_COMPRESSED_LEN)。因此更大的值在存储前总会被压缩;一个压不进 1 MB 以内的值——最常见的原因是数据本身是随机的——会被拒绝,并使 fails 计数器加一。值本身的绝对上限要高得多:序列化后超过 64 MB + (YAC_MAX_VALUE_RAW_LEN,即 + (1 << 26) - 1 字节)的值会被直接拒绝。 + +
+ +
+ 容量规划与观察指标 + + 从默认值起步,然后观察 + Yac::info 的各计数器——它们从 start_time 起累加,所以要比较相隔一段时间的两个快照: + + + + + 命中率健康(比如 >= 90%):缓存工作正常,无论其他计数器显示什么,都不用管; + + + + + 命中率低且 kicks 攀升:键池对这个键集合来说太小——存活条目在被重新读取之前就被驱逐了。调大 + yac.keys_memory_size; + + + + + recycles 频繁:这是真问题,不是无害的计数。一次回收意味着值分配器已经绕回、即将覆盖条目——被覆盖的值在重新读取之前就消亡了,存它花掉的字节白花了,命中率也会受损。这说明值池对存活数据的体量来说太小了。按效果排序: + + + + 给条目设置 TTL。以 ttl = 0 写入的值永远存活,一直占着池子,迫使游标更早绕回。TTL 限定了每个条目的存活时长,缩小了池子必须容纳的存活工作集; + + + + + 调大 + yac.values_memory_size,让池子装得下整个存活值集合(记住要按存活占用大约两倍来预算——值只有在游标绕回来覆盖它时才消亡); + + + + + 减少单个条目的存储量:如果 + yac.compress_threshold + 设置得高于 1024 这个下限,把它调低,让大的载荷被压缩;精简那些不需要完整缓存的值; + + + + + + + + fails 增长:有值存不进去,最常见的是单个值压缩后仍超过 1 MB 的存储上限——把值拆分。 + + + +
+ +
+ + diff --git a/reference/yac/yac/add.xml b/reference/yac/yac/add.xml index cae4197e5..d9b0d22af 100644 --- a/reference/yac/yac/add.xml +++ b/reference/yac/yac/add.xml @@ -1,6 +1,6 @@ - + @@ -12,7 +12,7 @@ &reftitle.description; public boolYac::add - stringarraykeys + stringarraykey mixedvalue intttl0 @@ -22,8 +22,7 @@ intttl0 - 向缓存中存储一个值。与 Yac::set 不同, - 它不会覆盖仍然有效的已有条目;遇到这种情况时存储会被拒绝。 + 向缓存中存储一个值。与 Yac::set 不同,它不会覆盖仍然有效的已有条目;遇到这种情况时存储会被拒绝。 @@ -31,7 +30,7 @@ &reftitle.parameters; - keys + key string 类型的键,或者一个由 @@ -44,9 +43,7 @@ value - 要存储的值。除 resource 外的所有 PHP 类型都可以存储。 - 仅在单键形式下使用;当 keys 是数组时, - 该参数位置实际上是可选的 ttl。 + 要存储的值。除 resource 外的所有 PHP 类型都可以存储。仅在单键形式下使用;当 key 是数组时,该参数位置实际上是可选的 ttl @@ -64,24 +61,8 @@ &reftitle.returnvalues; - 成功时返回 &true;,失败时返回 &false;。 - 当键已存在且未过期时,存储同样会被拒绝(返回 &false;)。 + 成功时返回 &true;,失败时返回 &false;。当键已存在且未过期时,存储同样会被拒绝(返回 &false;)。 - - - Yac 存储条目时不加锁。在高并发竞争下,存储可能会瞬时失败; - 如果该值必须最终写入成功,请重试: - -add("key", "value")) { - // 瞬时失败时重试 -} -?> -]]> - - - @@ -95,11 +76,31 @@ $yac = new Yac(); var_dump($yac->add("foo", "bar")); // bool(true) var_dump($yac->add("foo", "baz")); // bool(false):"foo" 已存在 +?> +]]> + + + + 添加带 TTL 的条目 + +add("short-lived", "value", 5); sleep(6); var_dump($yac->get("short-lived")); // bool(false):已过期 +?> +]]> + + + + 一次添加多个条目 + +add(array("a" => 1, "b" => 2), 60); diff --git a/reference/yac/yac/delete.xml b/reference/yac/yac/delete.xml index 32b4a3334..d995a04e9 100644 --- a/reference/yac/yac/delete.xml +++ b/reference/yac/yac/delete.xml @@ -1,6 +1,6 @@ - + @@ -12,7 +12,7 @@ &reftitle.description; public boolYac::delete - stringarraykeys + stringarraykey intdelay0 @@ -20,14 +20,9 @@ - 注意,Yac 并不会真正把条目从缓存中移除:删除只是把条目标记为 - 过期——delay0 时立即过期—— - 只有当后续的写入恰好复用了这个哈希槽时,该条目才会被覆盖: - 要么是同一个键被重新写入,要么是另一个键的插入恰好落在了这个槽上。 - 在那之前,槽位一直被占用,所以 Yac::info + 注意,Yac 并不会真正把条目从缓存中移除:删除只是把条目标记为过期——delay0 时立即过期——只有当后续的写入恰好复用了这个哈希槽时,该条目才会被覆盖:要么是同一个键被重新写入,要么是另一个键的插入恰好落在了这个槽上。在那之前,槽位一直被占用,所以 Yac::info 报告的 slots_used 计数不会减少, - Yac::dump 也仍会列出这些已删除的条目; - 检视 dump 输出时,需要自己检查 ttl 值把它们过滤掉。 + Yac::dump 也仍会列出这些已删除的条目;检视 dump 输出时,需要自己检查 ttl 值把它们过滤掉。 @@ -36,7 +31,7 @@ &reftitle.parameters; - keys + key string 类型的键,或者由待删除的键组成的 @@ -49,8 +44,7 @@ 条目变为失效前等待的秒数。省略或为 0 - 时,条目立即失效。正数值表示条目在这段时间内仍可读, - 到期后才失效。 + 时,条目立即失效。正数值表示条目在这段时间内仍可读,到期后才失效。 @@ -60,9 +54,7 @@ &reftitle.returnvalues; - 成功时返回 &true;;键不在缓存中时返回 &false;。 - 由于删除只是把条目标记为过期,一个已删除但尚未被覆盖的键 - 仍然算作存在:再次删除同一个键会返回 &true;。 + 成功时返回 &true;;键不在缓存中时返回 &false;。由于删除只是把条目标记为过期,一个已删除但尚未被覆盖的键仍然算作存在:再次删除同一个键会返回 &true;。 传入键的 array 时,只有当每个键都存在才返回 @@ -89,12 +81,33 @@ var_dump($yac->delete("never")); // bool(false):从未存储过 // 已过期的条目仍然出现在 dump 里 var_dump($yac->info()["slots_used"]); // int(1) print_r($yac->dump()); // "foo" 仍在列表中;其 ttl 已过期 +?> +]]> + + + + 延迟删除 + +set("tmp", "value"); var_dump($yac->delete("tmp", 60)); // bool(true) +?> +]]> + + + + 一次删除多个键 + +set("tmp", "value"); -// 一次删除多个键时,只有当每个键都存在才返回 true +// 只有当每个键都存在才返回 true var_dump($yac->delete(array("tmp", "nope"))); // bool(false):"nope" 不存在 ?> ]]> diff --git a/reference/yac/yac/dump.xml b/reference/yac/yac/dump.xml index 56423f0f9..fe9a4c589 100644 --- a/reference/yac/yac/dump.xml +++ b/reference/yac/yac/dump.xml @@ -1,6 +1,6 @@ - + @@ -30,9 +30,7 @@ 返回条目的最大数量。 - limit-1 会导出缓存当前持有的全部条目。 - 注意,对大型缓存构建完整列表可能占用可观的内存; - 内存紧张时,请改用 limitoffset 分页遍历。 + limit-1 会导出缓存当前持有的全部条目。注意,对大型缓存构建完整列表可能占用可观的内存;内存紧张时,请改用 limitoffset 分页遍历。 @@ -40,9 +38,7 @@ offset - 收集前跳过的条目数。该参数自 PECL yac 2.4.0 起可用; - 更早的版本总是从第一个条目开始。结合 limit, - 可用于对储存条目超过单次调用返回上限的缓存进行分页遍历。 + 收集前跳过的条目数。该参数自 PECL yac 2.4.0 起可用;更早的版本总是从第一个条目开始。结合 limit,可用于对储存条目超过单次调用返回上限的缓存进行分页遍历。 @@ -52,8 +48,7 @@ &reftitle.returnvalues; - 返回一个 array,每个导出的条目对应一个元素。 - 每个元素本身也是描述该条目的数组: + 返回一个 array,每个导出的条目对应一个元素。每个元素本身也是描述该条目的数组: @@ -71,8 +66,7 @@ crc - 存储值的 CRC32 校验和,用于检测撕裂读取(torn read)。 - 内嵌(embedded)条目没有值块,该字段为 0。 + 存储值的 CRC32 校验和,用于检测撕裂读取(torn read)。内嵌(embedded)条目没有值块,该字段为 0 @@ -93,33 +87,27 @@ v_len - 值的长度,单位为字节。对于被压缩的条目, - 这是压缩原始值的长度 - (自 yac 2.4.0 起;更早的版本报告的是存储的压缩后长度)。 + 值的长度,单位为字节。对于被压缩的条目,这是压缩原始值的长度(自 yac 2.4.0 起;更早的版本报告的是存储的压缩后长度)。 c_len - 仅被压缩的条目有此字段(自 yac 2.4.0 起): - 实际存入共享内存的压缩数据长度,单位为字节。 - 对比 c_lenv_len + 仅被压缩的条目有此字段(自 yac 2.4.0 起):实际存入共享内存的压缩数据长度,单位为字节。对比 c_lenv_len 可以看出每个条目通过压缩节省了多少空间。 size - 值块在共享内存中分配的大小,单位为字节。 - 内嵌条目为 0。 + 值块在共享内存中分配的大小,单位为字节。内嵌条目为 0 atime 最后访问时间(Unix 时间),每次成功的 - Yac::get 都会更新它。 - 缓存写满时,候选槽位中 atime + Yac::get 都会更新它。缓存写满时,候选槽位中 atime 最旧的条目会最先被驱逐(自 yac 2.4.0 起)。 @@ -127,18 +115,14 @@ hits 每个条目的命中计数器,每次成功的 - Yac::get 都会使其递增; - 条目被覆盖、删除或过期时重置(自 yac 2.4.0 起)。 + Yac::get 都会使其递增;当条目被新的 Yac::set 或 + Yac::add 覆盖时重置(自 yac 2.4.0 起)。 embedded - 值是否直接存储在槽位内部,而不是单独的值块中 - (自 yac 2.4.0 起)。小值——NULL、 - 布尔值、小整数、不超过 7 字节的字符串和空数组—— - 以内嵌方式存储,完全不占用值内存; - 这类条目的 crcsize + 值是否直接存储在槽位内部,而不是单独的值块中(自 yac 2.4.0 起)。小值——NULL、布尔值、小整数、不超过 7 字节的字符串和空数组——以内嵌方式存储,完全不占用值内存;这类条目的 crcsize 均报告为 0 @@ -205,25 +189,26 @@ Array ]]> - 条目按槽位顺序列出,而不是按存储顺序。 - 内嵌条目(直接保存在槽位内部的小标量)的 - crcsize 为零; - 存储在独立值块中的条目带有校验和与块大小, - 被压缩的条目还额外带有 c_len。 + 条目按槽位顺序列出,而不是按存储顺序。内嵌条目(直接保存在槽位内部的小标量)的 + crcsize 为零;存储在独立值块中的条目带有校验和与块大小,被压缩的条目还额外带有 c_len 分页遍历大型缓存 limit 限制单次调用返回的条目数, - offset 表示收集前跳过的条目数, - 两者组合即可对储存条目超过单次调用返回上限的缓存进行分页遍历。 + offset 表示收集前跳过的条目数,两者组合即可对储存条目超过单次调用返回上限的缓存进行分页遍历。 set("key$i", $i); +} + $page_size = 100; $page_num = 2; @@ -241,9 +226,7 @@ int(100) ]]> - 当缓存中的条目数少于请求页覆盖的范围时, - 返回的条目数会少于请求数; - 当 offset 指向最后一个已占用槽位之后时,返回空数组。 + 当缓存中的条目数少于请求页覆盖的范围时,返回的条目数会少于请求数;当 offset 指向最后一个已占用槽位之后时,返回空数组。 diff --git a/reference/yac/yac/get.xml b/reference/yac/yac/get.xml index bf36d1091..c376c9630 100644 --- a/reference/yac/yac/get.xml +++ b/reference/yac/yac/get.xml @@ -1,6 +1,6 @@ - + @@ -12,7 +12,7 @@ &reftitle.description; public mixedYac::get - stringarraykeys + stringarraykey mixeddefault&null; @@ -24,7 +24,7 @@ &reftitle.parameters; - keys + key string 类型的键,或者由键组成的 array。 @@ -35,14 +35,12 @@ default - 当请求的键(或多个键)不在缓存中时返回的值, - 自 yac 2.4.0 起可用。省略时,未命中返回 &false;。 + 当请求的键(或多个键)不在缓存中时返回的值,自 yac 2.4.0 起可用。省略时,未命中返回 &false;。 在 yac 2.4.0 之前,该参数位置是一个引用形式的 - $cas 令牌,而不是默认值。 - 传递过或依赖该令牌的代码在升级到 2.4.0 时必须更新。 + $cas 令牌,而不是默认值。传递过或依赖该令牌的代码在升级到 2.4.0 时必须更新。 @@ -53,15 +51,10 @@ &reftitle.returnvalues; - 对于 string 类型的键,命中时返回缓存的值, - 否则返回 default(未指定默认值时返回 &false;)。 + 对于 string 类型的键,命中时返回缓存的值,否则返回 default(未指定默认值时返回 &false;)。 - 对于由键组成的 array,返回一个数组, - 其中包含所有命中的值,以各自的键为索引。 - 自 yac 2.4.0 起,不在缓存中的键会被直接忽略 - (若指定了 default,则用默认值填充); - 在 2.4.0 之前,每个缺失的键都会插入一个 &false; 占位值。 + 对于由键组成的 array,返回一个数组,其中包含所有命中的值,以各自的键为索引。自 yac 2.4.0 起,不在缓存中的键会被直接忽略(若指定了 default,则用默认值填充);在 2.4.0 之前,每个缺失的键都会插入一个 &false; 占位值。 @@ -78,6 +71,16 @@ $yac = new Yac(); $yac->set("foo", "bar"); var_dump($yac->get("foo")); // string(3) "bar" var_dump($yac->get("missing")); // bool(false):未命中 +?> +]]> + + + + 区分存进去的 false 和未命中 + +get("flag")); // bool(false):存的就是这个 var_dump($yac->get("missing", false)); // bool(false):未命中,形态相同 var_dump($yac->get("flag", "__NONE__")); // bool(false):存的就是这个值 var_dump($yac->get("missing", "__NONE__")); // string(8) "__NONE__":未命中 +?> +]]> + + + + 一次获取多个键 + +set("foo", "bar"); $yac->set("foo2", "bar2"); + +// 传入键数组时,结果中只包含命中的键 var_dump($yac->get(array("foo", "foo2", "missing"))); // array(2) { ["foo"]=> string(3) "bar" ["foo2"]=> string(4) "bar2" } ?> diff --git a/reference/yac/yac/info.xml b/reference/yac/yac/info.xml index 695cbabb6..f40e01907 100644 --- a/reference/yac/yac/info.xml +++ b/reference/yac/yac/info.xml @@ -1,6 +1,6 @@ - + @@ -130,25 +130,24 @@ print_r($yac->info()); 46137344 - [slots_memory_size] => 4194304 - [values_memory_size] => 41943040 + [memory_size] => 75497472 + [slots_memory_size] => 8388608 + [values_memory_size] => 67108864 [segment_size] => 4194304 - [segment_num] => 10 + [segment_num] => 16 [miss] => 0 [hits] => 0 [fails] => 0 [kicks] => 0 [recycles] => 0 [start_time] => 1725955200 - [slots_size] => 32768 + [slots_size] => 65536 [slots_used] => 1 ) ]]> - 命中率可以按 hits / (hits + miss) 计算; - 持续增长的 kicksfails + 命中率可以按 hits / (hits + miss) 计算;持续增长的 kicksfails 计数器表明缓存正处于内存压力之下。 diff --git a/reference/yac/yac/set.xml b/reference/yac/yac/set.xml index a2e92be9c..b99036c5b 100644 --- a/reference/yac/yac/set.xml +++ b/reference/yac/yac/set.xml @@ -1,6 +1,6 @@ - + @@ -12,7 +12,7 @@ &reftitle.description; public boolYac::set - stringarraykeys + stringarraykey mixedvalue intttl0 @@ -22,8 +22,7 @@ intttl0 - 向缓存中存储一个值。如果键已存在, - 则覆盖已有条目,无论其是否已过期。 + 向缓存中存储一个值。如果键已存在,则覆盖已有条目,无论其是否已过期。 @@ -31,7 +30,7 @@ &reftitle.parameters; - keys + key string 类型的键,或者一个由 @@ -44,9 +43,7 @@ value - 要存储的值。除 resource 外的所有 PHP 类型都可以存储。 - 仅在单键形式下使用;当 keys 是数组时, - 该参数位置实际上是可选的 ttl。 + 要存储的值。除 resource 外的所有 PHP 类型都可以存储。仅在单键形式下使用;当 key 是数组时,该参数位置实际上是可选的 ttl @@ -79,11 +76,31 @@ $yac = new Yac(); $yac->set("foo", "bar"); // 存储单个值 $yac->set("foo", "baz"); // 覆盖已有条目 +?> +]]> + + + + 存储带 TTL 的条目 + +set("short-lived", "value", 5); sleep(6); var_dump($yac->get("short-lived")); // bool(false):已过期 +?> +]]> + + + + 一次存储多个条目 + +set(array("a" => 1, "b" => 2));