关于大型网站技术演进的思考(六)–存储的瓶颈(6)

在讲数据库水平拆分时候,我列出了水平拆分数据库需要解决的两个难题,它们分别是主键的设计问题和单表查询的问题,主键问题前文已经做了比较详细的讲述了,但是第二个问题我没有讲述,今天我将会讲讲如何解决数据表被垂直拆分后的单表查询问题。   要解决数据表被水平拆分后的单表查询问题,我们首先要回到问题的源头,我们为什么需要将数据库的表进行水平拆分。下面我们来推导下我们最终下定决心做水平拆分表的演进过程,具体如下:     第一个演进过程:进行了读写分离的表在数据增长后需要进行水平拆分吗?回答这个疑问我们首先要想想进行读写分离操作的表真的是因为数据量大吗?答案其实是否定的。最基本的读写分离的目的是为了解决数据库的某张表读写比率严重失衡的问题, 举个例子,有一张表每天会增加1万条数据,也就是说我们的系统每天会向这张表做1万次写的操作,当然也有可能我们还会更新或者删除这张表的某些已有的记 录,这些操作我们把它归并到写操作,那么这张表一天我们随意定义个估值吧2万5千次写操作,其实这种表的数据量并不大,一年下来也就新增的几百万条数据, 一个大型的商业级别的关系数据库,当我们为表建立好索引和分区后,查询几百万条数据它的效率并不低,这么说来查询的效率问题还不一定是读写分离的源头。其 实啊,这张表除了写操作每天还承受的读操作可能会是10万,20万甚至更高,这个时候问题来了,像oracle和mysql这样鼎鼎大名的关系数据库默认 的最大连接数是100,一般上了生产环境我们可能会设置为150或者200,这些连接数已经到了这些关系数据库的最大极限了,如果再加以提升,数据库性能 会严重下降,最终很有可能导致数据库由于压力过大而变成了一个巨锁,最终导致系统发生503的错误,如是我们就会想到采用读写分离方案,将数据库的读操作 迁移到专门的读库里,如果系统的负载指标和我列举的例子相仿,那么迁移的读库甚至不用做什么垂直拆分就能满足实际的业务需求,因为我们的目的只是为了减轻 数据库的连接压力。     第二个演进过程: 随着公司业务的不断增长,系统的运行的压力也越来越大了,我们已经了解了系统的第一个瓶颈是从存储开始了,如是我们开始谈论方案如何解决存储的问题,这时 我们发现我们已经做了读写分离,也使用了缓存,甚至连搜索技术也用上了,那么下个阶段就是垂直拆分了,垂直拆分很简单就是把表从数据库里拆出来,单独建库 建表,但是这种直截了当的方案想想就能感到这样的做法似乎没有打中系统的痛点,那么系统的痛点到底是什么呢?根据数据库本身的特性,我们会发现痛点主要是… Read More

关于大型网站技术演进的思考(七)–存储的瓶颈(7)

本文开篇提个问题给大家,关系数据库的瓶颈有哪些?我想有些朋友看到这个问题肯定会说出自己平时开发中碰到了一个跟数据库有关的什么什么问题,然后如何 解决的等等,这样的答案没问题,但是却没有代表性,如果出现了一个新的存储瓶颈问题,你在那个场景的处理经验可以套用在这个新问题上吗?这个真的很难说。   其实不管什么样的问题场景最后解决它都要落实到数据库的话,那么这个问题场景一定是击中了数据库的某个痛点,那么我前面的六篇文章里那些手段到底是在解决数据库的那些痛点,下面我总结下,具体如下:      痛点一:数据库的连接数不够用了。换句话说就是在同一个时间内,要求和数据库建立连接的请求超出了数据库所允许的最大连接数,如果我们对超出的连接数没 有进行有效的控制让它们直接落到了数据库上,那么就有可能会让数据库不堪重负,那么我们就得要分散这些连接,或者让请求排队。      痛点二:对于数据库表的操作无非两种一种是写操作,一种是读操作,在现实场景下很难出现读写都成问题的事情,往往是其中一种表的操作出现了瓶颈问题所引 起的,由于读和写都是操作同一个介质,这就导致如果我们不对介质进行拆分去单独解决读的问题或者写的问题会让问题变的复杂化,最后很难从根本上解决问题。      痛点三:实时计算和海量数据的矛盾。本系列讲存储瓶颈问题其实有一个范畴的,那就是本系列讲到的手段都是在使用关系数据库来完成实时计算的业务场景,而 现实中,数据库里表的数据都会随着时间推移而不断增长,当表的数据超出了一定规模后,受制于计算机硬盘、内存以及CPU本身的能力,我们很难完成对这些数据的实时处理,因此我们就必须要采取新的手段解决这些问题。   我今天之所以总结下这三个痛点,主要是为了告诉大家当我们面对存储瓶颈问题时候,我们要把问题最终落实到这个问题到底是因为触碰到了数据库的那些痛点,这样回过头来再看我前面说到的技术手段,我就会知道该用什么手段来解决问题了。   好了,多余的话就说到这里,下面开始本篇的主要内容了。首先给大伙看一张有趣的漫画,如下图所示: 身为程序… Read More

关于大型网站技术演进的思考(八)–存储的瓶颈终篇(8)

在开始本篇主要内容前,我们一起看看下面的几张截图,首先是第一张图,如下图所示: 这是一家电商网站的首页,当我们第一次打开这个首页,网站会弹出一个强制性的对话框,让用户选择货物配送的地址,如果是淘宝和京东的话,那么这个选择配货地址的选项是在商品里,如下图是淘宝的选择配送地点: 下图是京东选择配货地点: 那么图一 跟京东和淘宝有什么区别呢?图一的电商强制用户选择地区后,那么我们在查询这个商品时候会因为地区不同,显示的查询结果会不一样,这个就和网站做国际化有 点像,不过网站国际化是切语言和语言相关的静态资源,但是电商这个地域的选择是和业务相关的,不同的地域查询结果是不相同的,这个选择地域的弹出框很像一 个路由器。相比之下,淘宝和京东把商品的配送和商品相关,那么我们在这些网站里查询商品时候,其实是按照全国查询的,全国不同的地方查询同一个条件所获得 到的结果是一致的。从业务角度而言,这说明第一个电商的业务没有全国铺开,就算是铺开了,地域的差异也影响到物流的问题,而淘宝和京东则正是一个全国意义 的大型电商网站了。   回到技术的角度,这两种不同的做法有没有可能还和技术问题有关了?今天我就来探讨下这个问题。   不管网站 大与小,一个网站肯定可以分为客户端、服务端和存储端,勾连这不同的组成部分是网络,网络是一种通讯设施,距离的远近会直接影响到网络传输的效率问题,如 是乎就出现了像CDN这样的技术,很多大型互联网公司还会在不同的城市建立机房,这些手段的目的就是在解决距离对网络传输效率的影响,但是当这种就近解决 问题的方案落到存储层的时候,问题就来了。上篇里我说道web服务的水平扩展问题,这种水平扩展是基于一种无状态性的原理设计的,但是到了存储层我们不管 怎么拆分它,它都很难消除状态的问题,也就是存储层有状态性是它的天然属性。特别是碰到一个竞争性的存储资源时候,这种状态性会变得非常顽固,例如商品的 库存问题,如果我们把库存数据对等的平移到不同地域的数据中心,那么如何保证不同地方的库存信息总是准确的,这就成为了难题。这种问题放在一个小国家不是… Read More

jQuery实现的测试答题功能

有时在网页中要加入一个在线测试功能,例如在线调查,在线测试各类知识等应用,这类应用需要用到很多前后端技能。今天我给大家分享一个基于jQuery的前端应用——测试答题功能。 查看演示 下载源码 HTML 首先载入jquery库文件和quiz.js以及所需的CSS样式文件styles.css。 <script src="jquery.js"></script> <script src="quiz.js"></script> <link rel="stylesheet" href="styles.css" /> 然后在需要放置测试题的位置加入div#quiz-container。 <div id="quiz-container"></div> jQuery 首先,我们定义题目和答案选项,question是题目,answers是答案选项,correctAnswer是正确答案。可以看出定义的init是一个json数据格式。… Read More

HTML5获取地理位置定位信息

HTML5提供了地理位置定位功能(Geolocation API),能确定用户位置,我们可以借助HTML5的该特性开发基于地理位置信息的应用。本文结合实例给大家分享如何使用HTML5,借助百度、谷歌地图接口来获取用户准确的地理位置信息。 查看演示 下载源码 如何使用HTML5地理位置定位功能 定位功能(Geolocation)是HTML5的新特性,因此只有在支持HTML5的现代浏览器上运行,特别是手持设备如iphone,地理定位 更加精确。首先我们要检测用户设备浏览器是否支持地理定位,如果支持则获取地理信息。注意这个特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是 不可用的,所以我们在访问该应用时会提示是否允许地理定位,我们当然选择允许即可。 function getLocation(){ if (navigator.geolocation){ navigator.geolocation.getCurrentPosition(showPosition,showError); }else{ alert("浏览器不支持地理定位。"); } } 上面的代码可以知道,如果用户设备支持地理定位,则运行… Read More

PHP+jQuery+MySql实现红蓝投票功能

这是一个非常实用的投票实例,应用在双方观点对抗投票场景。用户可以选择支持代表自己观点的一方进行投票,本文以红蓝双方投票为例,通过前后台交互,直观展示红蓝双方投票数和所占比例,应用非常广泛。 查看演示 下载源码 本文是一篇综合知识应用类文章,需要您具备PHP、jQuery、MySQL以及html和css方面的基本知识。本文在《PHP+MySql+jQuery实现的“顶”和“踩”投票功能》一文基础上做了适当改进,共用了数据表,您可以先点击了解这篇文章。 HTML 我们需要在页面中展示红蓝双方的观点,以及对应的投票数和比例,以及用于投票交互的手型图片,本例以#red和#blue分别表示红蓝双 方。.redhand和.bluehand用来做手型投票按钮,.redbar和.bluebar展示红蓝双方比例调,#red_num 和#blue_num展示双方投票数。 <div class="vote"> <div class="votetitle">您对Helloweba提供的文章的看法?</div> <div class="votetxt">非常实用<span>完全看不懂</span></div> <div class="red" id="red"> <div… Read More

HTML5 Geolocation API : 实时跟踪应用

getCurrentPosition与watchPosition   watchPosition会监视你的移动,并在位置改变时向你报告位置。watchPPosition方法看上去确实与getCurrentPosition方法很像,不过行为稍有不同,每次位置比阿奴啊时会重复调用你的成功处理程序 watchPosition调用步骤: 你的应用watchPosition,传入一个成功处理函数 watchPosition在后台不断监视你的位置 你的位置改变时,watchPostion调用成功处理函数来报告你的新位置 watchPostion继续监视你的位置(并向成功处理程序报告),直至你调用clearWatch将它清除   HTML代码   我们已HTML5COL学院中级课程相关章节的课程为基础,再向HTML增加几个按钮,从而能开始和结束跟踪你的位置;我们设置开始按钮是因为用户不想一直被跟踪,他们通常希望对此有些控制;设置结束按钮,是考虑到对于移动设备来说,不停检查用户的位置是一个相当耗费电的操作,如果一直打开跟踪,会严重影响电池寿命: 注: 实时跟踪用户可能非常耗电。一定要为用户提供信息,指出日前正在跟踪,另外还要提供相应的一些控件 <!DOCTYPE html> <html> <head>… Read More

HTML5 Geolocation API应用:计算两地距离

找出HTML5COL学院的位置   在HTML5COL学院的前面几个章节中我们已经对HTML5 Geolocation API有了一定认识,接下来我们要对位置做些更有意思的处理;看看你与我们HTML5COL学院的办公室秘密位置相距多远。为此我们需要HTML5COL学院的坐标,而且需要知道如何计算两个坐标之间的距离。   增加一个<div>   首先,在HTML中增加一个 <div>: <!DOCTYPE html> <html> <head> <meta='keywords' content='HTML5COL学院,HTML5COL,CSS3,HTML5COL,编码社区'> </head> <body>… Read More

利用行动装置GPS定位寻找临近地点

早先已展示过,在网页内嵌Google地图、将地址转换为经纬度座标、在地图上显示自订地标图示等技巧,最后来个综合应用当作期末考。本次的练习题是”依使用者所在位置,找出距离最近的五个台北市消防分队”。 简单整理值得留意的技术细节: 在网页嵌入Google地图并放上自订标示点(Marker)的做法,可参考笔记-网页内嵌Google地图与地理位置模拟一文。 由市政府网站取得台北市消防分队地址,透过地理编码算出经纬度座标,可参考Google Maps API地址转换一文。而在本次范例中,我们预先将查到的经纬度数字一并写入CSV档中,不必每次重新查询。 要计算两个经纬度座标间的直线距离,Haversine公式是最常用的演算法,简单来说,就是把地球当成一个圆球,用球体表面任两点到圆心所形成的夹角,加上一堆Sin , Cos推算沿球体表面连接两点的弧线长度。依据英国学者研究指出,思考过度复杂数学公式可能会对中老年人的神经中枢有负面影响,为求养生保健,在此直接引用公式,对于数学细节就不再深究… HTML5世代的浏览器(IE要IE9+)多能支援地理资讯功能,可整合行动装置(手机、平版)的GPS取得使用者当时所在地理位置(存取前会弹出确认视窗征求使用者同意),如此我们便可依使用者所在位置提供不同资讯,例如:列出临近的商店、餐厅或服务据点…等等。要透过Javascript存取使用者的地理资讯,可使用Geolocation API。 使用者所在位置及各消防分队的经纬度都有了,便可利用Haversine公式算出各分队与目前位置的直线距离作为远近参考。(不考虑路线规划、交通状况等因素,那是导航软体或霹雳车RD该烦恼的事,为了好玩写程式没必要把自己逼上绝路XD至于有心挑战的朋友,Google Maps也有路线规划API,倒是可以参考) Javascript的Array.sort(compareFunction),提供了类似LINQ OrderBy(o => o.prop)的简便做法,让我惊喜了一下。原本以为要花点心思处理,没想到只用两行就搞定依距离远近排序的需求。 前篇文章介绍的动态文字图档权充Marker… Read More

利用HTML5 Canvas动态产生文字图示

前几篇Google Map API文章,一直有用到Google地图加上Marker的做法。(即下图的红色大头针图案) 不过,若全部的标示点用一样的图示,会显得无趣且容易混淆(如下图所示),虽然将滑鼠移到标示图案上方会显示名称,在使用者体验上总觉得还有改善空间。 事实上,Google Maps API在新增地标时,是可以自订图示的。MarkerOptions提供icon参数可指定图档URL,另外有shadow参点可指定阴影图档的URL,以取代预设的黑点红色大头针图示。 只是有个小问题,在消防分队位置显示范例中,台北市共有44个消防分队,即使能自订图示,可能也只是用44台消防车换掉44根大头针,对于识别度并没有太多提升,除非我们能预先制作44个刻有消防分队名称的图档,再一一对应到44个Marker使用… 身为程式魔人,44个图档用手工做是不被允许的,当然要自动产生才不会被人耻笑。我第一个想到是用ASP.NET动态产生图档的技巧,不过再转念一想,何不用HTML5的Canvas来实做,完全在Client解决? (IE6/7/8:那我们怎么办?念你们曾纵横江湖多年,也算时代英雄,你们自尽吧!) HTML5 Canvas要即时产生图档不是问题,再配合Canvas.toDataURL()就可取代图档案URL,作为MarkerOptions.icon参数的设定值,就能达到当场动态产生Marker图示的目的。 我试写了一个小函数,用Canvas作图,再用toDataURL()输出作为<img>的src来源: <!DOCTYPE html> <html> <head runat="server">… Read More

Google Maps API地址转换

将地址转换成地理座标的程序被称为地理编码 (Geocoding),Google Maps API亦支援地理编码服务(注意:有每天查询次数不可超过2,500次的限制,申请Google Maps API Premier可以提高到100,000次) ,呼叫方法很简单,使用URL “http: //maps.googleapis.com/maps/api/geocode/json?address=要转换的地址&sensor=ture或false”,便可得到一份JSON格式的地址座标资讯,address参数除了完整地址,也可以输入一般性地名或片段地址,另外也能指定传回XML格式、使用语系、检视范围(优先列出该范围内符合结果,最经典的例子是在台湾查询”中正路”、”中山路”之类的菜市场路名,要指定县市范围才能找对目标)…等等,完整参数说明可参见API文件。 先用浏览器来个简单测试,在网址输入http://maps.googleapis.com/maps/api/geocode/json?address=%E5%8F%B0%E5%8C%97%E5%B7%BF %E5%85%89%E5%BE%A9%E5%8D%97%E8%B7%AF100%E8%99%9F&sensor=false (地址中文部分经encodeURI()编码),会得到以下结果: { "results" : [ {… Read More

笔记-网页内嵌Google地图与地理位置模拟

终于有机会开始玩HTML5中行动装置GPS整合应用。 我的第一步是希望能在网页整合Google地图,即便实际需求不一定需要显示地图,但在开发测试阶段,要求开发人员直接由25.1234, 121.5678之类数字判断结果是否正确未免太不人道,因此用地图方式呈现特定经纬度资料是绝对必要的。第一个练习题就来试试在网页中显示特定经纬度的地图吧! Google地图Javascript API已经发展到了V3,整合应用起来相当方便省事,而官方的说明文件写得颇为详细(甚至有中文),要上手一点也不困难。以下便是我写的超简单的入门范例,试着在网页显示以政大校园八角亭为中心的地图。(八角亭是我每次猫空LSD的起点,经纬度数据在心跳表中唾手可得) <!DOCTYPE html>   <html> <head runat="server"> <title>內嵌Google地圖</title> <script src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.js'></script> <script src="https://maps.google.com/maps/api/js?sensor=false"></script> <meta name="viewport" content="initial-scale=1.0,… Read More

利用HTML5中Geolocation获取地理位置在Google Map上定位

本小菜刚开始学习HTML5,现在对其中的Geolocation颇感兴趣,结合Google Map的API实现基本的地图定位功能。 1.获取当前地理位置 调用方法 void getCurrentPosition(onSuccess, onError, options);即可。 其中onSuccess是获取当前位置信息成功时执行的回调函数,onError是获取当前位置信息失败时所执行的回调函数,options是一些可选熟悉列表。其中第二和第三个参数为可选属性。 在onSuccess回调函数中,用到了参数position,代表一个具体的position对象,表示当前位置。其具有如下属性: latitude:当前地理位置的纬度。 longitude:当前地理位置的经度。 altitude:当前位置的海拔高度(不能获取时为null)。 accuracy:获取到的纬度和经度的精度(以米为单位)。 altitudeAccurancy:获取到的海拔高度的经度(以米为单位)。 heading:设备的前进方向。用面朝正被方向的顺时针旋转角度来表示(不能获取时为null)。 speed:设备的前进速度(以米/秒为单位,不能获取时为null)。 timestamp:获取地理位置信息时的时间。… Read More