Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 15843 articles
Browse latest View live

升级到 Mac OS X 10.10 Yosemite (Beta)

$
0
0

上周四苹果发布了 Mac OS X 10.10 Yosemite Beta 公开测试版,如果你提前加入了 OS X Beta Program 的话会收到邮件,按照提示提取或手动输入 Redemption Code 后就可以下载安装了。和 升级 Mac OS X 10.9 Mavericks时候一样,升级 Mac OS X 10.10 Yosemite 直接通过 App Store 就可以完成。

目测改变最大的是界面,继续向扁平化、iOS 7 风格靠拢,菜单字体也变了。自己用得最多、最在意的两个程序是 Safari 和 Terminal.

Safari.app 改进挺大,终于加上了 Google Chrome 几年前就有的 “直接在地址栏搜索”,因为从来不关机,所以浏览器经常会有 n 个 tab 页放在那里,时间长了这些 tab 不容易找,单从 tab 上面的 title 没法快速识别自己要找哪个 tab,Safari 菜单上的 show all tabs 能快速预览所有 tabs,正是我想要的。

Mac OS X 10.10 Yosemite

Terminal.app 没有多大变化,依然没有 iTerm2.app 那种多窗口切分功能,只能依靠 tmux 做窗口、会话切分。

Calendar.app 也是常用的 app,这年头记不住事,全靠 Calendar/Reminder/Notes/Timer 之类的工具。不知道大脑退化是否和这些 app 有关,反正自从可以用电脑打字以后,很少碰过笔,现在拿笔写出来的字惨不忍睹~,不知道大家还记不记得曾经有 “书法” 这个词~

Mac OS X 10.10 Yosemite

Spotlight 功能大大加强,而且搜索的速度大大提高,也可能是因为我的硬盘是 SSD 的缘故,搜索结果基本上是实时显示。

Notifications 增加了 “Today” 标签页,用户可以在 “Today” 里看日历、提醒、天气、股票、计算器等常用信息,据说苹果开放了 API,第三方程序也可以将信息显示到 “Today” 里,貌似苹果打算这个新的信息展示页面替代老的 Dashboard.

iCloud Drive 可以到 System Preferences -> iCloud 开启,5GB 免费,和 Dropbox 用法一样。

可能因为我的使用习惯是保持系统最简,不怎么用第三方软件,不会出现乱七八糟的软件兼容、干扰等问题,Mac OS X 10.10 Yosemite 公开测试版在 我的 Mac上运行很稳定,完全可以当作正式版用~


三大应用性能隐形杀手:谁Kill了你的App?

$
0
0

对于移动开发者来讲,活跃用户流失=应用慢性死亡!当你的创意、用户体验和coding都无懈可击时,是谁在不知不觉中Kill了你的App?听云平台根据真实数据统计:“连接超时”、 “崩溃”和“CPU使用问题”正是Kill掉你的应用的三大隐形杀手!

 

杀手

头号隐形杀手:连接超时

根据听云平台统计,网络错误是App关闭的首要问题,而在移动应用中网络错误数据比例报错中最高的就是连接超时错误。想象一下当你花重金好不容易把你的App推广到用户手机上,而在用户初次尝试时发生连接超时无法正常使用,多数用户会选择再也不会打开你的应用第二次。

错误

根据听云平台对可公开的样本数据分析:一个应用存在连接超时错误,该错误从上午9点开始报错比例突增到2%以上。

类型

其中报错集中在接口域名下

主机图

具体报错连接是一个列表文件页面

列表

在应用中的现象是提示网络不佳

表现

该示例应用日活400万,月活4000万。听云平台分析,此问题将直接给开发者带来近10W个用户将永久不再使用。此问题如果持续一个月,近100W用户将永久不再使用这个App!小小的“连接超时”正在每天“偷走”开发者的用户,杀手本色尽显,“贵”为App头号杀手!

二号隐形杀手:崩溃

崩溃,是一种境界,教你也不会只能自己体会!App崩溃往往伴随着用户的“崩溃”!

根据听云平台对同一样本应用分析,发现该应用在7月1日崩溃比率从1‰左右上升到2‰ 。

汇总

听云分析:99%以上的崩溃都集中出在该应用的4.6.5版本,以此开发者可以判断原因是由于应用新版本上线所致。

 

新版

记录

同时听云平台还提供了崩溃当时调用的代码信息如下:

崩溃

其中安卓4.2.2和4.1.2崩溃比例最高

系统

其中小米1S手机崩溃比例最高

1s

通过听云平台分析可以直接定位“崩溃”原因,并且根据系统版本和手机型号的崩溃原因进行分析和改进,揪出App的二号杀手。

三号隐形杀手:CPU使用问题

发热

2014年7月武汉晨报报道:在广埠屯一家手机维修店了解到,最近武汉高温潮湿天气的来袭,让手机“中暑患者”有增多的趋势。“打了个电话,手机就滚烫滚烫的,刚开始也没怎么注意,现在手机发烫就干脆死机,这是咋了?”

据日本NHK网站2014年2月报道,去年全年,日本全国消费生活中心接到了520件左右的手机过热、手机死机等咨询案件,是前一年的5倍。

据半岛新闻2014年7月报道,司机小刘手机玩着玩着死机了,通着电话自动挂掉,由于频繁死机、速度变慢、温度升高甚至出现高温导致塑料材质的手机后盖出现融化的情况。

夏日来临,手机过热、手机突然死机又成了用户频繁投诉手机厂商的一大问题。

根据百度

根据百度搜索数据,有275W条“手机过热死机”的搜索结果。但是请不要把用户的问题都归结为手机电池,听云平台分析:CPU超载是杀死App的第三大杀手。

据听云平台数据显示

详细

当该应用在执行一个列表页程序时,CPU和内存使用率明显提升,对应的线程耗时时间明显增加。CPU频率设置过高时会导致过热,过热导致耗电更严重,CPU频率设置过低导致手机滞后,应用处理缓慢同样会导致耗电。更多时候,用户解决CPU超载问题只能关闭甚至卸载App。你的App就被Kill了!

囚禁杀手

如何囚禁“连接超时”、 “崩溃”和“CPU使用问题”乃至更多导致用户流失的杀手呢?

根据听云平台发布数据:69%开发者还处在裸奔状态!而作为中国最大应用性能管理服务商的基调网络日前所发布的听云平台,每日帮助开发者监控超过100亿次的真实用户请求,发现应用性能问题超过15万个,帮助应用留住因性能问题即将离开用户超过175万个,通过核心技术优势快速帮助开发者“囚禁”应用性能的“杀手”。想了解移动应用性能相关数据动态和报告,请登录听云平台永久免费版:www.tingyun.com

java.util.zip.Deflater使用不当引发jvm crash及问题排查

$
0
0

最近使用第三方开源库jflvlib录制flv格式视频,测试过程发现,视频录制进程经常挂掉;
java启动参数中已经配置内存溢出时导出日志文件-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/Logs/xxx.dump和jvm crash的日志输出路径-XX:ErrorFile=/export/Logs/xxx.log,但是进程挂掉后没有找到任何日志输出;

1. 启动视频录制,使用top命令查看进程cpu、内存消耗情况,内存暂用:83.1%≈1.5G

 
2. 使用jvisualvm查看Heap、PermGen内存暂用正常,heap使用:≈50M

 
  由于两种方式看到的内存相差很大;只有一种可能代码中使用了直接内存(Direct Memory),
  下载直接内存查看工具google-perftools:http://code.google.com/p/google-perftools/downloads/list

3. 使用perftools查看java.util.zip.Deflater占用绝大多数,代码中有使用开源项目jflvlib来生成视频,其中有一段使用java.util.zip.Deflater的视频压缩代码

 
  参考网上ibm一篇文章:http://www-01.ibm.com/support/docview.wss?uid=swg21227106,deflater必须要调用end方法,不然可能导致oom或者jvm crash。
If a deflater object is not explicitly closed and ended, a native memory leak occurs. This leak can result in OutOfMemoryError's and/or Java™ Virtual Machine (JVM) crashes.
修改后代码如下:

4. 根据配置jvm崩溃会有错误日志,jvm内存溢出也有会有二进制日志文件;由于崩溃现场没任何日志,一种可能操作系统直接干掉了该进程。
linux oom_killer是一种自我保护机制,当系统分配不出内存时(触发条件)会触发这个机制
查询操作系统日志:egrep -i 'killed process' /var/log/messages  确实进程被操作系统干掉了

 




 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



表单设计中8个不能不忽略的技巧

$
0
0

表单设计的就应该就像个温柔有礼貌的服务生

表单应该就像个温柔又有礼貌的服务生。想象你走进一间超级市场,走过两旁堆满商品的走道之后,左转右转,看到你想买的果酱并且挑选了两罐放在购物袋中。

终于你走向结账柜台,一个笑容甜美的收银人员对你温柔的问好,并接过你手中的果酱,告诉你价钱,帮你包装,然后找给你零钱和发票并且愉快的说再见。

现在你来到一个购物网站,在首页看到许多特价商品,你点选了食品的分类选项,来到果酱的分类。稍微看了一下果酱的介绍文章,然后点击鼠标把果酱放到购物车中,并点选结账:结果出现的是一个冷淡又死气沉沉的表单(Form)。

表单绝对是网站中用户和系统互动的最主要的元素,网站透过表单向用户提出问题,用户则透过表单向网站表达他的想法。标单又可以细分成三种元素:1、说明目的的标签;2、提供响应的输入方块或选单;3、以及提交表单的按钮。表单的设计就可以想象成一个称职的服务生,他的服务应该要符合下面几个项目:

1. 标签要清楚

标签就像是服务生的问候语和问题,应该要有礼貌、清楚、简单而且容易理解。

清楚的標籤標示

2. 仔细决定表单项目

绝对不要问一些不该问、或是不需要问得问题。例如:在不需要手机号码的情况下,要求用户输入手机号码。这种冒犯隐私的行为,是很容易招致网络用户厌恶的。

表单设计的就应该就像个温柔有礼貌的服务生

3. 标示清楚

卷标应该将「一定要输入」的项目标示清楚。如果一个表单有十个需要输入的项目,其中有三个一定要输入,那么就应该将「*」或其他符号标记在一定要输入的卷标的旁边(标记在输入框旁边不容易阅读),反之亦然。

4. 清楚提示的输入框

提供使用者输入的输入框的大小应该要经过设计来符合所需要输入的数据,输入地址的方框应该要比输入名字的方框要长一些。输入电话号码的方框应该适当的分成区码和号码两隔,让用户透过输入框的大小就可以了解所需要输入的格式。

清楚提示的輸入框

5. 常用的默认值

表单在一些常用的项目上,应该要填好许多用户常用的默认值,让用户不用一隔一隔慢慢的填写。如果你的表单是用户每天都要使用的,那默认值则可以大幅增加使用效率。

6. 提供良好的限制

如果有一个输入数值的方格,而输入的数值有大小限制,则可以考虑改用滑杆或旋扭取代。如果一定要采用输入框,则至少把数值的限制标示清楚,避免在使用者输入错误之后才跳出错误的对话框。

7. 不要预设寄送广告信

许多表单的最后都有一个选项:「我要收取 xxxx 网站的广告信件。」相信我,九成的使用者都不喜欢你默认这个选项给他们。当个有礼貌的服务生,不要强迫推销,让使用者决定自己喜欢的东西吧!

8. 千万不要随便清除输入的数据

这是表单最容易让用户生气的一个问题了!许多网站的表单写完并按下提交之后,画面上跳出了输入错误,然后就还我们一个空白全新的表单。这简直就像是 Alan Cooper 说的:「 就好像我写错一个字,然后服务生就把整张纸揉成一团丢在我脸上一样。

表单设计的就应该就像个温柔有礼貌的服务生

 

原文地址: http://dclick.fourdesire.com
作者: Taco Chen

十个让你的设计变成高富帅的技巧

$
0
0

朽木可雕!10个技巧让你的坏图瞬间变高大上

如果你经常逛灵感集网站,比如Awwwards,你会发现很多很棒的网站都有共同的特性——有档次的背景图。如果你拥有的图片比较小或者数量较少,你依然可以创造出惊人的视觉冲击感。只需要使用一些处理技巧,这里有10个方法,你可以试一下。

一、裁剪

最简单的工具可以产生最大的影响,这个秘密就是——裁剪。改变焦点或图像角度,垂直或水平方向,都可以创造更多视觉冲击力。一位设计师曾告诉我裁剪图片让我很不舒服,但现在成了我最好的编辑建议,我每天都在用。

朽木可雕!10个技巧让你的坏图瞬间变高大上

二、模糊

有一个趋势是现在的网页设计很多使用模糊化的背景。这可以淡化图片的原意,表现你希望的意思。常见的模糊风格包括把不完美的 图片处理的足够朦胧 ,但前提是需要有良好的色彩和紧凑的拍摄。虽然图片是模糊的,你依然可以辨别图片中传递的含义。

朽木可雕!10个技巧让你的坏图瞬间变高大上

三、合成

当你只有一张照片或少量的时候,打包合成是个不错的选择。将单张图片分解到多张面板上,玩对称和不平衡的配对,重复这个技巧找出完美的照片。

朽木可雕!10个技巧让你的坏图瞬间变高大上

四、色彩

Andy Warhol 认为:把色彩加在普通的照片上可以得到全新的东西。创建饱和度高的图像的时候也在创造艺术,你可以试试。如马赛克风格(沃霍尔的一个最著名的波普艺术玛丽莲•梦露的就是使用这种风格 )。

谈及颜色,考虑使用意外的颜色创造新奇感。如果你有张蓝色的猪照片,肯定会引起注意。 使用颜色来吸引人们的视觉并与之互动。令人震惊,

朽木可雕!10个技巧让你的坏图瞬间变高大上

五、图形

你可以使用形状覆盖到图片上面,来创造一个意想不到的效果。最近圆圈成为一种时尚设计元素,经常用于比如头部特写。但形状不像矩形,可用于各种图像。

这种效果用在简单的图像上效果会很好,而且框架要精心处理。图形放在大图片上,会隐藏掉一部分,凸显另一部分,从而形成焦点,变得更加吸引人。

朽木可雕!10个技巧让你的坏图瞬间变高大上

六、创造

如果你没有好的图片,那么去创造它。几乎每个人都有手机或像样的相机。创建一个小工作室存储起来。要知道,有些东西比别人更容易创建,你不一定使用高端器材或者完美布光,以达到专业摄影师的最佳效果,但是你可以在飞行中随手拍一张简单的图像。

毛主席说,自己动手,丰衣足食。

七、变小

这是一个…尺寸的问题。

就像使用有趣的图形或吸引人的裁剪能给图像带来注意力和焦点,尺寸也能创造不一样的效果。把图像变小——不是损坏的图像,你需要一张像样的照片,并给它焦点。如果小图像不能很好工作,可以考虑进行组合。(可以多次使用相同的图片或使用一系列不同的图像。)给小图片增加足够的空间使其效果更佳,广阔的空间和一个小图像之间的反差几乎总是引人注目的。

朽木可雕!10个技巧让你的坏图瞬间变高大上

八、放大

变大,是的变大。如果你只有一张照片,这个方式绝对是量身定做。大的图片通常会带来大的冲击力,但这种方法行之有效的唯一方法是使用正确的图片。它必须足够清晰,专注,强烈和明亮。只有完美的照片才能在超大号的设计上表现的足够良好。如果你质疑这种照片对项目是否合适,那么换其他方式。这种大胆的显示需要完美,足够大,稍微有点缺陷就能立马看出来。

朽木可雕!10个技巧让你的坏图瞬间变高大上

九、层叠

利用图像的层次感,可为整体风格加强联系,同时也可以突出重点。使用这个技巧关键一点是不能让背景和分层元素显得杂乱或格格不入。

虽然这不是一个完美的解决方案,但当你某张图片有缺陷时,利用层次掩盖掉那一部分是很聪明的做法。

朽木可雕!10个技巧让你的坏图瞬间变高大上

十、精简

若有所疑,保持简单。当你没太多时间或图片质量不行时,将图像主体提取出来放在白色的背景上。删除多余杂乱的,捕获你需要的东西,简洁干净,重点强烈突出,这个方法几乎能解决所有的设计难题。

朽木可雕!10个技巧让你的坏图瞬间变高大上

总结

裁剪,模糊,合成,色彩,图形,创造,变小,放大,层叠,精简,不同的方式都能帮你创造更好的图像。你有什么其他的技术用来帮助图像适合设计项目吗?在评论中分享你的想法。

 

原文地址:blog.enqoo

十大致癌食物黑名单公布,广大吃货情何以堪啊

$
0
0
中国还有什么食物真正放心吃的吗?中国医学科学院肿瘤医院公布十大致癌食物黑名单,其中包括腌制熏制食品、烧烤食品、霉变食品、隔夜菜和反复烧开的水等等。 不知从啥时开始,“食物”和“致癌”两个词被紧紧地联系在了一起,只要在搜索引擎中输入“食物”和“致癌”两个关键词,电脑屏幕上就会弹出成千上万个关于食物致癌的页面,可乐、方便面,甚至牛奶、豆浆,这些大家常吃的食物都被冠以“致癌”之名。 太恐怖了。这让广大吃货情何以堪啊!小编温馨提醒:每个人都离不开美食,但是健康至上!辛苦一辈子,不要毁在嘴上。葵瓜子、味精、口香糖、猪肝、腌菜、皮蛋、臭豆腐、油条……都在黑名单上。 1. 葵花子:向日葵因其生长快速,易吸收土壤中的重金属铅、镉、镍,对土壤而言可有效减轻重金属污染,具有净化环境的能力,为最佳景观绿肥作物。但是,对人体而言,吃进这些重金属则对身体有害,且吃葵花子会消耗大量的胆硷 choline,使体内脂肪代谢发生障碍,导致肝脏积聚大量脂肪,会严重影响肝细胞的功能。 2. 口香糖:口香糖中的天然橡胶虽无毒,但制程中所用的白片胶是加了毒性的硫化促进剂、防老剂等添加剂,刺激肠胃,引起不适。而口香糖中的代糖阿斯巴甜也是致癌物。 3. 味精 (麸! 胺酸钠):其中一半是对身体有益的左旋麸胺酸 L-Glutamine,但另一半却是身体不能利用的右旋麸胺酸 D-Glutamine 变成危害身体的自由基。每人每日摄入味精量不应超过 6 ! 克,摄入过多会使血液中麸胺酸和钠的含量升高,降低人体利用钙和镁,可能导致缺钙,影响牙齿、骨骼的强度。又可引起短期的头痛、心慌、恶心等症状,对人体生殖系统也有不良影响。 4. 猪肝:每公斤猪肝含胆固醇达 400 毫克以上,摄入胆固醇太多会导致动脉粥样硬化,同时肝是解毒器官,会累积大量黄麴毒素、抗生素、安眠药等代谢毒物,故猪肝不宜吃。 5. 油条、河粉、板条、米粉、粉丝:在制作过程中都必需添加明矾 (硫酸铝钾),如常吃这些东西,易导致贫血、骨质疏松症同时,体内铝过多,很难从肾脏排出,对大脑及神经细胞产生毒害,甚至引起老年痴呆症。又油条所重复使用的炸油,过度氧化亦有害健康。 6. 腌菜、萝卜乾:长期吃会引起钠、水在体内滞留,从而增加患心脏病的机会。另外,也含有亚硝酸胺或有不肖业者用福马林防腐,这些都是致癌物,易诱发癌症。 7. 市售瓶装鲜果汁:其中加了太多糖,比汽水的热量还要高,建议吃新鲜水果或现榨果汁就好。 8. 皮蛋:蛋含有一定量的铅,常食会引起人体铅中毒。铅中毒时的表现为失眠、贫血、好动、智力减退等。 9. 臭豆腐:臭豆腐在发酵过程中极易被微生物污染,它还含有大量的挥发性盐基氮和硫化氢等,是蛋白质分解的腐败物质,对人体有害。 10. 爆米花:做爆米花的转炉含有铅,在高压加热时,锅内的铅会熔化一定量,一部分铅会变成铅蒸汽和烟,污染原料,特别是在最後「爆」的一瞬间。爆米花中含铅量高达10 毫克/ 500 克左右,对人体(特别是对儿童)的造血系统? B神经和消化系统都有害。吃多了可能会得「爆米花肺」。

漏洞科普:对于XSS和CSRF你究竟了解多少

$
0
0

    随着Web2.0、社交网络、微博等等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上,Web业务的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显。

    黑客利用网站操作系统的漏洞和Web服务程序的SQL注入漏洞等得到Web服务器的控制权限,轻则篡改网页内容,重则窃取重要内部数据,更为严重的则是在网页中植入恶意代码,使得网站访问者受到侵害。

    如今,Web安全成为焦点,但网站的漏洞还是频频出现,在白帽子们进行网站测试时,恐怕对于SQL注入、XSS跨站、CSRF接触最多,但对于网站的开发者们来说,对这些熟知多少?本文从开发者的角度,对于XSS和CSRF进行简要概述。

PART1  XSS跨站脚本(Cross-site scripting)

XSS成因概括 :

    XSS其实就是Html的注入问题,攻击者的输入没有经过严格的控制进入了数据库,最终显示给来访的用户,导致可以在来访用户的浏览器里以浏览用户的身份执行Html代码,数据流程如下:攻击者的Html输入—>web程序—>进入数据库—>web程序—>用户浏览器。

‍‍检测方法:‍‍

//通常有一些方式可以测试网站是否有正确处理特殊字符:

><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>"><script>alert(document.cookie)</script><script>alert(document.cookie)</script><script>alert(vulnerable)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E<script>alert('XSS')</script><img src="javascript:alert('XSS')"><img src="http://xxx.com/yyy.png" onerror="alert('XSS')"><div style="height:expression(alert('XSS'),1)" />(这个仅限 IE 有效)

攻击手段和目的:

    攻击者使被攻击者在浏览器中执行脚本后,如果需要收集来自被攻击者的数据(如cookie或其他敏感信息),可以自行架设一个网站,让被攻击者通过JavaScript等方式把收集好的数据作为参数提交,随后以数据库等形式记录在攻击者自己的服务器上。 

a. 盗用 cookie ,获取敏感信息。

b.利用植入 Flash ,通过 crossdomain 权限设置进一步获取更高权限;或者利用Java等得到类似的操作。 

c.利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。 

d.利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。

e.在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS攻击的效果。

漏洞的防御和利用:

避免XSS的方法之一主要是将用户所提供的内容进行过滤,许多语言都有提供对HTML的过滤:

PHP的htmlentities()或是htmlspecialchars()。
Python的cgi.escape()。
ASP的Server.HTMLEncode()。
ASP.NET的Server.HtmlEncode()或功能更强的Microsoft Anti-Cross Site Scripting Library
Java的xssprotect(Open Source Library)。
Node.js的node-validator。

使用HTTP头指定类型:

很多时候可以使用HTTP头指定内容的类型,使得输出的内容避免被作为HTML解析。如在PHP语言中使用以下代码: 

header
('Content-Type: text/javascript; charset=utf-8');

即可强行指定输出内容为文本/JavaScript脚本(顺便指定了内容编码),而非可以引发攻击的HTML。

PART2 CSRF:冒充用户之手

示意图:

    XSS 是实现 CSRF 的诸多途径中的一条,但绝对不是唯一的一条。一般习惯上把通过 XSS 来实现的 CSRF 称为 XSRF。

    CSRF 顾名思义,是伪造请求,冒充用户在站内的正常操作。我们知道,绝大多数网站是通过 cookie 等方式辨识用户身份(包括使用服务器端 Session 的网站,因为 Session ID 也是大多保存在 cookie 里面的),再予以授权的。所以要伪造用户的正常操作,最好的方法是通过 XSS 或链接欺骗等途径,让用户在本机(即拥有身份 cookie 的浏览器端)发起用户所不知道的请求。

    要完成一次CSRF攻击,受害者必须依次完成两个步骤:

1.登录受信任网站A,并在本地生成Cookie。
2.在不登出A的情况下,访问危险网站B。

    看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:
1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。
2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了……)
3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
    上面大概地讲了一下CSRF攻击的思想,下面我将用几个例子详细说说具体的CSRF攻击,这里我以一个银行转账的操作作为例子(仅仅是例子,真实的银行网站没这么傻:>)

示例1:
银行网站A,它以GET请求来完成银行转账的操作,如:

http://www.mybank.com/Transfer.php?toBankId=11&money=1000

危险网站B,它里面有一段HTML的代码如下:

 <img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

    首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块……
    为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作……

示例2:
为了杜绝上面的问题,银行决定改用POST请求完成转账操作。
银行网站A的WEB表单如下:  

<form action="Transfer.php" method="POST">
        <p>ToBankId: <input type="text" name="toBankId" /></p>
        <p>Money: <input type="text" name="money" /></p>
        <p><input type="submit" value="Transfer" /></p></form>

后台处理页面Transfer.php如下:

<?php
      session_start();
    if (isset($_REQUEST[&#039;toBankId&#039;] && isset($_REQUEST[&#039;money&#039;]))
    {
       buy_stocks($_REQUEST[&#039;toBankId&#039;], $_REQUEST[&#039;money&#039;]);
    }
>

危险网站B,仍然只是包含那句HTML代码:

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

    和示例1中的操作一样,你首先登录了银行网站A,然后访问危险网站B,结果…..和示例1一样,你再次没了1000块~T_T,这次事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。 

示例3:
    经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:

<?php
     session_start();
     if (isset($_POST['toBankId'] && isset($_POST['money']))
     {
        buy_stocks($_POST['toBankId'], $_POST['money']);
     }
?>

然而,危险网站B与时俱进,它改了一下代码:

<html>
      <head>
        <script type="text/javascript">
          function steal()
          {
                   iframe = document.frames["steal"];
                   iframe.document.Submit("transfer");
          }
        </script>
      </head>
      <body onload="steal()">
        <iframe name="steal" display="none">
          <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
            <input type="hidden" name="toBankId" value="11">
            <input type="hidden" name="money" value="1000">
          </form>
        </iframe>
      </body></html>

    如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块……因为这里危险网站B暗地里发送了POST请求到银行!

    总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个<img>就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
    理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

如何防御?
请求令牌(一种简单有效的防御方法):
首先服务器端要以某种策略生成随机字符串,作为令牌(token),保存在 Session 里。然后在发出请求的页面,把该令牌以隐藏域一类的形式,与其他信息一并发出。在接收请求的页面,把接收到的信息中的令牌与 Session 中的令牌比较,只有一致的时候才处理请求,处理完成后清理session中的值,否则返回 HTTP 403 拒绝请求或者要求用户重新登陆验证身份
令牌来防止 CSRF 有以下几点要注意:
 a.虽然请求令牌原理和验证码有相似之处,但不应该像验证码一样,全局使用一个 Session Key。因为请求令牌的方法在理论上是可破解的,破解方式是解析来源页面的文本,获取令牌内容。如果全局使用一个 Session Key,那么危险系数会上升。原则上来说,每个页面的请求令牌都应该放在独立的 Session Key 中。我们在设计服务器端的时候,可以稍加封装,编写一个令牌工具包,将页面的标识作为 Session 中保存令牌的键。

b.在 ajax 技术应用较多的场合,因为很有请求是 JavaScript 发起的,使用静态的模版输出令牌值或多或少有些不方便。但无论如何,请不要提供直接获取令牌值的 API。这么做无疑是锁上了大门,却又把钥匙放在门口,让我们的请求令牌退化为同步令牌。

c.第一点说了请求令牌理论上是可破解的,所以非常重要的场合,应该考虑使用验证码(令牌的一种升级,目前来看破解难度极大),或者要求用户再次输入密码(亚马逊、淘宝的做法)。但这两种方式用户体验都不好,所以需要产品开发者权衡。

d.无论是普通的请求令牌还是验证码,服务器端验证过一定记得销毁。忘记销毁用过的令牌是个很低级但是杀伤力很大的错误。我们学校的选课系统就有这个问题,验证码用完并未销毁,故只要获取一次验证码图片,其中的验证码可以在多次请求中使用(只要不再次刷新验证码图片),一直用到。

如下也列出一些据说能有效防范 CSRF,其实效果甚微或甚至无效的做法:
a.通过 referer 判定来源页面:referer 是在 HTTP Request Head 里面的,也就是由请求的发送者决定的。如果我喜欢,可以给 referer 任何值。当然这个做法并不是毫无作用,起码可以防小白。但我觉得性价比不如令牌。

b.过滤所有用户发布的链接:这个是最无效的做法,因为首先攻击者不一定要从站内发起请求(上面提到过了),而且就算从站内发起请求,途径也远远不知链接一条。比如 <img src="./create_post.php" /> 就是个不错的选择,还不需要用户去点击,只要用户的浏览器会自动加载图片,就会自动发起请求。

c.在请求发起页面用 alert 弹窗提醒用户:这个方法看上去能干扰站外通过 iframe 发起的 CSRF,但攻击者也可以考虑用 window.alert = function(){}; 把 alert 弄哑,或者干脆脱离 iframe,使用 Flash 来达到目的。

总体来说,目前防御 CSRF 的诸多方法还没几个能彻底无解的。 作为开发者,我们能做的就是尽量提高破解难度。当破解难度达到一定程度,网站就逼近于绝对安全的位置了

参考文献

[1]. Preventing CSRF
[2]. Security Corner: Cross-Site Request Forgeries
[3]. 《Web安全测试之跨站请求伪造(CSRF)》
[4].百度百科-CSRF、XSS

为何找个优秀的Java程序员如此之难?

$
0
0

Java开发者供大于求,找一个优秀的开发者犹如大海捞针。这该赖谁?赖程序员对Java没兴趣吗?还是赖瞎了眼的招聘?抑或是语言本身?不管你同意与否,下面就列举了和这个问题相关的答案。

问题非语言,而是程序员自身

大多程序员都想做与众不同的人,大家都喜欢尝试。但除此之外,更多的程序员想要一个薪水丰厚的工作。最简单的方式就是学习Java——不管自己喜不喜欢写,这就是为什么众多无工作激情的程序员都沦为了Java程序“猿”。

“我不是指所有的Java程序员都是无能之辈”,博客写手Sandy Walsh如是说,他认为太多的程序员得到奖励只是因为盲目的学习使用软件包,而不是真正理解它们,“有太多太多优秀的Java程序员,不幸的是,无能的更多——将优秀的人淹没了。”

同时,Neil Sainsbury是一位Android程序员,他说问题的根源是Java写手们最终的理想是成为架构师。“我经常发现自己读代码的时候更多像在规划解决问题的方法,而不是解决问题。”

非但没有得到快速浏览代码及了解作者意图的能力,而且令上司经常一头雾水,不明白到底程序员们想给他们传递什么。“你得学习更多令你感到折磨的新词,例如Abstract Adapter Factory等等,让自己成为系统的一部分。”

问题的根源不是人,而是语言的设计

Java博客写手MichaelO.Church认为恰恰相反——Java语言的问题就在于根据一小片代码很难判断程序员的优秀与否。半数公司要某个程序员的时候都会看其一些代码小例。谨慎的开发团队在招募的时候往往会让被召人一天写多种代码以资评估。

对于一些工程,错雇会颠覆整个工程甚至整个公司就此陨落。 考虑到这个原因,技术面试在行业领先的公司会很频繁。

众所周知Java就像老太太的裹脚布——又臭又长,甚至写了500行都不能表达程序员的意图,再加上时间紧,招聘者或者程序员都会觉得很为难。

会Java的人太多

提到入门语言,很多程序员都有Java背景。就像找说英语的人很简单,但是找可以写书信语的,就不太简单了。

一个掌握Java基础的Java程序员会显得很有经验,招聘者给他们的一些简单的测试,在StackOverFlow就可以找到答案。 并且,优秀的程序员经常太忙(或太骄傲)而不能置身于复杂或者很长的编码任务。

同时,年轻且缺乏锻炼的招聘者常常在猎“程序员大侠(ninja programmer)”。Cordelia Dillon认为理想的程序员不该是招聘者草率招募的“编程大牛(rock star)coder”,而更应该像一个雕刻家或考古学家,慢工出细活。

如果招聘者真的很想谈论忍者和摇滚明星,或者甚至雕刻家和考古学家,他们应该先了解这些角色和他们招聘的软件开发人的角色的共同点。

公司的雇佣理念

公司很怕雇员的技术会很快过时,因为大多公司不想用另一种难招人的语言从头开始工程。为了保险使用公司自己制定的解决方法起见,公司宁愿招盲目敲Java的程序员。他们来之前是Java程序员身份,走之后仍是这个身份。

这就是为什么Sandy Wals会说问题不在于语言,而是公司的雇佣理念。“如果你打造一个将会有很长的生命周期的产品,你需要知道软件将会依赖开发它的程序员。如果你的应用是用比较冷门或者你有自己的封闭生态环境(就像苹果),那就…..想想都伤心。”


苹果收购BookLamp、Swell,二者均主打“个性化推荐”

$
0
0

  最近这几天,苹果一口气收购了两家初创小公司。这两家公司一家是为用户进行图书推荐服务的BookLamp,另一家是主打流媒体电台服务的Swell。 二者的共性是:都为用户提供个性化推荐服务(在此之前苹果还收购了音乐流媒体服务Beats——人工选取推荐音乐),而两家公司一共花了苹果4000-4500万美元。2个月内,先是音乐,又是图书、新闻和电台谈话,最近苹果对个性化推荐服务的兴趣挺高。

  BookLamp 最出名的一款产品为“图书基因组计划”(Book Genome Project),主要是通过大数据采集技术(其CEO Aaron Stanton去年表示,图书基因项目每周可以索引40,000 至100,000 个标题),对图书内容与风格作出分析,并以此为依据,根据读者对特定作者或书目的偏好,为其提供可能感兴趣的图书推荐。对此,这家公司称,自己希望做“图书界的Pandora”(注:一家提供我们用不了的自动音乐推荐系统服务提供商)。

   分析称,苹果收购BookLamp,无外这几点原因:

  ① 靠BookLamp的技术和人才帮助改善iBook服务,包括搜索和个性化推荐;

  ② 基于大数据分析技术,BookLamp向包括亚马逊、苹果以及许多纽约出版商、电子书分销商们提供内容分析服务,帮助他们分析一本书在特定读者中受欢迎程度;

  ③ 帮苹果获取更多用户,帮助其在图书市场与亚马逊展开竞争。

  据悉,亚马逊也曾试图收购BookLamp,但最终却收购了BookLamp的竞争对手GoodRead。这次苹果虽未公布具体的费用,但根据国外媒体披露,比较靠谱的数额大概为1000-1500万美元之间。

  而既然说到BookLamp要做“图书界的Pandora”,也得看看苹果最近收购的另一家小公司——个性化流媒体电台服务的Swell。

  援引Re/code报道,苹果收购这家公司应该花了3000万美元上下。鉴于BookLamp有被亚马盯上过的历史,我们也去搜索了一下,结果发现Swell也曾被Google Venture投资。

  与其他的电台产品相比,Swell的特色主要是提供新闻和电台谈话内容,而非音乐——就在5月底,苹果还用32亿美元收购了Beats Electronics,一家流媒体音乐服务提供商。Swell上的新闻来自于美国全国公共广播、美国广播公司、ESPN和英国广播公司,其筛选模式是机器算法与人工筛选并行,根据用户的收听历史创造个性化的播放列表。

手把手教你有效地做用户体验地图

$
0
0

@星玫玫玫 :如果你参加过收费的 workshop 或者看过讲设计方法的书,你一定听过体验地图(Experience Maps)。在一些些台版书籍里也叫使用者旅程图(User Journey Maps)。

如果你听过它,很可能你也吐槽过它。什么?要花那么多时间就为了做个破地图?到底有用没用啊?怎么没法得出个执行层结论?我是理科生接受不了没有正确答案啊啊啊?

今天机智的小星玫就以干货开场,展示理科生作为设计师的绝对优势 #让自己时刻都符合逻辑#

体验地图第一大优势:好看

它以视觉化的方式,将用户与产品或服务进行互动时的体验分阶段呈现出来,让体验地图中的每一个节点都能更直观地识别,评估和改善。不论是电子版还是满墙的便利贴,在效果上已经充满了形式美。

体验地图的第二大优势:非常贴合时下流行的「情感化设计

体验地图能协助团队精准锁定产品引发强烈情绪反应的时刻,同时找到最适合重新设计与改进的地图节点,这一切都几乎用户使用中的情感需求。

体验地图的第三大优势:能够多人参与,并且让所有人都横向梳理一遍产品流程

很夸张的是,大多数产品团队中,往往只有交互设计师认真从头到尾思考过产品流程;同时大多数产品,直到完成后才发现流程上的 bug,但此时只能假装没看见。

为什么你觉得体验地图无用?因为你不知道:

体验地图并不是一个独立的设计方法,它是产品前期用户研究过程中重要的一部分。在我做过的案例中,体验地图往往是最终收尾、拿结论的最关键节点——但是不能脱离了前期其它设计方法的材料准备。

哪些材料准备?

用户角色、观察记录,或者还可以再加上行为研究、调查问卷、竞品分析。

用户角色 —— 最有效的体验地图通常会配合用户角色以及情境故事一起制作。每个体验地图都应该呈现某个特定产品目标使用者的真实特性,并且该使用者有明确的任务和目标。以后或许会写如何有效地做用户角色。

观察记录、行为研究、调查问卷、竞品分析 —— 都是为了同一个目的,获取大量真实、可靠的原材料。体验地图上每个节点的对应内容,并不是拍脑袋想,而是应该经过长期的用户研究获取资料。所以,也可以说「体验地图是用户使用问题的有效梳理方式」。

So,结束快速结束理论部分。进入实例说明。

因为产品类型不同、研究目的不同,每次使用体验地图方法的步骤都是会有略微修改的。我举三个栗子:

1、一个连原型还没有的产品,他们希望从纯情感的角度来了解自己的产品应该为用户做什么,因而协助团队开始产品功能设计。他们的体验地图可能是这样的:

为设计加分:手把手教你有效地做用户体验地图

#每个节点位置的高低,是纯感性的#

2、一个线下实体产品,他们希望改善自己的服务体验。他们的体验地图可能是这样的,其中紫色卡片部分是服务流程中搜集到的问题:

为设计加分:手把手教你有效地做用户体验地图

#每个节点位置的高低,是由事实说明的,是理性的#

3、一个广泛用户群的产品,不同身份的用户角色会对应不同的体验流程。此时需要根据不同的用户角色,制作多个不同的体验流程图,最后重合的部分,就是此次设计中需要具体改善的地方。

为设计加分:手把手教你有效地做用户体验地图

好了,那么到底该如何做 用户体验地图?我以一个互联网产品举例,细致分解步骤。

背景:该公司希望我们帮忙研究「用户拍照行为」,从而作为他们即将开始设计的手机 ROM 拍照功能指导。

第一步,整理原始材料

根据之前的线下、线上调研,观察用户,用户访谈等等,我们获取了大量用户自拍行为中的问题和惊喜点,将它们以小便利贴的形式整理出来。并区分「问题」和「惊喜」的颜色。

为设计加分:手把手教你有效地做用户体验地图

第二步,找一个宽阔干净的新板子,写出用户行为流程

注意:每个行为节点 (touch point) 都是中性动词,要尽量细化,用词精准干净。

为设计加分:手把手教你有效地做用户体验地图

第三步,画出情感坐标,并把行为流程置于中性线上

为设计加分:手把手教你有效地做用户体验地图

第四步,把搜集到的「问题」和「惊喜」放到对应的每个行为节点上

惊喜点放在上面,问题点放在下面。

为设计加分:手把手教你有效地做用户体验地图

第五步,根据「问题」和「惊喜」的数量情况,和重要性程度,理性地判断每个行为节点的情感高低,并连线

注意:判断重要性是个略微感性的事,此时要基于用户角色,问自己这个用户角色对这个问题的在意程度有多少? 再注意:当一个行为节点可能产生两个结果,比如高兴或不高兴,优先考虑不高兴的情况,因为我们不是要做一件歌功颂德的事。

为设计加分:手把手教你有效地做用户体验地图

以上,一个体验地图就完成了, 我们要如何获得结论呢?

1、看看最高点,为它多做一点事情,将它推到极致。

2、看看最低点,思考能不能把其它体验值高的步骤,分摊一部分功能到这里,均衡体验情感。

比如下图是「用户自拍行为」体验地图,明显看出整个前期拍照行为都是走低的,而后期修图持续走高。此时就可以郑重考虑把更多的后期功能放到前期。

为设计加分:手把手教你有效地做用户体验地图

3、看看体验值中线以下的点,对应竞品分析,看看别人是怎么解决那些问题,并设置惊喜点的。

以上,你就可以有效地完成一个 用户体验地图。

CXF WEBSERVICE 安全验证

$
0
0

CXF 封装的接口,不希望对外暴露 WSDL结构,找到的CXF安全认证技术都是基于拦截器,在调用的时候返回认证错误信息, 不能保护WSDL不被看到,后来看到别人的一个实现方式最简单有效,基于URL拦截的安全保护,用FILTER。现在把这2种安全保护都记录下来,备用。

WSDL保护:

参考: http://www.myexception.cn/open-source/1505475.html

FILTER:

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		// TODO Auto-generated method stub

		HttpServletRequest httpRequest = (HttpServletRequest)request;
		Enumeration<String> enumeration = httpRequest.getParameterNames();
		while (enumeration.hasMoreElements()) {
			String param = (String) enumeration.nextElement();
			// 查找是否含有参数wsdl,因为使用WSDL也可以,所以这里比较时必须不区分大小写
			if (StringUtils.endsWithIgnoreCase("wsdl", param)) {
				response.getOutputStream().write("Servlet不存在".getBytes());
				return;
			}
		}
		chain.doFilter(request, response);
	}

配置的FILTER:
<url-pattern>/pe/*</url-pattern>
注:开始的时候配置的项目名/PEService ,地址是:http://localhost:8080/PEService/getResponse发现拦截不到,这个Servlet配置的名称只能拦截到项目名称之后的地址,即http://localhost:8080/PEService/之后的路径才能匹配,于是重新配置发布的地址<jaxws:endpoint id="getresponse" address="/pe/getResponse"

拦截/pe/*,成功匹配。

试图访问?WSDL结尾的地址都被拦截。

 

CXF安全认证参考: http://blog.csdn.net/hujiao_jingling/article/details/7239997

 

 

package com.hy;

import java.util.List;

import javax.xml.soap.SOAPException;

import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.helpers.XMLUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class AuthIntercetpr  extends AbstractPhaseInterceptor<SoapMessage> {
	//private static final Logger logger = Logger.getLogger(AuthIntercetpr.class);
    public static final String xml_namespaceUR_att = "http://gd.chinamobile.com//authentication";
	public static final String xml_header_el = "soap:Header";
	public static final String xml_authentication_el = "auth:authentication";
	public static final String xml_systemID_el = "auth:systemID";
	public static final String xml_userID_el = "auth:userID";
	public static final String xml_password_el = "auth:password";
	public AuthIntercetpr() {
		// 指定该拦截器在哪个阶段被激发
		super(Phase.READ);
	}

	// 处理消息
	public void handleMessage(SoapMessage message) {
		//logger.info("==================SoapMessage =" + message);
		// 获取SOAP消息的全部头
		String method = (String)message.get(Message.HTTP_REQUEST_METHOD);
		List<Header> headers = message.getHeaders();

		if (null == headers || headers.size() < 1) {
			throw new Fault(new SOAPException("SOAP消息头格式不对哦!"));
		}
		for (Header header : headers) {
			SoapHeader soapHeader = (SoapHeader) header;
			// 取出SOAP的Header元素
			Element element = (Element) soapHeader.getObject();
			//logger.info("ELEMENT =" + element.toString());
			XMLUtils.printDOM(element);
			NodeList userIdNodes = element
					.getElementsByTagName(xml_userID_el);
			NodeList pwdNodes = element
					.getElementsByTagName(xml_password_el);
			NodeList systemIdNodes = element
					.getElementsByTagName(xml_systemID_el);
			/*logger.info("############ 打印帐号信息 ##############");
			logger.info(userIdNodes.item(0) + "="
					+ userIdNodes.item(0).getTextContent());
			logger.info(systemIdNodes.item(0) + "="
					+ systemIdNodes.item(0).getTextContent());
			logger.info(pwdNodes.item(0) + "="
					+ pwdNodes.item(0).getTextContent());
			logger.info("############————————##############");*/
			if (null != userIdNodes&& userIdNodes.item(0).getTextContent().equals("test") ) {
				if (null != pwdNodes&& pwdNodes.item(0).getTextContent().equals("test")) {
					//logger.info("$$$$$$$$ 认证成功");
				} else {//认证失败则抛出异常,停止继续操作
					SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");
					throw new Fault(soapExc);
				}
			} else {//认证失败则抛出异常,停止继续操作
				SOAPException soapExc = new SOAPException("阁下可能不是合法用户!");
				throw new Fault(soapExc);
			}
		}
	}
}

 

 

将该类配置到CXF中:

 

<!--拦截器--><bean id="authIntercetpr" class="com.hy.AuthIntercetpr"></bean><!-- 上面不用管 ,id随意,implementor是实现类,address在客户端的地址中会用到--><jaxws:endpoint id="getresponse" implementor="com.hy.TestImpl" address="/pe/getResponse" publish="false">  <jaxws:inInterceptors>    <!-- 在此配置调用当前ws所触发的拦截器--><ref bean="authIntercetpr" /></jaxws:inInterceptors> </jaxws:endpoint>

 访问调用地址http://localhost:8080/PEService/pe/getResponse报错:

 

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><soap:Fault><faultcode>soap:Server</faultcode><faultstring>SOAP消息头格式不对哦!</faultstring></soap:Fault></soap:Body></soap:Envelope>

 

 

 

 

 



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



使用事务提升sqlite insert的性能

$
0
0

昨天发现sqlite插入性能很低,搜索了一下发现,其实sqlite的插入可以做到每秒50000条,但是处理事务的速度慢:

(19) INSERT is really slow - I can only do few dozen INSERTs per second

Actually, SQLite will easily do 50,000 or more  INSERT statements per second on an average desktop computer. But it will only do a few dozen transactions per second. Transaction speed is limited by the rotational speed of your disk drive. A transaction normally requires two complete rotations of the disk platter, which on a 7200RPM disk drive limits you to about 60 transactions per second.

Transaction speed is limited by disk drive speed because (by default) SQLite actually waits until the data really is safely stored on the disk surface before the transaction is complete. That way, if you suddenly lose power or if your OS crashes, your data is still safe. For details, read about  atomic commit in SQLite..

By default, each INSERT statement is its own transaction. But if you surround multiple INSERT statements with  BEGIN... COMMIT then all the inserts are grouped into a single transaction. The time needed to commit the transaction is amortized over all the enclosed insert statements and so the time per insert statement is greatly reduced.

sqlite FAQ#19

我原本的代码没有使用事务,所以每条insert语句都默认为一个事务。解决的办法是加上事务,执行SQL的时间就从10秒缩短到了0.07秒

发现了这个以后,我就尝试把可能的地方都加上事务,但是原本程序有一处逻辑,是执行一大堆insert,如果主键冲突就自然无视。但是如果把这堆sql变成事务,就会影响正确数据的插入,所以又把insert语句改成insert or ignore:

insert or ignore into test (id, key) values (20001, 'kyfxbl');

然后再放到一个事务里,效率大大提升

作者:kyfxbl 发表于2014-7-30 11:05:56 原文链接
阅读:107 评论:0 查看评论

从性能的角度谈SQL Server聚集索引键的选择

$
0
0

简介

    在SQL Server中,数据是按页进行存放的。而为表加上聚集索引后,SQL Server对于数据的查找就是按照聚集索引的列作为关键字进行了。因此对于聚集索引的选择对性能的影响就变得十分重要了。本文从旨在从性能的角度来谈聚集索引的选择,但这仅仅是从性能方面考虑。对于有特殊业务要求的表,则需要按实际情况进行选择。

 

聚集索引所在的列或列的组合最好是唯一的

    这个原因需要从数据的存放原理来谈。在SQL Server中,数据的存放方式并不是以行(Row)为单位,而是以页为单位。因此,在查找数据时,SQL Server查找的最小单位实际上是页。也就是说即使你只查找一行很小的数据,SQL Server也会将整个页查找出来,放到缓冲池中。

    每一个页的大小是8K。每个页都会有一个对于SQL Server来说的物理地址。这个地址的写法是 文件号:页号(理解文件号需要你对 文件和文件组有所了解).比如第一个文件的第50页。则页号为1:50。当表没有聚集索引时,表中的数据页是以堆(Heap)进行存放的,在页的基础上,SQL Server通过一个额外的行号来唯一确定每一行,这也就是传说中的RID。RID是文件号:页号:行号来进行表示的,假设这一行在前面所说的页中的第5行,则RID表示为1:50:5,如图1所示。

     1

    图1.RID的示例

  

    从RID的概念来看,RID不仅仅是SQL Server唯一确定每一行的依据,也是存放行的存放位置。当页通过堆(Heap)进行组织时,页很少进行移动。

    而当表上建立聚集索引时,表中的页按照B树进行组织。此时,SQL Server寻找行不再是按RID进行查找,转而使用了关键字,也就是聚集索引的列作为关键字进行查找。假设图1的表中,我们设置DepartmentID列作为聚集索引列。则B树的非叶子节点的行中只包含了DepartmentID和指向下一层节点的书签(BookMark)。

    而当我们创建的聚集索引的值不唯一时,SQL Server则无法仅仅通过聚集索引列(也就是关键字)唯一确定一行。此时,为了实现对每一行的唯一区分,则需要SQL Server为相同值的聚集索引列生成一个额外的标识信息进行区分,这也就是所谓的uniquifiers。而使用了uniquifier后,对性能产生的影响分为如下两部分:

  •     SQL Server必须在插入或者更新时对现在数据进行判断是否和现有的键重复,如果重复,则需要生成uniquifier,这个是一笔额外开销。
  •     因为需要对相同值的键添加额外的uniquifier来区分,因此键的大小被额外的增加了。因此无论是叶子节点和非叶子节点,都需要更多的页进行存储。从而还影响到了非聚集索引,使得非聚集索引的书签列变大,从而使得非聚集索引也需要更多的页进行存储。

    下面我们进行测试,创建一个测试表,创建聚集索引。插入10万条测试数据,其中每2条一重复,如图2所示。

     2

    图2.插入数据的测试代码

    

   此时,我们来查看这个表所占的页数,如图3所示。

     3

    图3.插入重复键后10万数据占了359页

 

    我们再次插入10万不重复的数据,如图4所示。

     4

    图4.插入10万不重复的建的代码

 

    此时,所占页数缩减为335页,如图5所示。

     5

    图5.插入不重复键后缩减为335页

 

     因此,推荐聚集索引所在列使用唯一键。

 

最好使用窄列或窄列组合作为聚集索引列

    这个道理和上面减少页的原理一样,窄列使得键的大小变小。使得聚集索引的非叶子节点减少,而非聚集索引的书签变小,从而叶子节点页变得更少。最终提高了性能。

 

使用值很少变动的列或列的组合作为聚集索引列

    在前面我们知道。当为表创建聚集索引后。SQL Server按照键查找行。因为在B数中,数据是有序的,所以当聚集索引键发生改变时,不仅仅需要改变值本身,还需要改变这个键所在行的位置(RID),因此有可能使得行从一页移动到另一页。从而达到有序。因此会带来如下问题:

  •     行从一页移动到另一页,这个操作是需要开销的,不仅如此,这个操作还可能影响到其他行,使得其他行也需要移动位置,有可能产生分页
  •     行在页之间的移动会产生 索引碎片
  •     键的改变会影响到非聚集索引,使得非聚集索引的书签也需要改变,这又是一笔额外的开销

     这也就是为什么很多表创建一列与数据本身无关的列作为主键比如AdventureWorks数据库中的Person.Address表,使用AddressID这个和数据本身无关的列作为聚集索引列,如图6所示。而使用AddressLine1作为主键的话,员工地址的变动则可能造成上面列表的问题。

     6

    图6.创建和数据本身无关的一列作为聚集索引列

 

最好使用自增列作为聚集索引列

    这个建议也同样推荐创建一个和数据本身无关的自增列作为聚集索引列。我们知道,如果新添加进来的数据如果聚集索引列需要插入当前有序的B树中,则需要移动其它的行来给新插入的行腾出位置。因此可能会造成分页和索引碎片。同样的,还会造成修改非聚集索引的额外负担。而使用自增列,新行的插入则会大大的减少分页和碎片。

   最近我碰到过一个情况。一个表每隔几个月性能就奇慢无比,初步查看是由于有大量的索引碎片。可是每隔几个月重建一次索引让我无比厌烦。最终我发现,问题是由于当时设计数据库的人员将聚集索引建在了GUID上,而GUID是随机生成的,则可能插入到表的任何位置,从而大大增加了碎片的数量。因此造成上面这种情况。

 

总结

    本文简单介绍了SQL Server存储的原理和应该规避的几种聚集索引建立情况,但这仅仅是从性能的角度来谈聚集索引的选择。对于聚集索引的选择,还是需要全面的考虑进行决定。

作者:zhongguoren666 发表于2014-7-30 10:07:01 原文链接
阅读:70 评论:0 查看评论

Cloudera impala简介及安装详解

$
0
0
一、Impala简介

Cloudera Impala对你存储在Apache Hadoop在HDFS,HBase的数据提供直接查询互动的SQL。除了像Hive使用相同的统一存储平台,Impala也使用相同的元数据,SQL语法(Hive SQL),ODBC驱动程序和用户界面(Hue Beeswax)。Impala还提供了一个熟悉的面向批量或实时查询和统一平台。

二、Impala安装
1.安装要求
(1)软件要求

  •   Red Hat Enterprise Linux (RHEL)/CentOS 6.2 (64-bit)
  •   CDH 4.1.0 or later
  •   Hive
  •   MySQL

注意:Impala不支持在Debian/Ubuntu, SuSE, RHEL/CentOS 5.7系统中安装。

(2)硬件要求

在Join查询过程中需要将数据集加载内存中进行计算,因此对安装Impalad的内存要求较高。

2、安装准备

(1)操作系统版本查看

>more/etc/issue

CentOSrelease 6.2 (Final)

Kernel \ron an \m

(2)机器准备

10.28.169.112mr5

10.28.169.113mr6

10.28.169.114mr7

10.28.169.115mr8

各机器安装角色

mr5:NameNode、ResourceManager、SecondaryNameNode、Hive、impala-state-store

mr6、mr7、mr8:DataNode、NodeManager、impalad

(3)用户准备

在各个机器上新建用户hadoop,并打通ssh

(4)软件准备

到cloudera官网下载:

Hadoop:

hadoop-2.0.0-cdh4.1.2.tar.gz

hive:

hive-0.9.0-cdh4.1.2.tar.gz

impala:

impala-0.3-1.p0.366.el6.x86_64.rpm

impala-debuginfo-0.3-1.p0.366.el6.x86_64.rpm

impala-server-0.3-1.p0.366.el6.x86_64.rpm

impala-shell-0.3-1.p0.366.el6.x86_64.rpm

impala依赖包下载:

bigtop-utils-0.4( http://beta.cloudera.com/impala/redhat/6/x86_64/impala/0/RPMS/noarch/)

其他依赖包下载地址: http://mirror.bit.edu.cn/centos/6.3/os/x86_64/Packages/

4、hadoop-2.0.0-cdh4.1.2安装

(1)安装包准备

hadoop用户登录到mr5机器,将hadoop-2.0.0-cdh4.1.2.tar.gz上传到/home/hadoop/目录下并解压:

    tar zxvf hadoop-2.0.0-cdh4.1.2.tar.gz

(2)配置环境变量

修改mr5机器hadoop用户主目录/home/hadoop/下的.bash_profile环境变量:

exportJAVA_HOME=/usr/jdk1.6.0_30

exportJAVA_BIN=${JAVA_HOME}/bin

exportCLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export  JAVA_OPTS="-Djava.library.path=/usr/local/lib-server -Xms1024m -Xmx2048m -XX:MaxPermSize=256m -Djava.awt.headless=true-Dsun.net.client.defaultReadTimeout=600

00-Djmagick.systemclassloader=no -Dnetworkaddress.cache.ttl=300-Dsun.net.inetaddr.ttl=300"

exportHADOOP_HOME=/home/hadoop/hadoop-2.0.0-cdh4.1.2

exportHADOOP_PREFIX=$HADOOP_HOME

exportHADOOP_MAPRED_HOME=${HADOOP_HOME}

exportHADOOP_COMMON_HOME=${HADOOP_HOME}

exportHADOOP_HDFS_HOME=${HADOOP_HOME}

exportHADOOP_YARN_HOME=${HADOOP_HOME}

export PATH=$PATH:${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin

exportJAVA_HOME JAVA_BIN PATH CLASSPATH JAVA_OPTS

exportHADOOP_LIB=${HADOOP_HOME}/lib

exportHADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop

(3)修改配置文件

在机器mr5上hadoop用户登录修改hadoop的配置文件(配置文件目录:hadoop-2.0.0-cdh4.1.2/etc/hadoop)

(1)、slaves :

添加以下节点

mr6

mr7

mr8

(2)、hadoop-env.sh :

增加以下环境变量

exportJAVA_HOME=/usr/jdk1.6.0_30

exportHADOOP_HOME=/home/hadoop/hadoop-2.0.0-cdh4.1.2

exportHADOOP_PREFIX=${HADOOP_HOME}

export HADOOP_MAPRED_HOME=${HADOOP_HOME}

exportHADOOP_COMMON_HOME=${HADOOP_HOME}

exportHADOOP_HDFS_HOME=${HADOOP_HOME}

exportHADOOP_YARN_HOME=${HADOOP_HOME}

exportPATH=$PATH:${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin

exportJAVA_HOME JAVA_BIN PATH CLASSPATH JAVA_OPTS

exportHADOOP_LIB=${HADOOP_HOME}/lib

exportHADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop

(3)、core-site.xml :

  fs.default.name

  hdfs://mr5:9000

  The name of the defaultfile system.Either the literal string "local" or a host:port forNDFS.

  true

io.native.lib.available

  true

  hadoop.tmp.dir

  /home/hadoop/tmp

  A base for other temporarydirectories.

(4)、hdfs-site.xml :

dfs.namenode.name.dir

  file:/home/hadoop/dfsdata/name

  Determines where on thelocal filesystem the DFS name node should store the name table.If this is acomma-delimited list of directories,then name table is replicated in all of thedirectories,for redundancy.

  true

dfs.datanode.data.dir

file:/home/hadoop/dfsdata/data

  Determines where on thelocal filesystem an DFS data node should store its blocks.If this is acomma-delimited list of directories,then data will be stored in all nameddirectories,typically on different devices.Directories that do not exist areignored.

  

  true

  dfs.replication

  3

  dfs.permission

  false

(5)、mapred-site.xml:

mapreduce.framework.name

  yarn

mapreduce.job.tracker

  hdfs://mr5:9001

  true

mapreduce.task.io.sort.mb

  512

mapreduce.task.io.sort.factor

  100

mapreduce.reduce.shuffle.parallelcopies

  50

  mapreduce.cluster.temp.dir

file:/home/hadoop/mapreddata/system

  true

mapreduce.cluster.local.dir

file:/home/hadoop/mapreddata/local

  true

(6)、yarn-env.sh :

增加以下环境变量

exportJAVA_HOME=/usr/jdk1.6.0_30

exportHADOOP_HOME=/home/hadoop/hadoop-2.0.0-cdh4.1.2

exportHADOOP_PREFIX=${HADOOP_HOME}

exportHADOOP_MAPRED_HOME=${HADOOP_HOME}

exportHADOOP_COMMON_HOME=${HADOOP_HOME}

exportHADOOP_HDFS_HOME=${HADOOP_HOME}

exportHADOOP_YARN_HOME=${HADOOP_HOME}

exportPATH=$PATH:${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin

exportJAVA_HOME JAVA_BIN PATH CLASSPATH JAVA_OPTS

exportHADOOP_LIB=${HADOOP_HOME}/lib

exportHADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop

(7)、yarn-site.xml:


yarn.resourcemanager.address

mr5:8080

yarn.resourcemanager.scheduler.address

mr5:8081

yarn.resourcemanager.resource-tracker.address

mr5:8082

yarn.nodemanager.aux-services

mapreduce.shuffle

yarn.nodemanager.aux-services.mapreduce.shuffle.class

org.apache.hadoop.mapred.ShuffleHandler

yarn.nodemanager.local-dirs

file:/home/hadoop/nmdata/local

thelocal directories used by the nodemanager

yarn.nodemanager.log-dirs

file:/home/hadoop/nmdata/log

thedirectories used by Nodemanagers as log directories

(4)拷贝到其他节点

(1)、在mr5上配置完第2步和第3步后,压缩hadoop-2.0.0-cdh4.1.2

rm hadoop-2.0.0-cdh4.1.2.tar.gz

tar  zcvf hadoop-2.0.0-cdh4.1.2.tar.gz  hadoop-2.0.0-cdh4.1.2

然后将hadoop-2.0.0-cdh4.1.2.tar.gz远程拷贝到mr6、mr7、mr8机器上

scp/home/hadoop/hadoop-2.0.0-cdh4.1.2.tar.gz hadoop@mr6:/home/hadoop/

scp/home/hadoop/hadoop-2.0.0-cdh4.1.2.tar.gz hadoop@mr7:/home/hadoop/

scp/home/hadoop/hadoop-2.0.0-cdh4.1.2.tar.gz hadoop@mr8:/home/hadoop/

(2)、将mr5机器上hadoop用户的配置环境的文件.bash_profile远程拷贝到mr6、mr7、mr8机器上

scp/home/hadoop/.bash_profile hadoop@mr6:/home/hadoop/

scp/home/hadoop/.bash_profile hadoop@mr7:/home/hadoop/

scp/home/hadoop/.bash_profile hadoop@mr8:/home/hadoop/

拷贝完成后,在mr5、mr6、mr7、mr8机器的/home/hadoop/目录下执行

source.bash_profile

使得环境变量生效

(5)启动hdfs和yarn

以上步骤都执行完成后,用hadoop用户登录到mr5机器依次执行:

hdfsnamenode -format

start-dfs.sh

start-yarn.sh

通过jps命令查看:

mr5成功启动了NameNode、ResourceManager、SecondaryNameNode进程;

mr6、mr7、mr8成功启动了DataNode、NodeManager进程。

(6)验证成功状态

通过以下方式查看节点的健康状态和作业的执行情况:

浏览器访问(本地需要配置hosts)

http://mr5:50070/dfshealth.jsp

http://mr5:8088/cluster

5、hive-0.9.0-cdh4.1.2安装

(1)安装包准备

使用hadoop用户上传hive-0.9.0-cdh4.1.2到mr5机器的/home/hadoop/目录下并解压:

     tar zxvf hive-0.9.0-cdh4.1.2

(2)配置环境变量

在.bash_profile添加环境变量:

exportHIVE_HOME=/home/hadoop/hive-0.9.0-cdh4.1.2

exportPATH=$PATH:${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:${HIVE_HOME}/bin

exportHIVE_CONF_DIR=$HIVE_HOME/conf

exportHIVE_LIB=$HIVE_HOME/lib

添加完后执行以下命令使得环境变量生效:

..bash_profile

(3)修改配置文件

修改hive配置文件(配置文件目录:hive-0.9.0-cdh4.1.2/conf/)

在hive-0.9.0-cdh4.1.2/conf/目录下新建hive-site.xml文件,并添加以下配置信息:

      

               hive.metastore.local

               true

      

               javax.jdo.option.ConnectionURL

               jdbc:mysql://10.28.169.61:3306/hive_impala?createDatabaseIfNotExist=true

      

               javax.jdo.option.ConnectionDriverName

               com.mysql.jdbc.Driver

      

      

                javax.jdo.option.ConnectionUserName

                hadoop

      

                javax.jdo.option.ConnectionPassword

               123456

   

                hive.security.authorization.enabled

                false

      

                hive.security.authorization.createtable.owner.grants

                ALL

      

                hive.querylog.location

                ${user.home}/hive-logs/querylog

      

(4)验证成功状态

完成以上步骤之后,验证hive安装是否成功

在mr5命令行执行hive,并输入”show tables;”,出现以下提示,说明hive安装成功:

>hive

hive>show tables;

OK

Time taken:18.952 seconds

hive>

6、impala安装

说明:

(1)、以下1、2、3、4步是在root用户分别在mr5、mr6、mr7、mr8下执行

(2)、以下第5步是在hadoop用户下执行

(1)安装依赖包:

安装mysql-connector-java:

    yum install mysql-connector-java

安装bigtop

rpm -ivh bigtop-utils-0.4+300-1.cdh4.0.1.p0.1.el6.noarch.rpm

安装libevent

rpm -ivhlibevent-1.4.13-4.el6.x86_64.rpm

如存在其他需要安装的依赖包,可以到以下链接:

http://mirror.bit.edu.cn/centos/6.3/os/x86_64/Packages/进行下载。

(2)安装impala的rpm,分别执行

rpm -ivh impala-0.3-1.p0.366.el6.x86_64.rpm

rpm -ivh impala-server-0.3-1.p0.366.el6.x86_64.rpm

rpm -ivh impala-debuginfo-0.3-1.p0.366.el6.x86_64.rpm

rpm -ivh impala-shell-0.3-1.p0.366.el6.x86_64.rpm

(3)找到impala的安装目录

完成第1步和第2步后,通过以下命令:

find / -name impala

输出:

/usr/lib/debug/usr/lib/impala

/usr/lib/impala

/var/run/impala

/var/log/impala

/var/lib/alternatives/impala

/etc/default/impala

/etc/alternatives/impala

找到impala的安装目录:/usr/lib/impala

(4)配置Impala

在Impala安装目录/usr/lib/impala下创建conf,将hadoop中的conf文件夹下的core-site.xml、hdfs-site.xml、hive中的conf文件夹下的hive-site.xml复制到其中。

在core-site.xml文件中添加如下内容:

dfs.client.read.shortcircuit

true

dfs.client.read.shortcircuit.skip.checksum

false

在hadoop和impala的hdfs-site.xml文件中添加如下内容并重启hadoop和impala:

            

dfs.datanode.data.dir.perm

755

dfs.block.local-path-access.user

hadoop

dfs.datanode.hdfs-blocks-metadata.enabled

true

(5)启动服务

(1)、在mr5启动Impala state store,命令如下:

>GLOG_v=1 nohup statestored-state_store_port=24000 &                     

如果statestore正常启动,可以在/tmp/statestored.INFO查看。如果出现异常,可以查看/tmp/statestored.ERROR定位错误信息。

(2)、在mr6、mr7、mr8启动Impalad,命令如下:

mr6:

>GLOG_v=1 nohup impalad -state_store_host=mr5-nn=mr5 -nn_port=9000 -hostname=mr6 -ipaddress=10.28.169.113 &

mr7:                                             

>GLOG_v=1 nohup impalad -state_store_host=mr5-nn=mr5 -nn_port=9000 -hostname=mr7 -ipaddress=10.28.169.114 &

mr8:                                             

>GLOG_v=1 nohup impalad -state_store_host=mr5-nn=mr5 -nn_port=9000 -hostname=mr8 -ipaddress=10.28.169.115 &      

       如果impalad正常启动,可以在/tmp/impalad.INFO查看。如果出现异常,可以查看/tmp/ impalad.ERROR定位错误信息。

(6)使用shell

使用impala-shell启动Impala Shell,分别连接各Impalad主机(mr6、mr7、mr8),刷新元数据,之后就可以执行shell命令。相关的命令如下(可以在任意节点执行):

>impala-shell

[Not connected]> connect mr6:21000

[mr6:21000] >refresh

[mr6:21000]>connectmr7:21000

[mr7:21000]>refresh

[mr7:21000]>connectmr8:21000

[mr8:21000]>refresh

(7)验证成功状态

使用impala-shell启动Impala Shell,分别连接各Impalad主机,刷新元数据,之后就可以执行shell命令。相关的命令如下(可以在任意节点执行):

>impala-shell

[Not connected]> connect mr6:21000

[mr6:21000]>refresh

[mr6:21000] >show databases

default

[mr6:21000] >

出现以上提示信息,说明安装成功。


三、Impala的使用

1、命令行功能
命令
描述
备注
connect连接Impala节点connect mr8:21000
describe查看表结构describe tab1
explain解析SQL语句explain select * from tab..
help帮助命令,查看命令的说明help connect
insert插入数据命令insert overwrite
insert into
quit退出命令 
refresh刷新源数据库 
select查询语句命令 
set设置impala查询选项 
shell执行本地linux命令 
show查看表和数据库命令 
use选择使用数据库 
version查看Impala版本 


set命令参数说明:

参数
默认值
PARTITION_AGGfalse
NUM_SCANNER_THREADS0
MAX_IO_BUFFERS0
MAX_SCAN_RANGE_LENGTH0
NUM_NODES0
DISABLE_CODEGENfalse
MAX_ERRORS0
ABORT_ON_ERRORfalse
BATCH_SIZE0
ALLOW_UNSUPPORTED_FORMATSfalse

2、当前支持的语言元素

Impala的查询语言是基于Hive的HiveQL,目前impala不支持针对表和分区的DDL,但是支持DML。其实大部分的HiveQL不需要修改就可以在impala上面执行的,包括JOIN, AGGREGATE, DISTINCT, UNION ALL, ORDER BY, LIMIT 和subquery等等。

(1)、select

l  数据类型:boolean, tinyint, smallint, int, bigint, float, double, timestamp, string

l  DISTINCT

l  FROM 子句支持子查询.

l  WHERE, GROUP BY, HAVING

l  ORDER BY,但是需要和limit一起使用

l  JOINS: Left、 right、 semi、 full and outer

l  UNION ALL

l  LIMIT

l  External tables

l  关系运算符:>、<、=等

l  算术运算符:加法、减法等

l  逻辑boolean操作符:and、or、not,但是impala不支持对应的&&、||、!

l  COUNT, SUM, CAST, LIKE, IN, BETWEEN, 和COALESCE


说明:

l  Join的时候大表一定要放在左边

l  Join subsequent tables according to which table has the mostselective filter. Joining the

table with the most selective filterresults in the fewest number of rows are being returned.


(2)、insert

当前版本的impala,insert只支持已经创建好的表和分区。所有表和分区结构的创建和修改只能通过HIVE来完成。

现在支持的insert包括:

l  INSERT INTO

l  INSERT OVERWRITE

说明:

Insert命令可能会导致Hive的元数据发送改变,所以在使用impala执行查询时最好先执行一下refresh命令刷新一下hive元数据。


(3)、refresh

为了准确地响应查询,impala必须要知道当前Hive中数据库的所有元数据,这样impala的客户端才能够直接进行正确查询。因此,如果使用impala客户端进行的一些操作修改hive的元数据后,最好impala的每一个节点都重新refresh,保证元数据是最新的。但是并不是所以的impala操作都需要refresh元数据。

在以下几种情况下impalad实例需要refresh元数据:

l  当前impalad实例修改了元数据

l  其他比如hive或者其他的impalad实例修改了元数据

l  通过impala-shell命令行或者ODBC驱动程序连接impala进行的操作导致数据库发生改变

Impalad实例不需要refresh的情况:

l  当集群中只有一个impalad实例的时候,即使这个实例修改了元数据,该impalad实例会自动更新自己的数据库元数据信息。这种情况下是不需要refresh的。

l  如果被修改元数据的数据库是一个后台数据库,也即impalad实例不需要连接该数据库以获得元数据的数据库,这种情况下也是不需要refresh的。

Hive元数据被修改的典型情况包括:

l  通过Hive进行了ALTER,CREATE, DROP 或 INSERT操作

l  通过impalad进行了INSERT操作

l   

(4)、DESCRIBE

l  DESCRIBE tableName:列出表的结构信息


(5)、SHOW

l  SHOW TABLES :列出所有的表

l  SHOW DATABASES :列出所有的数据库

l  SHOW SCHEMAS :列出所有的schema


(6)、USE

l  USE DATABASE

Impala的主要资源



作者:cqboy1991 发表于2014-7-30 9:57:43 原文链接
阅读:63 评论:0 查看评论

什么是探索性测试? - reach296

$
0
0

1、探索性测试的定义

探索性测试(ET)是敏捷世界里的一种重要测试方法,作为一个研究性的工具,它是用户故事测试和自动化回归集的重要补充。它是一种经过深思熟虑的测试方式,没有测试脚本,可以使你的测试超出各种明显已经测试过的场景。探索测试将学习,测试设计和测试执行整合在一起,形成一种测试方法。

探索性测试的最大特色是在对测试对象进行测试的同时学习测试对象并设计测试,在测试过程中运用获得的关于测试对象的信息设计新的更好的测试。他的典型过程如下图:

这相对于传统软件测试过程中严格的“先设计,后执行”来说,是具有很大区别的。

 

2、探索性测试的基本过程

探索性测试的基本过程包括如下:

        识别软件系统的目的;

        识别软件系统提供的功能;

        识别软件系统潜在的不稳定的区域;

        在探索软件系统的过程中记录关于软件的消息和问题;

        创建一个测试纲要,使用它来执行测试。

注意:上面的过程是一个循环的过程,并且没有很严格的执行顺序,完全能够先创建测试纲要,执行测试,然后在测试中进修软件系统;也能够先探索软件系统的各个区域,然后再列出需要测试的要点。

探索性测试强调创新的测试思维,在测试过程中不断地出现许多关于测试的新想法,

因而就像一把叉,下图就是一个所谓的“探索叉”(exploratory forks)。

探索性测试强调测试过程中要有更多的发散思维,这也是与保守测试方式的最大区别。

保守测试方式强调设想完善的测试用例,测试人员严格按测试用例执行测试,这多少限制了测试人员的测试思维,测试人员往往缺乏主观能动性。

 

下图展示了一个发散思维的过程,探索性测试强调发散,但并不是盲目地发散,在适当的时候还要收敛回来。

例如,当发觉在一个测试的分支路径上已经花了很长时间也没有找到问题的答案时,则能够考虑先放弃那个区域的探索,因为还有一个主线的测试任务。

探索性测试尤其适合于那些需求不是很明确的测试任务,或者是一名刚刚接手一项新的测试任务的测试人员使用。

3、探索性测试的价值

     3.1、探索性测试可以用来找到深层次的BUG。

     因为探索性测试人员是优秀的观察者,他们观察不正常和不期望的结果,并进行认真的思考,这种状态和按部就班的执行用例是不一样的,因此,它更容易发现一些隐藏的很深的问题。

     3.2、探索性测试可以加深测试人员对被测系统的了解。

     探索性测试强调对被测试对象的学习,并且是在测试过程中的学习,并在此基础上设计测试,因此,它使测试人员更容易深入的理解被测系统。

4、探索性测试的误区

     4.1、不要将探索性测试和随机测试混淆。

     探索性测试不是在键盘钱坐下并敲击,没有熟练技能,不会认真思考的“黑盒”测试人员所做的并不是探索性测试,一个合格的探索性测试人员需要认真思考和分析结果,并且在探索测试的过程中做记录。

     4.2、不要将探索性测试和回归测试混淆。

     探索性测试更注重的是思考和学习,不断发现新的问题,而版本的回归测试,是对原有的功能的保证,为持续迭代构筑安全网。重复的功能回归测试应该尽量用自动化的方式来完成,这样,才有足够的人力来进行探索性测试。

     4.3、探索性测试不能用来评估软件质量。

     尽管探索性测试是一种有效的测试方法,但是它不意味着是一种全面覆盖的测试方法。如果你要评估测试是否全面,可能你需要其他的手段。


本文链接: 什么是探索性测试?,转载请注明。


【协作】尽情称赞孩子吧!

$
0
0

译者: 五月撄宁原文地址: aeon.co

译者: tzsymomoforestbianzoubian五月撄宁(负责人)

图:为称赞点赞!

 卢卡•乔丹(Luca Zordan)摄/画廊藏品

所有人都认为过多的赞扬会让孩子恃宠而骄,但是个中学问并非如此简单

半年前,我带着儿子回南卡罗来纳州的娘家探望父母。有一天晚餐后,我洗了几个盘子,我父亲便冲我大声说喊道“干得好!”我知道他这是在一如既往地取笑我,因为之前,儿子很乖地吃了一大把蓝莓的时候,我也是大声说“干得好!”,后来那天晚上当他往前倾着小身体,经过一小番努力后,成功脱下自己的袜子时,我也这么喊了一句。我儿子那时候一岁半。

我当然了解这么做可能带来的危害:年轻一代被父母宠坏了,父母称他们为“小毕加索”或者“小爱因斯坦”,所以他们都超级自恋,听表扬听上了瘾。那又如何?我就喜欢表扬我的孩子,而且我一点儿也不觉得不好意思。当他砰砰敲打着他的小鼓时,或者用蜡笔在墙上涂鸦时,我会很自豪地告诉他,他是多么具有天分。当我的小宝贝每向前迈出一小步时,我都想对他表达出自己由衷的欢欣和喜爱之情。我的父母对此再怎么翻白眼也无济于事。

我们真的了解表扬的真相吗?从人类生物学家格温•杜瓦(Gwen Dewar)专门为像我一样的父母开设的育儿科学网站中,我们或许可以找到一些信息和建议:当孩子因其能力而非努力而受到我们的表扬时,他们会把才能和智慧看成是天生就有的,而不是需要通过后天培养和学习才获得的技能。没有诚意的表扬会让孩子觉得家长不理解他。仅仅表达出一种评判态度的表扬,比如“干得好!”,远不如向孩子们具体指出他们到底哪里干得好。

里根大学心理学家珍妮弗•亨德龙•柯普思(Jennifer Henderlong Corpus)和斯坦福大学心理学家马克•雷普尔(Mark Lepper)表示,过度表扬(比如:你简直太棒了!)可能会让孩子觉得你的标准特别高,因而害怕自己没办法一直做到这么好。而孩子完成了简单的任务就受到表扬会让他们觉得你很傻(难道你不知道这件事有多简单吗?)或者你认为他们很傻。两位心理学家还有一个更微妙的发现:对于孩子天性热衷的事情,如果家长给予过多的表扬往往会适得其反,不仅不会让孩子更有劲头,反而会损伤他们的积极性。

考虑到之前在教育孩子上有很多不当的地方,我虚心学习了来自旧金山大学的心理学家吉姆•泰勒(Jim Taylor)自以为了不起的慷慨言论:“干得好?哎,这个表扬太敷衍,一点用也没有,甚至会伤害孩子……如果你就想继续敷衍,那至少说‘好努力!’因为这会让孩子把注意力放到他为了做好事情而付出的努力上……实际上,小孩子根本不需要听人跟他说干得好!他们干好了事情,那份成就感就足够了……尤其是年幼的孩子,你根本不需要去表扬他们。”

然而,这些反对表扬的声音,对吗?首先,这些严厉批评中的第一处破绽在于,表扬对不同年龄的孩子有着不同的效果。比如2007年由目前就职于加州大学戴维斯分校的保尔•海斯汀(Paul Hastigns)牵头进行的一项研究发现,家长表扬学龄前儿童讲礼貌,能帮助孩子培养更出色的社交技能,而这一发现与泰勒所持的学龄前儿童根本不需要表扬的观点刚好相反。另一项发表于1997年、由宾夕法尼亚州林克明学院(Lycoming College)的苏•凯利(Sue Kelly)牵头进行的研究发现,那些在第一次实验中得到妈妈的鼓励进行独自探索的两岁孩子,在一年后的试验中,比那些在第一次实验中没有受到鼓励的孩子们表现出了更强的独立性。

而至于那些热情洋溢的过度表扬,波士顿大学(Boston College)的艾伦•温纳(Ellen Winner)以及其他一些学者发现,七岁以下的孩子还没有成熟到能够质疑父母的表扬是否发自内心,这也就意味着他们不会像大孩子一样受到“过高标准”问题的困扰。

与第一处破绽相比,赞美反对派理论显露出的第二个破绽则更为微妙和难以捉摸。荷兰乌得勒支大学(Utrecht University)在今年发表了一个研究报告,该研究由发展心理学博士生艾迪•布鲁梅尔门(Eddie Brummelman)带头。研究表明,事实上,过度赞美(就“太不可思议了”和“干得不错”相比)会给低自尊的孩子带来伤害,但对高自尊的孩子却是有好处的。

“当高自尊的孩子受到夸大的赞美时,更可能选择一些有挑战性的任务。”

首先,该研究证实了研究员们的假设,即比起高自尊1的孩子,父母更有可能对低自尊2的孩子给予过度赞美。研究员们选取了一组年龄在8到12岁间的孩子,事先对他们的自尊程度进行评级,然后带他们去参观美术馆。在参观过程中,孩子们需要各自完成一幅画,之后这些画作会由假定的“专业画家”进行点评。在实验的最后环节中,孩子们会被问到是愿意再参加一轮难度加大的绘画练习,还是一轮相对简单的练习。其中所有受到夸大赞美的孩子都把这赞美当成是发自内心的,不论他们的自尊程度如何。但是如预测所料,在低自尊的孩子群体中,与受到一般性赞美的孩子相比,受到夸大赞美的孩子更不愿意接受挑战。而另一方面,在高自尊的孩子群体中,受到夸大赞美的孩子则更愿意接受挑战。

这是可以理解的,因为高自尊的人一般都喜欢自我宣传,他们会寻找各种机会来展示自我才能,而低自尊的人则害怕失败,并会回避各种可能显露自身无用之处的情况。

报告写道:“所以,夸大的赞美会使低自尊的孩子主动躲避重要的学习机会,而这个过程最终会对他们的学习和表现产生不利影响。”尽管如此,事情的反面也不简单:“一般性的赞美也许能降低低自尊的孩子对于失败的恐惧,但它无法给予自信的孩子足够的动力去寻求挑战。”

然而,家长们真的知道自己孩子是低自尊型的还是高自尊型的吗?如果不知道,他们是否应该给孩子做个评估呢,然后根据评估结果相应地增加或者减少赞美的形容词?我自然不知道我两岁的儿子自我感觉如何。报告还写道:“尽管幼儿对‘好’和‘坏’有初步的认识,但是只有到儿童时代晚期,孩子们才会形成和表现出自尊。”如果我儿子还只有‘好’、‘坏’的概念,那么我很高兴自己给了他这么多的赞美——也许现在我正在培养他的自尊,以后,会有类似测试对此进行衡量的。

我向布鲁梅尔门提出了我的这个观点。他说还没有人做过该项实验,但是他倾向于同意这个猜想,并猜测“在儿童时代早期,夸大的赞美也许不但不会对孩子造成伤害,反而会有所帮助,因为幼儿通常都对未来抱有不切实际的乐观态度。当小孩子受到夸大的赞美时,他们可能会觉得自己能够达到为他们设定的高标准,由此寻求更多的挑战。”

所以我儿子很可能会对未来抱有乐观的期许——很好!我希望他能一直这样。我自己就走上了另一条路:当我离开父母去上大学的时候,只要我在课堂上举手发言,我的脸就会烧得通红。所以我就不怎么举手发言了。在我二十几岁的时候,每当老板直接点到我名字时,我就会脸红。我多希望我能更自信点儿。我认识一些人,他们的自信程度超过了自己的知识或才智水平,而我不确定这是否真的会对他们的生活造成伤害。去年,一项由宾夕法尼亚大学沃顿商学院(Wharton School at the University of Pennsylvania)的杰西卡•肯尼迪(Jessica Kennedy)带头的研究发现,展现自信的人,即使他们在任务中表现欠佳,别人也会认为他们能力不错,并且一般具有较高的社会地位。有人抱怨如今有太多的人过度自信,但对于这些人来说过度自信还是挺管用的。

“孩子才是父母行为表现形成的决定因素。这是个复杂的反馈回路,生物学和行为学在其中相互作用、相互影响。”

我同样不敢确定,自己缺乏自信到底是源于父母的某些行为还是他们某些行为的缺失。既然如此,我为何还要担心我对儿子一个劲的赞扬会毁了他呢?其他大人也在抚养照顾他,别的孩子和他的小伙伴也在帮助他成长,而且他也在自我成长,所有这些都是在这个变动不居的世界里不经意发生的。反对赞扬派理论的第三个破绽就此显现出来:身为父母,担心自己的言行举止会对孩子产生不良影响,这种想法反映出他们对于真正影响孩子发展的诸多因素存在误解。家庭教育是一个双向的动态过程,同时受到环境和父母孩子双方基因的影响。事实上,密歇根州立大学(Michigan State University)的埃诗里娅•克拉尔(Ashlea Klahr)和同事在2014年的《心理学公报》上发表的一篇综合研究报告认为,关切、控制和消极否定是衡量父母抚养行为的三项基本指标,每项指标都与孩子未来可能出现的反社会行为、焦虑、药物滥用等不良后果息息相关,而基因对于父母在这三项行为指标方面不同表现的影响占了23%-40%。关心,正如你想象的那样,包括通过语言表达对孩子的关爱,最有可能激发出一些正面结果,即孩子出现焦虑、抑郁等行为问题的可能性更小,更有可能做好学习准备并在学业上获得成就。这是迄今为止证明基因在父母行为以及该行为对孩子产生的影响方面发挥着重要作用最强有力的证据。

然而,最让人吃惊的是,报告中有证据证实一个孩子自身的性格是如何影响父母的行为方式的——换句话说,除了基因的影响之外,孩子自身才是父母行为表现形成的决定因素。这是个复杂的反馈回路,生物学和行为学在其中相互作用、相互影响,并且在每对父母和孩子身上的表现形式都不尽相同。

这个理论支持个性化的教育方式。“你需要思考下你自己属于哪种性格,让你觉得麻烦的事情有哪些,然后形成一套对你和你的孩子都合适的教育模式和策略,”克拉尔告诉我,“如果你作为父母试图表现出的言行举止让你自己都感到别扭和不自然,那整个教育过程对你来说会变得困难和压力重重。我们当然知道有些事对孩子有好处,有些事则不利于孩子成长,但由于孩子间存在个体差异,我们在好与坏之间还有许多自由选择的空间。”特别是当你把赞扬作为孩子发生良好转变的激励因素时,克拉尔建议,你要对自己在激发孩子积极行为方面的行动进行追踪评估,甚至可以把它写下来然后分析哪些有用哪些没用。“可以在你自己家里做一次小实验”她说。

纽约大学社会学教授道尔顿•康利(Dalton Conley)在他那本有趣的《家长宝典》(2014)中,正好对这样的家庭实验做了详实的记录。他花了好几年的时间用小熊糖、电子游戏时间和零花钱来“收买”他的儿子和女儿,以让他们做额外的数学题,数年后,他的女儿变得越来越喜欢阅读和文学,对数学不太感兴趣,而他的儿子有空时却不再看小说而去研究分形几何。“就这样,我不断为他们学习某一门学科(数学)提供外在的奖赏,而对他们另一门学科(阅读)的学习未加干预,但最后,奖励机制的存在与否几乎未对他们的学科热情产生半点影响。”换言之,其中一个孩子所获得的盛赞,放到另一个孩子身上可能效果完全不同,这取决于孩子们的兴趣、性格,以及父母的兴趣、性格等各方面因素。

“我们从不愿说赞扬对孩子不好,”克拉尔说。“我们鼓励父母去赞扬孩子。我们知道正面强化——对好的表现加以关注和赞赏——会带来最理想的结果,而严厉的、不明原因的惩罚会导致孩子行为问题、亲子矛盾和抑郁问题出现的几率大大增加。”

因此,那些认为仅凭赞扬孩子或是不予称赞便能帮助孩子走向成功的观点过分夸大了这些教育方式的作用。与这些观点相反,来自康奈尔大学(Cornell University)的儿童心理学家肯尼斯•巴里西(Kenneth Barish)坚持认为批评才是真正的问题所在。“我见过许多垂头丧气、愤怒沉郁的孩子;我也见过一些意志消沉的孩子,他们碰到一点儿微小的挫折或失意,就因此无法继续努力;我还见过一些自以为是、狂妄自大的孩子。而造成这种现象的罪魁祸首并不是称赞,而是批评。这些孩子中大多数都受到了过度的批评,而被过度表扬的孩子则寥寥无几。”

对过强的自尊心的抵制逐渐占据了优势,因为事实证明自尊的过度膨胀往往带来适得其反的效果:那些在掌声中长大的孩子不懂得如何改正自己的行为,也不知道如何面对拒绝和失败。他们缺乏毅力,而如今研究人员声称,毅力正是通往成功的关键。然而在我们这个飞速变化的世界里,我连未来社会需要什么都毫无头绪,又如何知道怎样的养育方式才会更有利于儿子将来的成功呢?

我自小练习古典的小提琴,学习上也勤奋努力。长大后我进入一流的大学和研究生院读书。但从我记事起,我就时常为未来感到担忧。与我不同的是,我丈夫从小就对学校毫不在意,他成天玩音乐、写曲子,从不因自己看不懂老师的课堂讲义而烦恼。他没有上大学,而是去了一所艺术学校,却还一直认为自己是个幸运的人,无论怎样都会拥有光明的前途。但是,我们都经历过挫败的沮丧和成功的喜悦,而且当我在脑海里汇集起所有可能用于衡量成功的因素时,我要说就世俗的成功而言,我俩的前途其实不相上下。那么我和丈夫谁应当成为儿子的榜样呢?在这个问题上,儿子身为男性这一事实或许能够提供一些解答的线索。从我和丈夫的成长模式来看,和女性相比,男性通常对自身才能有着更高的评价,即使实验表明他们的实际能力是不相上下的。而女性则更擅社交,她们大多数能在社会中得到更多的帮助。现在,我的儿子也许需要额外的赞扬才会养成良好习惯,但最终,无论我称赞与否,他都会比他的女性同伴们拥有更多的自我认同。

当你称赞蹒跚学步的孩童时,唯一可能导致不良后果的情况就是:在他们做了你不希望他们做的事情后,你仍然冲他们喊:“干得好!”

这些数据给了我一些启发。我决定从现在起给予儿子更具体的赞扬。我要为他在家具上涂鸦的努力本身而喝彩,而不是夸奖他在为涂鸦挑选有趣的蜡笔颜色时表现出的天分。但是墙壁是他的。从现在起,我会允许他看动画片;会在他伸过来的手掌中放一块曲奇,然后看着他的笑容慢慢舒展成南瓜灯上的样子;会赞许他在涂色时的专注神态,并且在他完成时加以表扬。

“在所有可能导致不良结果的行为里,”克拉尔说道,“赞扬过度是父母们最无需担心的事了。说真的,当你称赞蹒跚学步的孩童时,唯一可能导致不良后果的情况就是:在他们做了你不希望他们做的事情后,你仍然冲他们喊:‘干得好!’”

难道大多数孩子最终都不会变得懂事吗?无论我现在做什么或不做什么,难道我的儿子不会在某天明白墙壁是不能涂画的吗?让我为了我的小男孩而心怀感恩吧!毕竟,这个小生命随时都有可能消逝(母亲的天性使然,我总会时刻意识到这点)。那么,在这个残酷的世界开始吞噬他之前,我至少想让他在情感上得到充分的满足。

译注:

1. 高自尊:心理学名词。高自尊者有良好的自我认可度和自我接纳能力,能肯定自己的整体价值,对自己的优缺点也能有比较客观的评价。在做事上,高自尊者注重能力,且有责任心。

2. 低自尊:心理学名词。低自尊者的自我认可度和自我接纳能力较低,经常贬低自我价值,对外界评价过分关注。做事上,低自尊者常常表现出缺乏责任心、不能继续努力等行为。

欢迎加入 协作营,协作q群 153822117、262463682、261778861(入群请将名片改为译言ID) 协作翻译,你不是一个人在战斗!


zookeeper技术浅析

$
0
0

 Zookeeper是hadoop的一个子项目,虽然源自hadoop,但是我发现zookeeper脱离hadoop的范畴开发分布式框架的运用越来越多。今天我想谈谈zookeeper,本文不谈如何使用zookeeper,而是zookeeper到底有哪些实际的运用,哪些类型的应用能发挥zookeeper的优势,最后谈谈zookeeper对分布式网站架构能产生怎样的作用。

  Zookeeper是针对大型分布式系统的高可靠的协调系统。由这个定义我们知道zookeeper是个协调系统,作用的对象是分布式系统。为什么分布式系统需要一个协调系统了?理由如下:

  开发分布式系统是件很困难的事情,其中的困难主要体现在分布式系统的“部分失败”。“部分失败”是指信息在网络的两个节点之间传送时候,如果网络出了故障,发送者无法知道接收者是否收到了这个信息,而且这种故障的原因很复杂,接收者可能在出现网络错误之前已经收到了信息,也可能没有收到,又或接收者的进程死掉了。发送者能够获得真实情况的唯一办法就是重新连接到接收者,询问接收者错误的原因,这就是分布式系统开发里的“部分失败”问题。

  Zookeeper就是解决分布式系统“部分失败”的框架。Zookeeper不是让分布式系统避免“部分失败”问题,而是让分布式系统当碰到部分失败时候,可以正确的处理此类的问题,让分布式系统能正常的运行。

  下面我要讲讲zookeeper的实际运用场景:

  场景一:有一组服务器向客户端提供某种服务(例如:我前面做的分布式网站的服务端,就是由四台服务器组成的集群,向前端集群提供服务),我们希望客户端每次请求服务端都可以找到服务端集群中某一台服务器,这样服务端就可以向客户端提供客户端所需的服务。对于这种场景,我们的程序中一定有一份这组服务器的列表,每次客户端请求时候,都是从这份列表里读取这份服务器列表。那么这分列表显然不能存储在一台单节点的服务器上,否则这个节点挂掉了,整个集群都会发生故障,我们希望这份列表时高可用的。高可用的解决方案是:这份列表是分布式存储的,它是由存储这份列表的服务器共同管理的,如果存储列表里的某台服务器坏掉了,其他服务器马上可以替代坏掉的服务器,并且可以把坏掉的服务器从列表里删除掉,让故障服务器退出整个集群的运行,而这一切的操作又不会由故障的服务器来操作,而是集群里正常的服务器来完成。这是一种主动的分布式数据结构,能够在外部情况发生变化时候主动修改数据项状态的数据机构。Zookeeper框架提供了这种服务。这种服务名字就是:统一命名服务,它和javaEE里的JNDI服务很像。

  场景二:分布式锁服务。当分布式系统操作数据,例如:读取数据、分析数据、最后修改数据。在分布式系统里这些操作可能会分散到集群里不同的节点上,那么这时候就存在数据操作过程中一致性的问题,如果不一致,我们将会得到一个错误的运算结果,在单一进程的程序里,一致性的问题很好解决,但是到了分布式系统就比较困难,因为分布式系统里不同服务器的运算都是在独立的进程里,运算的中间结果和过程还要通过网络进行传递,那么想做到数据操作一致性要困难的多。Zookeeper提供了一个锁服务解决了这样的问题,能让我们在做分布式数据运算时候,保证数据操作的一致性。

  场景三:配置管理。在分布式系统里,我们会把一个服务应用分别部署到n台服务器上,这些服务器的配置文件是相同的(例如:我设计的分布式网站框架里,服务端就有4台服务器,4台服务器上的程序都是一样,配置文件都是一样),如果配置文件的配置选项发生变化,那么我们就得一个个去改这些配置文件,如果我们需要改的服务器比较少,这些操作还不是太麻烦,如果我们分布式的服务器特别多,比如某些大型互联网公司的hadoop集群有数千台服务器,那么更改配置选项就是一件麻烦而且危险的事情。这时候zookeeper就可以派上用场了,我们可以把zookeeper当成一个高可用的配置存储器,把这样的事情交给zookeeper进行管理,我们将集群的配置文件拷贝到zookeeper的文件系统的某个节点上,然后用zookeeper监控所有分布式系统里配置文件的状态,一旦发现有配置文件发生了变化,每台服务器都会收到zookeeper的通知,让每台服务器同步zookeeper里的配置文件,zookeeper服务也会保证同步操作原子性,确保每个服务器的配置文件都能被正确的更新。

  场景四:为分布式系统提供故障修复的功能。集群管理是很困难的,在分布式系统里加入了zookeeper服务,能让我们很容易的对集群进行管理。集群管理最麻烦的事情就是节点故障管理,zookeeper可以让集群选出一个健康的节点作为master,master节点会知道当前集群的每台服务器的运行状况,一旦某个节点发生故障,master会把这个情况通知给集群其他服务器,从而重新分配不同节点的计算任务。Zookeeper不仅可以发现故障,也会对有故障的服务器进行甄别,看故障服务器是什么样的故障,如果该故障可以修复,zookeeper可以自动修复或者告诉系统管理员错误的原因让管理员迅速定位问题,修复节点的故障。大家也许还会有个疑问,master故障了,那怎么办了?zookeeper也考虑到了这点,zookeeper内部有一个“选举领导者的算法”,master可以动态选择,当master故障时候,zookeeper能马上选出新的master对集群进行管理。

  下面我要讲讲zookeeper的特点:

  1. zookeeper是一个精简的文件系统。这点它和hadoop有点像,但是zookeeper这个文件系统是管理小文件的,而hadoop是管理超大文件的。

  2. zookeeper提供了丰富的“构件”,这些构件可以实现很多协调数据结构和协议的操作。例如:分布式队列、分布式锁以及一组同级节点的“领导者选举”算法。

  3. zookeeper是高可用的,它本身的稳定性是相当之好,分布式集群完全可以依赖zookeeper集群的管理,利用zookeeper避免分布式系统的单点故障的问题。

  4. zookeeper采用了松耦合的交互模式。这点在zookeeper提供分布式锁上表现最为明显,zookeeper可以被用作一个约会机制,让参入的进程不在了解其他进程的(或网络)的情况下能够彼此发现并进行交互,参入的各方甚至不必同时存在,只要在zookeeper留下一条消息,在该进程结束后,另外一个进程还可以读取这条信息,从而解耦了各个节点之间的关系。

  5. zookeeper为集群提供了一个共享存储库,集群可以从这里集中读写共享的信息,避免了每个节点的共享操作编程,减轻了分布式系统的开发难度。

  6. zookeeper的设计采用的是观察者的设计模式,zookeeper主要是负责存储和管理大家关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在 Zookeeper 上注册的那些观察者做出相应的反应,从而实现集群中类似 Master/Slave 管理模式。

  由此可见zookeeper很利于分布式系统开发,它能让分布式系统更加健壮和高效。

  前不久我参加了部门的hadoop兴趣小组,测试环境的hadoop、mapreduce、hive及hbase都是我来安装的,安装hbase时候安装要预先安装zookeeper,最早我是在四台服务器上都安装了zookeeper,但是同事说安装四台和安装三台是一回事,这是因为zookeeper要求半数以上的机器可用,zookeeper才能提供服务,所以3台的半数以上就是2台了,4台的半数以上也是两台,因此装了三台服务器完全可以达到4台服务器的效果,这个问题说明zookeeper进行安装的时候通常选择奇数台服务器。在学习hadoop的过程中,我感觉zookeeper是最难理解的一个子项目,原因倒不是它技术负责,而是它的应用方向很让我困惑,所以我有关hadoop技术第一篇文章就从zookeeper开始,也不讲具体技术实现,而从zookeeper的应用场景讲起,理解了zookeeper应用的领域,我想再学习zookeeper就会更加事半功倍。

  之所以今天要谈谈zookeeper,也是为我上一篇文章分布式网站框架的补充。虽然我设计网站架构是分布式结构,也做了简单的故障处理机制,比如:心跳机制,但是对集群的单点故障还是没有办法的,如果某一台服务器坏掉了,客户端任然会尝试连接这个服务器,导致部分请求的阻塞,也会导致服务器资源的浪费。不过我目前也不想去修改自己的框架,因为我总觉得在现有的服务上添加zookeeper服务会影响网站的效率,如果有独立的服务器集群部署zookeeper还是值得考虑的,但是服务器资源太宝贵了,这个可能性不大。幸好我们部门也发现了这样的问题,我们部门将开发一个强大的远程调用框架,将集群管理和通讯管理这块剥离出来,集中式提供高效可用的服务,等部门的远程框架开发完毕,我们的网站加入新的服务,我想我们的网站将会更加稳定和高效。

作者:jdbc 发表于2014-7-29 20:34:54 原文链接
阅读:93 评论:0 查看评论

java socket 长连接read阻塞问题

$
0
0

解决的方法有3个 :
1 约定发送的数据长度,比如 http的 keepAlive 就是必须依赖这个的 Content-Length
2 设置超时的时间,根据我的经验,只有在Socket级别设置才有效.
Socket socket = new Socket(host,port);
socket.setSoTimeout(100); // 如果超过100毫秒还没有数据,则抛出 SocketTimeoutException

3 让发送端发送完数据后,关闭连接。 这个在Http的操作时很常见。

( InputStream如何判断数据已经读取结束)

某些时候无法修改客户端的情况下情况一就只有pass掉了,情况二相对来说比较适合,当阻塞后直接抛出一个异常。情况三不适合长连接,因为整个通信过程中链路是不能中断的,也不能调shutdown结束。其实还有第四种方法:当读取到某些字符就不在往下读取了,比如读取到byebye就break。但是这也需要改客户端代码。选了一种折中的办法-设置超时:

StringBuilder sb = new StringBuilder();
try {
    client.setSoTimeout(500);
    while ((a = client.getInputStream().read(buf)) != -1) {
        sb.append(new String(buf, 0, a));
        if (a != size) {
            break;
        }
    }
} catch (Exception e) {
}
System.out.println(sb);

 

[转][转]TokuDB中的COLA-Tree和TokuMax中的Fractal tree(分形树)

$
0
0


TokuDB中的COLA-Tree


      目前无论是商业的SQL Server,还是开源的MySQL,都基本上还在用比较老的 B+Tree(SQL Server用的是标准的B-Tree)的索引结构。从原理来说,B系列树在查询过程中应该是不会慢的,而主要问题就是出现在插入。B-Tree在插入的时候,如果是最后一个node,那么速度非常快,因为是顺序写。但如果数据插入比较无序的时候,比如先插入5然后10000然后3然后800这样跨度很大的数据的时候,就需要先“找到这个数据应该被插入的位置”,然后插入数据。这个查找到位置的过程,如果非常离散,那么就意味着每次查找的时候,他的子叶节点都不在内存中,这时候就必须使用磁盘寻道时间来进行查找了。更新基本与插入是相同的。如果是一个运行时间很长的B-Tree,那么几乎所有的请求,都是随机IO。以上就是B-Tree在磁盘结构中最大的问题了。

        随机IO几乎是令所有DBA谈虎色变的一个问题,当数据量小的时候,所有数据都能一下放到内存中那么就没有这个问题(其实这个时候也就没有必要用B-Tree的这种块结构了),但是一旦数据量大于内存的话这个问题就陡然出现了。其实从本质来说,k-v存储要解决的问题就是这么一个:尽可能快得写入,以及尽可能快的读取。

        在分析解决方法之前,我们讨论几个极端。走一个极端的话,如果我每次写数据都顺序写,那么对Insert来说的话是最快的,但是每次Query就没法读了,因为我每次都需要Scan一遍整个表。那么如果我想获取最佳的读性能,那么方法就是像B-Tree那样全部排个序呗。但是因为B-Tree有那样的随机IO,这样我们有没有办法得到顺序写的写性能,有同时达到B-Tree的读性能呢?目前的方法主要有两种,一种是LMS-Tree(我将会在后面的博客中再做介绍,如果您实在等不及请见 July大牛的博文),另一种是COLA Tree。下面介绍的就是TokuDB中采用的COLA-Tree。



一、原理 

        我们假设有这样一种集合的结构,相邻行空间加倍。每一行要么全满要么全空,全满行的数据都是排好序的。

        数据插入的时候,以上图的数据存储状态为例,如果再写一个值的时候,会写在第一行,比如写了3,这个时候第一行是空的,所以就放到第一行。再写一个值11的时候,因为第一行已经写满了,所以将3取出来,和11做排序,尝试写第二行。又因为第二行也满了,所以将第二行的5和10也取出,对3,11,5,10进行排序。写入第三行。最后的结果就是:



二、磁盘IO访问的性能

        分析一下磁盘IO量。合并两行数据总数为X一共需要O(X/B)次IO(B是磁盘的一个block的大小),平摊到每个数据上只要O(1/B)次。如果数据总数为N,那么一个数据最多只可能merge logN次,所以做一次插入的cost只要O(logN / B)。对比使用B-Tree作为索引的话,由于B-tree高度为LogB(N),对于磁盘IO来说,访问磁盘的次数为logB(N) = logN/logB,对于数据的query来说访问磁盘的次数是一样的。

        这是TokuDB做的分析,其实我觉得这个分析有点牵强,我觉得这有点欺负B-Tree只能单个数据单个数据的插入,对于大量数据的同时插入没有优势。如果CacheOblivious Tree也是单个的插入,那么单个插入访问IO的最坏情况是O(N/B)?

        翻阅原论文,原论文中承认了单个插入访问IO的最坏情况是O(N/B),但这个论文里提出了方法将最坏的这个情况改善了,主要方法是对每个level复制一个同样大小的辅助数组(如下图的两行一组的结构),所有被插入的数据先放入原空间,如果原空间满了则放入这个新建空间(如果新建空间同时也满了则是算法设计失败)。Insert的时候由一个线程完成,对于要插入一个数据的情况,这时把要Insert的数据放入Level-0的空间中(如果原数组空间为空则放入原数组空间,若满则放入辅助数组,如果辅助数组满则是算法设计的失败);另外一个线程进行merge,merge的时候按下图的结构从左到右进行,把全满的一对level空间合并排序到下一个level存放(下一个level的原数组空间为空则放入原数组空间,若满则放入辅助数组,如果辅助数组满则是算法设计的失败)。每一次merge的结束有两个标志,其中之一是所有需要merge的level对全部merge完,其二就是merge过程一共移动了m个数据。那么m的取值是多少呢?应该满足两个原则,其一是需要保证每次merge不能使得相邻两个level同时出现全满的情况;其二就是m的取值应该尽可能的小(很显然插入的最坏情况下的时间复杂度是O(m)的)。这些牛逼的作者们推出了这么一个定理:对于k个level的数据库来说,每次merge的时候只要从低到高移动2k+2的数据项,就能保证相邻的两个level不会同时出现满员的情况(这个证明过程说实话我没有看的太懂,希望懂的各位能够指导我理解一下,谢谢各位!论文 在此的第9页的LEMMA-21)。这样对于一个数量为N的数据库来说,level层数为log(N),那么每次merge要移动的数据量为2log(N)+2,即IO次数只要(2log(N)+2)/B,即O(log(N)/B)。于是这个最坏情况的IO就神奇地从O(N/B)降到了O(log(N)/B)。

        看看查询的性能。为了提高查找的性能,TokuDB在每个数据上加了一个forwardpointer,指向下一行中第一个比它大的数据的位置(这个叫做Fractional Cascading)。平均地看,上一级的每个数都把下一级搜索范围限制到了常数个,所以磁盘IO的次数最差应该为O(logN),好像这个没有问题。


        TokuDB实际采用的方法对上面的Fractal Trees还做了改进,将插入的IO数量级从log(N)提高到了logB(N),但是由于TokuDB不是开源的,所以没法知道他们如何实现的。


三、性能分析

        下面对TokuDB的性能总结一下,经过大家的测试,数据随机插入速度提高了20-80倍,如果是纯顺序插入则会慢3.5倍。

        如果要存储blob,不要使用TokuDB,因为它限制记录不能太大;

        如果你注重update的性能,不要使用TokuDB,它没有InnoDB快;

        如果你想要缩小数据占用的存储空间,可以使用TokuDB,TokuDB也进行了文件压缩。

 

(转载此文请注明出处: http://blog.csdn.net/jiang1st2010/article/details/7901269

引申阅读: 

1.   http://www.mysqlperformanceblog.com/2009/04/28/detailed-review-of-tokutek-storage-engine

2.   http://tokutek.com/presentations/bender-Scalperf-9-09.pdf

3.   http://openquery.com/blog/tokuteks-fractal-tree-indexes

4.  《Cache-ObliviousStreaming B-trees》


来源: http://blog.csdn.net/jwh_bupt/article/details/7901269





TokuDB与fractal tree index


2009 年以索引技术创业的 TokuTek 发布了 TokuDB for MySQL, 看性能参数是挺不错的.当时就对它产生了极大的兴趣. 但非常不幸偶没有理解它的索引原理 (Tokutek 也不说). 再加上它不是很成熟, 没有 ACID, 多核支持也不好, 所以暂时搁置了.

设有 n 个数据吧.基本意思是有 log2(n) 个索引块, 块的大小分别是 1, 2, 4… 直到 2^k, 其和大于 n (要不就存不下了 ). 每个块只有空和填满两种状态.插入时如果碰到块满的情况就把两个小块合并为更大的块.因为较小的块可以在内存中合并 (反正内存中怎么折腾都不会慢的), 对较大的块来说在旋转存储器上的归并速度也是很快的, 这就是 TokuDB 高速最直接的原因. 压缩是另一个加分的因素.

看来最大的问题就是, 两个块合成新块时, 如果两个块都很大就比较麻烦了.

删除的问题并不清楚. 不过考虑到它作为数据仓库的用途, 这一点可以暂时原谅. 删除也可以用对数据加 flag 的方法解决. 好像更新也不是简单的事情.看起来很像变种单机 BigTable, 只是不知道现在 Google 改造存储系统的情况如何.kumofs 的作者说 kumofs 是第二代分布式存储系统(彻底没有单点问题), 这个情况有感兴趣的自己去研究吧.

变长的数据是容易处理的. 搜索的复杂度降到 O(logB(N)), 存储的只要是块的位置(或编号)就可以了.事务(包括灾难恢复)和并行化可能是难度最大的部分.

说到对存储到硬盘上的数据进行整理, 就不得不提到 Reiser4 引入的 Dancing Tree.写入之前对 Block 做整理的操作, 这是一个比较有效的优化, 只是可惜了…

TokuDB 还有 covering index (试译: 覆盖索引) 的支持. 覆盖索引要求所有要查询的列都在索引之中.如果有 (a, b, c) 的覆盖索引, 则查询 select b, c where a = xx 这类是很快的.(覆盖索引和多维排序索引有什么区别? 如果后者不能完成这个任务, 那是 MySQL 的错, 这绝对不是首创)

但偶不明白二维索引的实现方式. 暂时继续抱怀疑态度.

复杂度分析对于研究算法来说是十分必要的.Point Query 的复杂度 O(logN/logB), 实际上就等于 O(logB(N)), 你是不是忘了换底公式了?关于插入的复杂度, 允许多个块写到一起(包括内存上的优化)是非常显然的优化. 但随机插入的场合如果不能减少 IO 的话可不行.Fractal Tree 索引的效率和内存的关系并不大, 但实现上看起来挺吃 CPU 的.仔细想来, Fractal Tree Index 大批量的插入均摊复杂度确实是 O(logN / B).

Tokutek 的收费政策是生产环境未压缩纯数据(不算索引) 50 GB 以下不收费,包括所有的副本(也就是说 Replication 的话就要算多次了), 当然也没有技术支持.

超过部分每 100 GB / 年收费 $1000 (换算一下是 $0.83 / GB * Month ).Tokutek 认为单台机器能承担 5 TB 的数据, 这个数字偶是要怀疑的. 而且偶不愿意承担单点的风险.显然可以谈个优惠价出来, 实际上偶愿意接受的价格不超过 $0.05 / GB * Month.这个收费比 GAE DataStore 和 Amazon SimpleDB 都贵太多了, 实在不合算. 有人还在想 Oracle 怎样怎样… 

换一个角度说, 如果你用 NoSQL 存数据, 用它当索引(注意别涉及删除问题), 偶想肯定不会超过 50 GB 的 这个引擎存文本虽然没问题, 可是偶肯定不会这样推荐的.

TokuDB 的下载页面提供了 Fractal Tree Library 的下载, 只有 x86_64 的版本.(需要注册, 随便填填就过了, 需要验证 E-Mail, 没有审核)解压出来有一个大号的 .so 文件, include 目录下有 tokudb.h. 实现还算是比较完整. 提供了测试的程序, 但有说要是作为嵌入式数据库的话需要获得许可.

其他:

http://openquery.com/blog/tokuteks-fractal-tree-indexes



延伸阅读:

http://en.wikipedia.org/wiki/Fractal_tree_index

http://www.slideshare.net/mongodb/20121024-mongodbboston



作者:heiyeshuwu 发表于2014-7-30 18:06:30 原文链接
阅读:41 评论:0 查看评论

判断股票强弱最有效的一个方法

$
0
0

        简单地说,

                 (1)大盘指数涨的时候,该股票涨得比大盘指数大,当大盘指数调整时,该股票指数调整得很少 。

                 (2)大盘指数一波一波下跌,但是该股票却跌不下去,没有跟谁指数下跌,往往这种时候,当大盘涨一点点的时候,该股票就会大涨。

                 (3)大盘连续大涨,而该股票却一直下跌,这种股票一定要及时清理,比如最近的600077宋都股份,大盘涨了6个多点,它还跌了6个多点。这种股票千万要不得。

               

作者:cancan8538 发表于2014-7-30 16:44:44 原文链接
阅读:185 评论:2 查看评论
Viewing all 15843 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>