0

用Redis来做排行榜存储

Posted by reedboat on Dec 5, 2010 in 编程

随着SNS和微博产品的火热,NoSQL概念逐渐的兴起。出现了一大批各种各样的KeyValue存储系统。我比较感兴趣的是MongoDb和Redis, 因为单纯的Key-Value存储系统难以满足各种复杂的逻辑业务, 仍这两个数据库分别加入了一些关系性的特性,如能有效利用会有很好的效果。

redis目前提供四种数据类型:string,list,set,zset(sorted set)和hset(hash set)。
string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。
list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。
zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。
hset是另一个set,一个key对应的不再是一个元素而是一个hash表。

zset是个非常好的排行榜存储,一个key对应的一个数据集合,集合中的每个元素包涵两部分,value(待)排序的元素)和score(用来排序的得分依据)。例如用来存储微博关注数排行榜,value可以是微博用户的ID,而score则是该用户的关注数。
而且对于大部分排行榜数据,其实只需要存储Top N的数据,数据量小,效率高,用内存来存储非常合适,排行榜的实时性也可以做到很高。因为数据是用集合来存储的,存储的时候实际上是没有顺序的,排序计算是在获取的时候来做的.如果访问并发量很大的话,还可以再在前面做一个缓存。
利用redis的一个内置操作直接清除TopN外面的元素, 保持存储量的大小。
例如一个需要发布前30名的排行榜,我们使用的时候可以保留前500名的数据,防止需求变化。然后不断的往其中添加新数据,每当集合中的元素达到1000条的时候,进行一次trim操作,将集合的元素数量压缩成500。当获取前30名的时候,同样用redis做一个缓存,缓存时间设成30秒等。

redis zset数据结构支持的操作包括:
– 添加/删除/统计数量
– 修改score
– 获得score/排名
– 获取排名在某个区间的元素集合
– 获取score在某个范围的元素集合/数量
– 清理score/排名在某个区间外的元素
– 交集/并集运算

Tags: ,

 
1

非常简单的PHP模板引擎.

Posted by reedboat on Sep 10, 2010 in 编程

各种模板引擎很多,php3时代的phplib,使用简单方便,学习成本也低,但是因为每次执行都需要解析模板,性能存在一定的问题,逐渐被smarty替代。Smarty提供了模板编译,内容缓存。但是太复杂,承担了很多现在不应该由模版引擎承担的职责,使用的时候经常还需要翻看手册,smarty大量的文件载入其实也影响了性能。随着MVC模式的兴起,特别是zend framework的流行,视图和逻辑得到了更好的分离,模板引擎的需求越来越淡化了,越来越多的人开始认为php本身就是一个非常好的模板引擎。

真实的模板编写的过程是这样的,UI制作静态html页面,程序员来将其中的动态内容换成模板标签。所以以前认为通过模板引擎能够达到UI和研发工作的完全分离,互不干扰其实是基本达不到的。所以php做模板引擎没有太大的问题,方便而且灵活,可谓最强大的模板引擎。。

原生的php模板的缺陷在于两点

1。所有的输出标签都要用<?php echo ;?>, 书写太不方便,看起来也不够简洁,毕竟UI和程序员都是有可能修改模板的。

2. 太容易嵌入业务逻辑,有些人在时间紧迫的时候就可能会偷懒将业务逻辑直接写在模板里面。

第一个问题很简单就可以解决, 使用下面的函数即可简单的将<{,}>标签替换成<?php 和?> 并且自动添加echo和;

对于已经是原生的php模板,不需要做任何修改,都可以使用。下面的标签都合法。

(不想使用<{和}>符号的可自行修改下面的正则.)

<?php echo $var;?>
<?php echo strlen($var);?>
<{echo $var}>
<{$var}>
<{$this->var;}>
<{strlen($this->var);}>
<{$array.index}>

<{foreach($this->var as $key => $value):}>
<{endforeach}>
<{if ($a > $b ):}>
<{endif}>

同时为了性能考虑,也做了简单的编译支持。代码只有十几行,很容易修改放入自己的项目中。

<?php
function _include($_filename, array $_vars = null) {
    //这里简单的用global变量,只是为了代码的简洁,
    //实际使用的时候可通过其他方式传入。
    global $compile_dir;
    extract($_vars);
    $objfile = $compile_dir . "/" . md5( $_filename) . ".tpl.php";
    // 如果代码文件有修改,那么重新编译模板
    if ( @filemtime($_filename  ) >= @filemtime( $objfile ) ){
        _compile( $_filename, $objfile );
    }
    include $objfile;
}

function _compile( $_filename, $objfile ){
    $str = file_get_contents($_filename);
    //将数组引用的圆点替换成中括号和双引号
    $str = preg_replace('/<{(\s*\$\w[\w\d]+)\.([\w\d]+)\s*}>/',
            '<{$1["$2"]}>', $str);
    //将变量添加echo
    $str = preg_replace(
           '/<{\s*(?:echo\s*)?(\$[^ \s\(\)\.};]+)\s*;?\s*}>/',
           '<?php echo $1; ?>', $str);
    //替换函数调用,添加echo
    $str = preg_replace(
           '/<{\s*(?:echo\s*?)?([^ \t\r\n\(\)}]+)\(([^\t\r\n\(\)}@]+)\)(?:\s*;)?\s*}>/',
           '<?php echo $1($2); ?>', $str);
    //替换开始结束符号
    $str = str_replace( array( "<{", "}>" ), array( '<?php ', ' ?>'), $str);

    $fp  = fopen($objfile, "w+");
    fwrite($fp, $str);
    fclose($fp);
?>

至于第二点,对于一个团队来说,必须要有一定的规范来约束。可以经常组织一下CodeReview,不遵守规则的童鞋请大家喝可乐哈哈。

Tags: , , ,

 
0

学习设计模式

Posted by admin on Apr 21, 2008 in 编程

看了 http://www.javaeye.com/topic/18648?page=1 上面的讨论,感觉挺有收获。工厂模式说到底是为了减少依赖,便于维护。用设计模式的语言来说就是依赖抽象,不要依赖具体。几种工厂模式都是用来创建对象的,有时仔细想想,似乎没什么区别,情况稍有变化,就分不清是什么工厂模式了。设计模式背后的的OO思想是一致的,我觉得最主要的就是两条:

  1. 封装变化
  2. 减少依赖

所以各种模式常常看起来有许多的相似性,这很正常。判断设计模式,有时主要看意图。

简单工厂是为了创建单一产品。如果这个产品可能有多种类型,那么就需要使用工厂方法了。再者如果需要创建多种产品,而且彼此间相互依赖或者存在联系(即不是各种产品间的自由组合)时,就是抽象工厂发挥作用的时候了。(明天继续)

 
1

DOS命令

Posted by admin on Apr 25, 2007 in 编程

DOS 常用命令:
  dir 列文件名 deltree 删除目录树 cls 清屏 cd 改变当前目录

  copy 拷贝文件 diskcopy 复制磁盘 del 删除文件 format 格式化磁盘

  edit 文本编辑 mem 查看内存状况 md 建立子目录 move 移动文件、改目录名

  more 分屏显示 type 显示文件内容 rd 删除目录 sys 制作DOS系统盘
  ren 改变文件名 xcopy 拷贝目录与文件 chkdsk 检查磁盘 attrib 设置文件属性
  fdisk 硬盘分区 date 显示及修改日期 label 设置卷标号 defrag 磁盘碎片整理
  msd 系统检测 path 设置搜寻目录 share 文件共享 memmaker内存优化管理
  help 帮助 restore 恢复备份文件 set 设置环境变量 time 显示及修改时间
  tree 列目录树 debug 随机调试程序 doskey 重新调用DOS命令 prempt 设置提示符
undelete恢复被删的文件 scandisk检测、修理磁盘
网络命令
Ping
Ipconfig
/a
/renew
Tracert
Netstat
-a 显示所有连接及活动端口。
-e 显示以太网状态。
-n 以数字表格的形式现实地址和端口。
-o 显示与每个连接相关的进程id.
-p proto 显示由 proto指定的协议类型的连接
-r 显示路由表.
-s 按协议类型显示统计信息. 默认的统计有: IP(IPv6), ICMP(ICMPv6), TCP(TCPv6), UDP
ARP 显示和定制IP地址与物理(MAC)地址的转换表。
-a 显示所有的地址转换表
-g 同上.
-d 删除一个解析表中存在的项.
-s 指定静态解析项.
Finger  在运行 Finger 服务的指定系统上显示有关用户的信息,根据远程系统输出不同的变量。
-l  以长列表格式显示信息。
windows命令  
Tasklist
/SVC
重要语法
“&” 和“”
a & b,系统将在成功完成a后,接着执行b。
a b,系统将先执行a,未能成功完成则执行b,a执行成功将不执行b。

Copyright © 2012 苇叶舟 All rights reserved. Theme by Laptop Geek.