一切福田,不離方寸,從心而覓,感無不通。

Category Archives: Backend

深入浅出Node.js(一):什么是Node.js

【编者按】:Node.js从2009年诞生至今,已经发展了两年有余,其成长的速度有目共睹。从在github的访问量超过Rails,到去年底Node.jsS创始人Ryan Dalh加盟Joyent获得企业资助,再到今年发布Windows移植版本,Node.js的前景获得了技术社区的肯定。InfoQ一直在关注Node.js的发展,在今年的两次Qcon大会(北京站和杭州站)都有专门的讲座。为了更好地促进Node.js在国内的技术推广,我们决定开设“深入浅出Node.js”专栏,邀请来自Node.js领域的布道师、开发人员、技术专家来讲述Node.js的各方面内容,让读者对Node.js有更深入的了解,并且能够积极投入到新技术的讨论和实践中。 专栏的第一篇文章《什么是Node.js》尝试从各个角度来阐述Node.js的基本概念、发展历史、优势等,对该领域不熟悉的开发人员可以通过本文了解Node.js的一些基础知识。 从名字说起 有关Node.js的技术报道越来越多,Node.js的写法也是五花八门,有写成NodeJS的,有写成Nodejs的,到底哪一种写法最标准呢,我们不妨遵循官方的说法。在Node.js的官方网站上,一直将其项目称之为”Node“或者”Node.js“,没有发现其他的说法,”Node“用的最多,考虑到Node这个单词的意思和用途太广泛,容易让开发人员误解,我们采用了第二种称呼——”Node.js“,js的后缀点出了Node项目的本意,其他的名称五花八门,没有确切的出处,我们不推荐使用。 Node.js不是JS应用、而是JS运行平台 看到Node.js这个名字,初学者可能会误以为这是一个Javascript应用,事实上,Node.js采用C++语言编写而成,是一个Javascript的运行环境。为什么采用C++语言呢?据Node.js创始人Ryan Dahl回忆,他最初希望采用Ruby来写Node.js,但是后来发现Ruby虚拟机的性能不能满足他的要求,后来他尝试采用V8引擎,所以选择了C++语言。既然不是Javascript应用,为何叫.js呢?因为Node.js是一个Javascript的运行环境。提到Javascript,大家首先想到的是日常使用的浏览器,现代浏览器包含了各种组件,包括渲染引擎、Javascript引擎等,其中Javascript引擎负责解释执行网页中的Javascript代码。作为Web前端最重要的语言之一,Javascript一直是前端工程师的专利。不过,Node.js是一个后端的Javascript运行环境(支持的系统包括*nux、Windows),这意味着你可以编写系统级或者服务器端的Javascript代码,交给Node.js来解释执行,简单的命令类似于:

Node.js采用了Google Chrome浏览器的V8引擎,性能很好,同时还提供了很多系统级的API,如文件操作、网络编程等。浏览器端的Javascript代码在运行时会受到各种安全性的限制,对客户系统的操作有限。相比之下,Node.js则是一个全面的后台运行时,为Javascript提供了其他语言能够实现的许多功能。 Node.js采用事件驱动、异步编程,为网络服务而设计 事件驱动这个词并不陌生,在某些传统语言的网络编程中,我们会用到回调函数,比如当socket资源达到某种状态时,注册的回调函数就会执行。Node.js的设计思想中以事件驱动为核心,它提供的绝大多数API都是基于事件的、异步的风格。以Net模块为例,其中的net.Socket对象就有以下事件:connect、data、end、timeout、drain、error、close等,使用Node.js的开发人员需要根据自己的业务逻辑注册相应的回调函数。这些回调函数都是异步执行的,这意味着虽然在代码结构中,这些函数看似是依次注册的,但是它们并不依赖于自身出现的顺序,而是等待相应的事件触发。事件驱动、异步编程的设计(感兴趣的读者可以查阅笔者的另一篇文章《Node.js的异步编程风格》),重要的优势在于,充分利用了系统资源,执行代码无须阻塞等待某种操作完成,有限的资源可以用于其他的任务。此类设计非常适合于后端的网络服务编程,Node.js的目标也在于此。在服务器开发中,并发的请求处理是个大问题,阻塞式的函数会导致资源浪费和时间延迟。通过事件注册、异步函数,开发人员可以提高资源的利用率,性能也会改善。 从Node.js提供的支持模块中,我们可以看到包括文件操作在内的许多函数都是异步执行的,这和传统语言存在区别,而且为了方便服务器开发,Node.js的网络模块特别多,包括HTTP、DNS、NET、UDP、HTTPS、TLS等,开发人员可以在此基础上快速构建Web服务器。以简单的helloworld.js为例:

上面的代码搭建了一个简单的http服务器(运行示例部署在http://helloworld.cnodejs.net/中,读者可以访问),在本地监听80端口,对于任意的http请求,服务器都返回一个头部状态码为200、Content-Type'值为text/plain'的”Hello World“文字响应。从这个小例子中,我们可以看出几点: Node.js的网络编程比较便利,提供的模块(在这里是http)开放了容易上手的API接口,短短几行代码就可以构建服务器。 体现了事件驱动、异步编程,在createServer函数的参数中指定了一个回调函数(采用Javascript的匿名函数实现),当有http请求发送过来时,Node.js就会调用该回调函数来处理请求并响应。当然,这个例子相对简单,没有太多的事件注册,在以后的文章中读者会看到更多的实际例子。 Node.js的特点 下面我们来说说Node.js的特点。事件驱动、异步编程的特点刚才已经详细说过了,这里不再重复。 Node.js的性能不错。按照创始人Ryan Dahl的说法,性能是Node.js考虑的重要因素,选择C++和V8而不是Ruby或者其他的虚拟机也是基于性能的目的。Node.js在设计上也是比较大胆,它以单进程、单线程模式运行(很吃惊,对吧?这和Javascript的运行方式一致),事件驱动机制是Node.js通过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文切换,这意味着面对大规模的http请求,Node.js凭借事件驱动搞定一切,习惯了传统语言的网络服务开发人员可能对多线程并发和协作非常熟悉,但是面对Node.js,我们需要接受和理解它的特点。由此我们是否可以推测出这样的设计会导致负载的压力集中在CPU(事件循环处理?)而不是内存(还记得Java虚拟机抛出OutOfMemory异常的日子吗?),眼见为实,不如来看看淘宝共享数据平台团队对Node.js的性能测试: 物理机配置:RHEL 5.2、CPU 2.2GHz、内存4G Node.js应用场景:MemCache代理,每次取100字节数据 连接池大小:50 并发用户数:100 测试结果(socket模式):内存(30M)、QPS(16700)、CPU(95%) 从上面的结果,我们可以看到在这样的测试场景下,qps能够达到16700次,内存仅占用30M(其中V8堆占用22M),CPU则达到95%,可能成为瓶颈。此外,还有不少实践者对Node.js做了性能分析,总的来说,它的性能让人信服,也是受欢迎的重要原因。既然Node.js采用单进程、单线程模式,那么在如今多核硬件流行的环境中,单核性能出色的Node.js如何利用多核CPU呢?创始人Ryan Dahl建议,运行多个Node.js进程,利用某些通信机制来协调各项任务。目前,已经有不少第三方的Node.js多进程支持模块发布,专栏后面的文章会详细讲述Node.js在多核CPU下的编程。 Node.js的另一个特点是它支持的编程语言是Javascript。关于动态语言和静态语言的优缺点比较在这里不再展开讨论。只说三点: Javascript作为前端工程师的主力语言,在技术社区中有相当的号召力。而且,随着Web技术的不断发展,特别是前端的重要性增加,不少前端工程师开始试水”后台应用“,在许多采用Node.js的企业中,工程师都表示因为习惯了Javascript,所以选择Node.js。 Javascript的匿名函数和闭包特性非常适合事件驱动、异步编程,从helloworld例子中我们可以看到回调函数采用了匿名函数的形式来实现,很方便。闭包的作用则更大,看下面的代码示例:

在上面的代码中,我们需要在end事件中处理responseHTML变量,由于Javascript的闭包特性,我们可以在两个回调函数之外定义responseHTML变量,然后在data事件对应的回调函数中不断修改其值,并最终在end事件中访问处理。 Javascript在动态语言中性能较好,有开发人员对Javacript、Python、Ruby等动态语言做了性能分析,发现Javascript的性能要好于其他语言,再加上V8引擎也是同类的佼佼者,所以Node.js的性能也受益其中。 Node.js发展简史 2009年2月,Ryan Dahl在博客上宣布准备基于V8创建一个轻量级的Web服务器并提供一套库。 2009年5月,Ryan Dahl在GitHub上发布了最初版本的部分Node.js包,随后几个月里,有人开始使用Node.js开发应用。 2009年11月和2010年4月,两届JSConf大会都安排了Node.js的讲座。 2010年年底,Node.js获得云计算服务商Joyent资助,创始人Ryan Dahl加入Joyent全职负责Node.js的发展。 2011年7月,Node.js在微软的支持下发布Windows版本。 Node.js应用案例 虽然Node.js诞生刚刚两年多,但是其发展势头逐渐赶超Ruby/Rails,我们在这里列举了部分企业应用Node.js的案例,听听来自客户的声音。 在社交网站LinkedIn最新发布的移动应用中,NodeJS是该移动应用的后台基础。LinkedIn移动开发主管Kiran Prasad对媒体表示,其整个移动软件平台都由NodeJS构建而成: LinkedIn内部使用了大量的技术,但是在移动服务器这一块,我们完全基于Node。 (使用它的原因)第一,是因为其灵活性。第二,如果你了解Node,就会发现它最擅长的事情是与其他服务通信。移动应用必须与我们的平台API和数据库交互。我们没有做太多数据分析。相比之前采用的Ruby on Rails技术,开发团队发现Node在性能方面提高很多。他们在每台物理机上跑了15个虚拟服务器(15个实例),其中4个实例即可处理双倍流量。容量评估基于负载测试的结果。 企业社会化服务网站Yammer则利用Node创建了针对其自身平台的跨域代理服务器,第三方的开发人员可以通过该服务器实现从自身域托管的Javascript代码与Yammer平台API的AJAX通信。Yammer平台技术主管Jim Patterson对Node的优点和缺点提出了自己的看法: (优点)因为Node是基于事件驱动和无阻塞的,所以非常适合处理并发请求,因此构建在Node上的代理服务器相比其他技术实现(如Ruby)的服务器表现要好得多。此外,与Node代理服务器交互的客户端代码是由javascript语言编写的,因此客户端和服务器端都用同一种语言编写,这是非常美妙的事情。 (缺点)Node是一个相对新的开源项目,所以不太稳定,它总是一直在变,而且缺少足够多的第三方库支持。看起来,就像是Ruby/Rails当年的样子。 知名项目托管网站GitHub也尝试了Node应用。该Node应用称为NodeLoad,是一个存档下载服务器(每当你下载某个存储分支的tarball或者zip文件时就会用到它)。GitHub之前的存档下载服务器采用Ruby编写。在旧系统中,下载存档的请求会创建一个Resque任务。该任务实际上在存档服务器上运行一个git archive命令,从某个文件服务器中取出数据。然后,初始的请求分配给你一个小型Ruby Sinatra应用等待该任务。它其实只是在检查memcache flag是否存在,然后再重定向到最终的下载地址上。旧系统运行大约3个Sinatra实例和3个Resque worker。GitHub的开发人员觉得这是Node应用的好机会。Node基于事件驱动,相比Ruby的阻塞模型,Node能够更好地处理git存档。在编写新下载服务器过程中,开发人员觉得Node非常适合该功能,此外,他们还里利用了Node库socket.io来监控下载状态。 不仅在国外,Node的优点也同样吸引了国内开发人员的注意,淘宝就实际应用了Node技术: MyFOX 是一个数据处理中间件,负责从一个MySQL集群中提取数据、计算并输出统计结果。用户提交一段SQL语句,MyFOX根据该SQL命令的语义,生成各个数据库分片所需要执行的查询语句,并发送至各个分片,再将结果进行汇总和计算。 MyFOX的特点是CPU密集,无文件IO,并只处理只读数据。起初MyFOX使用PHP编写,但遇到许多问题。例如PHP是单线程的,MySQL又需要阻塞查询,因此很难并发请求数据,后来的解决方案是使用nginx和dirzzle,并基于HTTP协议实现接口,并通过curl_multi_get命 令进行请求。不过MyFOX项目组最终还是决定使用Node.js来实现MyFOX。 选择Node.js有许多方面的原因,比如考虑了兴趣及社区发展,同时也希望可以提高并发能力,榨干CPU。例如,频繁地打开和关闭连接会让大量端口处于等待状态,当并发数量上去之后,时常会因为端口不够用(处于TIME_WAIT状态)而导致连接失败。之前往往是通过修改系统设置来减少等待时间以绕开这个错误,然而使用连接池便可以很好地解决这个问题。此外,以前MyFOX会在某些缓存失效的情况下出现十分密集的访问压力,使用 Node.js便可以共享查询状态,让某些请求“等待片刻”,以便系统重新填充缓存内容。 小结 本文简要介绍了Node.js的基本知识,包括概念、特点、历史、案例等等。作为一个仅仅2岁的平台,Node.js的发展势头有目共睹,越来越多的企业开始关注并尝试Node.js,前后端开发人员应该了解相关的内容。 参考文献 [1] http://nodejs.org/ [2] http://beakkon.com/geek/node.js/why-node.js-single-thread-event-loop-javascript [3] http://www.tbdata.org/archives/1285 [4] http://www.infoq.com/interviews/node-ryan-dahl [5] http://www.infoq.com/cn/news/2011/08/enterprise-nodejs [6] http://www.infoq.com/cn/news/2010/11/nodejs-joyent [7] http://www.infoq.com/cn/news/2011/06/node-exe […]

龙生   28 Jun 2013
View Details

win下node-mongodb-native操作mongodb

nodejs win下没有npm功能,应用各种库文件相当杯具,这里用了node-mongodb-native在win下操作mongodb,小D很菜,对nodejs各种不懂,勉强简单封装了个对mongodb的curd操作,,,, 首先去下载https://github.com/christkv/node-mongodb-native,把文件lib下的东西放到了如下目录 如何操作看他的文档吧,e文不行的估计看例子也能看个大概….下面是封装代码mghp.js

因为是异步的所以连续操作的话要放在回调函数中,方法还有第三个参数,如果是true则关闭链接 s.Insert({ "ID": "10001", "name": "ygm" }, function() { …. },true); 查看操作结果 转自:http://www.cnblogs.com/ygm125/archive/2011/09/02/2163532.html

龙生   28 Jun 2013
View Details

声明式编程和命令式编程的比较

先统一一下概念,我们有两种编程方式:命令式和声明式。 我们可以像下面这样定义它们之间的不同: 命令式编程:命令“机器”如何去做事情(how),这样不管你想要的是什么(what),它都会按照你的命令实现。 声明式编程:告诉“机器”你想要的是什么(what),让机器想出如何去做(how)。 声明式编程和命令式编程的代码例子 举个简单的例子,假设我们想让一个数组里的数值翻倍。 我们用命令式编程风格实现,像下面这样:

我们直接遍历整个数组,取出每个元素,乘以二,然后把翻倍后的值放入新数组,每次都要操作这个双倍数组,直到计算完所有元素。 而使用声明式编程方法,我们可以用 Array.map 函数,像下面这样:

map 利用当前的数组创建了一个新数组,新数组里的每个元素都是经过了传入map的函数(这里是function(n) { return n*2 })的处理。 map函数所作的事情是将直接遍历整个数组的过程归纳抽离出来,让我们专注于描述我们想要的是什么(what)。注意,我们传入map的是一个纯函数;它不具有任何副作用(不会改变外部状态),它只是接收一个数字,返回乘以二后的值。 在一些具有函数式编程特征的语言里,对于list数据类型的操作,还有一些其他常用的声明式的函数方法。例如,求一个list里所有值的和,命令式编程会这样做:

而在声明式编程方式里,我们使用 reduce 函数:

reduce 函数利用传入的函数把一个 list 运算成一个值。它以这个函数为参数,数组里的每个元素都要经过它的处理。每一次调用,第一个参数(这里是sum)都是这个函数处理前一个值时返回的结果,而第二个参数(n)就是当前元素。这样下来,每此处理的新元素都会合计到sum中,最终我们得到的是整个数组的和。 同样,reduce 函数归纳抽离了我们如何遍历数组和状态管理部分的实现,提供给我们一个通用的方式来把一个 list 合并成一个值。我们需要做的只是指明我们想要的是什么? 声明式编程很奇怪吗? 如果你之前没有听说过map 和 reduce 函数,你的第一感觉,我相信,就会是这样。作为程序员,我们非常习惯去指出事情应该如何运行。“去遍历这个list”,“if 这种情况 then 那样做”,“把这个新值赋给这个变量”。当我们已经知道了如何告诉机器该如何做事时,为什么我们需要去学习这种看起来有些怪异的归纳抽离出来的函数工具? 在很多情况中,命令式编程很好用。当我们写业务逻辑,我们通常必须要写命令式代码,没有可能在我们的专项业务里也存在一个可以归纳抽离的实现。 但是,如果我们花时间去学习(或发现)声明式的可以归纳抽离的部分,它们能为我们的编程带来巨大的便捷。首先,我可以少写代码,这就是通往成功的捷径。而且它们能让我们站在更高的层面是思考,站在云端思考我们想要的是什么,而不是站在泥里思考事情该如何去做。 声明式编程语言:SQL 也许你还不能明白,但有一个地方,你也许已经用到了声明式编程,那就是SQL。 你可以把SQL当做一个处理数据的声明式查询语言。完全用SQL写一个应用程序?这不可能。但如果是处理相互关联的数据集,它就显的无比强大了。 像下面这样的查询语句:

如果我们用命令式编程方式实现这段逻辑:

我可没说SQL是一种很容易懂的语言,也没说一眼就能把它们看明白,但基本上还是很整洁的。 SQL代码不仅很短,不不仅容易读懂,它还有更大的优势。因为我们归纳抽离了how,我们就可以专注于what,让数据库来帮我们优化how. 我们的命令式编程代码会运行的很慢,因为需要遍历所有 list 里的每个狗的主人。 而SQL例子里我们可以让数据库来处理how,来替我们去找我们想要的数据。如果需要用到索引(假设我们建了索引),数据库知道如何使用索引,这样性能又有了大的提升。如果在此不久之前它执行过相同的查询,它也许会从缓存里立即找到。通过放手how,让机器来做这些有难度的事,我们不需要掌握数据库原理就能轻松的完成任务。 声明式编程:d3.js 另外一个能体现出声明式编程的真正强大之处地方是用户界面、图形、动画编程。 开发用户界面是有难度的事。因为有用户交互,我们希望能创建漂亮的动态用户交互方式,通常我们会用到大量的状态声明和很多相同作用的代码,这些代码实际上是可以归纳提炼出来的。 d3.js 里面一个非常好的声明时归纳提炼的例子就是它的一个工具包,能够帮助我们使用JavaScript和SVG来开发交互的和动画的数据可视化模型。 第一次(或第5次,甚至第10次)你开发d3程序时可能会头大。跟SQL一样,d3是一种可视化数据操作的强大通用工具,它能提供你所有how方法,让你只需要说出你想要什么。 下面是一个例子(我建议你看一下这个演示)。这是一个d3可视化实现,它为data数组里的每个对象画一个圆。为了演示这个过程,我们每秒增加一个圆。 里面最有趣的一段代码是:

没有必要完全理解这段代码都干了什么(你需要一段时间去领会),但关键点是: 首先我们收集了svg里所有的圆,然后把data数组数据绑定到对象里。 D3 对每个圆都绑定了那些点数据有一个关系表。最初我们只有两个点,没有圆,我们使用.enter()方法获取数据点。这里,我们的意图是画一个圆,中心是x 和 y,初始值是 0 ,半秒后变换成半径为5。 为什么我说这很有意思? 从头再看一遍代码,想一想,我们是在声明我们想要的图案是什么样子,还是在说如何作图。你会发现这里根本没有关于how的代码。我们只是在一个相当高的层面描述我们想要的是什么: 我要画圆,圆心在data数据里,当增加新圆时,用动画表示半径的增加。 这太神奇了,我们没有写任何循环,这里没有状态管理。画图操作通常是很难写,很麻烦,很让人讨厌,但这里,d3归纳提取了一些常用的操作,让我们专注于描述我们想要的是什么。 现在再看,d3.js 很容易理解吗?不是,它绝对需要你花一段时间去学习。而学习的过程基本上需要你放弃去指明如何做事的习惯,而去学会如何描述我想要的是什么。 最初,这可能是很困难的事,但经过一些时间的学习后,一些神奇的事情发生了——你变得非常非常有效率了。通过归纳提取how,d3.js 能让你真正的专注说明你想要看到的是什么,让你在一个个更高的层面解决问题,解放你的创作力。 声明式编程的总结 声明式编程让我们去描述我们想要的是什么,让底层的软件/计算机/等去解决如何去实现它们。 在很多情况中,就像我们看到的一样,声明式编程能给我们的编程带来真正的提升,通过站在更高层面写代码,我们可以更多的专注于what,而这正是我们开发软件真正的目标。 问题是,程序员习惯了去描述how,这让我们感觉很好很舒服——强力——能够控制事情的发生发展,不放走任何我们不能看见不能理解的处理过程。 有时候这种紧盯着how不放的做法是没问题的。如果我需要对代码进行更高性能的优化,我需要对what进行更深一步的描述来指导how。有时候对于某个业务逻辑没有任何可以归纳提取的通用实现,我们只能写命令式编程代码。 但大多数时候,我们可以、而且应该寻求声明式的写代码方式,如果没有发现现成的归纳提取好的实现,我们应该自己去创建。起初这会很难,必定的,但就像我们使用SQL和D3.js, […]

龙生   27 Jun 2013
View Details

防SQL注入-初级方法

转自:http://www.oschina.net/code/snippet_875961_22517

龙生   27 Jun 2013
View Details

利用SQLServer的SA权限关闭TCP/IP筛选的方法

use master --创建一个临时用的表 create table dbo.ctest (txt varchar(4000)) --将VBS的内容写入刚才的表中 insert into ctest (txt) values('On Error Resume Next   strComputer = "."   Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")   Set colNicConfig = objWMIService.ExecQuery  ("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")     For Each objNicConfig in colNicConfig    If objNicConfig.IPFilterSecurityEnabled Then      intDisableReturn = objNicConfig.DisableIPSec      If intDisableReturn = 0 Then        ''WScript.Echo "ip过滤已禁用."      ElseIf intDisableReturn = 1 Then        ''WScript.Echo "ip过滤已禁用." &        VbCrLf […]

龙生   26 Jun 2013
View Details

存储过程:SET Transaction Isolation Level Read语法的四种情况

这几天一直在弄存储过程,现在在这里跟大伙共享下资料: SETTransactionIsolationLevelRead UNCOMMITTED 使用这句东东呢可以分为四种情况,现在就在这里逐一介绍: 第一种情况: READ   COMMITTED 这句的作用是: 指定在读取数据时控制共享锁以避免脏读,但数据可在事务结束前更改,从而产生不可重复读取或幻像数据。该选项是   SQL   Server   的默认值。 第二种情况: READ   UNCOMMITTED 这句的作用是: 执行脏读或0级隔离锁定,这表示不发出共享锁,也不接受排它锁。当设置该选项时,可以对数据执行未提交读或脏读;在事务结束前可以更改数据内的数值,行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置 NOLOCK 相同。这是四个隔离级别中限制最小的级别。 第三种情况: REPEATABLE   READ 这句的作用是: 锁定查询中使用的所有数据以防止其他用户更新数据,但是其他用户可以将新的幻像行插入数据集,且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别,所以应只在必要时才使用该选项。 第四种情况: SERIALIZABLE 这句的作用是: 在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有   SELECT   语句中的所有表上设置   HOLDLOCK   相同。 转自: http://www.cnblogs.com/qanholas/archive/2012/01/04/2312152.html

龙生   25 Jun 2013
View Details

NoSQL架构实践(三) 以NoSQL为缓存

在《NoSQL架构实践》系列的前面两篇文章中,介绍了《以NoSQL为主》和《以NoSQL为辅》的架构。由于NoSQL数据库天生具有高性能、易扩展的特点,所以我们常常结合关系数据库,存储一些高性能的、海量的数据。从另外一个角度看,根据NoSQL的高性能特点,它同样适合用于缓存数据。用NoSQL缓存数据可以分为内存模式和磁盘持久化模式。 内存模式 说起内存模式缓存,我们自然就会想起大名鼎鼎的Memcached。在互联网发展过程中,Memcached曾经解救了数据库的大部分压力,做出了巨大的贡献,直到今天,它依然是缓存服务器的首选。Memcached的常见使用方式类似下面的代码: Memcached提供了相当高的读写性能,一般情况下,都足够应付应用的性能要求。但是基于内存的Memcached缓存的总数据大小受限于内存的大小。 当前如日中天、讨论得异常火热的NoSQL数据库Redis又为我们提供了功能更加强大的内存存储功能。跟Memcached比,Redis的一个key的可以存储多种数据结构Strings、Hashes、Lists、Sets、Sorted sets。Redis不但功能强大,而且它的性能完全超越大名鼎鼎的Memcached。Redis支持List、hashes等多种数据结构的功能,提供了更加易于使用的api和操作性能,比如对缓存的list数据的修改。 同样,其他一些NoSQL数据库也提供了内存存储的功能,所以也适合用来做内存缓存。比如Tokyo Tyrant就提供了内存hash数据库、内存tree数据库功能,内存tree数据可根据key的顺序进行遍历。你可以通过使用其提供的兼容Memcached协议或自定义的协议来使用。 持久化模式 虽然基于内存的缓存服务器具有高性能,低延迟的特点,但是内存成本高、内存数据易失却不容忽视。几十GB内存的服务器,在很多公司看来,还比较奢侈。所以,我们应该根据应用的特点,尽量的提高内存的利用率,降低成本。 大部分互联网应用的特点都是数据访问有热点,也就是说,只有一部分数据是被频繁访问的。如果全部都cache到内存中,无疑是对内存的浪费。 这时,我们可以利用NoSQL来做数据的缓存。其实NoSQL数据库内部也是通过内存缓存来提高性能的,通过一些比较好的算法,把热点数据进行内存cache,非热点数据存储到磁盘以节省内存占用。由于其数据库结构的简单,从磁盘获取一次数 据也比从数据库一次耗时的查询划算很多。用NoSQL数据库做缓存服务器不但具有不错的性能。而且还能够Cache比内存大的数据。 使用NoSQL来做缓存,由于其不受内存大小的限制,我们可以把一些不常访问、不怎么更新的数据也缓存起来。比如论坛、新闻的老数据、数据列表的靠后的页面,虽然用户访问不多,但是搜索引擎爬虫会访问,也可能导致系统负载上升。 如果NoSQL持久化缓存也使用类似基于内存的memcached设置过期时间的方式,那么持久化缓存就失去了意义。所以用NoSQL做缓存的过期策略最好不使用时间过期,而是数据是否被更新过,如果数据没有更新,那么就永久不过期。下面我们用代码(php)演示一种实现这种策略的方法: 场景:新闻站点的评论系统。用户对新闻页面的url进行评论,然后根据url进行查询展示。 我把上面代码演示的缓存使用方式称为基于版本的缓存。这种方式同样适用于基于内存的Memcached。它能实现缓存数据的实时性,让用户感觉不到延迟。只要用户一发表评论,该新闻的评论缓存就会失效。用户很少去评论一些过时的新闻,那么缓存就一直存在于NoSQL中,避免了爬虫访问过时新闻的评论数据而冲击数据库。 总结 目前国内的新浪微博已经在大量的使用Redis缓存数据,赶集网也在大量的使用Redis。Redis作为一些List,Hashes等数据结构的缓存,非常适合。 把NoSQL当持久化Cache使用的模式,在很多大数据量、有热点、查询非热点数据比较消耗资源的场景下比较有用。 NoSQL架构实践总结 到这里,关于NoSQL架构实践的三篇文章就结束了。NoSQL架构并不局限于我介绍的三种模式,他们之间也可以进行组合,应该根据你具体的应用场景灵活使用。不管是什么模式,都是为了解决我们的问题而出现的,所以在系统架构的时候,要问下自己,我为什么要用NoSQL;在对NoSQL架构模式选型的时候,要问下自己,我为什么要这么用NoSQL。 原文链接:http://www.cnblogs.com/sunli/archive/2011/03/31/nosql-architecture-practice_3.html 转自:http://database.51cto.com/art/201103/252469.htm

龙生   25 Jun 2013
View Details

NoSQL架构实践(二)以NoSQL为主

前面一篇《NoSQL架构实践(一)以NoSQL为辅》主要介绍了以NoSQL为辅助的架构,这种架构实施起来比较简单,易于理解,由于其中也使用了传统的关系数据库,让开发者更容易控制NoSQL带来的风险。接下来我们继续深入下去,换另外一个角度,“以NoSQL为主”来架构系统。 (三)纯NoSQL架构 只使用NoSQL作为数据存储。 图 4-纯NoSQL架构 在一些数据结构、查询关系非常简单的系统中,我们可以只使用NoSQL即可以解决存储问题。这样不但可以提高性能,还非常易于扩展。手机凤凰网的前端展示系统就使用了这种方案。 在一些数据库结构经常变化,数据结构不定的系统中,就非常适合使用NoSQL来存储。比如监控系统中的监控信息的存储,可能每种类型的监控信息都不太一样。这样可以避免经常对MySQL进行表结构调整,增加字段带来的性能问题。 这种架构的缺点就是数据直接存储在NoSQL中,不能做关系数据库的复杂查询,如果由于需求变更,需要进行某些查询,可能无法满足,所以采用这种架构的时候需要确认未来是否会进行复杂关系查询以及如何应对。 非常幸运的是,有些NoSQL数据库已经具有部分关系数据库的关系查询特性,他们的功能介于key-value和关系数据库之间,却具有key-value数据库的性能,基本能满足绝大部分web 2.0网站的查询需求。比如: MongoDB就带有关系查询的功能,能解决常用的关系查询,所以也是一种非常不错的选择。下面是一些MongoDB的资料: ◆《视觉中国的NoSQL之路:从MySQL到MongoDB》◆《Choosing a non-relational database; why we migrated from MySQL to MongoDB》◆最近的一次Mongo Beijing 开发者聚会也有一部分资料。 虽然Foursquare使用MongoDB的宕机事件的出现使人对MongoDB的自动Shard提出了质疑,但是毫无疑问,MongoDB在NoSQL中,是一个优秀的数据库,其单机性能和功能确实是非常吸引人的。由于上面的例子有详细的介绍,本文就不做MongoDB的使用介绍。 Tokyo Tyrant数据库带有一个名为table的存储类型,可以对存储的数据进行关系查询和检索。一个table库类似于MySQL中的一个表。下面我们看一个小演示: 我们要存储一批用户信息,用户信息包含用户名(name),年龄(age),email,最后访问时间(lastvisit),地区(area)。下面为写入的演示代码:     $tt = new TokyoTyrantTable ( "127.0.0.1", 1978 );     $tt->vanish ();//清空     $id = $tt->genUid ();//获取一个自增id     //put方法提供数据写入。 put ( string $key , array $columns );     $tt->put ( $id, array ("id" => $id, "name" => "zhangsan", "age" => 27, "email" => "zhangsan@gmail.com", "lastvisit" =>strtotime ( "2011-3-5 12:30:00" ), "area" => "北京" ) ); […]

龙生   25 Jun 2013
View Details

NoSQL架构实践(一)以NoSQL为辅

经常有朋友遇到困惑,看到NoSQL的介绍,觉得很好,但是却不知道如何正式用到自己的项目中。很大的原因就是思维固定在MySQL中了,他们问得最多的问题就是用了NoSQL,我如何做关系查询。那么接下来,我们看下怎么样在我们的系统中使用NoSQL。 怎么样把NoSQL引入到我们的系统架构设计中,需要根据我们系统的业务场景来分析,什么样类型的数据适合存储在NoSQL数据库中,什么样类型的数据必须使用关系数据库存储。明确引入的NoSQL数据库带给系统的作用,它能解决什么问题,以及可能带来的新的问题。下面我们分析几种常见的NoSQL架构。 (一)NoSQL作为镜像 不改变原有的以MySQL作为存储的架构,使用NoSQL作为辅助镜像存储,用NoSQL的优势辅助提升性能。 图 1 -NoSQL为镜像(代码完成模式 ) //写入数据的示例伪代码   //data为我们要存储的数据对象   data.title=”title”;   data.name=”name”;   data.time=”2009-12-01 10:10:01”;   data.from=”1”;   id=DB.Insert(data);   //写入MySQL数据库   NoSQL.Add(id,data);   //以写入MySQL产生的自增id为主键写入NoSQL数据库 如果有数据一致性要求,可以像如下的方式使用 //写入数据的示例伪代码   //data为我们要存储的数据对象   bool status=false; DB.startTransaction();   //开始事务   id=DB.Insert(data);   //写入MySQL数据库   if(id>0){       status=NoSQL.Add(id,data);   //以写入MySQL产生的自增id为主键写入NoSQL数据库   }   if(id>0 && status==true){       DB.commit();   //提交事务   }else{       DB.rollback();   //不成功,进行回滚   } 上面的代码看起来可能觉得有点麻烦,但是只需要在DB类或者ORM层做一个统一的封装,就能实现重用了,其他代码都不用做任何的修改。 这种架构在原有基于MySQL数据库的架构上增加了一层辅助的NoSQL存储,代码量不大,技术难度小,却在可扩展性和性能上起到了非常大的作用。只需要程序在写入MySQL数据库后,同时写入到NoSQL数据库,让MySQL和NoSQL拥有相同的镜像数据,在某些可以根据主键查询的地方,使用高效的NoSQL数据库查询,这样就节省了MySQL的查询,用NoSQL的高性能来抵挡这些查询。 图 2 -NoSQL为镜像(同步模式) 这种不通过程序代码,而是通过MySQL把数据同步到NoSQL中,这种模式是上面一种的变体,是一种对写入透明但是具有更高技术难度一种模式。这种模式适用于现有的比较复杂的老系统,通过修改代码不易实现,可能引起新的问题。同时也适用于需要把数据同步到多种类型的存储中。 MySQL到NoSQL同步的实现可以使用MySQL UDF函数,MySQL binlog的解析来实现。可以利用现有的开源项目来实现,比如: ◆MySQL memcached UDFs:从通过UDF操作Memcached协议。◆国内张宴开源的mysql-udf-http:通过UDF操作http协议。 有了这两个MySQL UDF函数库,我们就能通过MySQL透明的处理Memcached或者Http协议,这样只要有兼容Memcached或者Http协议的NoSQL数据库,那么我们就能通过MySQL去操作以进行同步数据。再结合lib_mysqludf_json,通过UDF和MySQL触发器功能的结合,就可以实现数据的自动同步。 (二)MySQL和NoSQL组合 MySQL中只存储需要查询的小字段,NoSQL存储所有数据。 […]

龙生   25 Jun 2013
View Details

“大数据”与“海量数据”有哪些区别?

很多年前,业界就在讨论一个话题:如何应对海量数据?特别是一些需要存储大量用户数据的行业,金融、电信、保险等热门行业。用户几乎在一天的每个小时,都有可能产生大量数据,这些行业的存储设备,必须要将期间产生的数据一丝不苟地记录下来。随着数据量的迅速增加,很多行业用户开始想办法变“数”为宝,从海量数据中挖掘有价值的信息。 如果仅仅是海量的结构性数据,那么解决的办法就比较的单一,用户通过购买更多的存储设备,提高存储设备的效率等解决此类问题。然而,当人们发现数据库中的数据可以分为三种类型:结构性数据、非结构性数据以及半结构性数据等复杂情况时,问题似乎就没有那么简单了。 大数据汹涌来袭 当类型复杂的数据汹涌袭来,那么对于用户IT系统的冲击又会是另外一种处理方式。很多业内专家和第三方调查机构通过一些市场调查数据发现,大数据时代即将到来。有调查发现,这些复杂数据中有85%的数据属于广泛存在于社交网络、物联网、电子商务等之中的非结构化数据。这些非结构化数据的产生往往伴随着社交网络、移动计算和传感器等新的渠道和技术的不断涌现和应用。 如今大数据的概念也存在着很多的炒作和大量的不确定性。为此,编者详细向一些业内专家详细了解有关方面的问题,请他们谈一谈,大数据是什么和不是什么,以及如何应对大数据等问题,将系列文章的形式与网友见面。 有人将多TB数据集也称作"大数据"。据市场研究公司IDC统计,数据使用预计将增长44倍,全球数据使用量将达到大约35.2ZB(1ZB = 10亿TB)。然而,单个数据集的文件尺寸也将增加,导致对更大处理能力的需求以便分析和理解这些数据集。 EMC曾经表示,它的1000多个客户在其阵列中使用1PB(千兆兆)以上的数据数据,这个数字到2020年将增长到10万。一些客户在一两年内还将开始使用数千倍多的数据,1EB(1艾字节 = 10亿GB)或者更多的数据。 对大企业而言,大数据的兴起部分是因为计算能力可用更低的成本获得,且各类系统如今已能够执行多任务处理。其次,内存的成本也在直线下降,企业可以在内存中处理比以往更多的数据,另外是把计算机聚合成服务器集群越来越简单。IDC认为,这三大因素的结合便催生了大数据。同时,IDC还表示,某项技术要想成为大数据技术,首先必须是成本可承受的,其次是必须满足IBM所描述的三个"V"判据中的两个:多样性(variety)、体量(volume)和速度(velocity)。 多样性是指,数据应包含结构化的和非结构化的数据。 体量是指聚合在一起供分析的数据量必须是非常庞大的。 而速度则是指数据处理的速度必须很快。 大数据"并非总是说有数百个TB才算得上。根据实际使用情况,有时候数百个GB的数据也可称为大数据,这主要要看它的第三个维度,也就是速度或者时间维度。 Garter表示,全球信息量正在以59%以上的年增长率增长,而量是在管理数据、业务方面的显著挑战,IT领袖必须侧重在信息量、种类和速度上。 量:企业系统内部的数据量的增加是由交易量、其它传统数据类型和新的数据类型引发的。过多的量是一个存储的问题,但过多的数据也是一个大量分析的问题。 种类:IT领袖在将大量的交易信息转化为决策上一直存在困扰 – 现在有更多类型的信息需要分析 – 主要来自社交媒体和移动(情景感知)。种类包括表格数据(数据库)、分层数据、文件、电子邮件、计量数据、视频、静态图像、音频、股票行情数据、金融交易和其它更多种类。 速度:这涉及到数据流、结构化记录的创建,以及访问和交付的可用性。速度意味着正在被生成的数据有多快和数据必须被多快地处理以满足需求。 虽然大数据是一个重大问题,Gartner分析师表示,真正的问题是让大数据更有意义,在大数据里面寻找模式帮助组织机构做出更好的商业决策。 诸子百家谈如何定义"大数据" 尽管"Big Data"可以翻译成大数据或者海量数据,但大数据和海量数据是有区别的。 定义一:大数据 = 海量数据 + 复杂类型的数据 Informatica中国区首席产品顾问但彬认为:"大数据"包含了"海量数据"的含义,而且在内容上超越了海量数据,简而言之,"大数据"是"海量数据"+复杂类型的数据。 但彬进一步指出:大数据包括交易和交互数据集在内的所有数据集,其规模或复杂程度超出了常用技术按照合理的成本和时限捕捉、管理及处理这些数据集的能力。 大数据是由三项主要技术趋势汇聚组成: 海量交易数据:在从 ERP应用程序到数据仓库应用程序的在线交易处理(OLTP)与分析系统中,传统的关系数据以及非结构化和半结构化信息仍在继续增长。随着企业将更多的数据和业务流程移向公共和私有云,这一局面变得更加复杂。 海量交互数据:这一新生力量由源于 Facebook、Twitter、LinkedIn 及其它来源的社交媒体数据构成。它包括了呼叫详细记录(CDR)、设备和传感器信息、GPS 和地理定位映射数据、通过管理文件传输(Manage File Transfer)协议传送的海量图像文件、Web 文本和点击流数据、科学信息、电子邮件等等。 海量数据处理:大数据的涌现已经催生出了设计用于数据密集型处理的架构,例如具有开放源码、在商品硬件群中运行的 Apache Hadoop。对于企业来说,难题在于以具备成本效益的方式快速可靠地从 Hadoop 中存取数据。 定义二:大数据包括A、B、C三个要素 如何理解大数据?NetApp 大中华区总经理陈文认为,大数据意味着通过更快获取信息来使做事情的方式变得与众不同,并因此实现突破。大数据被定义为大量数据(通常是非结构化的),它要求我们重新思考如何存储、管理和恢复数据。那么,多大才算大呢?考虑这个问题的一种方式就是,它是如此之大,以至于我们今天所使用的任何工具都无法处理它,因此,如何消化数据并把它转化成有价值的洞见和信息,这其中的关键就是转变。 基于从客户那里了解的工作负载要求, NetApp所理解的大数据包括A、B、C三个要素:分析(Analytic),带宽(Bandwidth)和内容(Content)。 1. 大分析(Big Analytics),帮助获得洞见 – 指的是对巨大数据集进行实时分析的要求,它能带来新的业务模式,更好的客户服务,并实现更好的结果。 2. 高带宽(Big Bandwidth),帮助走得更快 – 指的是处理极端高速的关键数据的要求。它支持快速有效地消化和处理大型数据集。 3. 大内容(Big Content),不丢失任何信息- 指的是对于安全性要求极高的高可扩展的数据存储,并能够轻松实现恢复。它支持可管理的信息内容存储库、而不只是存放过久的数据,并且能够跨越不同的大陆板块。 大数据是一股突破性的经济和技术力量,它为 IT 支持引入了新的基础架构。大数据解决方案消除了传统的计算和存储的局限。借助于不断增长的私密和公开数据,一种划时代的新商业模式正在兴起,它有望为大数据客户带来新的实质性的收入增长点以及富于竞争力的优势。 转自:http://server.51cto.com/sCollege-300607_1.htm

龙生   25 Jun 2013
View Details
1 244 245 246 282