一直在说分布式,感觉很神秘高大上,其实php的下memcached实现分布式还是很简单的,下面就简单梳理一下。
1. memcached 的分布式实现
memcached 的分布式,是由程序实现的,比如有多个memcached 服务器 server1,server2,server3 和 server4 等
php 中可以使用函数 addServer 来将这些服务加入
bool Memcache::addServer ( string $host [, int $port = 11211 [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callback $failure_callback [, int $timeoutms ]]]]]]]] )
其中:$host : 主机
$port : 端口
$persistent: 控制是否持久化连接 默认 true
$weight : 存储权重
$timeout : 控制超时时间 默认 1s
$retry_interval: 控制超时重连时间,默认15s 值为-1 时表示放弃重连
其他参数略
添加函数 add | set
bool Memcache::add ( string $key , mixed $var [, int $flag [, int $expire ]] )
其中: $key : 键名
$var : 值
$flag : 对值进行压缩 一般取值 MEMCACHE_COMPRESSED
$expire: 以秒计算的过期时间 0 表示不过期 但是最长时间30天后 仍然会过期
我们讲了上面俩函数,主要是说明下面的例子:
<?php
$memcache_host1 = '192.168.1.101';
$memcache_host2 = '192.168.1.102';
$memcache_host3 = '192.168.1.103';
$memcache_host4 = '192.168.1.104';
$memcache = new Memcache;
$memcache->addServer($memcache_host1, 11211,MEMCACHE_COMPRESSED,10);
$memcache->addServer($memcache_host2, 11211,MEMCACHE_COMPRESSED,20);
$memcache->addServer($memcache_host3, 11211,MEMCACHE_COMPRESSED,30);
$memcache->addServer($memcache_host4, 11211,MEMCACHE_COMPRESSED,40);
$key1 = md5('key1');
$key2 = md5('key2');
$key3 = md5('key3');
#code here...
$key10 = md5('key10');
$value = array(1,2,3,4,5,6,7,8,9,10);
$memcache->add($key1, $value[0]);
$memcache->add($key2, $value[1]);
$memcache->add($key3, $value[2]);
#code here...
$memcache->add($key10, $value[9]);
2. 先了解一些命令
我们使用下面的命令,连接一下服务
telnet 127.0.0.1 11211
看一下常用命令
常用命令 | 命令说明 |
stats items | 显示所有缓存项目的统计信息 |
stats slabs | 显示所有的slab统计情况 |
stats cachedump 1 3 | 查看 slab_id为1 的前3条数据 |
stats reset | 清空所有统计数据 等同于 flush_all |
get foo | 查询key为foo的值 |
set foo 1 0 6 hello1 | 储存一个键名为 foo 失效时间为0 存储值长度为6 值为 hello1 的键值对 第二个参数? |
delete foo | 删除一个键为foo的值 |
add/incr/decr/replace | 添加/增量/减量/替换值 |
3. 查询存储结果
stats items #我们看到有俩个字段 item1 和 item2
#第一个是我之前测试存入的
stats cachedump 1 2
ITEM foo [3 b; 0 s]
ITEM ac [12 b; 0 s]
END
#第二个是我刚刚存入的 server2
stats cachedump 2 3
ITEM c2add694bf942dc77b376592d9c86ef [1 b; 0 s]
ITEM c2add694bf942dc77b376592d9c862cd [1 b; 0 s]
其他的分别1 条 3条 和 4条数据
我们使用 get 命令查看每一条的值都是不相同的,这就保证了数据的唯一性
为啥4个memcached 存入的条数 不一样呢, 原来我们在 addServer 中添加了第四个字段 权重字段
根据总的权重分布,和各自的占比 然后存入不同权重的数据量
4. 我们在session中使用 memcached
session.save_handler = memcache
session.save_path ="tcp://127.0.0.1:11211"
#如果有多个服务器,可以使用","进行分割,也可以设置响应的权重
#即将host:port后面添加参数
#如: ?persistent=1&weight=2
5. memcached 在Laravel中的使用
#config/cache.php 文件
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
很明显,我们在 servers 中添加 对应的多台memcached 服务器就好了
如果需要启动这个作为缓存,在.env 文件中添加 CACHE_DRIVER=memcached 即可
对了,肿么多了个参数 sasl ? 里面还有用户名和密码,详情请点击 这里 进行安装配置
6. memcached的特点和弊端
(1) 保存的item数量没有限制 只要内存足够
(2) 32位系统中使用的最大存储空间是 2GB 64位无限制
(3) key最长250 超过无法存储
(4) 单个key存储数据最大1M 超过无法存储
(5) 算法 hash存储(例如取余 增加服务器 会导致命中失败) 一致性存储 (增加服务器不会影响)
(6) 不能遍历所有key 操作会引起阻塞