php yac实现原理
Yac 实现原理
Yac(Yet Another Cache)是一个基于共享内存的 PHP 扩展,用于实现高性能的缓存功能。其核心实现原理主要基于共享内存和哈希表结构。
共享内存机制
Yac 使用共享内存(Shared Memory)作为缓存数据的存储介质,允许多个 PHP 进程共享同一块内存区域。共享内存的分配和管理通过系统调用(如 shmget、shmat)实现,避免了进程间通信的开销。
- 共享内存通过键值(
key_t)标识,确保不同进程可以访问同一块内存。 - 内存分配大小在 Yac 初始化时通过配置参数(如
yac.shm_size)指定。 - 共享内存的生命周期与系统相关,即使 PHP 进程结束,共享内存中的数据仍可能保留。
哈希表结构
Yac 使用哈希表(Hash Table)存储键值对数据,通过哈希算法快速定位缓存项。
- 哈希表采用开放寻址法(Open Addressing)解决冲突。
- 哈希表的大小在初始化时固定,通常为 2 的幂次方,以提高哈希计算效率。
- 每个缓存项包含键、值、过期时间和哈希值等信息。
内存管理
Yac 通过内存分块(Slab Allocation)管理共享内存,减少内存碎片。

- 内存分为多个固定大小的块(Slab),每个块存储一个缓存项。
- 不同 Slab 大小用于存储不同大小的缓存数据,提高内存利用率。
- 内存分配和释放通过链表管理,避免频繁的系统调用。
过期机制
Yac 支持缓存项的过期时间(TTL),通过惰性删除(Lazy Expiration)和定期清理结合实现。
- 惰性删除:在访问缓存时检查是否过期,过期则删除。
- 定期清理:后台进程或特定触发条件下扫描并清理过期数据。
进程安全
Yac 通过信号量(Semaphore)或自旋锁(Spin Lock)实现多进程并发安全。

- 写操作加锁,确保同一时间只有一个进程修改共享内存。
- 读操作无锁,支持高并发读取。
性能优化
Yac 通过以下方式优化性能:
- 内存预分配:初始化时分配全部所需内存,避免运行时动态分配。
- 无序列化:直接存储 PHP 变量值,减少序列化/反序列化开销。
- 本地缓存:部分场景下结合本地内存缓存,减少共享内存访问。
核心代码逻辑
以下是 Yac 核心逻辑的简化实现(伪代码):
// 初始化共享内存
shm_id = shmget(key, size, IPC_CREAT);
shm_addr = shmat(shm_id, NULL, 0);
// 哈希表操作
hash = hash_function(key);
slot = hash % table_size;
while (table[slot].key != NULL) {
if (table[slot].key == key) {
// 更新现有项
break;
}
slot = (slot + 1) % table_size; // 开放寻址
}
// 写入缓存
table[slot].key = key;
table[slot].value = value;
table[slot].expire = time() + ttl;
// 读取缓存
if (table[slot].expire > time()) {
return table[slot].value;
} else {
// 惰性删除
table[slot].key = NULL;
return NULL;
}
适用场景
Yac 适用于以下场景:
- 高并发读写的缓存需求。
- 多进程共享数据的场景。
- 对性能要求苛刻的应用,如 API 响应缓存。
限制与注意事项
- 共享内存大小固定,无法动态扩展。
- 不支持持久化,服务器重启后数据丢失。
- 大量缓存项可能导致哈希冲突,影响性能。






