romeoz / rock-cache
内存中键值存储的统一API。存储可以使用:APC、Redis、Memcache、Couchbase或MongoDB。所有存储对象都拥有一个接口,因此您可以在不更改工作代码的情况下进行切换。
Requires
- php: >=5.4.0
- romeoz/rock-events: 0.11.*
Requires (Dev)
- phpunit/phpunit: ^4.7.0
- romeoz/rock-mongodb: 0.15.*
Suggests
- romeoz/rock-mongodb: required for using MongoDB as storage
README
可以使用哪些存储
所有存储对象都有一个接口,因此您可以在不更改工作代码的情况下进行切换。
特性
- 所有存储的一个接口 - 您可以在不更改代码的情况下更改存储
- 标签缓存(版本控制和分组方法)
- 锁定 - 排除“竞态条件”(“狗群”或“缓存缺失风暴”)的影响
- 值序列化器(json或PHP序列化器)
- 自动反序列化
- 独立模块/组件,用于Rock框架
目录
安装
从命令行
composer require romeoz/rock-cache
或在您的composer.json中
{ "require": { "romeoz/rock-cache": "*" } }
快速开始
####Memcached
$config = [ 'hashKey' => CacheInterface::HASH_MD5, // Default: HASH_MD5 'serializer' => CacheInterface::SERIALIZE_JSON // Default: SERIALIZE_PHP - php serializator ]; $memcached = new \rock\cache\Memcached($config); // or \rock\cache\versioning\Memcached for approach versioning $tags = ['tag_1', 'tag_2']; $value = ['foo', 'bar']; $expire = 0; // If use expire "0", then time to live infinitely $memcached->set('key_1', $value, $expire, $tags); // automatic unserialization $memcached->get('key_1'); // result: ['foo', 'bar']; $memcached->flush(); // Invalidate all items in the cache
####MongoDB
$connection = new \rock\mongodb\Connection; $collection = $connection->getCollection('cache') $collection->createIndex('id', ['unique' => true]); $collection->createIndex('expire', ['expireAfterSeconds' => 0]); // create TTL index $config = [ 'storage' => $connection, 'cacheCollection' => 'cache' ]; $mongoCache = new \rock\cache\MongoCache($config); ...
####锁定键
在多线程模式下可能发生竞态条件。为了避免这种影响,您需要在键上安装一个锁。
$memcached = new \rock\cache\Memcached $value = $memcached->get('key_1'); if ($value !== false) { return $value; } if ($memcached->lock('key_1')) { // the query to DBMS or other... $memcached->set('key_1', 'foo'); $memcached->unlock('key_1'); }
文档
####get($key) 通过键返回值。
####getMulti(array $keys) 通过键返回多个值。
####set($key, mixed $value, $expire = 0, array $tags = null) 将值设置为缓存。
####setMulti($key, mixed $value, $expire = 0, array $tags = null) 将多个键值设置为缓存。
####add($key, mixed $value, $expire = 0, array $tags = null) 将值添加到缓存。
如果服务器上已存在,则返回false。
####exists($key) 检查键是否存在。
####touch($key, $expire = 0) 更改键的过期时间(TTL)。
####touchMulti(array $keys, $expire = 0) 更改多个键的过期时间(TTL)。
####increment($key, $offset = 1, $expire = 0, $create = true) 增加缓存的值。
####decrement($key, $offset = 1, $expire = 0, $create = true) 减少缓存的值。
####remove($key) 从缓存中移除值。
####removeMulti(array $keys) 从缓存中移除多个值。
####getTag($tag) 根据标签返回键。
####getMultiTags(array $tags) 根据多个标签返回键。
####existsTag($tag) 检查标签是否存在。
####removeTag($tag) 移除标签。
####removeMultiTag(array $tags) 移除多个标签。
####getAllKeys() 返回所有键。
支持:
Memcached
、Redis
、APC
。
####getAll() 返回所有值。
支持:
Memcached
、APC
。
####lock($key) 在键上设置锁。
####unlock($key) 解锁键。
####flush() 从缓存中移除所有值。
####status() 返回服务器状态。
支持:
Memcached
、Memcache
、Redis
、APC
、Couchbase
。
####getStorage() 返回原生缓存存储实例。
演示
- 安装Docker 或 askubuntu
docker run --name demo -d -p 8080:80 romeoz/docker-rock-cache
- 打开演示 https://:8080/
要求
您可以使用每个存储单独,对每个存储的要求单独。
- PHP 5.4+ 和 7.0+
- Redis 2.8/3.0/3.2/4.0。应安装
apt-get install redis-server
或docker run --name redis -d -p 6379:6379 romeoz/docker-redis:4.0
(推荐)。还应安装 PHP 扩展apt-get install php-redis
- Memcached。应安装
apt-get install memcached
或docker run --name memcached -d -p 11211:11211 romeoz/docker-memcached
(推荐)。还应安装 php-extension Memcacheapt-get install php-memcache
或 Memcachedapt-get install php-memcached
。
php-extension Memcached 依赖项
- APCu。应安装
apt-get install php-apcu
。
对于 PHP 5.6 及以下版本,允许 pecl-extensions APCu 4.0 及以下。 安装示例。
- Couchbase DB 4.x.x。PHP 5.6 或更高版本,php-extension couchbase 2.3.x-2.4.x。 逐步安装 或
docker run --name couchbase -d couchbase/server:community-4.1.1
(安装示例)。 - MongoDB 2.6-3.0。若要将 MongoDB 作为存储使用,需要 Rock MongoDB:
composer require romeoz/rock-mongodb
所有未加粗的依赖项均为可选
有一个现成的 docker 容器: docker run --name phpfpm_full -d romeoz/docker-phpfpm:5.6-full
。但是,由于安装了大量的 pecl-extensions,这可能会对您来说是不必要的。
存储比较
Redis 是最佳的关键值存储缓存。如果您需要容错和非常易于扩展的集群,并且能够承担得起(推荐硬件要求),请使用 Couchbase。Redis 和 Couchbase 存储中的数据在服务器重启后也会恢复。
标记方法的差异
###标签分组
最快的方法,但存在缓存溢出的可能性。
设置值
$cache = new \rock\cache\Memcached; $cache->set('key_1', 'text_1', 0, ['tag_1', 'tag_2']); $cache->set('key_2', 'text_2', 0, ['tag_1']);
内存中查看
key_1: text_1
key_2: text_2
tag_1: [key_1, key_2]
tag_2: [key_1]
删除标签
$cache->removeTag('tag_2');
内存中查看
key_2: text_2
tag_1: [key_1, key_2]
###版本标签
是最佳实践,但比分组标签的方法慢,因为获取包含标签的缓存时,会发送多个请求来比较版本。没有缓存溢出。
参考文献:nablas by D.Koterov (RUS) 或 "Reset group caches and tagging" by A.Smirnov (RUS)。
设置值
$cache = new \rock\cache\versioning\Memcached; $cache->set('key_1', 'text_1', 0, ['tag_1', 'tag_2']); $cache->set('key_2', 'text_2', 0, ['tag_1']);
内存中查看
key_1: [
value : text_1,
tags : [
tag_1 : 0.20782200 1403858079,
tag_2 : 0.20782200 1403858079
]
]
// tag : microtime
key_2: [
value : text_2,
tags : [
tag_1 : 0.20782200 1403858079,
]
]
tag_1: 0.20782200 1403858079
tag_2: 0.20782200 1403858079
删除标签
$cache->removeTag('tag_2');
内存中查看
key_1: [
value : text_1,
tags : [
tag_1 : 0.20782200 1403858079,
tag_2 : 0.20782200 1403858079
]
]
key_2: [
value : text_2,
tags : [
tag_1 : 0.20782200 1403858079,
]
]
tag_1: 0.20782200 1403858079
tag_2: 0.29252400 1403858537
返回值
$cache->get('key_1'); // result: false
内存中查看
key_2: [
value : text_2,
tags : [
tag_1 : 0.20782200 1403858079,
]
]
tag_1: 0.20782200 1403858079
许可证
Rock Cache 库是开源软件,采用 MIT 许可证。