Archive

Author Archive

Memcache内存分配策略

December 14th, 2010 Tank 2 comments

上周由于接手个一个新的项目,该项目对于memcache的依赖非常大,从而导致我不得不真的开始深入了解memcache的内存使用情况,这里总结下我个人的收获,也算是一次小的memcache优化吧。

一、Memcache内存分配机制

        关于这个机制网上有很多解释的,我个人的总结如下。

  1. Page为内存分配的最小单位。

    Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定。如果需要申请内存时,memcached会划分出一个新的page并分配给需要的slab区域。page一旦被分配在重启前不会被回收或者重新分配(page ressign已经从1.2.8版移除了)
    Memcached pages

  2. Slabs划分数据空间。

    Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储。如下图,每个slab只存储大于其上一个slab的size并小于或者等于自己最大size的数据。例如:slab 3只存储大小介于137 到 224 bytes的数据。如果一个数据大小为230byte将被分配到slab 4中。从下图可以看出,每个slab负责的空间其实是不等的,memcached默认情况下下一个slab的最大值为前一个的1.25倍,这个可以通过修改-f参数来修改增长比例。
    Memcached slab

  3. Chunk才是存放缓存数据的单位。

    Chunk是一系列固定的内存空间,这个大小就是管理它的slab的最大存放大小。例如:slab 1的所有chunk都是104byte,而slab 4的所有chunk都是280byte。chunk是memcached实际存放缓存数据的地方,因为chunk的大小固定为slab能够存放的最大值,所以所有分配给当前slab的数据都可以被chunk存下。如果时间的数据大小小于chunk的大小,空余的空间将会被闲置,这个是为了防止内存碎片而设计的。例如下图,chunk size是224byte,而存储的数据只有200byte,剩下的24byte将被闲置。
    Memcached chunk

  4. Slab的内存分配。

    Memcached在启动时通过-m指定最大使用内存,但是这个不会一启动就占用,是随着需要逐步分配给各slab的。
             如果一个新的缓存数据要被存放,memcached首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请。slab申请内存时以page为单位,所以在放入第一个数据,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,在从这个chunk数组中选择一个用于存储数据。如下图,slab 1和slab 2都分配了一个page,并按各自的大小切分成chunk数组。

  5. Memcached内存分配策略。

    综合上面的介绍,memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储。
    这里有几个特点要注意,

    1. Memcached分配出去的page不会被回收或者重新分配
    2. Memcached申请的内存不会被释放
    3. slab空闲的chunk不会借给任何其他slab使用

 

      知道了这些以后,就可以理解为什么总内存没有被全部占用的情况下,memcached却出现了丢失缓存数据的问题了。

关于memcached命令行参数可以参考:http://techgurulive.com/2010/01/26/how-to-configure-memcached-memcached-configuration-parameters/

Categories: Memcache Tags:

通过设置公共父域名的cookie达到垮子域名的效果

December 13th, 2010 Tank No comments

        今天为了能够成功访问公司另外一个部门的资源,不得不跨域设置cookie,因为对方使用了cookie做身份验证,否则请求会被拒绝。解决方案如下:

       假设我现在使用的域名是 tank.tkiicpp.com,而我需要访问 subdomain.tkiicpp.com的一个资源,并且需要在cookie里指定一个特殊值以标识身份,例如: vendor = tkiicpp,这样才能通过 subdomain.tkiicpp.com 的身份验证,这个时候出现了一个问题,我必须在 tank.tkiicpp.com 域下设置一个 cookie 能够在 subdomain.tkiicpp.com 域使用。幸好这两个域名都是 tkiicpp.com 的子域名,这个就是解决这个问题的关键,通过设置一个cookie到父域名( tkiicpp.com ) 下,在访问 subdomain.tkiicpp.com 的时候,这个cookie会被默认带上,java代码如下:

        Cookie cookie = new Cookie("vendor", "tkiicpp");
        //设置为-1指定当前cookie不持久化,将随浏览器的关闭而被清理
        cookie.setMaxAge(-1);
        //指定cookie的域为父域名,注意域名开头必须为“.”
        cookie.setDomain(".tkiicpp.com");
        //指定cookie影响的域名下的路径,默认是没有的,如果不写,cookie将被忽略,这里设置为所有路径都使用
        cookie.setPath("/");

        response.addCookie(cookie);

        为了能够在IE里设置父域名的cookie,必须添加下面在header属性,关于P3P的详细资料可以查看http://www.w3.org/TR/P3P/#P3PPolicies

    response.addHeader("P3P", "CP=CAO PSA OUR");

 

参考资料:

1、http://blogs.unbolt.net/index.php/brinley/2010/03/31/p3p-fix-for-internet-explorer-to-access-cross-domain-cookie-in-iframe

Categories: Java, web Tags:

Free book download(zz)

November 10th, 2010 Tank No comments

首先找到优秀的外国的空间存储器。

              http://rapidshare.de

    http://rapidshare.com

    http://mihd.net/

    http://depositfiles.com/

    http://megaupload.com

    http://www.mediafire.com/

    http://www.2shared.com/

    http://www.file2you.net/upload/

    http://www.hungryflix.com/

    http://www.sendspace.com/

    http://www.gbaopan.com

    www.uploading.com

    www.51dir.com

    http://www.51ok.com/

    www.hivot.com

    http://sexupload.com

    http://ultrashare.net

    http://rapidupload.com

    http://zshare.net

    http://uploadspy.com

    http://savefile.com

    .http://mytempdir.com

    http://upload.com

    http://hyperupload.com

    http://sendspace.com

    http://www.up-file.com

    http://bestsharing.com

    http://www.live-share.com

    http://www.speedyshare.com

    http://www.quickdump.com

    http://upload.hostiran.net

    http://www.file.sc

    http://uploaded.to

    http://www.yousendit.com

    http://www.rogepost.com

    http://www.f-forge.com

    http://badongo.com

    rapidshare的资源最丰富,包括电影,软件,书籍。对免费用户唯一的缺点就是等待的时间太长,下载一本书,等待一段时间。下载几本书,等待可能要几个小时。由于资源的丰富,又不得不依赖它,真是又爱又恨。网上有介绍破解流量限制的软件,个人试了很多,都不好用,有兴趣的在网上搜索一下学习。

    直接用google搜索,书名+rapidshare.de/files、书名+inurl:rapidshare,rapidshare.com/users+关键词。

    还有很多面向 rapidshare的搜索引擎:

    http://www.rapidfox.net/

    http://www.rapidsharefiles.net/

    http://www.rapidexplorer.net/

    http://www.freechinaguide.com/search/

    http://www.funfail.com/

    http://shareminer.com/

    http://filesbot.com/

    http://www.rapidsharer.org/

    针对Rapidshare等免费存储空间专门的搜索引擎,但是试过就知道,效率绝对不及Google。

    个人用搜索用户的笨方法找到自己想要的资料,这有点像在金沙江淘金,比较费力。

    大家不妨用多种方法试一试。

    http://filesbot.com/?q=users

    GRE

    http://rapidshare.com/users/S6NML7

    http://rapidshare.com/users/URE983

    http://www.freebooksource.com/IELTS-SAT-TOEFL-GRE-GMAT.htm

    经济

    http://rapidshare.com/users/RD4HZB

    词汇

    http://rapidshare.com/users/6CEKPE

    计算机

    http://rapidshare.com/users/T8Q8RB

    rapidshare的搜索应用

    http://rapidshare.com/users/S6NML7

    http://mihd.net/

    http://depositfiles.com/

    这两个几乎没有限制,本人用得比较多。搜索方法与上面类似。

    http://megaupload.com

    有用户数量限制,每次用都说用户已满,没有用过,不过很多人推荐。

    其它的存储空间没有用过,不好评价。

    第二种方法就是BitTorrent,Emule等软件下载。

    没有英语环境的人学习英语,并查找英文资料,就是要融入英语国家的生活氛围、生活习惯、生活圈子。这时候,多学习学习外国的相关文化等资料是有好处的。读书,就是一种学习的手段。

    北美的图书资料异常丰富,往往你所想知道的信息都在某本书里。但是,如何找到这些书呢?

    互联网的到来使得以前很多遥不可及的书籍唾手可得。这里我介绍的就是一种基于互联网的读书方式。

    很多人已经知道如何用BitTorrent(BT,变态)、Emule(电驴)等p2p(点对点)的软件工具去下载电影、音乐,但是,其实它们也是可以用来下载书籍的。没事的时候,完全可以用它们的搜索功能(或其他搜索方式)去搜索相关的书籍。

    重点推荐mininova:http://www.mininova.org/ 是我很欣赏的一个BitTorrent资源网站,提供了电影、书籍、软件等BT种子。这里我主要谈该站提供的书籍方面的种子。

    相关书籍大体上来讲分为2种,电子书http://www.mininova.org/sub/50 (eBook,主要以PDF格式为主)和音频书籍http://www.mininova.org/sub/51 (Audio Book,主要以MP3格式为主)。11838 torrents in subcategory "Ebooks",其实外国的数字图书馆也不过几万书籍,这里就就有一万多本书,完全能够满足基本需求了。

    音频书籍其实是很好的一种资源。有很多人不喜欢看书,那么就听书吧。举个例子,畅销书《穷爸爸富爸爸》的作者除了写书,其实他还创作了好些音频书籍,来具体地介绍如何理财,如果有机会多听听的话一方面可以提高英语听力,另外一方面,也能很好地提高自己的相关知识水平。此外,还有好些音频书籍,例如介绍如何理解人的身体语言、如何调解心理情绪等等。音频书籍虽然用起来更省心,但是毕竟需要占用大量的硬盘空间,电子书籍则往往只需要很小的空间。而且,电子书籍是纸质书籍的电子版,因此更普及,涵盖的面更广。在网上,你能发现很多有趣、甚至稀奇古怪的电子书籍。Emule http://lib.verycd.com/e_magazine/ 这个地方主要书籍是杂志。

    包括考研原材料来自于《The Economist》。

    第三种方法就是论坛,博客收集的书籍上传的地址。

    与“网上读书论坛”的专家找书版类似的地方,上面能够找到很多好书籍。http://www.rapidshared.org/index.php?t=category&n=ebooks

    自称是世界上最大的一键式文件在线存放服务商。用户上传文件被下载过即可永久保存。

    Cnshare

    http://www.cnshare.org/

    是rapidshare的中文版。

    Asiaing

    http://www.asiaing.com/

    报纸、杂志、电子书籍,种类齐全。

    Ebooksclub

    http://ebooksclub.org/?module=index

    下载电子书最简单的办法就是找别人已经下载好的。

    最值得推荐的就是渡岸学术网

    http://www.freeduan.com/eb/index.htm

    这里的书籍相当丰富,多为教材与学术性书籍,很适合研究用。

    大多数的书籍配有详细说明和图书封面,美观,赏心悦目。

    

    推荐“海外选书系统”搜索书籍,可以结合http://books.google.com 与http://www.amazon.com/

    用。“海外选书系统”按中图法分类,很适合中国人。

    http://www.cnpbook.com/expert/index.php?toURI=useredit.php?curUser=1可以结合duxiu中西合璧。梦寐以求的学习方式来临

 

源地址:http://blog.renren.com/GetEntry.do?id=478196447&owner=245489196

Categories: Resources Tags:

自己动手解决Flash builder 4正式版license过期问题

September 29th, 2010 Tank No comments

Flash Builder 4正式版的确是一个非常优秀的flex开发工具,对于我这个flash外行偶尔也会使用下,不过最近我的license过期了,启动的时候就弹出无奈的提示框,于是自己尝试跟踪了下程序,找到了一个针对目前版本(2010.09.29)的破解方案。由于涉及到Flash Builder 的验证方式,所以不保证以后的版本可以解决。

我用的方法时直接修改Flash Builder的过期时间,所以需要使用到一个工具SQLite,具体破解步骤如下:

1、下载SQLite的工具

     到SQLite网站上下载一个SQLite修改工具,http://www.sqlite.org/download.html

     我用的是“Precompiled Binaries For Windows”下的第一个。关于SQLite是什么我就不介绍了,反正目前版本的Flash Builder用这种标准格式存储的数值。

2、修改pcd.db的过期时间

      将下载的zip包解压到一个目录,我放到了c:\sqlite, 然后启动命令行(这个工具是基于命令行的,没有图形界面,好像还有有界面的sqlite工具,可以自行搜索后下载),到c:\sqlite目录(cd c:\sqlite)。

      执行下面的命令

sqlite3.exe "D:\Program Files\Common Files\Adobe\Adobe PCD\pcd.db"

      这个命令是将Flash Builder的数据库打开,然后输入如下命令:

update domain_data set value = '2015/08/03' where subDomain =
'FlashBuilder-CS5-Win-PR' and key = 'ExpirationDate';

      这里的“2015/08/03”是你要设置的过期时间,自己安排吧。

      按下Ctrl + C 退出程序。

      好了,我们要做的以及完成了,启动下程序试下吧。

 

仅以此文纪念下我第一次破解程序吧。

Java中的查找路径问题

August 9th, 2010 Tank No comments

一直使用IDE或者基于web容器来运行Java程序,所以很少去考虑一些基础的,但是非常重要的问题——Java运行时的文件查找路径。

最近由于需要运行一个自己开发的小系统,需要独立运行Java进程,这个时候才发现,其实IDE和web容器为我们默默的做的很多事情。

1、首先一个路径问题就是——class类的查找

        classpath相对来说到时我们经常遇到的问题,用来指定系统运行时需要加载的类文件的路径(自定义查找的可以不依赖这个),通常在web容器中会将 WEB-INF/lib 作为依赖包的路径,而classes作为未打包的class文件的默认路径。

        其实这个属性值在运行JVM时可以通过-classpath或者-cp来指定,具体的用法如下:

        -classpath / -cp 后接一个空格,然后是要被指定的路径,路径分为两种类型:第一种是压缩包(.jar或者.zip文件),另一种是文件夹,每个路径之间使用分号(:)分隔File.pathSeparator(window上是“;”,Linux上是“:”)来分隔。

         如果是压缩包,需要指定完整的文件路径,例如有一个jms.jar文件,放在 /data/project/lib 下,则需要指定为/data/project/lib/jms.jar,这样造成一个问题是,基本上每个项目都会有很多依赖包,手动写太麻烦,其实可以使用另外一种方式指定,例如: /data/project/lib/* ,这样指定 /data/project/lib 下的所有压缩包都可以在运行时被查找。

        如果是为压缩的class文件夹,则只需要指定到根目录,例如:编译后的class文件都在 /data/classes/com/google/ 下,其中com/google是包的路径,则只需要指定classpath为 /data/classes/,注意这里没有 “*” 号,所以是查找未压缩的类文件。

        具体的一个classpath可以像这个:

java -cp .:/data/project/lib/*:/data/project/ext/jms.jar:\
/data/project/classes Test

 

2、接下来是程序运行时查找资源文件

Java程序运行时查找资源一般有两种方式可以获得:

第一种是使用File类,new File(String fileName)可以通过相对路径获得指定文件,但是这个“相对路径”是一个困扰人的地方,如果能够指定绝对路径倒是可以高枕无忧的使用这个方法,但是使用相对路径的时候,往往会让人很迷惑。例如:

public class Test {
    public static void main(String[] args) {
        File file = new File(".");
        System.out.println(file.getAbsolutePath());
    }
}

这段代码返回的路径为你运行代码是路径,例如:在/data/test/ 目录下运行,输出为/data/test/.;在/data/other/ 目录运行,输出则为/data/other/. 。这说明File的默认路径其实是随着运行的路径在变化的,其实默认值就是执行命令的路径。

但是用惯了在classes下面直接查找ApplicationResources.properties文件的人,代码里查找时一般会只用相对路径直接查找,这个时候不稳定的根目录就是一个大问题。不可能真的每次都期待启动的时候先到正确的目录下(用脚本处理还是可以的),所以尝试下改变默认的跟路径吧。

user.dir,作为一个Java程序的运行时参数,可以指定默认的File路径,指定方式为

java -Duser.dir=/data/project/classes/ Test

执行下Test类会发现输出的确变成了/data/project/classes。

但是如果在classes目录下方一个ApplicationResources.properties文件, 修改file 为 new File("ApplicationResources.properties"); 理论上我们认为这样可以找到对应的文件,而且程序执行后输出的路径是: /data/project/classes/ApplicationResources.properties ,这个和实际的路径完全相同的,不过如果尝试读写文件,或者判断file.exists(), 却会发现文件找不到。这个问题由于牵涉到native的代码,还没有搞清楚为什么,这种情况下回发现调用file.getAbsolutePath()返回的路径虽然是对的,但是file.createNewFile()却依旧在执行程序的路径下生成文件,说明JVM使用的虚拟文件系统和实际的系统发生了偏差。

经过搜索和跟踪代码,可以肯定的一点是,user.dir属性看起来是修改的,但是File类在获得绝对路径和文件流时使用了不同的路径查找方式,前者的确使用了user.dir属性,而且不严重是否存在,而后者使用的还是一个看不到的(所以也没法修改的)属性,代表启动JVM的实际路径,并查找文件。相关的讨论可以参考:http://stackoverflow.com/questions/2275362/java-file-exists-inconsistencies-when-setting-user-dir

如果一定要避免这个相对路径的问题,可以使用绝对路径的方式

//使用user.dir指定资源文件的路径
File file = new File("ApplicationResources.properties"); //使用相对路径先查找文件
file = new File(file.getAbsolutePath()); //使用前面查找到的绝对路径重新创建File实例
System.out.println(file.exists()); //这个时候会发现file已经可以找到了

不过这样的代码看起来不是那么的优雅。如果直接指定绝对路径的情况下可以使用File的方式。

第二种方式是使用ClassLoader类加载。

ClassLoader类提供了几种方法获得资源:

URL getResource(String name);

Enumeration<URL> getResources(String name);

URL findResource(String name);

这里只列出几个,其他的比较类似。getResource方法其实是先委托ClassLoader的父类去依次加载,如果没有找到,才使用自己的findResource方法去查找,所以findResouce方法决定了自定义的资源文件是否可以找到。使用方法如下

//获得URL后使用
URL url = Test.class.getClassLoader()
              .getResource("ApplicationResources.properties");
//获得直接获得文件流
InputStream propertyInput = Test.class.getClassLoader()
             .getResourceAsStream("ApplicationResources.properties");

findResource()方法其实和File的构造方法比较类似,都可以使用绝对路径和相对路径,绝对路径和URL格式的相对路径这里不讨论,这里只说明在当前机器上的相对路径下如何查找到自定义的资源文件。

使用ClassLoader加载资源时,如果找不到,则直接返回NULL的URL,或者抛出异常。如果我们将ApplicationResources.properties放到classes目录下,然后修改启动参数如下

java -cp .:/data/project/lib/*:/data/project/classes/ Test

则可以正常的找到ApplicationResources.properties文件,因为ClassLoader会从classpath中去查找资源文件,就想查找class类文件一样(注意classes添加方式是没有使用*号的,即认为这个目录下是为压缩的class文件),查找的优先级按classpath中声明的顺序。

如果设置了user.dir参数会怎样影响ClassLoader的查找呢?

将ApplicationResources.properties文件复制到新的目录/data/project/temp/下,并修改启动参数:

java -cp .:/data/project/lib/*:/data/project/classes/
     -Duser.dir=/data/project/temp/ Test

如果输出获得的URL会发现ApplicationResources.properties文件是在temp目录下被找到的,说明ClassLoader会优先查找user.dir路径。

所以综合以上的分析,获得一个资源文件的最优方式是使用ClassLoader来查找,这样只需要指定classpath就可以做到,而且查找到的文件时正确的、可用的,而使用File会需要修改user.dir,可能带来的影响还不详细(至少已经影响到ClassLoader了),更主要的是修改了以后会造成虚拟的文件系统和实际系统不同步,要么自己痛苦的修改为绝对路径,要么就会出现不可预知的错误。

 

PS:通过输出执行时的环境和properties信息发现,IDE的确只指定了classpath来完成这个任务,web容器的以后补上。查看的代码为

        System.out.println("\n\nEnvs:\n");
        for (Entry entry : System.getenv().entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }

        System.out.println("\n\nProperties:\n");
        for (Entry entry : System.getProperties().entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }

 

        在最近的工作中发现ClassLoader获取资源的一个小问题,就是无法获取jar文件,因为在ClassLoader中所有的jar包会作为资源文件的目录看待(个人理解),所以jar包里的class文件可以直接通过包路径找到,例如:java.util.Date 就是直接以rt.jar为跟路径开始查找的。要获得一个jar文件似乎只能尝试使用File类,不过可以通过ClassLoader先获取一个jar包里的class文件的URL(getResource方法返回的就是URL),然后通过url获取path,这个path会以file:**/*.jar!为前缀,需要自己解析出jar文件的绝对路径,这样才能保证jar文件可以被找到。有点麻烦。不过幸好一般情况下不需要直接访问jar文件的。

Categories: Java Tags: , ,

搞定Google Syntax for WordPress MU

June 29th, 2010 Tank No comments

昨天花了半天时间专门处理代码高亮的插件问题,尝试了很多个都以失败告终。一直以为是因为版本兼容的问题。

我使用的是WordPress MU2.9.2版,很多插件都是很早发布的,所以不确定问题在哪。幸好发现了“WordPress与Google Syntax的兼容性问题”,发现的确pre标签的属性被修改了。不过这个只解决一个问题,就是默认的WordPress编辑器的visual和html切换时的问题,在wp-admin/includes/post.php的“initArray”最后面添加了一行代码,

    'extended_valid_elements' => "pre[name|class]"

之后的确不会在切换时不会在去掉name属性了。

可是这样代码高亮还是显示不出来,因为保存时还是会将name和class两个属性都去掉。经搜索发现,WordPress MU的确对HTML标签做了过滤操作,具体见“变态的WordPress MU的html过滤”。由于不会PHP,也不想改那么多不懂的地方,于是继续搜索更加可行的解决方案。“怎样在WordPress MU中使用Javascript标签”这篇文章的方法比较简单方便,于是尝试着做了下面的改动:

修改wp-includes文件夹下的kses.php文件,查找到“allowedposttags”,这里定义了所有允许的标签和相应的属性,由于Google Syntax插件只需要对pre标签添加两个属性:name和class(更多的属性自己可以考虑添加),所以我找到在“allowedposttags”里的pre标签(所有标签是按字母顺序排列的,很好找)的定义

    'pre' => array(
              'style' => array(),
              'width' => array())
 

在里面添加了name和class属性,如下

    'pre' => array(
             'style' => array(),
             'width' => array(),
             'name'  => array(),
             'class' => array()
    )

这样保存的时候就不会过滤掉name和class属性了,Google Syntax也可以正常显示了。

Hello world

June 8th, 2010 Tank No comments

终于搭建好了一个Wordpress mu的博客,简单体验了下,的确很不错。

所以以后的关于生活和技术的总结就留在这里了。

第一篇:Hello world。

Categories: Life Tags: