浏览 5822 次
锁定老帖子 主题:memcache遍历策略
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2012-11-08
最后修改:2012-11-08
用memcache,不好遍历。我想了一个办法。 键分三种, 第1种,只有一个就是news_index_index,值的模样是逗号分隔的字符串或数组。 第2种,news_index_XXX,XXX是数字,长度不限,如果xxx=1200,则news_index_1200只能存 120000-120099的新闻id,值的模样同上。 第3 种,news_XXX,XXX长度不限,就是新闻id,值就是点击量,int型 分3步,存,取,遍历(倍数为100)。 存 假设有一个item,key为news_index_index,值为如同1,2,4,44,这样的数据。 当一篇新闻的id例如12004,则除以100取整,得到120, 查询key=news_index_index if (没有120) { 在key=news_index_index的item 的值中添加120; 添加news_index_120的item ,值为空。 } 查询key=news_index_120,查有无12004 if (有12004) { key为news_12004 的item 的值加1; }else { key=news_index_120,的item的值加上一个12004; 添加一个item,key=news_12004,value=1 } 取 如果要id为333367的点击量,则直接取key为 news_333367的item的值即可 遍历 当我要遍历所有在 memcache中的新闻id时,则有了上述机制后,太简单了,就不说了。 备注 另外,为防止数据过多,可以在半夜把点击量保存到数据库中,然后清除第2、3种键,并把第一个键的值清空。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2012-11-08
谨受教……………………………………
|
|
返回顶楼 | |
发表时间:2012-11-08
上php代码
<?php /** * 新闻点击量memcache使用 * $mem = Sys::get_memcache();是获得memcache对象的 * 建议每晚把流量加到表中,或每隔1小时等,然后每晚清除 * 实际应用中缓存应该是稀疏的,除非被搜索引擎遍历等,关系也不大。 * * @author: */ class Dao_NewsClick { //取某id的流量 public function load($id, $type='news') { $id = intval($id); $mem = Sys::get_memcache(); $key = "{$type}_{$id}" ; $result = $mem->get($key); if ($result === false) { return null; }else { return $result; } } /** * id的流量加1 */ public function save($husheng_id, $type='news') { $rate = 100; //倍率 $key1 = "{$type}_index_index"; //总索引的键 $mem = Sys::get_memcache(); $id = intval($husheng_id); $index = intval( $id / $rate ); //索引 $key2 = "{$type}_index_{$index}"; $key3 = "{$type}_{$id}"; //先查总索引; $index_index = (array)$mem->get($key1); if ($index_index === false) { //如果没有,要先生成 $mem->set($key1, array(), 0, 0); //存个数组进去 $index_index = (array)$mem->get($key1); } if (!in_array($index, $index_index)) { $index_index[] = $index; $mem->set($key1, $index_index,0,0); //保存到总索引 $mem->set($key2, array()); } //查具体的桶 $barrel = (array)$mem->get($key2); if (!in_array($id, $barrel)) { $barrel[] = $id; $mem->set($key2, $barrel,0,0); $mem->set($key3,1,0,0); }else { $mem->increment($key3); } } /** * 打印所有成html,调试用 */ public function print_html($type="news") { echo "<ul>"; $key1 = "{$type}_index_index"; //总索引的键 $mem = Sys::get_memcache(); $index_index = (array)$mem->get($key1); foreach ($index_index as $value) { $key2 = "{$type}_index_{$value}"; $barrel = (array)$mem->get($key2); foreach ($barrel as $v2) { $key3 = "{$type}_{$v2}"; $v3 = $mem->get($key3); echo "<li>{$v2}:{$v3}</li>"; } } echo "</ul>"; } /** * 清除所有键,只留一个总的空的。 */ public function clear_all($type="news") { $key1 = "{$type}_index_index"; //总索引的键 $mem = Sys::get_memcache(); $index_index = (array)$mem->get($key1); foreach ($index_index as $value) { $key2 = "{$type}_index_{$value}"; $barrel = (array)$mem->get($key2); foreach ($barrel as $v2) { $key3 = "{$type}_{$v2}"; $mem->delete($key3); } $mem->delete($key2); } $mem->set($key1, array(),0,0); } } |
|
返回顶楼 | |
发表时间:2012-11-12
唉唉,请说详细点嘛,这样看起来很乱的了
|
|
返回顶楼 | |
发表时间:2012-11-12
如果是遍历,还不如直接访问数据的。
|
|
返回顶楼 | |
发表时间:2012-11-12
你可以用redis
|
|
返回顶楼 | |
发表时间:2012-11-13
memcache做你这个太煎熬了,推荐redis,我们公司的使用redis,每几分钟把点击数更新到数据库中去
|
|
返回顶楼 | |