缓存应对的场景
一个网页存在不同区域的内容,不同区域的更新内容和频率各不相同
动态计算信息,并根据结果展示不同的内容,例如登陆状态,每个用户状态不同,显示不同
页面级的缓存(静态文件),只提高了读的效率,没有解决写的效率的问题
memcached
在数据库和动态内容之间建立缓存区,并部署在独立服务器上,用于加速读写操作,这里是使用memcached
来说明
memcached是啥?
memcached使用了高效的基于key的hash算法来存储数据结构,并且使用了精心设计的内存分配器,使得查询时间复杂度达到O(1),不管存了多少数据,查询出来的时间都不变(看不懂就跳过,其实我也不是特别明白)。
几个点说明
既然是缓存,即对要缓存的数据进行过期时间设置
作为分布式缓存系统,memcached可以运行在独立服务器上,使用TCP Socket来访问
使用了libevent函数库来实现网络并发模型,其中包括epoll,较大并发依然有很好的性能
存储复杂内容的时候,使用序列化技术,将要存储的对象进行序列化,取出时,在进行反序列化操作
应用场景
缓存用户登录状态(读操作)
<?php
$user_ticket = '0sdb129dst1ef021263ff121';
$memcache = memcache_conect('192.168.100.100', 11711);
$user = $memcache->get($user_ticket);
if ($user !== false) {
var_dump($user); //缓存获取的对象,打印出来
exit;
}
$sql = "select * from users where user_ticket = '{$user_ticket}'"; // 没有缓存对象,从数据库读取
$conn = mysql_connect('localhost', 'root', 'pass','db_user');
$res = mysql_query($sql, $conn);
$user = mysql_fetch_array($res, MYSQL_ASSOC);
$memcach->add($user_ticket, $user, false, 3600); // 将从数据库读取的内容,缓存起来,下次就从缓存读取
var_dump($user);
阅读数+1(写操作)
<?php
$page = 'article_9212f.html';
$memcache = memcache_connect('192.168.100.100', 11711);
$count = $memcache->increment($page, 1);
if ($count === false) {
$memcache->add($page, 1, false, 0); // 第一次,使用新增缓存数据
exit(1);
}
if ($count == 1000) { // 当缓存数达到1000时,执行一次写入数据库操作
$memcache->set($page, 0, false, 0); // 对1000的缓存项,进行归零操作,便于下个1000的递增
$sql = "update page_view set view_count=view_count + ".$count." where page = '{$page}'";
$conn = mysql_connect('localhost','root','pass','db_user');
mysql_query($sql,$conn);
mysql_close($conn);
}
扩展memcached
memcached的水平扩展代码实现
<?php
function memcache_connector($key){
// 多台主机IP
$hosts = [
'192.168.100.101',
'192.168.100.102',
'192.168.100.103',
];
// $key 实现md5加密获得类似“e4u7r3194fj12dfhu1”值
// 只获取前5个字符
// 使用hexdc将前5个字符进行十进制转换
// 获得数值进行“模3”的处理,如果有4台主机,就进行“模4”的处理,依次类推,注意,0代表第一台主机
$host_index = hexdec(substr(md5($key), 0, 5)) % 3;
$host = $hosts[$host_index];
return memcache_connect($host, 11711);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。