关于
我的项目
热度排行
- [转] 宫崎骏用动漫教给我们的人生哲理,每一句都能说到心里! - (日期:[八月 24, 2013] 点击:[53,441])
- Google 网页爬虫报告无法连接站点解决办法 - (日期:[七月 20, 2014] 点击:[38,654])
- 架设Tiny Tiny RSS(TTRSS)阅读器,找回Google Reader! - (日期:[九月 27, 2013] 点击:[27,786])
- SkyDrive、DropBox和Google Drive三大公有云存储服务对比 - (日期:[六月 25, 2013] 点击:[25,609])
- 升级到至强E5440后,与i5 CPU笔记本性能对比 - (日期:[二月 18, 2014] 点击:[23,755])
- 公钥私钥加密解密数字证书数字签名详解 - (日期:[四月 19, 2014] 点击:[22,968])
- 本站建站技术合集 - (日期:[九月 20, 2013] 点击:[22,522])
- 使用OpenerDNS解决无法访问Google的问题 - (日期:[七月 5, 2014] 点击:[21,822])
- WordPress博客添加“返回顶部”按钮 - (日期:[七月 14, 2013] 点击:[21,225])
- Linux文件系统基础之inode和dentry - (日期:[三月 13, 2015] 点击:[20,182])
- 云存储中的HTTP鉴权算法分析 - (日期:[二月 7, 2014] 点击:[18,647])
- 存储基础知识之——磁盘阵列原理及操作实战 - (日期:[二月 9, 2014] 点击:[17,514])
- 精选37条强大的常用linux shell命令组合 - (日期:[九月 4, 2013] 点击:[17,442])
- DNS原理、架构和配置详解 - (日期:[九月 6, 2013] 点击:[16,820])
- Netty和Jetty的Java NIO 网络框架模型分析 - (日期:[七月 13, 2013] 点击:[16,339])
- CoreOS 初识之安装 - (日期:[十一月 16, 2014] 点击:[16,193])
- Windows与Linux文件系统互访的几种方法 - (日期:[八月 21, 2014] 点击:[15,737])
- Dijkstra算法求解最短路径分析 - (日期:[七月 12, 2014] 点击:[14,933])
- NAS解决方案实现多媒体文件共享播放 - (日期:[十二月 21, 2014] 点击:[13,942])
- 简介 - (日期:[九月 1, 2012] 点击:[13,771])
- 如何编程实现 2 + 2 = 5? - (日期:[六月 2, 2014] 点击:[13,273])
- 搭建了一个iNews程序 - (日期:[十月 15, 2013] 点击:[13,246])
- 2014年9月曝出的Bash ShellShock漏洞简析 - (日期:[九月 26, 2014] 点击:[13,148])
- 彻底解决WordPress博客垃圾评论的问题 - (日期:[八月 5, 2013] 点击:[13,109])
- 如何使用1M的内存排序100万个8位数 - (日期:[三月 27, 2014] 点击:[12,561])
- 全部日志列表 - (日期:[十一月 11, 2012] 点击:[12,367])
- 关于回调函数和this指针探讨 - (日期:[八月 24, 2014] 点击:[12,226])
- 给定一个long型常量,其值为x,给定long型变量a,要求a & x 的取值集合 - (日期:[九月 8, 2012] 点击:[11,713])
- 开源好用的电子书管理服务Talebook(Calibre网络版)安装使用指南 - (日期:[四月 23, 2022] 点击:[11,515])
- WordPress建站必备实用插件 - (日期:[八月 7, 2014] 点击:[11,369])
分类目录
文章归档
- 2025年一月 (1)
- 2024年十二月 (1)
- 2024年四月 (1)
- 2024年二月 (1)
- 2023年九月 (1)
- 2023年一月 (1)
- 2022年十月 (1)
- 2022年八月 (2)
- 2022年四月 (1)
- 2022年三月 (1)
- 2021年十二月 (2)
- 2021年十月 (2)
- 2021年九月 (1)
- 2021年八月 (1)
- 2021年五月 (1)
- 2021年三月 (2)
- 2021年一月 (2)
- 2020年十二月 (5)
- 2020年十一月 (2)
- 2020年十月 (2)
- 2020年九月 (1)
- 2020年八月 (5)
- 2020年七月 (2)
- 2019年九月 (1)
- 2018年八月 (1)
- 2018年七月 (1)
- 2018年六月 (1)
- 2018年五月 (1)
- 2018年三月 (1)
- 2018年二月 (1)
- 2018年一月 (2)
- 2017年十二月 (3)
- 2017年十月 (4)
- 2017年九月 (1)
- 2017年七月 (1)
- 2017年六月 (1)
- 2016年十二月 (1)
- 2016年十月 (1)
- 2016年九月 (1)
- 2016年七月 (2)
- 2016年六月 (1)
- 2016年二月 (3)
- 2015年十二月 (3)
- 2015年十一月 (2)
- 2015年十月 (1)
- 2015年八月 (2)
- 2015年七月 (4)
- 2015年六月 (1)
- 2015年三月 (2)
- 2015年二月 (1)
- 2015年一月 (4)
- 2014年十二月 (2)
- 2014年十一月 (2)
- 2014年十月 (5)
- 2014年九月 (8)
- 2014年八月 (11)
- 2014年七月 (17)
- 2014年六月 (7)
- 2014年五月 (15)
- 2014年四月 (16)
- 2014年三月 (14)
- 2014年二月 (5)
- 2013年十二月 (5)
- 2013年十一月 (3)
- 2013年十月 (13)
- 2013年九月 (13)
- 2013年八月 (13)
- 2013年七月 (9)
- 2013年六月 (8)
- 2013年五月 (1)
- 2013年三月 (3)
- 2013年一月 (1)
- 2012年十一月 (1)
- 2012年九月 (12)
- 2012年八月 (3)
- 2011年二月 (1)
- 2009年三月 (1)
- 2009年二月 (1)
- 2008年十一月 (1)
- 2008年六月 (1)
- 2008年四月 (1)
- 2008年三月 (1)
作者归档: 童燕群
二阶段提交及相关学习笔记
在分布式数据库中,处理分布式事务是比较重要的技术。分布式事务的处理保证了数据的一致性。二阶段提交在可用性和一致性性上面做到了最好的折中。是一种基本的事务处理机制或者协议。
对于二阶段提交的准确解释可以参考维基百科词条:http://zh.wikipedia.org/wiki/%E4%BA%8C%E9%98%B6%E6%AE%B5%E6%8F%90%E4%BA%A4
理解二阶段提交关键是要结合redo、undo日志,日志可以固化到DB中,也可以回滚即丢弃,基于此,才能做到预提交与实际提交的分离。
在分布式系统中,一般来说不止是1个协调者与2~3个参与者之间交互,当考虑容错性时,通常会考虑如下场景:
协调者在完成了一阶段的预提交过程后,得出了本事务的执行结论,在本地日志中记录了结论,正待向参与者发出结论时,宕机,这样除了协调者本身之外,就没有人知道该事务的结论。因此必须等待协调者恢复之后才能继续该事务,在此之前所有参与者都将阻塞。各个阶段所获取的资源一直不释放,可能导致整个集群业务受阻。
解决该问题的办法是将第二阶段(正式提交阶段)再变为两个阶段,先让集群中若干个参与者知道自己将要提交结论,而不是记录本地日志,这样该协调者无论在哪个阶段宕机,都可以由新选出的协调者通过查询各个参与节点的状态来判断当前处于哪个阶段,从而继续后面的各个阶段的操作。也就是三阶段提交了,这样参与者与协调者的交互步骤增加,实际操作起来也变得复杂很多,因此实用性不强。
[转] 深入多线程编程
线程库
多线程编程定式
无锁编程(Lock Free)
阻塞型同步(Blocking Synchronization)
非阻塞型同步(Non-blocking Synchronization)
优先级反转(Priority Inversion)
优先级继承(Priority Inheritance)
优先级顶置(Priority Overhead)
内存屏障
转载自:http://blog.chinaunix.net/uid-20682147-id-3160080.html
PDF文档查阅链接:
一道基础的词法解析题
原日志信息
标题:《计算单词数目的小程序-2009-05-24考试》
发布时间:5/24/2009
作者:童燕群
2009年,公司开始推行技能鉴定考试,这是我第一次参加的技能鉴定考试,那次考试最终以成绩不作为技术等级评定的依据收场。据说有的部门直接以金钱来奖励考分高者,在天涯论坛上面闹得沸沸扬扬。当年做这道题目时用完了所有考试时间,但是仍然没有调通,晚上回家后又接着奋战几个小时,重新写了这份代码。在现在看来,当时那个迫切想写代码的心情真的是难以理解。软件维护工作做多了,好像是会有这样的感觉。
直接贴代码,题目在代码头部的注释中。
[分享]百度分布式数据库
很老的视频了,感觉讲得不错,百度09年都已经SSD了,我们却还在挣扎着怎样精简流程来节省元数据的访问。右边是视频中用于讲解的PPT。
[转] 宫崎骏用动漫教给我们的人生哲理,每一句都能说到心里!
引导语:那些触动心弦的台词,那些感动灵魂的画面,那些照亮前行方向哲理,那些陪伴我们成长的童话……让我们一起重温那些青葱岁月里,宫崎骏给我们带来的温暖细腻的小美好~
曾经发生的事不可能忘记,只是暂时想不起来而已。——《千与千寻》
我到现在都想不起自己的名字。可是真是不可思议,我居然还记得你的名字。——《千与千寻》
人生就是一列开往坟墓的列车,路途上会有很多站,很难有人可以至始至终陪着走完。——《千与千寻》
当陪你的人要下车时,即使不舍,也该心存感激,然后挥手道别。——《千与千寻》
一直向前走。千万别向后看。否则就永远回不去那个世界了。——《千与千寻》
千万不可以丢失自我。——《千与千寻》
只有一个人在旅行时,才听得到自己的声音,它会告诉你,这世界比想象中的宽阔,这个世界上,你可以碰到机遇,而绝不可能碰到“神”,自己的路,还是得自己走!——《千与千寻》
这世上有一条路无论如何也不能走,那就是歧途,只要走错一步结果都会是粉身碎骨。——《千与千寻》
我一直在躲避,但我终于找到要保护的人了,那就是你。——《哈尔的移动城堡》
人老的好处就是,看到什么怪物,都没什么好害怕的了。——《哈尔的移动城堡》
因为爱你,只要你一个肯定,我就足够勇敢。——《哈尔的移动城堡》
爱上某人,不是因为他给了你需要的东西,而是因为他给了你从未有过的感觉。——《哈尔的移动城堡》
[转] 舌尖上的科学家
17世纪50年代的某一天清晨,如果你来到位于比利时西部的一座公园,有可能会看到一个奇怪的遛鸟人:只见他伸出舌头,把舌尖嘬得像一条小蛇,吸引一只麻雀来吃,只听吸溜一声,麻雀将“小蛇”吞了下去……这个人不是疯子,他是著名科学家范赫尔蒙特,正在进行消化的研究。他的实验是这样的:伸出舌头,让一只驯化的麻雀来吃,麻雀把他的舌头吞下去,这样就使他的舌尖感觉到了麻雀喉咙里那强烈的酸味,从而让他弄明白了一个问题:麻雀为什么消化得那么快?
因被天上掉下的苹果砸昏了头,在报复性地猛吃烂苹果时发现了万有引力的牛顿,还有一则流传至今的轶事:在煮牛奶时,由于太专心,放糖时他竟把自己的手表当作糖放到了牛奶里。在吃饭问题上和牛顿一样狼狈的还有安培。在和妻子分居两地时,不得不亲自下厨的安培,就发出过“煮饭比物理难”的感叹。但让牛顿羡慕得流口水的是,为了给安培补充营养,每次回家,妻子都要给他准备一块牛肉,让安培感觉自己“像是上帝的子民,在逾越节里吃着羊羔肉,洋溢着感谢”。这舌尖上的爱,或许正是成就一代电磁学大师的第一块基石。
就在一些科学家为吃饭苦恼时,另一些科学家却把食物转化成了科学成果。1955年12月的一天,美国科学家罗伯特·小温特沃夫走到食品店,买了一瓶花生酱,回到实验室,他舀出一匙花生酱,放到高温高压环境中,将其“烹饪”成了钻石。
1950年代,美国科学家詹姆斯·沃森在剑桥大学的卡文迪许实验室工作。英国的工作条件非常合他的胃口,可英国那“无味的肉,没有颜色的菜,和那煮得稀烂的土豆”却总是叫他的肠胃剧烈地疼痛。就是在这样的痛苦中,沃森成功地建立了DNA双螺旋结构模型,并因此获得了诺贝尔奖。印度数学奇才拉马努扬在剑桥大学时也经历了同样的遭遇,不过却没有沃森幸运,因严重的营养不良,年仅33岁便与世长辞。
与之相比,无论走到哪里都可以看到中餐馆的华裔科学家就非常幸运了。1956年5月,杨振宁去哥伦比亚大学拜访李政道,没有找到停车的地方,他们就开着车绕着哥大转,他们一边转一边讨论起了宇称不守恒的可能性,最后,他们烦了,不再讨论下去,在一家中餐馆前把车停了下来。在中餐馆里,两人基本上得出了一个让他们名扬世界的结论:宇称不守恒。
1960年代初,美国物理学家默里·盖尔曼受一种烹饪技术的启发:“把一片野鸡肉放在两片小牛肉中间烹调,然后再把两片小牛肉扔掉”,发现了强相互作用对称,而美国拓扑学家斯梅尔则受到厨师揉面团的启发,提出了一种几何模型——“斯梅尔马蹄”。
受“揉面团”启发的还有中国天文学家张衡。一天,张衡的妻子正在厨房烙饼,突然见丈夫走进来,抓起一团面就揉了起来,只见他把面揉成圆圆的一团,又把它在芝麻里一滚。妻子还以为张衡闹着玩呢,却听他眉飞色舞地说:“老婆,这个面团呢,好比是天球,上面的芝麻,好比是星星……”在希腊语里,“美食家”一词藏在“天文学家”一词里,不错,张衡就是一位潜伏的美食家,他做出了一张让我们无比骄傲的大饼——天体模型“浑天仪”。
[转载信息]
作者:李浅予
原文地址:http://blog.sina.com.cn/s/blog_4a923e3201018u79.html
文章已发表于2013年第33期《三联生活周刊》。
一个明显的jetty-8大文件传输性能大幅降低问题分析
这个问题很早就分析、修改和验证过了,一直没有来得及总结整理。今天突然想起来了,首先用我那蹩脚的英语给jetty的维护团队提了一个问题单,在等待他们回复的同时,我也把我发现问题的过程分享一下。
问题单链接:https://bugs.eclipse.org/bugs/show_bug.cgi?id=415282
经过打断点和调试,发现如下调用占用了性能下降(相对于jetty7版本)的绝大多数处理耗时:
public class HttpOutput extends ServletOutputStream
{
/* ------------------------------------------------------------ */
private void write(Buffer buffer) throws IOException
{
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
throw new EofException();
// Block until we can add _content.
while (_generator.isBufferFull())
{
_generator.blockForOutput(getMaxIdleTime());
if (_closed)
throw new IOException("Closed");
if (!_generator.isOpen())
throw new EofException();
}
// Add the _content
_generator.addContent(buffer, Generator.MORE);
// Have to flush and complete headers?
if (_generator.isAllContentWritten())
{
flush();
close();
}
else if (_generator.isBufferFull())
_connection.commitResponse(Generator.MORE);
// Block until our buffer is free
while (buffer.length() > 0 && _generator.isOpen())
{
_generator.blockForOutput(getMaxIdleTime());
}
}
}
具体的耗时消耗在:_generator.blockForOutput(getMaxIdleTime());
从函数名字都可以看出来,当网络繁忙时,会走到这个流程,在blockForOutPut中,首先会注册一个socket可写的事件,当该socket上面可以写数据时,通知当前业务线程,随后业务线程投入休眠。等待事件分发线程检查可读事件,并唤醒自己。这样在这个交互中不可避免的会损失部分数据传输性能,每一包数据虽然只会损失一点点性能,但是传输一个很大的文件时,就会发现这个损失的巨大,在10GE的网卡上面,数据传输的性能降低到了原来的1/10,这个影响太明显了。
那么问题到底出在哪里呢?
看下面的代码:
public class HttpGenerator extends AbstractGenerator
{
public void addContent(Buffer content, boolean last) throws IOException
{
if (_noContent)
throw new IllegalStateException("NO CONTENT");
if (_last || _state==STATE_END)
{
LOG.warn("Ignoring extra content {}",content);
content.clear();
return;
}
_last = last;
// Handle any unfinished business?
if (_content!=null && _content.length()>0 || _bufferChunked)
{
if (_endp.isOutputShutdown())
throw new EofException();
flushBuffer();
if (_content != null && _content.length()>0)
{
if (_bufferChunked)
{
Buffer nc=_buffers.getBuffer(_content.length()+CHUNK_SPACE+content.length());
nc.put(_content);
nc.put(HttpTokens.CRLF);
BufferUtil.putHexInt(nc, content.length());
nc.put(HttpTokens.CRLF);
nc.put(content);
content=nc;
}
else
{
Buffer nc=_buffers.getBuffer(_content.length()+content.length());
nc.put(_content);
nc.put(content);
content=nc;
}
}
}
_content = content;
_contentWritten += content.length();
// Handle the _content
if (_head)
{
content.clear();
_content=null;
}
else if (_endp != null && (_buffer==null || _buffer.length()==0) && _content.length() > 0 && (_last || isCommitted() && _content.length()>1024))
{
_bypass = true;
}
else if (!_bufferChunked)
{
// Yes - so we better check we have a buffer
if (_buffer == null)
_buffer = _buffers.getBuffer();
// Copy _content to buffer;
int len=_buffer.put(_content);
_content.skip(len);
if (_content.length() == 0)
_content = null;
}
}
}
问题出在下面这段代码上面:
// Handle the _content
if (_head)
{
content.clear();
_content=null;
}
else if (_endp != null && (_buffer==null || _buffer.length()==0) && _content.length() > 0 && (_last || isCommitted() && _content.length()>1024))
{
_bypass = true;
}
else if (!_bufferChunked)
{
// Yes - so we better check we have a buffer
if (_buffer == null)
_buffer = _buffers.getBuffer();
// Copy _content to buffer;
int len=_buffer.put(_content);
_content.skip(len);
if (_content.length() == 0)
_content = null;
}
我的理解,_bypass变量标志不使用缓存,直接将数据刷到客户端,如果这是jetty8的新增特性,那么也不应该是到外层再调用blockforoutput方法,而是直接flushbuffer即可。很明显这是一个bug,bypass的判断条件有误,_buffer为空,这是不使用缓存的条件,但是_buffer.length() == 0并不是该特性的条件,每一次初始化的时候都会默认操作_buffer使得_buffer.length() == 0。这样就导致了每一包数据都走进了blockforoutput流程。应该是一个明显的笔误,问题的修改方法即是去掉该不当的判断条件,只保留_buffer==null的判断。
同前面的jetty若干性能问题的分析一样,这个问题的分析也耗费了大量的时间和精力,最终是借助于比对jetty7和jetty8的代码和不停的加日志打点调试得出的。每一个问题的解决都是一段辛酸的故事。