转与顶:牟长青和他28推徒弟们的下场

此贴来自转载,甚合吾口味,快哉快哉!!
很久以来,互联网上一直游荡着这么一群人:他们没有创意、没有新意、没有研究领域、没有理论体系、甚至……可能连自己的人格都没有。

他们有的只是伪原、只是转载、只是剽窃、只是炒作、只是互相拉拢(三人一群五人一拨)、只是忽悠新人、只互相吹棒、只是“礼尚往来”,用他们自己的话说“那是扩展人脉”。

记得贾志新在5G上也喷过这些所谓的网络推广,他更偏激,原意好像是:

一些所谓的网络推广无非就是在墙上、电线竿子上、到处乱贴小广告。跟现在随处可见的“城市蝗虫—办证”是一个操性。

最近CCTV的焦点访谈给出的揭密答案是:【这帮搞网络推广的就是网络黑社会】。似乎只能把网络黑社会这顶屎盆子扣在这帮人的头上才可以抵消人们盲目相信网络推广的无上威力。

可是,偏偏中国的互联网环境就适合这样最低层的从业者生长和漫延,更有甚者,已经把他们膜拜到某某专家、某某大师的位子,听到这样的称呼,我他妈的都笑喷了。

好,擒贼先擒王,先从这伙人的头目入手:牟长青

牟长青,一个来自重庆的进京务工人员,自称从接触互联网就一直做的是网络推广的工作,做过个人网站,有五年多的网络推广经验,自诩为擅长数据分析和网站流量推广。

爱浅谈,爱软文,爱吐血, 爱被徒弟们捧为网络推广大师, 也爱不搭理那些想借我大名炒作的人,我不是误人子弟的吹手, 也不是徒增网络垃圾的制造器, 我是牟长青, 我只代表我自己。 我和你们不一样, 我是2B推的创始人。 不信你动我试试。 老子笔名就是mcq0544。

下面,我就说说这帮以牟长青为首的网络2B们的推广之路,说得兴许有些残酷,还望见谅:

1.拼命打造一个“神仙”。

2.以“神仙”的口吻互相吹棒。

3.“神仙”拉小鬼,小鬼装“神仙”。

牟长青的忽悠就是这样一个被众人推上“神坛”的人,那些P大的站长们,可能没人知道他不是做网络推广的。可是有几人知道,你们除了知道牟长青的名字外,还知道什么?

哦,你也许还会说,他建了几个站,请问,你是先知道他的站?还是先知道他的人?我知道他有个站长导航、还有个什么9go9、还有就是最近刚成立的2B推

站长导航我可能上过3次,因为太无聊,不知道站长在上面能导个什么。全都是他的几个博客,在上面来回导。9go9我可能上过1次,一看他就是想将来建立一个收费的链接交换平台,没有任何创意能够吸引我。2B推好像是最近携他的几个徒弟共同弄的这么一个平台,我可能上去过2次,第一次还没访问成功,丫的都没个301转向。

如果,如果我是先看到这几个网站,然后才知道牟长青这个人,我肯定会佩服这个站长,因为吸引我的是他网站本身的优秀,而不是他本人的炒作。比如说焉牛网、5GME我都是闻其站名才知人名。

牟长青利用自己接触互联网早的机会,又擅长写一些八股之类的软文(什么浅谈呀、谈谈呀、吐血呀),历经“七七八十一载”,终于在小小的站长群里炒出了点名气,然后到处指手划脚,到处分享自己的“经验心得”。

可怜的站长们根本不知道互联网上的经验是过时最快的,而且好多经验是在某一个特定的互联网环境下才能生效的。他们哪里知道这些,只管跟着牟大师走就行了。很像44年前,天安门城楼下的那些红卫兵跟着他们心中的“红太阳”。

以无耻、无畏、无用、无能的软文手段吸引了大批互联网新人的眼球,牟长青从此被站长们供奉了成“神仙”。所以,后来才有了何涛那个恶心让人想吐的自我意淫差点演变成狗的管鹏

我会始终坚持认为:一个没有好功能、好服务、好内容网站的几乎跟太监长了前列腺没多大区别。可牟长青们偏偏能教站长把像太监似的网站长上前列腺!我永远也不会相信一个人在网上咋咋呼呼到处卖弄的网站突然有一天会被VC看重。

真正触犯我意识底层开始思考这帮二B们丑恶的嘴脸,还是看到5G公开宣布反对垃圾推广的那天,我隐约猜到像牟长青那样的“专家”们早就应该命悬一线了,整天除了给互联网上倒转垃圾、暴光域名、徒增笑耳之外,没见过有什么新点子、新模式、新产品是他们想出来的,这伙人已然成为互联网上人见人打的过街鼠。

也许你还会反驳我去年11月11号牟率子弟弄的那个2B推一夜之间的Alexa排名,呵呵,这太容易了,你随便叫个凤姐或芙蓉啥的,在她们的微博上嘀咕一声,肯定排名会进5K。

因为论名气,随着互联网上名人的越来越多,这些没有真才实学的牟长青们很可能会输给凤姐、芙蓉、小月月他们。论智商,随着中国互联网创业者的意识逐渐增强,他们知道真正俯首称臣的对象是用户而不是什么推广专家的时候,可能牟长青和他那些2B推们就真的该晾到一边了。

至少百姓网已经明显意识到了这点,请大家好好阅读百姓网的这篇贴子:“把市场费用给用户,而不给牛B的网址站和徐牛哥”。

各位,请好好想想张悟本是怎么锒铛入狱的,今天的牟长青跟张悟本不管是在炒作手法还是骗人招术上,他们都如出一辙,都是先把自己包装成专家、大师的行头来招摇撞骗!全国上下皆骂张悟本乃无耻之流,但你要说几句牟长青,却被此人归谬为你是想借他之名去炒作。(见过自恋的,没见过这么自恋的)

这样一个既不敢正视自己违法乱纪的坏种,又在不断为自己的黑社会行径进行狡辩的毒瘤,我们只能交给亲爱的祖国去处理。

好吧,敦请有关司法部门、公安机关介入调查这起互联网经济时代的隐形罪犯!
http://blog.donews.com/zszwyds/2011/01/21/2btui/

推荐:java虚拟机基础

这是来自阿里巴巴的温少的作品,整个文档从以下几个方面介绍了JVM基础知识。
• HotSpot
• ClassFile
• ClassLoader
• 内存模型、锁、同步
• JVM内存管理和垃圾收集.
我在这里附上下载地址:JVM基础.pdf
    作者基础很好,也很用心。作者对JVM和并发很有研究,还有另一个作品,就是广为人知的fastjson,号称世界上最快的java的json工具,事实也是这样。其中fastjson用到了ASM包中的一部分代码。ASM包被用来动态地修改class文件的代码,在动态代理等经常用到。比如spring,jsonlib都用到了类似的技术。
     fastjson我在自己的代码中已经使用了,效果确实不错。至于有人反映有一些小BUG,目前还没遇到。
    前几天想要破解一个java商业软件,因为不熟悉JVM,只好用反编译工具反编译JAR文件,修改源代码,再重新编译的方式来完成了。这样做,最明显的缺点是,反编译工具反编译的代码可读性差(在编译时,一些编译器会自动对代码进行混淆,反编译后也是混淆后的代码,变量和方法名都不具可读性),反编译的代码不一定正确,包关系丢失等,并且重新编译还有复杂的依赖关系。最后只有写了个注册机。如果熟悉JVM就好办了,用ASM包或者直接修改class文件均可。因此强烈推荐感兴趣的童鞋深入了解下JVM。

Program ape,you should be praticed in english

    就在刚刚,有一位童鞋问到:
  请问,xp下的php环境,$new_time = mktime();要报错,是不是不能用mktime()
  报错如下:  Strict standards:mktime()[function.mktime]:You should be using the time() instead in D:\xampp\htdocs
     其实他一问这个问题,我就断定不可能的事情,绝对是他用错了。我敢打赌,90%的程序员搞不懂时间这个问题,地理知识比较差劲,我也是一知半解。所以只可能是函数用错了。我一翻中文手册,快速地瞥了一眼,立马叹到糟糕,中文手册里肯定是遗漏了。当然这也不能怪翻译手册的,因为他们是无私奉献的,另外他们也都是老手,所以很多早已熟知的细节就不会再提了,况且中文手册都是针对新手的(连手册都不去看的况且称之为爱好者吧,老手也不会纠结于函数)。我不相信一个连英文都不认识几个的程序员,水平能有多高。其中国情等缘由就不细说了。
     在php官方的英文手册在是这么说的:
 Note:

As of PHP 5.1, when called with no arguments, mktime() throws an E_STRICT notice: use the time() function instead.

     不用解释了,一定是他的错。
    我记得前段时间还有某人问到为什么php中解析ini文件时,用#注释的ini文件解析会报错。马上断定,他用的是.parse_ini_file函数,查了下php中文手册,一看没有,立马想到,肯定是遗漏了。再次查看英文手册,答案明晃晃地闪了我的眼睛:
5.3.0 Added optional scanner_mode parameter. Single quotes may now be used around variable assignments. Hash marks (#) may no longer be used as comments and will throw a deprecation warning if used.
     还记得有人问为什么用ini_set改了安全模式还是没用。我立马知道,这一定是个不肯思考的coder。因为第一,假如你用ini_set就能轻易改系统的设置,那么这设置还有什么用呢?人家主机商不让你用某些函数,你ini_set一下解除了屏蔽,这不是个冷笑话么?最简单的逻辑问题也想不透;其二,这个页面php中文手册没有翻译,我想他也没去看手册吧,更别说看英文手册了。关键的是我回答了他以后,指出让其不要看中文手册,多看手册英文,被痛骂一顿“那要中文手册干嘛,XXX,要不是老子XXX”。。果断对其进行人格鄙视。
     So,program ape,you should be praticed in english.

转:用WinHex制作无法修改的AutoRun.inf文件

    在我们日常工作中,经常需要使用闪存(也称为U盘或者优盘)主要是AutoRun.inf文件在起作用,我们可以使用WinHex解决这一问题。首先 格式化闪存,文件系统选择默认的FAT32格式即可(由于格式的通用性比较好,所以最好选择FAT32)。然后在闪存根目录下手工新建一个名为 AutoRun.inf的文件(可以新建任何一个文件,然后改名为Autorun.inf就可以了。),接着打开WinHex,按下F9功能键,或者从 “工具”菜单下选择“磁盘编辑器”,打开需要处理的闪存(如果你插了多个,请确定那个闪存的盘符),定位到AutoRun.inf文件,可以看到文件名中 间有一个空格,文件名的后面也有一个空格,现在请将后面的空格(20)直接修改为“E5”,确认后保存再退出就可以了。
看起来AutoRun.inf的文件名没有发生任何变化,但这个时候,任何人都不能再打开它或者修改它了。或者,也可以将“20”更改为“E2”,这样可以将AutoRun.inf文件隐藏起来,使你不会每次都看见它而纳闷。
        (注:未验证,这种属于MBR的修改,危险性较大,勿轻易尝试)

Linux利器 strace

    strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
   strace使用参数

-p 跟踪指定的进程
-f 跟踪由fork子进程系统调用
-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
-r 打印每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
-c 统计每种系统调用所执行的时间,调用次数,出错次数。
-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出


应用场景

#1.跟踪你的web服务器系统调用
系统调用优化,也是web性能优化的一个较为重要的方向,尤其是在I/O密集型web应用的情况。我们这里的测试环境是CentOS5.4+Nginx+FastCGI。

<?php
//file:hello.php
define('DOCUMENT_ROOT', dirname(__FILE__));
include("hello.inc");
include("./hello.inc");
include(DOCUMENT_ROOT . "/hello.inc");
?>
#strace -f -F -o strace_nginx strace /wwwchroot/nginx/sbin/nginx -c /wwwchroot/nginx/nginx.conf
... (有部分不重要的数据影响排版,在这里使用...代替)
//--接受来自客户端的http请求
4165  recv(16, "GET /hello.php HTTP/1.1\r\nHost: f"..., 32768, 0) = 391
4165  epoll_ctl(9, EPOLL_CTL_MOD, 16, {EPOLLIN|EPOLLOUT|EPOLLET, {u32=3081162952, u64=698098541354471624}}) = 0
//--进行DNS查找
4165  getsockname(16, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("222.73.211.214")}, [16]) = 0
//--新建一个socket,连接Fast-CGI,端口号为9000
4165  socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 17
4165  ioctl(17, FIONBIO, [1])           = 0
4165  epoll_ctl(9, EPOLL_CTL_ADD, 17, {EPOLLIN|EPOLLOUT|EPOLLET, {u32=3081163048, u64=697886249710965032}}) = 0
4165  connect(17, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 )
4165  epoll_wait(9, {{EPOLLOUT, {u32=3081163048, u64=697886249710965032}}, {...}, 5\
12, 300000) = 2
4165  gettimeofday({1295420285, 130967}, NULL) = 0
4165  recv(16, 0xbfdd7d8b, 1, MSG_PEEK) = -1 EAGAIN (Resource temporarily unavailable)
4165  getsockopt(17, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
//--将用户http请求交给Fast-CGI
4165  writev(17, [{"\1\1\0\1\0\10\0\0\0\1\0\0\0\0\0\0\1\4\0\1\3\30\0\0\21\7GATEWA"..., 832}], 1) = 832
4165  epoll_wait(9, {{EPOLLIN|EPOLLOUT, {u32=3081163048, u64=697886249710965032}}}, 512, 300000) = 1
4165  gettimeofday({1295420285, 131559}, NULL) = 0
//--接收Fast-CGI响应
4165  recv(17, "\1\6\0\1\0V\2\0X-Powered-By: PHP/5.2.10"..., 65536, 0) = 112
4165  readv(17, [{"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65424}], 1) = 0
4165  mmap2(NULL, 274432, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7514000
4165  close(17)                         = 0
4165  munmap(0xb7514000, 274432)        = 0
//-- 响应客户端http请求,即http响应
4165  writev(16, [{"HTTP/1.1 200 OK\r\nServer: nginx/0"..., 228}, {"22\r\n", 4}, ..., 5) = 273
4165  write(5, "116.66.34.82 - - [19/Jan/2011:14"..., 191) = 191
4165  setsockopt(16, SOL_TCP, TCP_NODELAY, [1], 4) = 0
4165  recv(16, 0x9b024e8, 32768, 0)     = -1 EAGAIN (Resource temporarily unavailable)

阅读剩余部分...

为什么程序里经常用 i ,j,k等作变量

    为什么程序里经常用 i ,j,k等作变量,特别是循环里。我们都会不自觉地写出for(i=0;i<n;i++){}这样的代码,而不是for(a=0;a<b;a++){}    呢?
      这个问题说起来确实很无聊。因为没有任何人规定要这么做,只是约定俗成了。话说在很久很久以前,机器语言,汇编语言等古老的语言里,变量和变量类型这个概念并不明显。50年代,fortran作为第一门高级语言诞生了,其中有了一个高级语言的雏形,也是我们现在看到的高级语言的始祖。在fortran里,有一个规则,叫IN规则。Fortran规定,凡以字母I,J,K,L,M,N六个字母开头的变量名,如无另外说明则为整型变量。而以i开头,是因为其是integer的缩写。而整形数是程序里最频繁出现的数据类型,所以程序里就会见到很多i,j,k,l,m,n开头的变量,然后到了循环里,就干脆简写成以上字母了。慢慢的,就成了习惯。
     最后,以上纯属牵强附会,哈哈。不过本人到确实写过半年的fortran,很是怀念。

MySQL Optimize Table

    Optimize Table是个好东西,很难说他能帮我们提高系统运行效率(具体的讨论可以到这里看:http://www.xaprb.com/blog/2010/02/07/how-often-should-you-use-optimize-table/),但明显的是可以帮我们回收更多的空间、减少碎片。
    官方是这么说的
OPTIMIZE TABLE should be used if you have deleted a large part of a table or if you have made many changes to a table with variable-length rows (tables that have VARCHAR, VARBINARY, BLOB, or TEXT columns). Deleted rows are maintained in a linked list and subsequent INSERT operations reuse old row positions. You can use OPTIMIZE TABLE to reclaim the unused space and to defragment the data file. After extensive changes to a table, this statement may also improve performance of statements that use the table, sometimes significantly.

1. 回收空间 Defragment

在InnoDB的维护过程中,我们总会遇到磁盘耗尽、或者InnoDB Tablespaces用完的情况。这时候,在考虑扩容等方案之前,最好先使用Optimize Table试试。如果你的表大字段(Text Blob Varchar),并且更新、删除较频繁的话,Optimize之后可能会腾出大量的空间。需要注意的是这仅仅是针对INNODB而言的

2. InnoDB 和 MyISAM

目前支持optimize命令的引擎有 MyISAM, InnoDB, and ARCHIVE,对于InnoDB,会将optimize命令映射为ALTER TABLE命令,该命令会重建数据表,更新索引统计信息、回收主键索引中空间。
     如果你的MySQL是有备库的,如果你只希望在主库上执行的话,那么可以加上关键字NO_WRITE_TO_BINLOG(或者LOCAL,意思完全相同)。


转:Mongodb亿级数据量的性能测试

进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:

(所有插入都是单线程进行,所有读取都是多线程进行)

1) 普通插入性能 (插入的数据每条大约在1KB左右)

2) 批量插入性能 (使用的是官方C#客户端的InsertBatch),这个测的是批量插入性能能有多少提高

3) 安全插入功能 (确保插入成功,使用的是SafeMode.True开关),这个测的是安全插入性能会差多少

4) 查询一个索引后的数字列,返回10条记录(也就是10KB)的性能,这个测的是索引查询的性能

5) 查询两个索引后的数字列,返回10条记录(每条记录只返回20字节左右的2个小字段)的性能,这个测的是返回小数据量以及多一个查询条件对性能的影响

6) 查询一个索引后的数字列,按照另一个索引的日期字段排序(索引建立的时候是倒序,排序也是倒序),并且Skip100条记录后返回10条记录的性能,这个测的是Skip和Order对性能的影响

7) 查询100条记录(也就是100KB)的性能(没有排序,没有条件),这个测的是大数据量的查询结果对性能的影响

8) 统计随着测试的进行,总磁盘占用,索引磁盘占用以及数据磁盘占用的数量

并且每一种测试都使用单进程的Mongodb和同一台服务器开三个Mongodb进程作为Sharding(每一个进程大概只能用7GB左右的内存)两种方案

其实对于Sharding,虽然是一台机器放3个进程,但是在查询的时候每一个并行进程查询部分数据,再有运行于另外一个机器的mongos来汇总数据,理论上来说在某些情况下性能会有点提高

基于以上的种种假设,猜测某些情况性能会下降,某些情况性能会提高,那么来看一下最后的测试结果怎么样?

备注:测试的存储服务器是 E5620  @ 2.40GHz,24GB内存,CentOs操作系统,打压机器是E5504 @ 2.0GHz,4GB内存,Windows Server 2003操作系统,两者千兆网卡直连。

mongodb.png

从这个测试可以看出,对于单进程的方式:

1) Mongodb的非安全插入方式,在一开始插入性能是非常高的,但是在达到了两千万条数据之后性能骤减,这个时候恰巧是服务器24G内存基本占满的时候(随着测试的进行mongodb不断占据内存,一直到操作系统的内存全部占满),也就是说Mongodb的内存映射方式,使得数据全部在内存中的时候速度飞快,当部分数据需要换出到磁盘上之后,性能下降很厉害。(这个性能其实也不算太差,因为我们对三个列的数据做了索引,即使在内存满了之后每秒也能插入2MB的数据,在一开始更是每秒插入25MB数据)。Foursquare其实也是把Mongodb当作带持久化的内存数据库使用的,只是在查不到达到内存瓶颈的时候Sharding没处理好。

2) 对于批量插入功能,其实是一次提交一批数据,但是相比一次一条插入性能并没有提高多少,一来是因为网络带宽已经成为了瓶颈,二来我想写锁也会是一个原因。

3) 对于安全插入功能,相对来说比较稳定,不会波动很大,我想可能是因为安全插入是确保数据直接持久化到磁盘的,而不是插入内存就完事。

4) 对于一列条件的查询,性能一直比较稳定,别小看,每秒能有8000-9000的查询次数,每次返回10KB,相当于每秒查询80MB数据,而且数据库记录是2亿之后还能维持这个水平,性能惊人。

5) 对于二列条件返回小数据的查询,总体上性能会比4)好一点,可能返回的数据量小对性能提高比较大,但是相对来说性能波动也厉害一点,可能多了一个条件就多了一个从磁盘换页的机会。

6) 对于一列数据外加Sort和Skip的查询,在数据量大了之后性能明显就变差了(此时是索引数据量超过内存大小的时候,不知道是否有联系),我猜想是Skip比较消耗性能,不过和4)相比性能也不是差距特别大。

7) 对于返回大数据的查询,一秒瓶颈也有800次左右,也就是80M数据,这就进一步说明了在有索引的情况下,顺序查询和按条件搜索性能是相差无几的,这个时候是IO和网络的瓶颈。

8) 在整个过程中索引占的数据量已经占到了总数据量的相当大比例,在达到1亿4千万数据量的时候,光索引就可以占据整个内存,此时查询性能还是非常高,插入性能也不算太差,mongodb的性能确实很牛。

那么在来看看Sharding模式有什么亮点:

1) 非安全插入和单进程的配置一样,在内存满了之后性能急剧下降。安全插入性能和单进程相比慢不少,但是非常稳定。

2) 对于一个条件和两个条件的查询,性能都比较稳定,但条件查询性能相当于单进程的一半,但是在多条件下有的时候甚至会比单进程高一点。我想这可能是某些时候数据块位于两个Sharding,这样Mongos会并行在两个Sharding查询,然后在把数据进行合并汇总,由于查询返回的数据量小,网络不太可能成为瓶颈了,使得Sharding才有出头的机会。

3) 对于Order和Skip的查询,Sharding方式的差距就出来了,我想主要性能损失可能在Order,因为我们并没有按照排序字段作为Sharding的Key,使用的是_id作为Key,这样排序就比较难进行。

4) 对于返回大数据量的查询,Sharding方式其实和单进程差距不是很大,我想数据的转发可能是一个性能损耗的原因(虽然mongos位于打压机本机,但是数据始终是转手了一次)。

5) 对于磁盘空间的占用,两者其实是差不多的,其中的一些差距可能是因为多个进程都会多分配一点空间,加起来有的时候会比单进程多占用点磁盘(而那些占用比单进程少的地方其实是开始的编码错误,把实际数据大小和磁盘文件占用大小搞错了)。

测试最后的各个Sharding分布情况如下:

{
        "sharded" : true,
        "ns" : "testdb.test",
        "count" : 209766143,
        "size" : 214800530672,
        "avgObjSize" : 1024.0000011441311,
        "storageSize" : 222462757776,
        "nindexes" : 4,
        "nchunks" : 823,
        "shards" : {
                "shard0000" : {
                        "ns" : "testdb.test",
                        "count" : 69474248,
                        "size" : 71141630032,
                        "avgObjSize" : 1024.0000011515058,
                        "storageSize" : 74154252592,
                        "numExtents" : 65,
                        "nindexes" : 4,
                        "lastExtentSize" : 2146426864,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 11294125824,
                        "indexSizes" : {
                                "_id_" : 2928157632,
                                "Number_1" : 2832745408,
                                "Number1_1" : 2833974208,
                                "Date_-1" : 2699248576
                        },
                        "ok" : 1
                },
                "shard0001" : {
                        "ns" : "testdb.test",
                        "count" : 70446092,
                        "size" : 72136798288,
                        "avgObjSize" : 1024.00000113562,
                        "storageSize" : 74154252592,
                        "numExtents" : 65,
                        "nindexes" : 4,
                        "lastExtentSize" : 2146426864,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 11394068224,
                        "indexSizes" : {
                                "_id_" : 2969355200,
                                "Number_1" : 2826453952,
                                "Number1_1" : 2828403648,
                                "Date_-1" : 2769855424
                        },
                        "ok" : 1
                },
                "shard0002" : {
                        "ns" : "testdb.test",
                        "count" : 69845803,
                        "size" : 71522102352,
                        "avgObjSize" : 1024.00000114538,
                        "storageSize" : 74154252592,
                        "numExtents" : 65,
                        "nindexes" : 4,
                        "lastExtentSize" : 2146426864,
                        "paddingFactor" : 1,
                        "flags" : 1,
                        "totalIndexSize" : 11300515584,
                        "indexSizes" : {
                                "_id_" : 2930942912,
                                "Number_1" : 2835243968,
                                "Number1_1" : 2835907520,
                                "Date_-1" : 2698421184
                        },
                        "ok" : 1
                }
        },
        "ok" : 1
}

虽然在最后由于时间的关系,没有测到10亿级别的数据量,但是通过这些数据已经可以证明Mongodb的性能是多么强劲了。另外一个原因是,在很多时候可能数据只达到千万我们就会对库进行拆分,不会让一个库的索引非常庞大。在测试的过程中还发现几个问题需要值得注意:

1) 在数据量很大的情况下,对服务进行重启,那么服务启动的初始化阶段,虽然可以接受数据的查询和修改,但是此时性能很差,因为mongodb会不断把数据从磁盘换入内存,此时的IO压力非常大。

2) 在数据量很大的情况下,如果服务没有正常关闭,那么Mongodb启动修复数据库的时间非常可观,在1.8中退出的-dur貌似可以解决这个问题,据官方说对读取没影响,写入速度会稍稍降低,有空我也会再进行下测试。

3) 在使用Sharding的时候,Mongodb时不时会对数据拆分搬迁,这个时候性能下降很厉害,虽然从测试图中看不出(因为我每一次测试都会测试比较多的迭代次数),但是我在实际观察中可以发现,在搬迁数据的时候每秒插入性能可能会低到几百条。其实我觉得能手动切分数据库就手动切分或者手动做历史库,不要依赖这种自动化的Sharding,因为一开始数据就放到正确的位置比分隔再搬迁效率不知道高多少。个人认为Mongodb单数据库存储不超过1亿的数据比较合适,再大还是手动分库吧。

4) 对于数据的插入,如果使用多线程并不会带来性能的提高,反而还会下降一点性能(并且可以在http接口上看到,有大量的线程处于等待)。

5) 在整个测试过程中,批量插入的时候遇到过几次连接被远程计算机关闭的错误,怀疑是有的时候Mongodb不稳定关闭了连接,或是官方的C#客户端有BUG,但是也仅仅是在数据量特别大的时候遇到几次。

最新补充:在之后我又进行了几天测试,把测试数据量进一步加大到5亿,总磁盘占用超过500G,发现和2亿数据量相比,所有性能都差不多,只是测试6和测试7在超过2亿级别数据之后,每400万记录作为一个循环,上下波动30%的性能,非常有规律
rrefer:http://www.cnblogs.com/lovecindywang/archive/2011/03/02/1969324.html

    Page :
  1. 1
  2. 2